From 699ebee13fed98e9504db5f3e50287db07171426 Mon Sep 17 00:00:00 2001 From: Ankur Date: Mon, 18 May 2015 16:06:41 +0530 Subject: [PATCH 01/16] Adding common plugin for hardware/software sensor fusion - gaming_rv Tested on rd-pq device for tizen 2.4 repo Change-Id: I62436db7534a325515ae49594cde02b02ef3e51f --- src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp | 49 ++++++++++++++-------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp b/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp index 997bc7b..0b3559f 100755 --- a/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp +++ b/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp @@ -56,10 +56,17 @@ void pre_process_data(sensor_data &data_out, const float *data_in, float gaming_rv_sensor::gaming_rv_sensor() : m_accel_sensor(NULL) , m_gyro_sensor(NULL) +, m_fusion_sensor(NULL) , m_time(0) { cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance(); + sensor_hal *fusion_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(FUSION_SENSOR); + if (!fusion_sensor_hal) + m_hardware_fusion = false; + else + m_hardware_fusion = true; + m_name = string(SENSOR_NAME); register_supported_event(GAMING_RV_RAW_DATA_EVENT); m_enable_gaming_rv = 0; @@ -113,12 +120,14 @@ bool gaming_rv_sensor::on_start(void) { AUTOLOCK(m_mutex); - m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); - m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_accel_sensor->start(); - m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT); - m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_gyro_sensor->start(); + if (!m_hardware_fusion) { + m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); + m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_accel_sensor->start(); + m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_gyro_sensor->start(); + } m_fusion_sensor->register_supported_event(FUSION_EVENT); m_fusion_sensor->register_supported_event(FUSION_GAMING_ROTATION_VECTOR_ENABLED); @@ -134,12 +143,14 @@ bool gaming_rv_sensor::on_stop(void) { AUTOLOCK(m_mutex); - m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); - m_accel_sensor->delete_interval((intptr_t)this, false); - m_accel_sensor->stop(); - m_gyro_sensor->delete_client(GYROSCOPE_RAW_DATA_EVENT); - m_gyro_sensor->delete_interval((intptr_t)this, false); - m_gyro_sensor->stop(); + if (!m_hardware_fusion) { + m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); + m_accel_sensor->delete_interval((intptr_t)this, false); + m_accel_sensor->stop(); + m_gyro_sensor->delete_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->delete_interval((intptr_t)this, false); + m_gyro_sensor->stop(); + } m_fusion_sensor->delete_client(FUSION_EVENT); m_fusion_sensor->delete_interval((intptr_t)this, false); @@ -155,8 +166,10 @@ bool gaming_rv_sensor::add_interval(int client_id, unsigned int interval) { AUTOLOCK(m_mutex); - m_accel_sensor->add_interval(client_id, interval, false); - m_gyro_sensor->add_interval(client_id, interval, false); + if (!m_hardware_fusion) { + m_accel_sensor->add_interval(client_id, interval, false); + m_gyro_sensor->add_interval(client_id, interval, false); + } m_fusion_sensor->add_interval(client_id, interval, false); @@ -167,8 +180,10 @@ bool gaming_rv_sensor::delete_interval(int client_id) { AUTOLOCK(m_mutex); - m_accel_sensor->delete_interval(client_id, false); - m_gyro_sensor->delete_interval(client_id, false); + if (!m_hardware_fusion) { + m_accel_sensor->delete_interval(client_id, false); + m_gyro_sensor->delete_interval(client_id, false); + } m_fusion_sensor->delete_interval(client_id, false); @@ -211,7 +226,7 @@ int gaming_rv_sensor::get_sensor_data(unsigned int event_type, sensor_data_t &da if (event_type != GAMING_RV_RAW_DATA_EVENT) return -1; - m_fusion_sensor->get_sensor_data(FUSION_ORIENTATION_ENABLED, fusion_data); + m_fusion_sensor->get_sensor_data(FUSION_GAMING_ROTATION_VECTOR_ENABLED, fusion_data); data.accuracy = SENSOR_ACCURACY_GOOD; data.timestamp = get_timestamp(); -- 2.7.4 From 5fe76a606713339ab90027546372565e148aef7e Mon Sep 17 00:00:00 2001 From: Ankur Date: Mon, 18 May 2015 16:33:47 +0530 Subject: [PATCH 02/16] Adding common plugin for hardware/software sensor fusion - geomagnetic_rv Tested on rd-pq device with tizen 2.4 repo Change-Id: Ifa9a10a1ab60dcde364f7b26f4e8ee4ea66df509 --- .../geomagnetic_rv/geomagnetic_rv_sensor.cpp | 49 ++++++++++++++-------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/rotation_vector/geomagnetic_rv/geomagnetic_rv_sensor.cpp b/src/rotation_vector/geomagnetic_rv/geomagnetic_rv_sensor.cpp index 381dbe2..d39f81a 100755 --- a/src/rotation_vector/geomagnetic_rv/geomagnetic_rv_sensor.cpp +++ b/src/rotation_vector/geomagnetic_rv/geomagnetic_rv_sensor.cpp @@ -56,10 +56,17 @@ void pre_process_data(sensor_data &data_out, const float *data_in, float geomagnetic_rv_sensor::geomagnetic_rv_sensor() : m_accel_sensor(NULL) , m_magnetic_sensor(NULL) +, m_fusion_sensor(NULL) , m_time(0) { cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance(); + sensor_hal *fusion_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(FUSION_SENSOR); + if (!fusion_sensor_hal) + m_hardware_fusion = false; + else + m_hardware_fusion = true; + m_name = string(SENSOR_NAME); register_supported_event(GEOMAGNETIC_RV_RAW_DATA_EVENT); m_enable_geomagnetic_rv = 0; @@ -113,12 +120,14 @@ bool geomagnetic_rv_sensor::on_start(void) { AUTOLOCK(m_mutex); - m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); - m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_accel_sensor->start(); - m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT); - m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_magnetic_sensor->start(); + if (!m_hardware_fusion) { + m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); + m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_accel_sensor->start(); + m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_magnetic_sensor->start(); + } m_fusion_sensor->register_supported_event(FUSION_EVENT); m_fusion_sensor->register_supported_event(FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED); @@ -134,12 +143,14 @@ bool geomagnetic_rv_sensor::on_stop(void) { AUTOLOCK(m_mutex); - m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); - m_accel_sensor->delete_interval((intptr_t)this, false); - m_accel_sensor->stop(); - m_magnetic_sensor->delete_client(GEOMAGNETIC_RAW_DATA_EVENT); - m_magnetic_sensor->delete_interval((intptr_t)this, false); - m_magnetic_sensor->stop(); + if (!m_hardware_fusion) { + m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); + m_accel_sensor->delete_interval((intptr_t)this, false); + m_accel_sensor->stop(); + m_magnetic_sensor->delete_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->delete_interval((intptr_t)this, false); + m_magnetic_sensor->stop(); + } m_fusion_sensor->delete_client(FUSION_EVENT); m_fusion_sensor->delete_interval((intptr_t)this, false); @@ -155,8 +166,10 @@ bool geomagnetic_rv_sensor::add_interval(int client_id, unsigned int interval) { AUTOLOCK(m_mutex); - m_accel_sensor->add_interval(client_id, interval, false); - m_magnetic_sensor->add_interval(client_id, interval, false); + if (!m_hardware_fusion) { + m_accel_sensor->add_interval(client_id, interval, false); + m_magnetic_sensor->add_interval(client_id, interval, false); + } m_fusion_sensor->add_interval(client_id, interval, false); @@ -167,8 +180,10 @@ bool geomagnetic_rv_sensor::delete_interval(int client_id) { AUTOLOCK(m_mutex); - m_accel_sensor->delete_interval(client_id, false); - m_magnetic_sensor->delete_interval(client_id, false); + if (!m_hardware_fusion) { + m_accel_sensor->delete_interval(client_id, false); + m_magnetic_sensor->delete_interval(client_id, false); + } m_fusion_sensor->delete_interval(client_id, false); @@ -211,7 +226,7 @@ int geomagnetic_rv_sensor::get_sensor_data(unsigned int event_type, sensor_data_ if (event_type != GEOMAGNETIC_RV_RAW_DATA_EVENT) return -1; - m_fusion_sensor->get_sensor_data(FUSION_ORIENTATION_ENABLED, fusion_data); + m_fusion_sensor->get_sensor_data(FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED, fusion_data); data.accuracy = SENSOR_ACCURACY_GOOD; data.timestamp = get_timestamp(); -- 2.7.4 From 70b127df6edaff532aad29324f3659dd6ffc1998 Mon Sep 17 00:00:00 2001 From: Ankur Date: Mon, 18 May 2015 17:42:58 +0530 Subject: [PATCH 03/16] Updating Linear Acceleration sensor as per fusion sensor restructuring Tested on rd-pq device with tizen 2.4 repo Change-Id: I989940c47b8673e9f607c229e44188759659934f --- src/linear_accel/linear_accel_sensor.cpp | 183 ++++++++++++++++++++++++++----- src/linear_accel/linear_accel_sensor.h | 16 ++- 2 files changed, 170 insertions(+), 29 deletions(-) diff --git a/src/linear_accel/linear_accel_sensor.cpp b/src/linear_accel/linear_accel_sensor.cpp index fe2d608..c967ce2 100755 --- a/src/linear_accel/linear_accel_sensor.cpp +++ b/src/linear_accel/linear_accel_sensor.cpp @@ -33,6 +33,8 @@ #define SENSOR_NAME "LINEAR_ACCEL_SENSOR" #define SENSOR_TYPE_LINEAR_ACCEL "LINEAR_ACCEL" +#define SENSOR_TYPE_GRAVITY "GRAVITY" +#define SENSOR_TYPE_ORIENTATION "ORIENTATION" #define ELEMENT_NAME "NAME" #define ELEMENT_VENDOR "VENDOR" @@ -42,9 +44,19 @@ #define ELEMENT_ACCEL_ROTATION_DIRECTION_COMPENSATION "ACCEL_ROTATION_DIRECTION_COMPENSATION" #define ELEMENT_ACCEL_SCALE "ACCEL_SCALE" #define ELEMENT_LINEAR_ACCEL_SIGN_COMPENSATION "LINEAR_ACCEL_SIGN_COMPENSATION" +#define ELEMENT_ORIENTATION_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_GRAVITY_SIGN_COMPENSATION "GRAVITY_SIGN_COMPENSATION" +#define ELEMENT_PITCH_ROTATION_COMPENSATION "PITCH_ROTATION_COMPENSATION" +#define ELEMENT_ROLL_ROTATION_COMPENSATION "ROLL_ROTATION_COMPENSATION" +#define ELEMENT_AZIMUTH_ROTATION_COMPENSATION "AZIMUTH_ROTATION_COMPENSATION" #define INITIAL_VALUE -1 #define GRAVITY 9.80665 +#define DEVIATION 0.1 + +#define PI 3.141593 +#define AZIMUTH_OFFSET_DEGREES 360 +#define AZIMUTH_OFFSET_RADIANS (2 * PI) #define MS_TO_US 1000 #define MIN_DELIVERY_DIFF_FACTOR 0.75f @@ -55,7 +67,9 @@ linear_accel_sensor::linear_accel_sensor() : m_accel_sensor(NULL) -, m_gravity_sensor(NULL) +, m_gyro_sensor(NULL) +, m_magnetic_sensor(NULL) +, m_fusion_sensor(NULL) , m_time(0) { cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance(); @@ -79,6 +93,13 @@ linear_accel_sensor::linear_accel_sensor() INFO("m_raw_data_unit = %s", m_raw_data_unit.c_str()); + if (!config.get(SENSOR_TYPE_ORIENTATION, ELEMENT_ORIENTATION_DATA_UNIT, m_orientation_data_unit)) { + ERR("[ORIENTATION_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + INFO("m_orientation_data_unit = %s", m_orientation_data_unit.c_str()); + if (!config.get(SENSOR_TYPE_LINEAR_ACCEL, ELEMENT_DEFAULT_SAMPLING_TIME, &m_default_sampling_time)) { ERR("[DEFAULT_SAMPLING_TIME] is empty\n"); throw ENXIO; @@ -106,6 +127,12 @@ linear_accel_sensor::linear_accel_sensor() INFO("m_accel_scale = %f", m_accel_scale); + if (!config.get(SENSOR_TYPE_GRAVITY, ELEMENT_GRAVITY_SIGN_COMPENSATION, m_gravity_sign_compensation, 3)) { + ERR("[GRAVITY_SIGN_COMPENSATION] is empty\n"); + throw ENXIO; + } + + INFO("m_gravity_sign_compensation = (%d, %d, %d)", m_gravity_sign_compensation[0], m_gravity_sign_compensation[1], m_gravity_sign_compensation[2]); if (!config.get(SENSOR_TYPE_LINEAR_ACCEL, ELEMENT_LINEAR_ACCEL_SIGN_COMPENSATION, m_linear_accel_sign_compensation, 3)) { ERR("[LINEAR_ACCEL_SIGN_COMPENSATION] is empty\n"); @@ -114,6 +141,27 @@ linear_accel_sensor::linear_accel_sensor() INFO("m_linear_accel_sign_compensation = (%d, %d, %d)", m_linear_accel_sign_compensation[0], m_linear_accel_sign_compensation[1], m_linear_accel_sign_compensation[2]); + if (!config.get(SENSOR_TYPE_ORIENTATION, ELEMENT_AZIMUTH_ROTATION_COMPENSATION, &m_azimuth_rotation_compensation)) { + ERR("[AZIMUTH_ROTATION_COMPENSATION] is empty\n"); + throw ENXIO; + } + + INFO("m_azimuth_rotation_compensation = %d", m_azimuth_rotation_compensation); + + if (!config.get(SENSOR_TYPE_ORIENTATION, ELEMENT_PITCH_ROTATION_COMPENSATION, &m_pitch_rotation_compensation)) { + ERR("[PITCH_ROTATION_COMPENSATION] is empty\n"); + throw ENXIO; + } + + INFO("m_pitch_rotation_compensation = %d", m_pitch_rotation_compensation); + + if (!config.get(SENSOR_TYPE_ORIENTATION, ELEMENT_ROLL_ROTATION_COMPENSATION, &m_roll_rotation_compensation)) { + ERR("[ROLL_ROTATION_COMPENSATION] is empty\n"); + throw ENXIO; + } + + INFO("m_roll_rotation_compensation = %d", m_roll_rotation_compensation); + m_interval = m_default_sampling_time * MS_TO_US; } @@ -125,12 +173,15 @@ linear_accel_sensor::~linear_accel_sensor() bool linear_accel_sensor::init() { - m_gravity_sensor = sensor_plugin_loader::get_instance().get_sensor(GRAVITY_SENSOR); m_accel_sensor = sensor_plugin_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR); + m_gyro_sensor = sensor_plugin_loader::get_instance().get_sensor(GYROSCOPE_SENSOR); + m_magnetic_sensor = sensor_plugin_loader::get_instance().get_sensor(GEOMAGNETIC_SENSOR); + + m_fusion_sensor = sensor_plugin_loader::get_instance().get_sensor(FUSION_SENSOR); - if (!m_accel_sensor || !m_gravity_sensor) { - ERR("Failed to load sensors, accel: 0x%x, gravity: 0x%x", - m_accel_sensor, m_gravity_sensor); + if (!m_accel_sensor || !m_gyro_sensor || !m_magnetic_sensor || !m_fusion_sensor) { + ERR("Failed to load sensors, accel: 0x%x, gyro: 0x%x, mag: 0x%x, fusion: 0x%x", + m_accel_sensor, m_gyro_sensor, m_magnetic_sensor, m_fusion_sensor); return false; } @@ -146,13 +197,21 @@ sensor_type_t linear_accel_sensor::get_type(void) bool linear_accel_sensor::on_start(void) { AUTOLOCK(m_mutex); - m_gravity_sensor->add_client(GRAVITY_RAW_DATA_EVENT); - m_gravity_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_gravity_sensor->start(); - m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); m_accel_sensor->start(); + m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_gyro_sensor->start(); + m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_magnetic_sensor->start(); + + m_fusion_sensor->register_supported_event(FUSION_EVENT); + m_fusion_sensor->register_supported_event(FUSION_ORIENTATION_ENABLED); + m_fusion_sensor->add_client(FUSION_EVENT); + m_fusion_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_fusion_sensor->start(); activate(); return true; @@ -161,13 +220,21 @@ bool linear_accel_sensor::on_start(void) bool linear_accel_sensor::on_stop(void) { AUTOLOCK(m_mutex); - m_gravity_sensor->delete_client(GRAVITY_RAW_DATA_EVENT); - m_gravity_sensor->delete_interval((intptr_t)this, false); - m_gravity_sensor->stop(); - m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); m_accel_sensor->delete_interval((intptr_t)this, false); m_accel_sensor->stop(); + m_gyro_sensor->delete_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->delete_interval((intptr_t)this, false); + m_gyro_sensor->stop(); + m_magnetic_sensor->delete_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->delete_interval((intptr_t)this, false); + m_magnetic_sensor->stop(); + + m_fusion_sensor->delete_client(FUSION_EVENT); + m_fusion_sensor->delete_interval((intptr_t)this, false); + m_fusion_sensor->unregister_supported_event(FUSION_EVENT); + m_fusion_sensor->unregister_supported_event(FUSION_ORIENTATION_ENABLED); + m_fusion_sensor->stop(); deactivate(); return true; @@ -176,8 +243,11 @@ bool linear_accel_sensor::on_stop(void) bool linear_accel_sensor::add_interval(int client_id, unsigned int interval) { AUTOLOCK(m_mutex); - m_gravity_sensor->add_interval(client_id, interval, false); m_accel_sensor->add_interval(client_id, interval, false); + m_gyro_sensor->add_interval(client_id, interval, false); + m_magnetic_sensor->add_interval(client_id, interval, false); + + m_fusion_sensor->add_interval(client_id, interval, false); return sensor_base::add_interval(client_id, interval, false); } @@ -185,15 +255,78 @@ bool linear_accel_sensor::add_interval(int client_id, unsigned int interval) bool linear_accel_sensor::delete_interval(int client_id) { AUTOLOCK(m_mutex); - m_gravity_sensor->delete_interval(client_id, false); m_accel_sensor->delete_interval(client_id, false); + m_gyro_sensor->delete_interval(client_id, false); + m_magnetic_sensor->delete_interval(client_id, false); + + m_fusion_sensor->delete_interval(client_id, false); return sensor_base::delete_interval(client_id, false); } +sensor_data_t linear_accel_sensor::calculate_gravity(sensor_data_t data) +{ + sensor_data_t gravity_data; + float pitch, roll, azimuth; + float azimuth_offset; + + quaternion quat(data.values[0], data.values[1], + data.values[2], data.values[3]); + + euler_angles euler = quat2euler(quat); + + if(m_orientation_data_unit == "DEGREES") { + euler = rad2deg(euler); + azimuth_offset = AZIMUTH_OFFSET_DEGREES; + } + else { + azimuth_offset = AZIMUTH_OFFSET_RADIANS; + } + + euler.m_ang.m_vec[0] *= m_pitch_rotation_compensation; + euler.m_ang.m_vec[1] *= m_roll_rotation_compensation; + euler.m_ang.m_vec[2] *= m_azimuth_rotation_compensation; + + pitch = euler.m_ang.m_vec[0]; + roll = euler.m_ang.m_vec[1]; + if (euler.m_ang.m_vec[2] >= 0) + azimuth = euler.m_ang.m_vec[2]; + else + azimuth = euler.m_ang.m_vec[2] + azimuth_offset; + + if(m_orientation_data_unit == "DEGREES") { + azimuth *= DEG2RAD; + pitch *= DEG2RAD; + roll *= DEG2RAD; + } + + + if ((roll >= (M_PI/2)-DEVIATION && roll <= (M_PI/2)+DEVIATION) || + (roll >= -(M_PI/2)-DEVIATION && roll <= -(M_PI/2)+DEVIATION)) { + gravity_data.values[0] = m_gravity_sign_compensation[0] * GRAVITY * sin(roll) * cos(azimuth); + gravity_data.values[1] = m_gravity_sign_compensation[1] * GRAVITY * sin(azimuth); + gravity_data.values[2] = m_gravity_sign_compensation[2] * GRAVITY * cos(roll); + } else if ((pitch >= (M_PI/2)-DEVIATION && pitch <= (M_PI/2)+DEVIATION) || + (pitch >= -(M_PI/2)-DEVIATION && pitch <= -(M_PI/2)+DEVIATION)) { + gravity_data.values[0] = m_gravity_sign_compensation[0] * GRAVITY * sin(azimuth); + gravity_data.values[1] = m_gravity_sign_compensation[1] * GRAVITY * sin(pitch) * cos(azimuth); + gravity_data.values[2] = m_gravity_sign_compensation[2] * GRAVITY * cos(pitch); + } else { + gravity_data.values[0] = m_gravity_sign_compensation[0] * GRAVITY * sin(roll); + gravity_data.values[1] = m_gravity_sign_compensation[1] * GRAVITY * sin(pitch); + gravity_data.values[2] = m_gravity_sign_compensation[2] * GRAVITY * cos(roll) * cos(pitch); + } + gravity_data.value_count = 3; + gravity_data.timestamp = m_time; + gravity_data.accuracy = SENSOR_ACCURACY_GOOD; + + return gravity_data; +} + void linear_accel_sensor::synthesize(const sensor_event_t &event, vector &outs) { sensor_event_t lin_accel_event; + sensor_data_t gravity_data; unsigned long long diff_time; @@ -211,17 +344,13 @@ void linear_accel_sensor::synthesize(const sensor_event_t &event, vectorget_sensor_data(GRAVITY_RAW_DATA_EVENT, gravity_data); + sensor_data_t gravity_data, accel_data, fusion_data; + m_fusion_sensor->get_sensor_data(FUSION_ORIENTATION_ENABLED, fusion_data); m_accel_sensor->get_sensor_data(ACCELEROMETER_RAW_DATA_EVENT, accel_data); + gravity_data = calculate_gravity(fusion_data); + accel_data.values[0] = m_accel_rotation_direction_compensation[0] * (accel_data.values[0] - m_accel_static_bias[0]) / m_accel_scale; accel_data.values[1] = m_accel_rotation_direction_compensation[1] * (accel_data.values[1] - m_accel_static_bias[1]) / m_accel_scale; accel_data.values[2] = m_accel_rotation_direction_compensation[2] * (accel_data.values[2] - m_accel_static_bias[2]) / m_accel_scale; diff --git a/src/linear_accel/linear_accel_sensor.h b/src/linear_accel/linear_accel_sensor.h index 4ef10ab..e8f8395 100755 --- a/src/linear_accel/linear_accel_sensor.h +++ b/src/linear_accel/linear_accel_sensor.h @@ -41,11 +41,15 @@ public: bool get_properties(sensor_properties_s &properties); private: sensor_base *m_accel_sensor; - sensor_base *m_gravity_sensor; - cmutex m_value_mutex; + sensor_base *m_gyro_sensor; + sensor_base *m_magnetic_sensor; + sensor_base *m_fusion_sensor; sensor_data m_accel; - sensor_data m_gravity; + sensor_data m_gyro; + sensor_data m_magnetic; + + cmutex m_value_mutex; unsigned long long m_time; unsigned int m_interval; @@ -54,14 +58,20 @@ private: string m_vendor; string m_raw_data_unit; + string m_orientation_data_unit; int m_default_sampling_time; float m_accel_static_bias[3]; int m_accel_rotation_direction_compensation[3]; float m_accel_scale; int m_linear_accel_sign_compensation[3]; + int m_gravity_sign_compensation[3]; + int m_azimuth_rotation_compensation; + int m_pitch_rotation_compensation; + int m_roll_rotation_compensation; bool on_start(void); bool on_stop(void); + sensor_data_t calculate_gravity(sensor_data_t data); }; #endif -- 2.7.4 From 57b8e1b2e9725c6652bd000247fbfe60ca488777 Mon Sep 17 00:00:00 2001 From: Ankur Date: Tue, 19 May 2015 16:39:57 +0530 Subject: [PATCH 04/16] Fixing Proximity state definitions Change-Id: I650b15614b923ed592061bb4bc393e300308480c --- src/proxi/proxi_sensor_hal.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/proxi/proxi_sensor_hal.h b/src/proxi/proxi_sensor_hal.h index ebb24b9..3b96b04 100755 --- a/src/proxi/proxi_sensor_hal.h +++ b/src/proxi/proxi_sensor_hal.h @@ -28,12 +28,19 @@ using std::string; class proxi_sensor_hal : public sensor_hal { public: - enum proxi_node_state_event_t { //changed as per IIO definitions - PROXIMITY_NODE_STATE_NEAR = 1, - PROXIMITY_NODE_STATE_FAR = 2, - PROXIMITY_NODE_STATE_UNKNOWN = 0, + enum proxi_node_state_event_t { //changed as per Input Event Method definitions + PROXIMITY_NODE_STATE_NEAR = 0, + PROXIMITY_NODE_STATE_FAR = 1, + PROXIMITY_NODE_STATE_UNKNOWN = -1, }; +// In case of IIO input method, use the following definitions as the values returned by sensor are different. +// enum proxi_node_state_event_t { //changed as per IIO Method definitions +// PROXIMITY_NODE_STATE_NEAR = 1, +// PROXIMITY_NODE_STATE_FAR = 2, +// PROXIMITY_NODE_STATE_UNKNOWN = 0, +// }; + proxi_sensor_hal(); virtual ~proxi_sensor_hal(); string get_model_id(void); -- 2.7.4 From 2210a3e617f0188e346961bf72df1a0cd3eadd40 Mon Sep 17 00:00:00 2001 From: Ankur Date: Mon, 18 May 2015 17:55:26 +0530 Subject: [PATCH 05/16] Adding common plugin for hardware/software sensor fusion - linear accel sensor Change-Id: Ie0a5eaf3607b14ced68d0cb545c29f0b442afff6 --- src/linear_accel/linear_accel_sensor.cpp | 51 ++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/linear_accel/linear_accel_sensor.cpp b/src/linear_accel/linear_accel_sensor.cpp index c967ce2..6e21ab2 100755 --- a/src/linear_accel/linear_accel_sensor.cpp +++ b/src/linear_accel/linear_accel_sensor.cpp @@ -78,6 +78,12 @@ linear_accel_sensor::linear_accel_sensor() m_enable_linear_accel = 0; register_supported_event(LINEAR_ACCEL_RAW_DATA_EVENT); + sensor_hal *fusion_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(FUSION_SENSOR); + if (!fusion_sensor_hal) + m_hardware_fusion = false; + else + m_hardware_fusion = true; + if (!config.get(SENSOR_TYPE_LINEAR_ACCEL, ELEMENT_VENDOR, m_vendor)) { ERR("[VENDOR] is empty\n"); @@ -197,15 +203,19 @@ sensor_type_t linear_accel_sensor::get_type(void) bool linear_accel_sensor::on_start(void) { AUTOLOCK(m_mutex); + m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); m_accel_sensor->start(); - m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT); - m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_gyro_sensor->start(); - m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT); - m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); - m_magnetic_sensor->start(); + + if (!m_hardware_fusion) { + m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_gyro_sensor->start(); + m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_magnetic_sensor->start(); + } m_fusion_sensor->register_supported_event(FUSION_EVENT); m_fusion_sensor->register_supported_event(FUSION_ORIENTATION_ENABLED); @@ -223,12 +233,15 @@ bool linear_accel_sensor::on_stop(void) m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); m_accel_sensor->delete_interval((intptr_t)this, false); m_accel_sensor->stop(); - m_gyro_sensor->delete_client(GYROSCOPE_RAW_DATA_EVENT); - m_gyro_sensor->delete_interval((intptr_t)this, false); - m_gyro_sensor->stop(); - m_magnetic_sensor->delete_client(GEOMAGNETIC_RAW_DATA_EVENT); - m_magnetic_sensor->delete_interval((intptr_t)this, false); - m_magnetic_sensor->stop(); + + if (!m_hardware_fusion) { + m_gyro_sensor->delete_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->delete_interval((intptr_t)this, false); + m_gyro_sensor->stop(); + m_magnetic_sensor->delete_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->delete_interval((intptr_t)this, false); + m_magnetic_sensor->stop(); + } m_fusion_sensor->delete_client(FUSION_EVENT); m_fusion_sensor->delete_interval((intptr_t)this, false); @@ -244,8 +257,11 @@ bool linear_accel_sensor::add_interval(int client_id, unsigned int interval) { AUTOLOCK(m_mutex); m_accel_sensor->add_interval(client_id, interval, false); - m_gyro_sensor->add_interval(client_id, interval, false); - m_magnetic_sensor->add_interval(client_id, interval, false); + + if (!m_hardware_fusion) { + m_gyro_sensor->add_interval(client_id, interval, false); + m_magnetic_sensor->add_interval(client_id, interval, false); + } m_fusion_sensor->add_interval(client_id, interval, false); @@ -256,8 +272,11 @@ bool linear_accel_sensor::delete_interval(int client_id) { AUTOLOCK(m_mutex); m_accel_sensor->delete_interval(client_id, false); - m_gyro_sensor->delete_interval(client_id, false); - m_magnetic_sensor->delete_interval(client_id, false); + + if (!m_hardware_fusion) { + m_gyro_sensor->delete_interval(client_id, false); + m_magnetic_sensor->delete_interval(client_id, false); + } m_fusion_sensor->delete_interval(client_id, false); -- 2.7.4 From 8692956fc14e36fcd6f5319df1b99e2f35885881 Mon Sep 17 00:00:00 2001 From: Ankur Date: Fri, 22 May 2015 12:03:54 +0530 Subject: [PATCH 06/16] Adding documentation for adding hardware fusion sensor in virtual sensors Change-Id: I12d4b3a93a811709be80db62df5950cc98894cba --- src/fusion/hardware_fusion_sensor.html | 163 +++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/fusion/hardware_fusion_sensor.html diff --git a/src/fusion/hardware_fusion_sensor.html b/src/fusion/hardware_fusion_sensor.html new file mode 100644 index 0000000..aae6fea --- /dev/null +++ b/src/fusion/hardware_fusion_sensor.html @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + +

Supporting +Virtual Sensors based on On-Chip(Hardware Based) Sensor Fusion +Solution

+


+

+

Software +Fusion Sensor:

+


+

+

The +fusion sensor registers for accelerometer, gyroscope and geomagnetic +sensors. Uses the data from these three sensors to fusion_event, +which is used by various sensors to generate their specific sensor +events.

+


+

+

->The +virtual sensor starts the hardware and fusion sensor.

+

->Fusion +sensor registers for hardware sensors. It received accelerometer, +gyroscope and/or geomagnetic sensor events.

+

->Based +on what all events are received, fusion sensor generates a fusion +sensor event.

+

->The +FUSION_EVENT is sent to all virtual sensors which have registered for +fusion sensor.

+

->The +virtual sensors then use the data from FUSION_EVENT to create their +specific virtual sensor events.

+


+

+

Hardware +Fusion Sensor:

+


+

+

In +case hardware based fusion sensor is present, individual sensors +won't be required by fusion sensor to generate FUSION_EVENT.

+

So, +virtual sensors won't have to register and start the individual +hardware sensors (accel, gyro or geomagnetic) for receiving +FUSION_EVENT. They will just have to register for hardware fusion +sensor event and they will receive the hardware sensor event.

+


+

+

Adding +hardware fusion sensor in virtual sensors:

+

In +case hardware fusion sensor is present, instead of registering of +individual hardware sensors and fusion sensor, virtual sensor will +register for just sensor hal fusion sensor. +

+


+

+

Also, +fusion sensor will register for just fusion_sensor_hal and send the +events to all virtual sensor registered for fusion sensor events.

+


+

+

For +this, the virtual sensor must register/start specific sensors in case +hardware fusion sensor is present or not.

+


+

+

In +any virtual sensor class, to add support for both hardware and +software sensor fusion, +

+


+

+

->In +the constructor use sensor_plugin_loader to check if the hal sensor +fusion is present or not:

+

sensor_plugin_loader::get_instance().get_sensor_hal(FUSION_SENSOR)

+


+

+

->If +it returns NULL, in that case, hardware fusion sensor is not present, +else the hardware fusion is present.

+

->Store +this result in virtual_sensor::m_hardware_fusion

+


+

+

sensor_hal +*fusion_sensor_hal = +sensor_plugin_loader::get_instance().get_sensor_hal(FUSION_SENSOR);

+

if +(!fusion_sensor_hal)

+

  m_hardware_fusion += false;

+

else

+

  m_hardware_fusion += true;

+


+

+


+

+

->Bases +on this, in on_start, on_stop, add_interval, delete_interval etc +functions, the physical sensors will be started in case hardware +fusion sensor is not present and only fusion sensor will be started +in case hardware fusion sensor is present.

+


+

+


+

+

bool +orientation_sensor::on_start(void)

+

{

+

  AUTOLOCK(m_mutex);

+


+

+

  if +(!m_hardware_fusion) {

+

    m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT);

+

    m_accel_sensor->add_interval((intptr_t)this, +(m_interval/MS_TO_US), false);

+

    m_accel_sensor->start();

+

    m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT);

+

    m_gyro_sensor->add_interval((intptr_t)this, +(m_interval/MS_TO_US), false);

+

    m_gyro_sensor->start();

+

    m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT);

+

    m_magnetic_sensor->add_interval((intptr_t)this, +(m_interval/MS_TO_US), false);

+

    m_magnetic_sensor->start();

+

  }

+


+

+

  m_fusion_sensor->register_supported_event(FUSION_EVENT);

+

  m_fusion_sensor->register_supported_event(FUSION_ORIENTATION_ENABLED);

+

  m_fusion_sensor->add_client(FUSION_EVENT);

+

  m_fusion_sensor->add_interval((intptr_t)this, +(m_interval/MS_TO_US), false);

+

  m_fusion_sensor->start();

+


+

+

  activate();

+

  return +true;

+

}

+ + -- 2.7.4 From f3e7421d21da32a676e71acb458c57af91575705 Mon Sep 17 00:00:00 2001 From: Ankur Date: Fri, 29 May 2015 14:42:59 +0530 Subject: [PATCH 07/16] Code Cleanup: cleaning up unused functions and variables from gaming rotation vector removing unused functions, variables and macros from gaming rotation vector Change-Id: Ia59c6d171fc4ed01ffe5e670fbc61a9c3f67c05f --- src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp | 12 ------------ src/rotation_vector/gaming_rv/gaming_rv_sensor.h | 5 ----- 2 files changed, 17 deletions(-) diff --git a/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp b/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp index 0b3559f..36a8d4d 100755 --- a/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp +++ b/src/rotation_vector/gaming_rv/gaming_rv_sensor.cpp @@ -37,22 +37,11 @@ #define MIN_DELIVERY_DIFF_FACTOR 0.75f -#define INITIAL_VALUE -1 - #define MS_TO_US 1000 -#define ELEMENT_NAME "NAME" #define ELEMENT_VENDOR "VENDOR" -#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" #define ELEMENT_DEFAULT_SAMPLING_TIME "DEFAULT_SAMPLING_TIME" -void pre_process_data(sensor_data &data_out, const float *data_in, float *bias, int *sign, float scale) -{ - data_out.m_data.m_vec[0] = sign[0] * (data_in[0] - bias[0]) / scale; - data_out.m_data.m_vec[1] = sign[1] * (data_in[1] - bias[1]) / scale; - data_out.m_data.m_vec[2] = sign[2] * (data_in[2] - bias[2]) / scale; -} - gaming_rv_sensor::gaming_rv_sensor() : m_accel_sensor(NULL) , m_gyro_sensor(NULL) @@ -69,7 +58,6 @@ gaming_rv_sensor::gaming_rv_sensor() m_name = string(SENSOR_NAME); register_supported_event(GAMING_RV_RAW_DATA_EVENT); - m_enable_gaming_rv = 0; if (!config.get(SENSOR_TYPE_GAMING_RV, ELEMENT_VENDOR, m_vendor)) { ERR("[VENDOR] is empty\n"); diff --git a/src/rotation_vector/gaming_rv/gaming_rv_sensor.h b/src/rotation_vector/gaming_rv/gaming_rv_sensor.h index 9a2a7e7..6572907 100755 --- a/src/rotation_vector/gaming_rv/gaming_rv_sensor.h +++ b/src/rotation_vector/gaming_rv/gaming_rv_sensor.h @@ -50,11 +50,6 @@ private: cmutex m_value_mutex; - orientation_filter m_orientation_filter; - orientation_filter m_orientation_filter_poll; - - unsigned int m_enable_gaming_rv; - unsigned long long m_time; unsigned int m_interval; -- 2.7.4 From 2ee554166327c80f89603b5e886a016d9c0932f2 Mon Sep 17 00:00:00 2001 From: Ramasamy Date: Fri, 5 Jun 2015 16:19:01 +0900 Subject: [PATCH 08/16] Adding octave code to compute gyro bias - gyro bias is needed for calibrated gyroscope sensor event - updated octave design code to simulate the gyroscope bias and plot it - substituted euler error code(which showed only drift) with gyroscope bias Change-Id: I3e411db520d6103326c4e2950e05d6930e34dd9b --- .../design/lib/estimate_orientation.m | 6 +++++- src/sensor_fusion/design/sf_orientation.m | 25 +++++++++++----------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/sensor_fusion/design/lib/estimate_orientation.m b/src/sensor_fusion/design/lib/estimate_orientation.m index d7f023a..b2e3b73 100755 --- a/src/sensor_fusion/design/lib/estimate_orientation.m +++ b/src/sensor_fusion/design/lib/estimate_orientation.m @@ -23,7 +23,7 @@ % - Quaternion based approach % - Estimation and correction of orientation errors and bias errors for gyroscope using Kalman filter -function [quat_driv, quat_aid, quat_error] = estimate_orientation(Accel_data, Gyro_data, Mag_data) +function [quat_driv, quat_aid, quat_error, gyro_bias] = estimate_orientation(Accel_data, Gyro_data, Mag_data) PLOT_SCALED_SENSOR_COMPARISON_DATA = 1; PLOT_INDIVIDUAL_SENSOR_INPUT_DATA = 1; @@ -42,6 +42,7 @@ function [quat_driv, quat_aid, quat_error] = estimate_orientation(Accel_data, G GRAVITY = 9.80665; PI = 3.141593; NON_ZERO_VAL = 0.1; + PI_DEG = 180; MOVING_AVERAGE_WINDOW_LENGTH = 20; RAD2DEG = 57.2957795; @@ -62,6 +63,8 @@ function [quat_driv, quat_aid, quat_error] = estimate_orientation(Accel_data, G mag_z = zeros(1,BUFFER_SIZE); MTime = zeros(1,BUFFER_SIZE); + gyro_bias = zeros(3,BUFFER_SIZE); + if MAG_DATA_DISABLED != 1 Mx = Mag_data(1,:); My = Mag_data(2,:); @@ -270,6 +273,7 @@ function [quat_driv, quat_aid, quat_error] = estimate_orientation(Accel_data, G Bx = x(4,i); By = x(5,i); Bz = x(6,i); + gyro_bias(:,i) = [x1; x2; x3] * PI_DEG + [Bx; By; Bz]; end end diff --git a/src/sensor_fusion/design/sf_orientation.m b/src/sensor_fusion/design/sf_orientation.m index 3a97580..1c181cb 100755 --- a/src/sensor_fusion/design/sf_orientation.m +++ b/src/sensor_fusion/design/sf_orientation.m @@ -100,7 +100,11 @@ Mag_data(3,:) = (((dlmread("data/100ms/orientation/roll_pitch_yaw/magnetic.txt") Mag_data(4,:) = ((dlmread("data/100ms/orientation/roll_pitch_yaw/magnetic.txt")(:,4))')(1:BUFFER_SIZE); % estimate orientation -[Quat_driv, Quat_aid, Quat_err] = estimate_orientation(Accel_data, Gyro_data, Mag_data); +[Quat_driv, Quat_aid, Quat_err, Gyro_bias] = estimate_orientation(Accel_data, Gyro_data, Mag_data); + +Gyro_bias(1,:) = Gyro_bias(1,:) + Bias_Gx; +Gyro_bias(2,:) = Gyro_bias(2,:) + Bias_Gy; +Gyro_bias(3,:) = Gyro_bias(3,:) + Bias_Gz; for i = 1:BUFFER_SIZE euler_aid(i,:) = quat2euler(Quat_aid(i,:)); @@ -112,7 +116,7 @@ for i = 1:BUFFER_SIZE OR_driv(1,i) = ROLL_PHASE_CORRECTION * euler_driv(i,2)' * RAD2DEG; OR_driv(2,i) = PITCH_PHASE_CORRECTION * euler_driv(i,1)' * RAD2DEG; OR_driv(3,i) = YAW_PHASE_CORRECTION * euler_driv(i,3)' * RAD2DEG; - + if (OR_driv(3,i) < 0) OR_driv(3,i) = OR_driv(3,i) + 360; end @@ -120,11 +124,6 @@ for i = 1:BUFFER_SIZE if (OR_aid(3,i) < 0) OR_aid(3,i) = OR_aid(3,i) + 360; end - - euler_err(i,:) = quat2euler(Quat_err(i,:)); - OR_err(1,i) = euler_err(i,2)' * RAD2DEG; - OR_err(2,i) = euler_err(i,1)' * RAD2DEG; - OR_err(3,i) = euler_err(i,3)' * RAD2DEG; end % Rotation Plot Results @@ -140,10 +139,10 @@ UA = OR_driv(2,:); p2 = plot(1:length(UA),UA(1,1:length(UA)),'b'); hold on; grid on; -UA = OR_err(2,:); +UA = Gyro_bias(1,:); p3 = plot(1:length(UA),UA(1,1:length(UA)),'g'); title(['Pitch']); -legend([p1 p2 p3],'Aiding System', 'Driving System', 'Quaternion based error'); +legend([p1 p2 p3],'Aiding System', 'Driving System', 'Gyroscope Bias error'); subplot(3,1,2) UA = OR_aid(1,:); p1 = plot(1:length(UA),UA(1,1:length(UA)),'r'); @@ -153,10 +152,10 @@ UA = OR_driv(1,:); p2 = plot(1:length(UA),UA(1,1:length(UA)),'b'); hold on; grid on; -UA = OR_err(1,:); +UA = Gyro_bias(2,:); p3 = plot(1:length(UA),UA(1,1:length(UA)),'g'); title(['Roll']); -legend([p1 p2 p3],'Aiding System', 'Driving System', 'Quaternion based error'); +legend([p1 p2 p3],'Aiding System', 'Driving System', 'Gyroscope Bias error'); subplot(3,1,3) UA = OR_aid(3,:); p1 = plot(1:length(UA),UA(1,1:length(UA)),'r'); @@ -166,7 +165,7 @@ UA = OR_driv(3,:); p2 = plot(1:length(UA),UA(1,1:length(UA)),'b'); hold on; grid on; -UA = OR_err(3,:); +UA = Gyro_bias(3,:); p3 = plot(1:length(UA),UA(1,1:length(UA)),'g'); title(['Yaw']); -legend([p1 p2 p3],'Aiding System', 'Driving System', 'Quaternion based error'); +legend([p1 p2 p3],'Aiding System', 'Driving System', 'Gyroscope Bias error'); -- 2.7.4 From c7faf9a41e75487df1a208a02eddb71f8aa68a1d Mon Sep 17 00:00:00 2001 From: Ramasamy Date: Fri, 5 Jun 2015 16:45:00 +0900 Subject: [PATCH 09/16] Compensating drift before computing noise covariance - Improving accuracy of orientation detection by moving the drift compensation code before computing noise covariance. - resturcturing of the existing octave code. Change-Id: I09691d944ae0c3d731b6fabd098a3652991f7dc7 --- .../design/lib/estimate_orientation.m | 51 ++++++++++++---------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/sensor_fusion/design/lib/estimate_orientation.m b/src/sensor_fusion/design/lib/estimate_orientation.m index b2e3b73..511b646 100755 --- a/src/sensor_fusion/design/lib/estimate_orientation.m +++ b/src/sensor_fusion/design/lib/estimate_orientation.m @@ -172,15 +172,38 @@ function [quat_driv, quat_aid, quat_error, gyro_bias] = estimate_orientation(Ac gyr_y(i) = Gy(i) * PI; gyr_z(i) = Gz(i) * PI; - gyr_x(i) = gyr_x(i) - Bx; - gyr_y(i) = gyr_y(i) - By; - gyr_z(i) = gyr_z(i) - Bz; - euler = quat2euler(quat_aid(i,:)); roll(i) = euler(2); pitch(i) = euler(1); yaw(i) = euler(3); + if i > 1 + A_T(i) = ATime(i) - ATime(i-1); + G_T(i) = GTime(i) - GTime(i-1); + M_T(i) = MTime(i) - MTime(i-1); + end + + dt = G_T(i) * US2S; + + % Driving System (Gyroscope) quaternion generation + % convert scaled gyro data to rad/s + qDot = 0.5 * quat_prod(q, [0 gyr_x(i) gyr_y(i) gyr_z(i)]); + + % Integrate to yield quaternion + q = q + qDot * dt * PI; + + % normalise quaternion + quat_driv(i,:) = q / norm(q); + + % Kalman Filtering + quat_error(i,:) = quat_prod(quat_aid(i,:), quat_driv(i,:)); + + euler_e = quat2euler(quat_error(i,:)); + + gyr_x(i) = gyr_x(i) - (Bx + euler_e(1)); + gyr_y(i) = gyr_y(i) - (By + euler_e(2)); + gyr_z(i) = gyr_z(i) - (Bz + euler_e(3)); + if i <= MOVING_AVERAGE_WINDOW_LENGTH var_Gx(i) = NON_ZERO_VAL; var_Gy(i) = NON_ZERO_VAL; @@ -196,13 +219,7 @@ function [quat_driv, quat_aid, quat_error, gyro_bias] = estimate_orientation(Ac var_pitch(i) = var(pitch((i-MOVING_AVERAGE_WINDOW_LENGTH):i)); var_yaw(i) = var(yaw((i-MOVING_AVERAGE_WINDOW_LENGTH):i)); end - if i > 1 - A_T(i) = ATime(i) - ATime(i-1); - G_T(i) = GTime(i) - GTime(i-1); - M_T(i) = MTime(i) - MTime(i-1); - end - dt = G_T(i) * US2S; Qwn = [var_Gx(i) 0 0;0 var_Gy(i) 0;0 0 var_Gz(i);]; Qwb = (2 * (ZigmaW^2) / TauW) * eye(3); @@ -228,20 +245,6 @@ function [quat_driv, quat_aid, quat_error, gyro_bias] = estimate_orientation(Ac % compute covariance of prediction P = (F * P * F') + Q; - % Driving System (Gyroscope) quaternion generation - % convert scaled gyro data to rad/s - qDot = 0.5 * quat_prod(q, [0 gyr_x(i) gyr_y(i) gyr_z(i)]); - - % Integrate to yield quaternion - q = q + qDot * dt * PI; - - % normalise quaternion - quat_driv(i,:) = q / norm(q); - - % Kalman Filtering - quat_error(i,:) = quat_prod(quat_aid(i,:), quat_driv(i,:)); - - euler_e = quat2euler(quat_error(i,:)); x1 = euler_e(1)'/PI; x2 = euler_e(2)'/PI; x3 = euler_e(3)'/PI; -- 2.7.4 From 850ec1aa7dd85d5c252c64a0cd3b8771bca422cc Mon Sep 17 00:00:00 2001 From: Ankur Date: Fri, 29 May 2015 14:33:13 +0530 Subject: [PATCH 10/16] Adding tilt sensor event definitions [sensor_tilt.h] to avoid build break the sensor_tilt.h file containing the tilt sensor event definitions was missing. This was causing the build to break. Added the tilt sensor event definitions with tilt_raw_data_event. signed-off-by: Ankur Garg Change-Id: I2d7768d70d05c7e4c1be08910276b958e76ef761 --- src/libsensord/sensor_tilt.h | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/libsensord/sensor_tilt.h diff --git a/src/libsensord/sensor_tilt.h b/src/libsensord/sensor_tilt.h new file mode 100644 index 0000000..8b15d01 --- /dev/null +++ b/src/libsensord/sensor_tilt.h @@ -0,0 +1,52 @@ +/* + * libsensord + * + * Copyright (c) 2015 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 __SENSOR_TILT_H__ +#define __SENSOR_TILT_H__ + +//! Pre-defined events for the tilt sensor +//! Sensor Plugin developer can add more event to their own headers + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup SENSOR_TILT tilt Sensor + * @ingroup SENSOR_FRAMEWORK + * + * These APIs are used to control the tilt sensor. + * @{ + */ + +enum tilt_event_type { + TILT_RAW_DATA_EVENT = (TILT_SENSOR << 16) | 0x0001, +}; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif +//! End of a file -- 2.7.4 From 640f8468a27d4500c97f90114963d85394f48752 Mon Sep 17 00:00:00 2001 From: Ramasamy Date: Fri, 5 Jun 2015 17:03:36 +0900 Subject: [PATCH 11/16] Added code to compute gyro bias in orientation_filter - orientation_filter code will compute gyro bias by adding gyro drift and stocastic noise - null offset bias will be computed and added to gyro bias on individual virtual sensor code. - needed for uncalibrated gyroscope virtual sensor Change-Id: I09cc8af16c12ea77faee704d0ccf6ba0b4d72736 --- src/sensor_fusion/orientation_filter.cpp | 6 ++++++ src/sensor_fusion/orientation_filter.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/sensor_fusion/orientation_filter.cpp b/src/sensor_fusion/orientation_filter.cpp index c3a6c92..67ff072 100644 --- a/src/sensor_fusion/orientation_filter.cpp +++ b/src/sensor_fusion/orientation_filter.cpp @@ -234,6 +234,8 @@ inline void orientation_filter::time_update() euler_error = (quat2euler(quat_error)).m_ang / (TYPE) PI; + m_gyro_bias = euler_error.m_ang * (TYPE) PI; + quaternion quat_eu_er(1, euler_error.m_ang.m_vec[0], euler_error.m_ang.m_vec[1], euler_error.m_ang.m_vec[2]); @@ -298,6 +300,8 @@ inline void orientation_filter::time_update_gaming_rv() euler_error = (quat2euler(quat_error)).m_ang / (TYPE) PI; + m_gyro_bias = euler_error.m_ang * (TYPE) PI; + euler_aid = quat2euler(m_quat_aid); euler_driv = quat2euler(quat_output); @@ -351,6 +355,8 @@ inline void orientation_filter::measurement_update() vect vec(arr_bias); m_bias_correction = vec; + + m_gyro_bias = m_gyro_bias + vec; } template diff --git a/src/sensor_fusion/orientation_filter.h b/src/sensor_fusion/orientation_filter.h index c89a6b8..892c87c 100644 --- a/src/sensor_fusion/orientation_filter.h +++ b/src/sensor_fusion/orientation_filter.h @@ -58,6 +58,7 @@ public: vect m_state_old; vect m_state_error; vect m_bias_correction; + vect m_gyro_bias; quaternion m_quat_aid; quaternion m_quat_driv; rotation_matrix m_rot_matrix; -- 2.7.4 From 356c0559f7aa15747284c6a958458c3cb7e62ccb Mon Sep 17 00:00:00 2001 From: Ramasamy Date: Fri, 5 Jun 2015 17:08:57 +0900 Subject: [PATCH 12/16] Updating standalone c-library test code for orientation sensor - Updating the standalone c-library test code to test if gyro bias values are computed correctly in sensor fusion algorithm. - these test code generally does not follow coding guidelines as these files are not part of tizen build and is used only for internal testing purposes. Change-Id: Iada88a8e5f1122cb0381b4aaac0a57269b43edc5 --- src/sensor_fusion/test/orientation_sensor.cpp | 3 +++ .../test_projects/orientation_sensor_test/orientation_sensor_main.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/sensor_fusion/test/orientation_sensor.cpp b/src/sensor_fusion/test/orientation_sensor.cpp index 784ac3b..decb3cc 100644 --- a/src/sensor_fusion/test/orientation_sensor.cpp +++ b/src/sensor_fusion/test/orientation_sensor.cpp @@ -42,6 +42,7 @@ void pre_process_data(sensor_data *data_out, sensor_data *data_in, void orientation_sensor::get_device_orientation(sensor_data *accel_data, sensor_data *gyro_data, sensor_data *magnetic_data) { + vect vec_bias_gyro(bias_gyro); pre_process_data(accel_data, accel_data, bias_accel, sign_accel, scale_accel); normalize(*accel_data); @@ -52,6 +53,8 @@ void orientation_sensor::get_device_orientation(sensor_data *accel_data, orien_filter.m_magnetic_alignment_factor = magnetic_alignment_factor; orien_filter.get_device_orientation(accel_data, gyro_data, magnetic_data); + + orien_filter.m_gyro_bias = orien_filter.m_gyro_bias + vec_bias_gyro; } #endif diff --git a/src/sensor_fusion/test/test_projects/orientation_sensor_test/orientation_sensor_main.cpp b/src/sensor_fusion/test/test_projects/orientation_sensor_test/orientation_sensor_main.cpp index 2710332..feb7e77 100644 --- a/src/sensor_fusion/test/test_projects/orientation_sensor_test/orientation_sensor_main.cpp +++ b/src/sensor_fusion/test/test_projects/orientation_sensor_test/orientation_sensor_main.cpp @@ -86,6 +86,8 @@ int main() orientation = orien_sensor.orien_filter.m_orientation; + cout << "Gyro Bias in radians\t" << orien_sensor.orien_filter.m_gyro_bias; + orientation = rad2deg(orientation); orientation.m_ang.m_vec[0] *= pitch_phase_compensation; @@ -97,6 +99,8 @@ int main() orien_file << orientation.m_ang; + orientation = orien_sensor.orien_filter.m_orientation; + cout << "Orientation angles\t" << orientation.m_ang << "\n\n"; cout << "Orientation matrix\t" << orien_sensor.orien_filter.m_rot_matrix.m_rot_mat << "\n\n"; -- 2.7.4 From 89028ed6f7e6839bf0cf7d286684007f33964383 Mon Sep 17 00:00:00 2001 From: Ramasamy Date: Fri, 5 Jun 2015 20:04:44 +0900 Subject: [PATCH 13/16] Moving drift compensation before computing covariance in c++ library - Moving drift compensation before computing noise covariance as this provides marginal improvement in orientation estimation. Change-Id: Ic236f8400203e70d9b870186c8e098c4bcc8395f --- src/sensor_fusion/orientation_filter.cpp | 92 +++++++++++++------------------- src/sensor_fusion/orientation_filter.h | 2 + 2 files changed, 38 insertions(+), 56 deletions(-) diff --git a/src/sensor_fusion/orientation_filter.cpp b/src/sensor_fusion/orientation_filter.cpp index 67ff072..ef2e228 100644 --- a/src/sensor_fusion/orientation_filter.cpp +++ b/src/sensor_fusion/orientation_filter.cpp @@ -148,6 +148,32 @@ inline void orientation_filter::compute_covariance() { TYPE var_gyr_x, var_gyr_y, var_gyr_z; TYPE var_roll, var_pitch, var_azimuth; + quaternion quat_diff, quat_error; + + if(!is_initialized(m_quat_driv.m_quat)) + m_quat_driv = m_quat_aid; + + quaternion quat_rot_inc(0, m_gyro.m_data.m_vec[0], m_gyro.m_data.m_vec[1], + m_gyro.m_data.m_vec[2]); + + quat_diff = (m_quat_driv * quat_rot_inc) * (TYPE) 0.5; + + m_quat_driv = m_quat_driv + (quat_diff * (TYPE) m_gyro_dt * (TYPE) PI); + m_quat_driv.quat_normalize(); + + m_quat_output = phase_correction(m_quat_driv, m_quat_aid); + + m_orientation = quat2euler(m_quat_output); + + quat_error = m_quat_aid * m_quat_driv; + + m_euler_error = (quat2euler(quat_error)).m_ang; + + m_gyro.m_data = m_gyro.m_data - m_euler_error.m_ang; + + m_euler_error.m_ang = m_euler_error.m_ang / (TYPE) PI; + + m_gyro_bias = m_euler_error.m_ang * (TYPE) PI; insert_end(m_var_gyr_x, m_gyro.m_data.m_vec[0]); insert_end(m_var_gyr_y, m_gyro.m_data.m_vec[1]); @@ -178,8 +204,6 @@ inline void orientation_filter::compute_covariance() template inline void orientation_filter::time_update() { - quaternion quat_diff, quat_error, quat_output; - euler_angles euler_error; euler_angles orientation; m_tran_mat.m_mat[0][1] = m_gyro.m_data.m_vec[2]; @@ -210,43 +234,22 @@ inline void orientation_filter::time_update() m_state_new.m_vec[j] = NEGLIGIBLE_VAL; } - if(!is_initialized(m_quat_driv.m_quat)) - m_quat_driv = m_quat_aid; - - quaternion quat_rot_inc(0, m_gyro.m_data.m_vec[0], m_gyro.m_data.m_vec[1], - m_gyro.m_data.m_vec[2]); - - quat_diff = (m_quat_driv * quat_rot_inc) * (TYPE) 0.5; - - m_quat_driv = m_quat_driv + (quat_diff * (TYPE) m_gyro_dt * (TYPE) PI); - m_quat_driv.quat_normalize(); - - quat_output = phase_correction(m_quat_driv, m_quat_aid); - - m_quat_9axis = quat_output; + m_quat_9axis = m_quat_output; m_quat_gaming_rv = m_quat_9axis; - m_orientation = quat2euler(quat_output); - m_rot_matrix = quat2rot_mat(m_quat_driv); - quat_error = m_quat_aid * m_quat_driv; - - euler_error = (quat2euler(quat_error)).m_ang / (TYPE) PI; - - m_gyro_bias = euler_error.m_ang * (TYPE) PI; - - quaternion quat_eu_er(1, euler_error.m_ang.m_vec[0], euler_error.m_ang.m_vec[1], - euler_error.m_ang.m_vec[2]); + quaternion quat_eu_er(1, m_euler_error.m_ang.m_vec[0], m_euler_error.m_ang.m_vec[1], + m_euler_error.m_ang.m_vec[2]); m_quat_driv = (m_quat_driv * quat_eu_er) * (TYPE) PI; m_quat_driv.quat_normalize(); if (is_initialized(m_state_new)) { - m_state_error.m_vec[0] = euler_error.m_ang.m_vec[0]; - m_state_error.m_vec[1] = euler_error.m_ang.m_vec[1]; - m_state_error.m_vec[2] = euler_error.m_ang.m_vec[2]; + m_state_error.m_vec[0] = m_euler_error.m_ang.m_vec[0]; + m_state_error.m_vec[1] = m_euler_error.m_ang.m_vec[1]; + m_state_error.m_vec[2] = m_euler_error.m_ang.m_vec[2]; m_state_error.m_vec[3] = m_state_new.m_vec[3]; m_state_error.m_vec[4] = m_state_new.m_vec[4]; m_state_error.m_vec[5] = m_state_new.m_vec[5]; @@ -256,8 +259,6 @@ inline void orientation_filter::time_update() template inline void orientation_filter::time_update_gaming_rv() { - quaternion quat_diff, quat_error, quat_output; - euler_angles euler_error; euler_angles orientation; euler_angles euler_aid; euler_angles euler_driv; @@ -281,29 +282,8 @@ inline void orientation_filter::time_update_gaming_rv() m_pred_cov = (m_tran_mat * m_pred_cov * tran(m_tran_mat)) + m_driv_cov; - if(!is_initialized(m_quat_driv.m_quat)) - m_quat_driv = m_quat_aid; - - quaternion quat_rot_inc(0, m_gyro.m_data.m_vec[0], m_gyro.m_data.m_vec[1], - m_gyro.m_data.m_vec[2]); - - quat_diff = (m_quat_driv * quat_rot_inc) * (TYPE) 0.5; - - m_quat_driv = m_quat_driv + (quat_diff * (TYPE) m_gyro_dt * (TYPE) PI); - m_quat_driv.quat_normalize(); - - quat_output = phase_correction(m_quat_driv, m_quat_aid); - - m_orientation = quat2euler(quat_output); - - quat_error = m_quat_aid * m_quat_driv; - - euler_error = (quat2euler(quat_error)).m_ang / (TYPE) PI; - - m_gyro_bias = euler_error.m_ang * (TYPE) PI; - euler_aid = quat2euler(m_quat_aid); - euler_driv = quat2euler(quat_output); + euler_driv = quat2euler(m_quat_output); euler_angles euler_gaming_rv(euler_aid.m_ang.m_vec[0], euler_aid.m_ang.m_vec[1], euler_driv.m_ang.m_vec[2]); @@ -311,9 +291,9 @@ inline void orientation_filter::time_update_gaming_rv() m_quat_gaming_rv = euler2quat(euler_gaming_rv); if (is_initialized(m_state_new)) { - m_state_error.m_vec[0] = euler_error.m_ang.m_vec[0]; - m_state_error.m_vec[1] = euler_error.m_ang.m_vec[1]; - m_state_error.m_vec[2] = euler_error.m_ang.m_vec[2]; + m_state_error.m_vec[0] = m_euler_error.m_ang.m_vec[0]; + m_state_error.m_vec[1] = m_euler_error.m_ang.m_vec[1]; + m_state_error.m_vec[2] = m_euler_error.m_ang.m_vec[2]; m_state_error.m_vec[3] = m_state_new.m_vec[3]; m_state_error.m_vec[4] = m_state_new.m_vec[4]; m_state_error.m_vec[5] = m_state_new.m_vec[5]; diff --git a/src/sensor_fusion/orientation_filter.h b/src/sensor_fusion/orientation_filter.h index 892c87c..3133f8b 100644 --- a/src/sensor_fusion/orientation_filter.h +++ b/src/sensor_fusion/orientation_filter.h @@ -66,6 +66,8 @@ public: quaternion m_quat_9axis; quaternion m_quat_gaming_rv; quaternion m_quaternion; + quaternion m_quat_output; + euler_angles m_euler_error; TYPE m_gyro_dt; int m_magnetic_alignment_factor; -- 2.7.4 From 0cf26fae7c18563d9e95b3d95192176a6c48cf0f Mon Sep 17 00:00:00 2001 From: Ankur Date: Tue, 16 Jun 2015 14:50:48 +0530 Subject: [PATCH 14/16] Adding support for uncal_gyro sensor in fusion_sensor Modifying the fusion sensor to support uncallibrated gyroscope sensor Change-Id: I223e58181b0cbcd3d152548cc2c6401826b35348 --- src/fusion/fusion_sensor.cpp | 99 ++++++++++++++++++++++++++++++------------ src/libsensord/sensor_fusion.h | 14 +++--- 2 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/fusion/fusion_sensor.cpp b/src/fusion/fusion_sensor.cpp index 42a8e41..48ba309 100755 --- a/src/fusion/fusion_sensor.cpp +++ b/src/fusion/fusion_sensor.cpp @@ -44,6 +44,7 @@ #define GEOMAGNETIC_RV_ENABLED 5 #define ORIENTATION_ENABLED 7 #define ROTATION_VECTOR_ENABLED 7 +#define UNCAL_GYRO_ENABLED 7 #define INITIAL_VALUE -1 @@ -282,7 +283,8 @@ void fusion_sensor::synthesize(const sensor_event_t &event, vectorget_sensor_data(ACCELEROMETER_RAW_DATA_EVENT, accel_data); @@ -373,7 +401,8 @@ int fusion_sensor::get_sensor_data(const unsigned int event_type, sensor_data_t if (event_type == FUSION_ORIENTATION_ENABLED || event_type == FUSION_ROTATION_VECTOR_ENABLED || - event_type == FUSION_GAMING_ROTATION_VECTOR_ENABLED) + event_type == FUSION_GAMING_ROTATION_VECTOR_ENABLED || + event_type == FUSION_UNCAL_GYRO_ENABLED) { m_gyro_sensor->get_sensor_data(GYROSCOPE_RAW_DATA_EVENT, gyro_data); pre_process_data(gyro, gyro_data.values, m_gyro_static_bias, m_gyro_rotation_direction_compensation, m_gyro_scale); @@ -382,7 +411,8 @@ int fusion_sensor::get_sensor_data(const unsigned int event_type, sensor_data_t if (event_type == FUSION_ORIENTATION_ENABLED || event_type == FUSION_ROTATION_VECTOR_ENABLED || - event_type == FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED) + event_type == FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED || + event_type == FUSION_UNCAL_GYRO_ENABLED) { m_magnetic_sensor->get_sensor_data(GEOMAGNETIC_RAW_DATA_EVENT, magnetic_data); pre_process_data(magnetic, magnetic_data.values, m_geomagnetic_static_bias, m_geomagnetic_rotation_direction_compensation, m_geomagnetic_scale); @@ -391,20 +421,35 @@ int fusion_sensor::get_sensor_data(const unsigned int event_type, sensor_data_t m_orientation_filter_poll.m_magnetic_alignment_factor = m_magnetic_alignment_factor; - if (event_type == FUSION_ORIENTATION_ENABLED || event_type == FUSION_ROTATION_VECTOR_ENABLED) + if (event_type == FUSION_ORIENTATION_ENABLED || + event_type == FUSION_ROTATION_VECTOR_ENABLED || + event_type == FUSION_UNCAL_GYRO_ENABLED) m_orientation_filter_poll.get_device_orientation(&accel, &gyro, &magnetic); else if (event_type == FUSION_GAMING_ROTATION_VECTOR_ENABLED) m_orientation_filter_poll.get_device_orientation(&accel, &gyro, NULL); else if (event_type == FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED) m_orientation_filter_poll.get_device_orientation(&accel, NULL, &magnetic); - data.accuracy = SENSOR_ACCURACY_GOOD; - data.timestamp = get_timestamp(); - data.value_count = 4; - data.values[0] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[0]; - data.values[1] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[1]; - data.values[2] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[2]; - data.values[3] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[3]; + if (event_type == FUSION_UNCAL_GYRO_ENABLED) { + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = get_timestamp(); + data.value_count = 3; + data.values[0] = m_orientation_filter_poll.m_gyro_bias.m_vec[0]; + data.values[1] = m_orientation_filter_poll.m_gyro_bias.m_vec[1]; + data.values[2] = m_orientation_filter_poll.m_gyro_bias.m_vec[2]; + } + else if (event_type != FUSION_ORIENTATION_ENABLED || + event_type != FUSION_ROTATION_VECTOR_ENABLED || + event_type != FUSION_GAMING_ROTATION_VECTOR_ENABLED || + event_type != FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED) { + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = get_timestamp(); + data.value_count = 4; + data.values[0] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[0]; + data.values[1] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[1]; + data.values[2] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[2]; + data.values[3] = m_orientation_filter_poll.m_quaternion.m_quat.m_vec[3]; + } return 0; } diff --git a/src/libsensord/sensor_fusion.h b/src/libsensord/sensor_fusion.h index 8f80499..1a65ea3 100755 --- a/src/libsensord/sensor_fusion.h +++ b/src/libsensord/sensor_fusion.h @@ -37,12 +37,14 @@ extern "C" */ enum fusion_event_type { FUSION_EVENT = (FUSION_SENSOR << 16) | 0x0001, - FUSION_CALIBRATION_NEEDED_EVENT = (FUSION_SENSOR << 16) | 0x0002, - FUSION_ORIENTATION_ENABLED = (FUSION_SENSOR << 16) | 0x0003, - FUSION_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0004, - FUSION_GAMING_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0005, - FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0006, - FUSION_TILT_ENABLED = (FUSION_SENSOR << 16) | 0x0007, + FUSION_UNCAL_GYRO_EVENT = (FUSION_SENSOR << 16) | 0x0002, + FUSION_CALIBRATION_NEEDED_EVENT = (FUSION_SENSOR << 16) | 0x0003, + FUSION_ORIENTATION_ENABLED = (FUSION_SENSOR << 16) | 0x0004, + FUSION_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0005, + FUSION_GAMING_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0006, + FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0007, + FUSION_TILT_ENABLED = (FUSION_SENSOR << 16) | 0x0008, + FUSION_UNCAL_GYRO_ENABLED = (FUSION_SENSOR << 16) | 0x0009, }; /** -- 2.7.4 From d8a2b899d9a0fdad534bdf70d98507624178a23f Mon Sep 17 00:00:00 2001 From: Ankur Date: Tue, 16 Jun 2015 18:18:42 +0530 Subject: [PATCH 15/16] Adding Uncal Gyro Sensor and related files Adding uncal_gyro sensor files. Change-Id: I5d76a4a40ba774c50fcf0130c78e32011bd106a9 --- packaging/sensord.spec | 2 + sensor_plugins.xml.in | 1 + src/CMakeLists.txt | 7 + src/libsensord/CMakeLists.txt | 1 + src/libsensord/client_common.cpp | 2 + src/libsensord/sensor_internal.h | 1 + src/libsensord/sensor_internal_deprecated.h | 1 + src/libsensord/sensor_uncal_gyro.h | 52 +++++ src/uncal_gyro/CMakeLists.txt | 24 +++ src/uncal_gyro/uncal_gyro_sensor.cpp | 319 ++++++++++++++++++++++++++++ src/uncal_gyro/uncal_gyro_sensor.h | 70 ++++++ virtual_sensors.xml | 21 ++ 12 files changed, 501 insertions(+) create mode 100644 src/libsensord/sensor_uncal_gyro.h create mode 100644 src/uncal_gyro/CMakeLists.txt create mode 100644 src/uncal_gyro/uncal_gyro_sensor.cpp create mode 100644 src/uncal_gyro/uncal_gyro_sensor.h diff --git a/packaging/sensord.spec b/packaging/sensord.spec index 499c99e..5ca2327 100755 --- a/packaging/sensord.spec +++ b/packaging/sensord.spec @@ -31,6 +31,7 @@ BuildRequires: pkgconfig(capi-system-info) %define geomagnetic_rv_state ON %define gaming_rv_state ON %define tilt_state ON +%define uncal_gyro_state ON %define build_test_suite OFF %description @@ -82,6 +83,7 @@ cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DACCEL=%{accel_state} \ -DORIENTATION=%{orientation_state} -DGRAVITY=%{gravity_state} \ -DLINEAR_ACCEL=%{linear_accel_state} -DRV=%{rv_state} \ -DGEOMAGNETIC_RV=%{geomagnetic_rv_state} -DGAMING_RV=%{gaming_rv_state} \ + -DUNCAL_GYRO=%{uncal_gyro_state} \ -DTILT=%{tilt_state} -DTEST_SUITE=%{build_test_suite} \ -DLIBDIR=%{_libdir} -DINCLUDEDIR=%{_includedir} diff --git a/sensor_plugins.xml.in b/sensor_plugins.xml.in index c1822ce..66d7d26 100755 --- a/sensor_plugins.xml.in +++ b/sensor_plugins.xml.in @@ -25,5 +25,6 @@ + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 65f0ec7..39dc767 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,10 @@ IF("${TILT}" STREQUAL "ON") set(SENSOR_FUSION_ENABLE "1") set(TILT_ENABLE "1") ENDIF() +IF("${UNCAL_GYRO}" STREQUAL "ON") +set(SENSOR_FUSION_ENABLE "1") +set(UNCAL_GYRO_ENABLE "1") +ENDIF() IF("${GRAVITY}" STREQUAL "ON") set(SENSOR_FUSION_ENABLE "1") set(ORIENTATION_ENABLE "1") @@ -75,6 +79,9 @@ ENDIF() IF("${TILT_ENABLE}" STREQUAL "1") add_subdirectory(tilt) ENDIF() +IF("${UNCAL_GYRO_ENABLE}" STREQUAL "1") +add_subdirectory(uncal_gyro) +ENDIF() add_subdirectory(rotation_vector) add_subdirectory(server) diff --git a/src/libsensord/CMakeLists.txt b/src/libsensord/CMakeLists.txt index a8b8aab..bd56d4b 100755 --- a/src/libsensord/CMakeLists.txt +++ b/src/libsensord/CMakeLists.txt @@ -62,4 +62,5 @@ install(FILES sensor_temperature.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/senso install(FILES sensor_motion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/) install(FILES sensor_fusion.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/) install(FILES sensor_deprecated.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/) +install(FILES sensor_uncal_gyro.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/) install(FILES ${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff --git a/src/libsensord/client_common.cpp b/src/libsensord/client_common.cpp index 082c31d..29d056f 100755 --- a/src/libsensord/client_common.cpp +++ b/src/libsensord/client_common.cpp @@ -45,6 +45,7 @@ log_element g_log_elements[] = { FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, GAMING_RV_SENSOR, 0, 1), FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, FUSION_SENSOR, 0, 1), FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, TILT_SENSOR, 0, 1), + FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, UNCAL_GYROSCOPE_SENSOR, 0, 1), FILL_LOG_ELEMENT(LOG_ID_EVENT, GEOMAGNETIC_CALIBRATION_NEEDED_EVENT, 0, 1), FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_CHANGE_STATE_EVENT, 0,1), @@ -69,6 +70,7 @@ log_element g_log_elements[] = { FILL_LOG_ELEMENT(LOG_ID_EVENT, GAMING_RV_RAW_DATA_EVENT, 0, 10), FILL_LOG_ELEMENT(LOG_ID_EVENT, FUSION_EVENT, 0, 10), FILL_LOG_ELEMENT(LOG_ID_EVENT, TILT_RAW_DATA_EVENT, 0, 10), + FILL_LOG_ELEMENT(LOG_ID_EVENT, UNCAL_GYRO_RAW_DATA_EVENT, 0, 10), }; typedef unordered_map log_map; diff --git a/src/libsensord/sensor_internal.h b/src/libsensord/sensor_internal.h index 7842cda..477e6f0 100755 --- a/src/libsensord/sensor_internal.h +++ b/src/libsensord/sensor_internal.h @@ -56,6 +56,7 @@ extern "C" #include #include #include +#include typedef void (*sensor_cb_t)(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data); diff --git a/src/libsensord/sensor_internal_deprecated.h b/src/libsensord/sensor_internal_deprecated.h index fdcbab1..3f6aede 100755 --- a/src/libsensord/sensor_internal_deprecated.h +++ b/src/libsensord/sensor_internal_deprecated.h @@ -55,6 +55,7 @@ extern "C" #include #include #include +#include #define MAX_KEY_LEN 30 diff --git a/src/libsensord/sensor_uncal_gyro.h b/src/libsensord/sensor_uncal_gyro.h new file mode 100644 index 0000000..92494a7 --- /dev/null +++ b/src/libsensord/sensor_uncal_gyro.h @@ -0,0 +1,52 @@ +/* + * libsensord + * + * Copyright (c) 2015 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 __SENSOR_UNCAL_GYRO_H__ +#define __SENSOR_UNCAL_GYRO_H__ + +//! Pre-defined events for the uncal gyroscope sensor +//! Sensor Plugin developer can add more event to their own headers + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup UNCAL_SENSOR_GYRO Gyro Sensor + * @ingroup SENSOR_FRAMEWORK + * + * These APIs are used to control the gyro sensor. + * @{ + */ + +enum uncal_gyro_event_type { + UNCAL_GYRO_RAW_DATA_EVENT = (UNCAL_GYROSCOPE_SENSOR << 16) | 0x0001, +}; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif +//! End of a file diff --git a/src/uncal_gyro/CMakeLists.txt b/src/uncal_gyro/CMakeLists.txt new file mode 100644 index 0000000..12d5b3d --- /dev/null +++ b/src/uncal_gyro/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 2.6) +project(uncal_gyro CXX) + +SET(SENSOR_NAME uncal_gyro_sensor) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}/src/libsensord) +include_directories(${CMAKE_SOURCE_DIR}/src/sensor_fusion) + +FOREACH(flag ${gravity_pkgs_LDFLAGS}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +FOREACH(flag ${uncal_gyro_pkgs_CFLAGS}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +add_library(${SENSOR_NAME} SHARED + uncal_gyro_sensor.cpp + ) + +target_link_libraries(${SENSOR_NAME} ${uncal_gyro_pkgs_LDFLAGS} "-lm") + +install(TARGETS ${SENSOR_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/sensord) diff --git a/src/uncal_gyro/uncal_gyro_sensor.cpp b/src/uncal_gyro/uncal_gyro_sensor.cpp new file mode 100644 index 0000000..f173f3f --- /dev/null +++ b/src/uncal_gyro/uncal_gyro_sensor.cpp @@ -0,0 +1,319 @@ +/* + * sensord + * + * Copyright (c) 2015 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 + +#define SENSOR_NAME "UNCAL_GYROSCOPE_SENSOR" +#define SENSOR_TYPE_UNCAL_GYRO "UNCAL_GYROSCOPE" + +#define GYROSCOPE_ENABLED 0x01 +#define GYRO_BIAS_ENABLED 0x02 +#define UNCAL_GYRO_BIAS_ENABLED 3 + +#define INITIAL_VALUE -1 + +#define MS_TO_US 1000 +#define MIN_DELIVERY_DIFF_FACTOR 0.75f + +#define PI 3.141593 +#define AZIMUTH_OFFSET_DEGREES 360 +#define AZIMUTH_OFFSET_RADIANS (2 * PI) + +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_DEFAULT_SAMPLING_TIME "DEFAULT_SAMPLING_TIME" + +uncal_gyro_sensor::uncal_gyro_sensor() +: m_accel_sensor(NULL) +, m_gyro_sensor(NULL) +, m_magnetic_sensor(NULL) +, m_fusion_sensor(NULL) +, m_time(0) +{ + cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance(); + + sensor_hal *fusion_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(FUSION_SENSOR); + if (!fusion_sensor_hal) + m_hardware_fusion = false; + else + m_hardware_fusion = true; + + m_name = string(SENSOR_NAME); + register_supported_event(UNCAL_GYRO_RAW_DATA_EVENT); + + if (!config.get(SENSOR_TYPE_UNCAL_GYRO, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_UNCAL_GYRO, ELEMENT_RAW_DATA_UNIT, m_raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + INFO("m_raw_data_unit = %s", m_raw_data_unit.c_str()); + + if (!config.get(SENSOR_TYPE_UNCAL_GYRO, ELEMENT_DEFAULT_SAMPLING_TIME, &m_default_sampling_time)) { + ERR("[DEFAULT_SAMPLING_TIME] is empty\n"); + throw ENXIO; + } + + INFO("m_default_sampling_time = %d", m_default_sampling_time); + + m_interval = m_default_sampling_time * MS_TO_US; +} + +uncal_gyro_sensor::~uncal_gyro_sensor() +{ + INFO("uncal_gyro_sensor is destroyed!\n"); +} + +bool uncal_gyro_sensor::init(void) +{ + m_accel_sensor = sensor_plugin_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR); + m_gyro_sensor = sensor_plugin_loader::get_instance().get_sensor(GYROSCOPE_SENSOR); + m_magnetic_sensor = sensor_plugin_loader::get_instance().get_sensor(GEOMAGNETIC_SENSOR); + + m_fusion_sensor = sensor_plugin_loader::get_instance().get_sensor(FUSION_SENSOR); + + if (!m_accel_sensor || !m_gyro_sensor || !m_magnetic_sensor || !m_fusion_sensor) { + ERR("Failed to load sensors, accel: 0x%x, gyro: 0x%x, mag: 0x%x, fusion: 0x%x", + m_accel_sensor, m_gyro_sensor, m_magnetic_sensor, m_fusion_sensor); + return false; + } + + INFO("%s is created!\n", sensor_base::get_name()); + + return true; +} + +sensor_type_t uncal_gyro_sensor::get_type(void) +{ + return UNCAL_GYROSCOPE_SENSOR; +} + +bool uncal_gyro_sensor::on_start(void) +{ + AUTOLOCK(m_mutex); + + if (!m_hardware_fusion) { + m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT); + m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_accel_sensor->start(); + m_gyro_sensor->add_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_gyro_sensor->start(); + m_magnetic_sensor->add_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_magnetic_sensor->start(); + } + + m_fusion_sensor->register_supported_event(FUSION_UNCAL_GYRO_EVENT); + m_fusion_sensor->register_supported_event(FUSION_UNCAL_GYRO_ENABLED); + m_fusion_sensor->add_client(FUSION_UNCAL_GYRO_EVENT); + m_fusion_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false); + m_fusion_sensor->start(); + + activate(); + return true; +} + +bool uncal_gyro_sensor::on_stop(void) +{ + AUTOLOCK(m_mutex); + + if (!m_hardware_fusion) { + m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT); + m_accel_sensor->delete_interval((intptr_t)this, false); + m_accel_sensor->stop(); + m_gyro_sensor->delete_client(GYROSCOPE_RAW_DATA_EVENT); + m_gyro_sensor->delete_interval((intptr_t)this, false); + m_gyro_sensor->stop(); + m_magnetic_sensor->delete_client(GEOMAGNETIC_RAW_DATA_EVENT); + m_magnetic_sensor->delete_interval((intptr_t)this, false); + m_magnetic_sensor->stop(); + } + + m_fusion_sensor->delete_client(FUSION_UNCAL_GYRO_EVENT); + m_fusion_sensor->delete_interval((intptr_t)this, false); + m_fusion_sensor->unregister_supported_event(FUSION_UNCAL_GYRO_EVENT); + m_fusion_sensor->unregister_supported_event(FUSION_UNCAL_GYRO_ENABLED); + m_fusion_sensor->stop(); + + deactivate(); + return true; +} + +bool uncal_gyro_sensor::add_interval(int client_id, unsigned int interval) +{ + AUTOLOCK(m_mutex); + + if (!m_hardware_fusion) { + m_accel_sensor->add_interval(client_id, interval, false); + m_gyro_sensor->add_interval(client_id, interval, false); + m_magnetic_sensor->add_interval(client_id, interval, false); + } + + m_fusion_sensor->add_interval(client_id, interval, false); + + return sensor_base::add_interval(client_id, interval, false); +} + +bool uncal_gyro_sensor::delete_interval(int client_id) +{ + AUTOLOCK(m_mutex); + + if (!m_hardware_fusion) { + m_accel_sensor->delete_interval(client_id, false); + m_gyro_sensor->delete_interval(client_id, false); + m_magnetic_sensor->delete_interval(client_id, false); + } + + m_fusion_sensor->delete_interval(client_id, false); + + return sensor_base::delete_interval(client_id, false); +} + +void uncal_gyro_sensor::synthesize(const sensor_event_t &event, vector &outs) +{ + sensor_event_t uncal_gyro_event; + unsigned long long diff_time; + float azimuth_offset; + + if (event.event_type == GYROSCOPE_RAW_DATA_EVENT) { + diff_time = event.data.timestamp - m_time; + + if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR)) + return; + + m_gyro.m_data.m_vec[0] = event.data.values[0]; + m_gyro.m_data.m_vec[1] = event.data.values[1]; + m_gyro.m_data.m_vec[2] = event.data.values[2]; + + m_gyro.m_time_stamp = event.data.timestamp; + + m_enable_uncal_gyro |= GYROSCOPE_ENABLED; + } + + if (event.event_type == FUSION_UNCAL_GYRO_EVENT) { + diff_time = event.data.timestamp - m_time; + + if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR)) + return; + + m_fusion.m_data.m_vec[0] = event.data.values[0]; + m_fusion.m_data.m_vec[1] = event.data.values[1]; + m_fusion.m_data.m_vec[2] = event.data.values[2]; + + m_fusion.m_time_stamp = event.data.timestamp; + + m_enable_uncal_gyro |= GYRO_BIAS_ENABLED; + } + + if (m_enable_uncal_gyro == UNCAL_GYRO_BIAS_ENABLED) { + m_enable_uncal_gyro = 0; + + m_time = get_timestamp(); + uncal_gyro_event.sensor_id = get_id(); + uncal_gyro_event.event_type = UNCAL_GYRO_RAW_DATA_EVENT; + uncal_gyro_event.data.value_count = 6; + uncal_gyro_event.data.timestamp = m_time; + uncal_gyro_event.data.accuracy = SENSOR_ACCURACY_GOOD; + uncal_gyro_event.data.values[0] = m_gyro.m_data.m_vec[0]; + uncal_gyro_event.data.values[1] = m_gyro.m_data.m_vec[1]; + uncal_gyro_event.data.values[2] = m_gyro.m_data.m_vec[2]; + + uncal_gyro_event.data.values[3] = m_fusion.m_data.m_vec[0]; + uncal_gyro_event.data.values[4] = m_fusion.m_data.m_vec[1]; + uncal_gyro_event.data.values[5] = m_fusion.m_data.m_vec[2]; + + push(uncal_gyro_event); + } + + return; +} + +int uncal_gyro_sensor::get_sensor_data(const unsigned int event_type, sensor_data_t &data) +{ + sensor_data_t fusion_data, gyro_data; + + if (event_type != UNCAL_GYRO_RAW_DATA_EVENT) + return -1; + + m_fusion_sensor->get_sensor_data(FUSION_UNCAL_GYRO_ENABLED, fusion_data); + m_gyro_sensor->get_sensor_data(GYROSCOPE_RAW_DATA_EVENT, gyro_data); + + data.accuracy = fusion_data.accuracy; + data.timestamp = get_timestamp(); + data.value_count = 6; + data.values[0] = gyro_data.values[0]; + data.values[1] = gyro_data.values[1]; + data.values[2] = gyro_data.values[2]; + data.values[3] = fusion_data.values[0]; + data.values[4] = fusion_data.values[1]; + data.values[5] = fusion_data.values[2]; + + return 0; +} + +bool uncal_gyro_sensor::get_properties(sensor_properties_s &properties) +{ + properties.resolution = 0.000001; + properties.vendor = m_vendor; + properties.name = SENSOR_NAME; + properties.min_interval = 1; + properties.fifo_count = 0; + properties.max_batch_count = 0; + + return true; +} + +extern "C" sensor_module* create(void) +{ + uncal_gyro_sensor *sensor; + + try { + sensor = new(std::nothrow) uncal_gyro_sensor; + } catch (int err) { + ERR("Failed to create module, err: %d, cause: %s", err, strerror(err)); + return NULL; + } + + sensor_module *module = new(std::nothrow) sensor_module; + retvm_if(!module || !sensor, NULL, "Failed to allocate memory"); + + module->sensors.push_back(sensor); + return module; +} diff --git a/src/uncal_gyro/uncal_gyro_sensor.h b/src/uncal_gyro/uncal_gyro_sensor.h new file mode 100644 index 0000000..dccb6f0 --- /dev/null +++ b/src/uncal_gyro/uncal_gyro_sensor.h @@ -0,0 +1,70 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _UNCAL_GYRO_SENSOR_H_ +#define _UNCAL_GYRO_SENSOR_H_ + +#include +#include +#include + +class uncal_gyro_sensor : public virtual_sensor { +public: + uncal_gyro_sensor(); + virtual ~uncal_gyro_sensor(); + + bool init(void); + + void synthesize(const sensor_event_t &event, vector &outs); + + bool add_interval(int client_id, unsigned int interval); + bool delete_interval(int client_id); + bool get_properties(sensor_properties_s &properties); + sensor_type_t get_type(void); + + int get_sensor_data(const unsigned int event_type, sensor_data_t &data); + +private: + sensor_base *m_accel_sensor; + sensor_base *m_magnetic_sensor; + sensor_base *m_gyro_sensor; + sensor_base *m_fusion_sensor; + + sensor_data m_fusion; + sensor_data m_gyro; + + cmutex m_value_mutex; + + unsigned int m_enable_uncal_gyro; + + unsigned long long m_time; + unsigned int m_interval; + + string m_vendor; + string m_raw_data_unit; + int m_default_sampling_time; + float m_gyro_static_bias[3]; + int m_gyro_rotation_direction_compensation[3]; + float m_gyro_scale; + + bool on_start(void); + bool on_stop(void); +}; + +#endif /*_UNCAL_GYRO_SENSOR_H_*/ diff --git a/virtual_sensors.xml b/virtual_sensors.xml index 3005df6..06263c0 100755 --- a/virtual_sensors.xml +++ b/virtual_sensors.xml @@ -73,6 +73,13 @@ + + + + + + + @@ -148,6 +155,13 @@ + + + + + + + @@ -223,5 +237,12 @@ + + + + + + + -- 2.7.4 From ae70a6bddd6bf2a4a90e504b5895f7e2e47550d1 Mon Sep 17 00:00:00 2001 From: Ankur Date: Tue, 16 Jun 2015 18:24:09 +0530 Subject: [PATCH 16/16] Updating Test files to test the Uncal_gyro sensor Add test cases for uncal_gyro sensor to the test files Change-Id: I20243d3ec6e5967ee96a3120a3178af30ab2cd1d --- test/src/api-test.c | 3 +++ test/src/check-sensor.c | 12 ++++++++++++ test/src/sensor-test.c | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/test/src/api-test.c b/test/src/api-test.c index 599041a..8910bd4 100644 --- a/test/src/api-test.c +++ b/test/src/api-test.c @@ -235,6 +235,9 @@ int main(int argc, char **argv) result = check_sensor_api(GAMING_RV_RAW_DATA_EVENT, interval); fprintf(fp, "Gaming Rotation Vector - RAW_DATA_REPORT_ON_TIME - %d\n", result); + result = check_sensor_api(UNCAL_GYROSCOPE_SENSOR, interval); + fprintf(fp, "Uncal Gyro Sensor - RAW_DATA_REPORT_ON_TIME - %d\n", result); + result = check_sensor_api(TEMPERATURE_RAW_DATA_EVENT, interval); fprintf(fp, "Temperature - RAW_DATA_REPORT_ON_TIME - %d\n", result); diff --git a/test/src/check-sensor.c b/test/src/check-sensor.c index 9bba712..6f86cf2 100644 --- a/test/src/check-sensor.c +++ b/test/src/check-sensor.c @@ -75,6 +75,9 @@ void printpollinglogs(sensor_type_t type,sensor_data_t data) case(GAMING_RV_SENSOR): printf("Gaming Rv [%lld] [%6.6f] [%6.6f] [%6.6f] [%6.6f]\n\n", data.timestamp, data.values[0], data.values[1], data.values[2], data.values[3]); break; + case(UNCAL_GYROSCOPE_SENSOR): + printf("Uncal gyro [%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; default: return; } @@ -139,6 +142,11 @@ int get_event(sensor_type_t sensor_type, char str[]) if (strcmp(str, "RAW_DATA_EVENT") == 0) return GAMING_RV_RAW_DATA_EVENT; break; + case UNCAL_GYROSCOPE_SENSOR: + if (strcmp(str, "RAW_DATA_EVENT") == 0) + return UNCAL_GYRO_RAW_DATA_EVENT; + break; + } return -1; } @@ -190,6 +198,10 @@ void callback(sensor_t sensor, unsigned int event_type, sensor_data_t *data, voi case GAMING_RV_SENSOR: printf("Gaming RV [%lld] [%6.6f] [%6.6f] [%6.6f] [%6.6f]\n", data->timestamp, data->values[0], data->values[1], data->values[2], data->values[3]); break; + case UNCAL_GYROSCOPE_SENSOR: + printf("Uncal gyro [%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; + default: return; } diff --git a/test/src/sensor-test.c b/test/src/sensor-test.c index 99ea138..cb37818 100644 --- a/test/src/sensor-test.c +++ b/test/src/sensor-test.c @@ -45,6 +45,7 @@ void usage() printf("[geomagnetic_rv] "); printf("[gaming_rv] "); printf("[light]\n"); + printf("[uncal_gyro]"); printf("event:"); printf("[RAW_DATA_EVENT]\n"); printf("-p: [polling]\n"); @@ -128,6 +129,10 @@ int main(int argc, char **argv) sensor_type = PROXIMITY_SENSOR; event = PROXIMITY_CHANGE_STATE_EVENT; } + else if (strcmp(argv[1], "uncal_gyro") == 0) { + sensor_type = UNCAL_GYROSCOPE_SENSOR; + event = UNCAL_GYRO_RAW_DATA_EVENT; + } else { usage(); } -- 2.7.4