From 226c4193197442b9a1a462f75377023f6d501290 Mon Sep 17 00:00:00 2001 From: akhilkedia94 Date: Fri, 29 Jul 2016 16:53:35 +0900 Subject: [PATCH] Face Down Gesture Sensor Detects the face down gesture defined as - The phone being face up (<20 degrees from screen pointing vertically upwards) and then face down (<20 degrees from vertically downwards) in 2 second. Change-Id: I8045109a3266baaa11ab0316e07857474a5b1e8b Signed-off-by: akhilkedia94 --- src/sensor/CMakeLists.txt | 6 + src/sensor/gesture/face_down_alg.h | 32 +++++ src/sensor/gesture/face_down_alg_impl.cpp | 88 ++++++++++++ src/sensor/gesture/face_down_alg_impl.h | 44 ++++++ src/sensor/gesture/face_down_sensor.cpp | 204 +++++++++++++++++++++++++++ src/sensor/gesture/face_down_sensor.h | 66 +++++++++ src/server/sensor_loader.cpp | 6 + src/shared/sensor_deprecated.h | 6 +- src/shared/sensor_types.h | 1 + src/test/src/api-test.c | 3 + src/test/src/check-sensor.c | 10 ++ src/test/src/multi-thread-performance-test.c | 1 + src/test/src/sensor-test.c | 5 + 13 files changed, 471 insertions(+), 1 deletion(-) create mode 100644 src/sensor/gesture/face_down_alg.h create mode 100644 src/sensor/gesture/face_down_alg_impl.cpp create mode 100644 src/sensor/gesture/face_down_alg_impl.h create mode 100644 src/sensor/gesture/face_down_sensor.cpp create mode 100644 src/sensor/gesture/face_down_sensor.h diff --git a/src/sensor/CMakeLists.txt b/src/sensor/CMakeLists.txt index 3cbd1a7..33c3fe0 100644 --- a/src/sensor/CMakeLists.txt +++ b/src/sensor/CMakeLists.txt @@ -15,6 +15,7 @@ SET(RV "OFF") SET(ORIENTATION "OFF") ENDIF() SET(MOTION "OFF") +SET(FACE_DOWN "ON") INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/shared @@ -63,6 +64,11 @@ IF("${RV}" STREQUAL "ON") SET(SENSOR_DEFINITIONS ${SENSOR_DEFINITIONS} "-DENABLE_ROTATION_VECTOR") FILE(GLOB SENSOR_SRCS ${SENSOR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/rotation_vector/fusion_utils/*.cpp) ENDIF() +IF("${FACE_DOWN}" STREQUAL "ON") + FILE(GLOB_RECURSE SENSOR_SRCS ${SENSOR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/gesture/*.cpp) + SET(SENSOR_HEADERS ${SENSOR_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/gesture) + SET(SENSOR_DEFINITIONS ${SENSOR_DEFINITIONS} "-DENABLE_FACE_DOWN") +ENDIF() IF("${MOTION}" STREQUAL "ON") add_subdirectory(motion) ENDIF() diff --git a/src/sensor/gesture/face_down_alg.h b/src/sensor/gesture/face_down_alg.h new file mode 100644 index 0000000..16ab460 --- /dev/null +++ b/src/sensor/gesture/face_down_alg.h @@ -0,0 +1,32 @@ +/* + * sensord + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FACE_DOWN_ALG_H__ +#define __FACE_DOWN_ALG_H__ + +#include + +class face_down_alg { +public: + virtual ~face_down_alg() {}; + virtual void push_event(const sensor_event_t & event) = 0; + virtual bool get_face_down(void) = 0; +}; + +#endif /* __FACE_DOWN_ALG_H __ */ diff --git a/src/sensor/gesture/face_down_alg_impl.cpp b/src/sensor/gesture/face_down_alg_impl.cpp new file mode 100644 index 0000000..051fd3b --- /dev/null +++ b/src/sensor/gesture/face_down_alg_impl.cpp @@ -0,0 +1,88 @@ +/* + * sensord + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#define GRAVITY 9.80665 +#define TWENTY_DEGREES 0.349066 +#define ONE_SIXTY_DEGREES 2.79253 +#define WINDOW_SIZE (2000*100) + +face_down_alg_impl::face_down_alg_impl() +{ + m_current_time = 0; + m_last_event_time = 0; + m_latest_down_time = 0; +} + +face_down_alg_impl::~face_down_alg_impl() +{ +} + +void face_down_alg_impl::push_event(const sensor_event_t & event) +{ + //_I("face_down_alg: %llu acc[2]: %f",event.data->timestamp,event.data->values[2]); + m_current_time = event.data->timestamp; + remove_old_up_time(); + + if (event.data->values[2] < (GRAVITY * cos(ONE_SIXTY_DEGREES))) + m_latest_down_time = event.data->timestamp; + + if (event.data->values[2] > (GRAVITY * cos(TWENTY_DEGREES))) + m_oldest_up_time.push(event.data->timestamp); +} + +void face_down_alg_impl::remove_old_up_time(void) +{ + while (m_oldest_up_time.size() > 0 && (m_current_time - m_oldest_up_time.front() > WINDOW_SIZE)) + m_oldest_up_time.pop(); +} + +bool face_down_alg_impl::get_face_down(void) +{ + unsigned long long down = is_facing_down(); + unsigned long long up = was_facing_up(); + //_I("face_down_alg: down: %llu, up: %llu", down, up); + + if (down < up) + return false; + + if (m_current_time - m_last_event_time < WINDOW_SIZE) + return false; + + m_last_event_time = m_current_time; + return true; +} + +unsigned long long face_down_alg_impl::is_facing_down(void) +{ + if (m_current_time - m_latest_down_time < WINDOW_SIZE) + return m_latest_down_time; + return 0; +} + +unsigned long long face_down_alg_impl::was_facing_up(void) +{ + remove_old_up_time(); + if (m_oldest_up_time.size() == 0) + return ULLONG_MAX; + return m_oldest_up_time.front(); +} diff --git a/src/sensor/gesture/face_down_alg_impl.h b/src/sensor/gesture/face_down_alg_impl.h new file mode 100644 index 0000000..4afa3bb --- /dev/null +++ b/src/sensor/gesture/face_down_alg_impl.h @@ -0,0 +1,44 @@ +/* + * sensord + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FACE_DOWN_ALG_IMPL_H__ +#define __FACE_DOWN_ALG_IMPL_H__ + +#include +#include +#include + +class face_down_alg_impl : public virtual face_down_alg { +public: + face_down_alg_impl(); + ~face_down_alg_impl(); + void push_event(const sensor_event_t & event); + bool get_face_down(void); +private: + unsigned long long m_current_time; + unsigned long long m_last_event_time; + unsigned long long m_latest_down_time; + std::queue m_oldest_up_time; + void remove_old_up_time(void); + unsigned long long is_facing_down(); + unsigned long long was_facing_up(); + +}; + +#endif /* __FACE_DOWN_ALG_IMPL_H__ */ diff --git a/src/sensor/gesture/face_down_sensor.cpp b/src/sensor/gesture/face_down_sensor.cpp new file mode 100644 index 0000000..9aca0f4 --- /dev/null +++ b/src/sensor/gesture/face_down_sensor.cpp @@ -0,0 +1,204 @@ +/* + * sensord + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define SENSOR_NAME "SENSOR_FACE_DOWN" + +#define SENSOR_FREQUENCY 50 + +face_down_sensor::face_down_sensor() +: m_gravity_sensor(NULL) +, m_time(0) +, m_state(false) +{ +} + +face_down_sensor::~face_down_sensor() +{ + _I("%s is destroyed!", SENSOR_NAME); +} + +bool face_down_sensor::init(void) +{ + m_gravity_sensor = sensor_loader::get_instance().get_sensor(GRAVITY_SENSOR); + + if (!m_gravity_sensor) { + _E("cannot load gravity sensor sensor[%s]", SENSOR_NAME); + return false; + } + + m_alg = get_alg(); + if (!m_alg) + return false; + + _I("%s is created!", SENSOR_NAME); + return true; +} + +sensor_type_t face_down_sensor::get_type(void) +{ + return GESTURE_FACE_DOWN_SENSOR; +} + +unsigned int face_down_sensor::get_event_type(void) +{ + return CONVERT_TYPE_EVENT(GESTURE_FACE_DOWN_SENSOR); +} + +const char *face_down_sensor::get_name(void) +{ + return SENSOR_NAME; +} + +bool face_down_sensor::get_sensor_info(sensor_info & info) +{ + info.set_type(get_type()); + info.set_id(get_id()); + info.set_privilege(SENSOR_PRIVILEGE_PUBLIC); + info.set_name(get_name()); + info.set_vendor("Samsung Electronics"); + info.set_min_range(0); + info.set_max_range(1); + info.set_resolution(1); + info.set_min_interval(1); + info.set_fifo_count(0); + info.set_max_batch_count(0); + info.set_supported_event(get_event_type()); + info.set_wakeup_supported(false); + + return true; +} + +void face_down_sensor::synthesize(const sensor_event_t & event) +{ + if (event.event_type != GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME) + return; + + m_time = event.data->timestamp; + m_alg->push_event(event); + m_state = m_alg->get_face_down(); + if (!m_state) + return; + + sensor_event_t *face_down_event; + sensor_data_t *face_down_data; + int data_length; + + face_down_event = (sensor_event_t *)malloc(sizeof(sensor_event_t)); + if (!face_down_event) { + _E("Failed to allocate memory"); + return; + } + + get_data(&face_down_data, &data_length); + face_down_event->sensor_id = get_id(); + face_down_event->event_type = FACE_DOWN_RAW_DATA_EVENT; + face_down_event->data_length = data_length; + face_down_event->data = face_down_data; + + push(face_down_event); + + _I("[face_down_sensor] : True"); +} + +int face_down_sensor::get_data(sensor_data_t ** data, int *length) +{ + sensor_data_t *sensor_data; + sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t)); + + sensor_data->accuracy = SENSOR_ACCURACY_GOOD; + sensor_data->timestamp = m_time; + sensor_data->value_count = 1; + sensor_data->values[0] = m_state; + + *data = sensor_data; + *length = sizeof(sensor_data_t); + + return 0; +} + +bool face_down_sensor::set_interval(unsigned long interval) +{ + m_interval = interval; + return true; +} + +bool face_down_sensor::set_batch_latency(unsigned long latency) +{ + return false; +} + +bool face_down_sensor::on_start(void) +{ + if (m_gravity_sensor) + m_gravity_sensor->start(); + + m_time = 0; + m_state = false; + return activate(); +} + +bool face_down_sensor::on_stop(void) +{ + if (m_gravity_sensor) + m_gravity_sensor->stop(); + + m_time = 0; + m_state = false; + + return deactivate(); +} + +bool face_down_sensor::add_interval(int client_id, unsigned int interval, bool is_processor) +{ + m_gravity_sensor->add_interval(client_id, interval, true); + return sensor_base::add_interval(client_id, interval, is_processor); +} + +bool face_down_sensor::delete_interval(int client_id, bool is_processor) +{ + m_gravity_sensor->delete_interval(client_id, true); + return sensor_base::delete_interval(client_id, is_processor); +} + +face_down_alg_impl *face_down_sensor::get_alg(void) +{ + face_down_alg_impl *alg = new(std::nothrow) face_down_alg_impl(); + retvm_if(!alg, NULL, "Failed to allocate memory"); + + return alg; +} diff --git a/src/sensor/gesture/face_down_sensor.h b/src/sensor/gesture/face_down_sensor.h new file mode 100644 index 0000000..7bb0809 --- /dev/null +++ b/src/sensor/gesture/face_down_sensor.h @@ -0,0 +1,66 @@ +/* + * sensord + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FACE_DOWN_SENSOR_H__ +#define __FACE_DOWN_SENSOR_H__ + +#include +#include +#include + +class face_down_sensor : public virtual_sensor { +public: + face_down_sensor(); + ~face_down_sensor(); + + /* initialize sensor */ + bool init(void); + + /* sensor info */ + sensor_type_t get_type(void); + unsigned int get_event_type(void); + const char *get_name(void); + + bool get_sensor_info(sensor_info & info); + + /* synthesize event */ + void synthesize(const sensor_event_t & event); + + bool add_interval(int client_id, unsigned int interval, bool is_processor); + bool delete_interval(int client_id, bool is_processor); + + /* get data */ + int get_data(sensor_data_t ** data, int *length); +private: + sensor_base * m_gravity_sensor; + face_down_alg_impl *m_alg; + + unsigned long long m_time; + bool m_state; + unsigned int m_interval; + + bool set_interval(unsigned long interval); + bool set_batch_latency(unsigned long latency); + + bool on_start(void); + bool on_stop(void); + face_down_alg_impl *get_alg(void); +}; + +#endif /* __FACE_DOWN_SENSOR_H__ */ diff --git a/src/server/sensor_loader.cpp b/src/server/sensor_loader.cpp index 0db7f6b..21694c8 100644 --- a/src/server/sensor_loader.cpp +++ b/src/server/sensor_loader.cpp @@ -50,6 +50,9 @@ #include #include #endif +#ifdef ENABLE_FACE_DOWN +#include +#endif using std::vector; using std::string; @@ -186,6 +189,9 @@ void sensor_loader::create_sensors(void) #ifdef ENABLE_ORIENTATION create_virtual_sensors("Orientation"); #endif +#ifdef ENABLE_FACE_DOWN + create_virtual_sensors("Face Down"); +#endif } template diff --git a/src/shared/sensor_deprecated.h b/src/shared/sensor_deprecated.h index 41a4092..c81e2d1 100644 --- a/src/shared/sensor_deprecated.h +++ b/src/shared/sensor_deprecated.h @@ -50,6 +50,8 @@ enum event_types_t { ROTATION_VECTOR_RAW_DATA_EVENT = (ROTATION_VECTOR_SENSOR << 16) | 0x0001, + FACE_DOWN_RAW_DATA_EVENT = (GESTURE_FACE_DOWN_SENSOR << 16) | 0x0001, + RV_RAW_RAW_DATA_EVENT = (RV_RAW_SENSOR << 16) | 0x0001, ULTRAVIOLET_RAW_DATA_EVENT = (ULTRAVIOLET_SENSOR << 16) | 0x0001, @@ -161,6 +163,9 @@ enum event_types_t { #define CONTEXT_BASE_DATA_SET CONTEXT_REPORT_EVENT #define CONTEXT_EVENT_REPORT CONTEXT_REPORT_EVENT +#define FACE_DOWN_BASE_DATA_SET FACE_DOWN_RAW_DATA_EVENT +#define FACE_DOWN_EVENT_RAW_DATA_REPORT_ON_TIME FACE_DOWN_RAW_DATA_EVENT + enum accelerometer_rotate_state { ROTATION_UNKNOWN = 0, ROTATION_LANDSCAPE_LEFT = 1, @@ -258,4 +263,3 @@ enum motion_no_move_t { #endif #endif //__SENSOR_DEPRECATED_H__ - diff --git a/src/shared/sensor_types.h b/src/shared/sensor_types.h index 277cbc4..18e40f4 100644 --- a/src/shared/sensor_types.h +++ b/src/shared/sensor_types.h @@ -74,6 +74,7 @@ extern "C" DEF_SENSOR(GESTURE_WRIST_UP_SENSOR) \ DEF_SENSOR(GESTURE_WRIST_DOWN_SENSOR) \ DEF_SENSOR(GESTURE_MOVEMENT_STATE_SENSOR) \ + DEF_SENSOR(GESTURE_FACE_DOWN_SENSOR) \ \ DEF_SENSOR_VALUE(ACTIVITY_TRACKER_SENSOR, 0x1A00) \ DEF_SENSOR(ACTIVITY_LEVEL_MONITOR_SENSOR) \ diff --git a/src/test/src/api-test.c b/src/test/src/api-test.c index bdeec6a..2a1ff11 100644 --- a/src/test/src/api-test.c +++ b/src/test/src/api-test.c @@ -262,6 +262,9 @@ int main(int argc, char **argv) result = check_sensor_api(BIO_LED_RED_RAW_DATA_EVENT, interval); fprintf(fp, "BIO_LED_RED - RAW_DATA_REPORT_ON_TIME - %d\n", result); + result = check_sensor_api(FACE_DOWN_RAW_DATA_EVENT, interval); + fprintf(fp, "Face Down - RAW_DATA_REPORT_ON_TIME - %d\n", result); + printf("Logs printed in ./auto_test.output\n"); fclose(fp); return 0; diff --git a/src/test/src/check-sensor.c b/src/test/src/check-sensor.c index 406008a..04ea726 100644 --- a/src/test/src/check-sensor.c +++ b/src/test/src/check-sensor.c @@ -84,6 +84,9 @@ void printpollinglogs(sensor_type_t type,sensor_data_t data) case(GYROSCOPE_UNCAL_SENSOR): printf("Gyroscope Uncal [%lld] [%6.6f] [%6.6f] [%6.6f] [%6.6f] [%6.6f] [%6.6f]\n\n", data.timestamp, data.values[0], data.values[1], data.values[2], data.values[3], data.values[4], data.values[5]); break; + case(GESTURE_FACE_DOWN_SENSOR): + printf("Face Down [%lld] [%6.6f]\n\n", data.timestamp, data.values[0]); + break; default: return; } @@ -164,6 +167,10 @@ int get_event(sensor_type_t sensor_type, char str[]) if (strcmp(str, "RAW_DATA_EVENT") == 0) return GYROSCOPE_UNCAL_RAW_DATA_EVENT; break; + case GESTURE_FACE_DOWN_SENSOR: + if (strcmp(str, "RAW_DATA_EVENT") == 0) + return FACE_DOWN_RAW_DATA_EVENT; + break; default: return -1; @@ -230,6 +237,9 @@ void callback(sensor_t sensor, unsigned int event_type, sensor_data_t *data, voi case GYROSCOPE_UNCAL_SENSOR: printf("Gyroscope Uncal [%lld] [%6.6f] [%6.6f] [%6.6f] [%6.6f] [%6.6f] [%6.6f]\n\n", data->timestamp, data->values[0], data->values[1], data->values[2], data->values[3], data->values[4], data->values[5]); break; + case GESTURE_FACE_DOWN_SENSOR: + printf("Face Down [%lld] [%6.6f] \n", data->timestamp, data->values[0]); + break; default: return; diff --git a/src/test/src/multi-thread-performance-test.c b/src/test/src/multi-thread-performance-test.c index 9130d47..588c0e7 100644 --- a/src/test/src/multi-thread-performance-test.c +++ b/src/test/src/multi-thread-performance-test.c @@ -53,6 +53,7 @@ void usage() printf("[ultraviolet] "); printf("[light]\n"); printf("[gyro_uncal]"); + printf("[face_down]"); } diff --git a/src/test/src/sensor-test.c b/src/test/src/sensor-test.c index 823f246..ff2b005 100644 --- a/src/test/src/sensor-test.c +++ b/src/test/src/sensor-test.c @@ -49,6 +49,7 @@ void usage() printf("[bio_led_red] "); printf("[light]\n"); printf("[gyroscope_uncal]"); + printf("[face_down]"); printf("event:"); printf("[RAW_DATA_EVENT]\n"); printf("-p: [polling]\n"); @@ -148,6 +149,10 @@ int main(int argc, char **argv) sensor_type = BIO_LED_RED_SENSOR; event = BIO_LED_RED_RAW_DATA_EVENT; } + else if (strcmp(argv[1], "face_down") == 0) { + sensor_type = GESTURE_FACE_DOWN_SENSOR; + event = FACE_DOWN_RAW_DATA_EVENT; + } else { usage(); return -1; -- 2.7.4