如何在DragonBoard 410c上添加一个customized virtual sensors

随着近些年移动消费产品的快速发展,越来越多的传感器被添加到移动设备当中。而基于传感器各种各样的功能,工程师们开发出丰富多彩的应用,大大丰富了人们对移动设备产品的体验,也一定程度推动了移动消费产品的快速发展。而在未来,运动监测,健康和医疗方面,传感器的开发都将更加重要,而人们对传感器数据的精确度和灵敏性也要求越来越高。为止,在android设备中,为了提高某些应用所需传感器数据的精确性,高通在中间层提供一套基于物理传感器算法的虚拟传感器设备的框架。而本篇我们就来实例一下如何在DragonBoard 410c上添加一个虚拟传感器设备。(这里的虚拟传感器指的是基于软件的传感器设备)


一、 首先我们来了解下什么是虚拟传感器设备,哪些又是物理传感器设备。


Google为Sensor提供了统一的HAL接口,可以在hardware/libhardware/include/hardware/sensors.h看到各类传感器的定义。如下图:




我们可以看到,目前一共支持多达26种sensor,而像加速度传感器,陀螺仪,磁力传感器,光线传感器和距离传感器,温度,压力传感器等等这些都是在物理中实际存在的传感器我们称之为物理传感器,而像线性加速度传感器,旋转矢量传感器,方向传感器等这些都是基于软件的传感器,它们不是物理设备,它们都是从从一个或更多基于硬件的传感器获取它们的数据,然后基于某段算法来提供一种数据,这种模仿基于硬件的传感器我们称为虚拟传感器或软件传感器。


二、程序设计


在高通软件架构中,在HAL层,所有的传感器,包括物理和虚拟传感器都是由NativeSensorManager统一管理着。它的软件框图如下:



NativeSensorManager会在sensor HAL得到加载的时候进行初始化。这里不详细论述它的过程。我们继续关注物理传感器和虚拟传感器。这两种传感器在软件架构上调用和管理是平行的。如下图:



好,那我们现在也知道了什么是虚拟传感器,那么如何在DragonBoard 410c上添加一个虚拟传感器呢。有以下步骤:



而下面给出一个实例,以compasssensor为例,此例在HAL层增加了一个未校准磁力数据的虚拟磁力传感器,它与物理真实磁力传感器的区别是它提供的是未校准的磁力传感器数据,以这个为例子的目的是因为比较易懂,也仅供参考。


The uncalibrated magnetic field sensor can provided more information. Applications can use the data to apply its own algorithms. We can also use this sensor type to debug magnetometer issues.

diff --git a/CompassSensor.cpp b/CompassSensor.cpp
index 66b1db2..045839d 100644
@@ -212,6 +212,19 @@ again:
data->type = SENSOR_TYPE_MAGNETIC_FIELD;
data->timestamp = mPendingEvent.timestamp;
+ /* The raw data is stored inside sensors_event_t.data after
+ * sensors_event_t.magnetic. Notice that the raw data is
+ * required to composite the virtual sensor uncalibrated
+ * magnetic field sensor.
+ *
+ * data[0~2]: calibrated magnetic field data.
+ * data[3]: magnetic field data accuracy.
+ * data[4~6]: uncalibrated magnetic field data.
+ */
+ data->data[4] = mPendingEvent.data[0];
+ data->data[5] = mPendingEvent.data[1];
+ data->data[6] = mPendingEvent.data[2];
+
data++;
numEventReceived++;
}
diff --git a/NativeSensorManager.cpp b/NativeSensorManager.cpp
index f8c0f98..aa2a134 100644
@@ -284,6 +284,7 @@ int NativeSensorManager::getDataInfo() {
int has_compass = 0;
int has_gyro = 0;
int event_count = 0;
+ struct sensor_t sensor_mag;
strlcpy(path, EVENT_PATH, sizeof(path));
file = path + strlen(EVENT_PATH);
@@ -350,6 +351,7 @@ int NativeSensorManager::getDataInfo() {
case SENSOR_TYPE_MAGNETIC_FIELD:
has_compass = 1;
list->driver = new CompassSensor(list);
+ sensor_mag = *(list->sensor);
break;
case SENSOR_TYPE_PROXIMITY:
list->driver = new ProximitySensor(list);
@@ -378,9 +380,20 @@ int NativeSensorManager::getDataInfo() {
*/
CalibrationManager *cm = CalibrationManager::defaultCalibrationManager();
struct SensorRefMap *ref;
- int dep = (1ULL << SENSOR_TYPE_ACCELEROMETER) | (1ULL << SENSOR_TYPE_MAGNETIC_FIELD);
+
+ if ((cm != NULL) && has_compass) {
+ /* The uncalibrated magnetic field sensor shares the same vendor/name as the
+ * calibrated one. */
+ sensor_mag.type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+ if (!initVirtualSensor(&context[mSensorCount], mSensorCount,
+ 1ULL << SENSOR_TYPE_MAGNETIC_FIELD, sensor_mag)) {
+ mSensorCount++;
+ }
+ }
if ((cm != NULL) && has_acc && has_compass) {
+ int dep = (1ULL << SENSOR_TYPE_ACCELEROMETER) | (1ULL << SENSOR_TYPE_MAGNETIC_FIELD);
+
/* HAL implemented orientation. Android will replace it for
* platform with Gyro with SensorFusion.
* The calibration manager will first match "oem-orientation" and
diff --git a/algo/common/common_wrapper.c b/algo/common/common_wrapper.c
index 74ab0a5..1a54d98 100644
@@ -304,6 +304,25 @@ static int config_magnetic(int cmd, struct sensor_algo_args *args)
return 0;
}
+/* The magnetic field raw data is supposed to store at the sensors_event_t:data[4~6]*/
+static int convert_uncalibrated_magnetic(sensors_event_t *raw, sensors_event_t *result,
+ struct sensor_algo_args *args)
+{
+ if (raw->type == SENSOR_TYPE_MAGNETIC_FIELD) {
+ result->uncalibrated_magnetic.x_uncalib = raw->data[4];
+ result->uncalibrated_magnetic.y_uncalib = raw->data[5];
+ result->uncalibrated_magnetic.z_uncalib = raw->data[6];
+
+ result->uncalibrated_magnetic.x_bias = raw->data[4] - raw->data[0];
+ result->uncalibrated_magnetic.y_bias = raw->data[5] - raw->data[1];
+ result->uncalibrated_magnetic.z_bias = raw->data[6] - raw->data[2];
+
+ return 0;
+ }
+
+ return -1;
+}
+
static int cal_init(const struct sensor_cal_module_t *module)
{
AKMPRMS *prms = &g_prms;
@@ -370,6 +389,16 @@ static const char* rotation_vector_match_table[] = {
NULL
};
+static struct sensor_algo_methods_t mag_uncalib_methods = {
+ .convert = convert_uncalibrated_magnetic,
+ .config = NULL,
+};
+
+static const char* mag_uncalib_match_table[] = {
+ MAGNETIC_FIELD_UNCALIBRATED_NAME,
+ NULL
+};
+
static struct sensor_cal_algo_t algo_list[] = {
{
.tag = SENSOR_CAL_ALGO_TAG,
@@ -397,6 +426,16 @@ static struct sensor_cal_algo_t algo_list[] = {
.module = &SENSOR_CAL_MODULE_INFO,
.methods = &rotation_vector_methods,
},
+
+ {
+ .tag = SENSOR_CAL_ALGO_TAG,
+ .version = SENSOR_CAL_ALGO_VERSION,
+ .type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+ .compatible = mag_uncalib_match_table,
+ .module = &SENSOR_CAL_MODULE_INFO,
+ .methods = &mag_uncalib_methods,
+ },
+
};
static struct sensor_cal_methods_t cal_methods = {
diff --git a/sensors.h b/sensors.h
index db739ff..f545312 100644
--- a/ sensors.h
+++ b/ sensors.h
@@ -86,12 +86,14 @@ __BEGIN_DECLS
#define STEP_DETECTOR_NAME "step_detector"
#define GEOMAGNETIC_ROTATION_VECTOR_NAME "geomagnetic_field"
-#define SUPPORTED_SENSORS_TYPE ((1ULL << SENSOR_TYPE_ACCELEROMETER) | \
- (1ULL << SENSOR_TYPE_MAGNETIC_FIELD) | \
- (1ULL << SENSOR_TYPE_PROXIMITY) | \
- (1ULL << SENSOR_TYPE_LIGHT) | \
- (1ULL << SENSOR_TYPE_GYROSCOPE ) | \
- (1ULL << SENSOR_TYPE_PRESSURE))
+/* The hardware sensor type supported by HAL */
+#define SUPPORTED_SENSORS_TYPE ( \
+ (1ULL << SENSOR_TYPE_ACCELEROMETER) | \
+ (1ULL << SENSOR_TYPE_MAGNETIC_FIELD) | \
+ (1ULL << SENSOR_TYPE_PROXIMITY) | \
+ (1ULL << SENSOR_TYPE_LIGHT) | \
+ (1ULL << SENSOR_TYPE_GYROSCOPE ) | \
+ (1ULL << SENSOR_TYPE_PRESSURE))
/*****************************************************************************/


以上就是410c平台sensor代码中如何添加一个基于软件的虚拟传感器整个过程,当然比较简单,现实当中的虚拟传感器存在很多算法,会很复杂,一般都是有第三方sensor厂商提供,但按照上述实例,我们可以快速的定位到相关代码入口,完成基于410c平台添加一个虚拟传感器设备。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值