基于RSL10可穿戴设备的人体行为识别系统
作者:Justice_Gao
一、作品简介
可穿戴设备数量在日常生活中呈指数增长,广泛应用于各个领域,例如医疗保健、生活娱乐、制造业等。 利用可穿戴设备进行人体活动识别,可在不侵犯用户隐私的前提下有效地监控个人身体状况,具有很好的应用前景。本发明首先利用可穿戴设备采集人体活动是的多种传感器数据(包括加速度计、角速度计),通过蓝牙与手机建立通信连接,在手机端部署识别模型,进行人体活动识别,例如走路、跑步、坐下去、站起来、弯腰、起床、跌倒等常见活动。该项目的难点在于需要开发低功耗的数据采集系统,并获取一定量的数据,提取各类活动特征,通过机器学习方法实现有效识别。未来推广后,该项目可应用于老年人或病患安全监控、儿童异常行为识别、健身爱好者运动量评估等。
二、系统框图
如图1所示,将RSL10的纽扣传感器穿戴在身上,主要是在胸口,也可以在腰部增加一个,通过采集数据、数据处理、特征提取、训练机器学习模型、服务器部署算法等过程,通过小程序与云服务器通信,定时将用户运动时产生的六轴数据发送至服务器,并投放至存储在服务器上的机器学习算法模型中进行动作识别,最后服务器返回识别结果至小程序端,并以页面展示和语音播报两种方式呈现,以达到实时检测的效果。在用户完成运动时,将运动期间存储的六轴数据发至服务器,并投放至波峰检测代码中,根据波峰和动作的对应关系计算出每种动作的完成个数,并返回至小程序端进行页面显示。
图1 系统框图
三、部分功能说明
如图2所示,RSL10是一款超低功耗的芯片,采用ARM Cortex-M3处理器和LPDSP32 DSP内核。内部包含DC/DC电源管理模块,AES128加密引擎、DMA、88kB数据存储RAM、384kB Flash,ADC、SPI主从总线、I2C、PWM、UART、Timers,可以很好应用于可穿戴式应用。
图2 RSL10内部资源
如图3所示,BHI160集成了MCU及6轴惯性测量单元(IMU),包括一个3轴陀螺仪和3轴加速度计。Fuser Core是超低功耗32位微控制器,专为Bosch Sensortec的传感器融合和运动识别算法优化定制。与标准微控制器相比,其耗电显著降低,与Cortex M0相比省电最高达95%,与以Cortex M4为基础的设备相比省电最高达90%。
图3 BHI160传感器外设接口示意图
嵌入式软件部分的主要作用是采集加速度和角速度原始传感器,通过蓝牙上传到手机端进行算法处理,识别人体行为。系统及BHI160传感器都初始化以后,与手机建立蓝牙连接,通过蓝牙将数据传输给手机应用端。数据的第一个字节为包序列,后19个字节分别为方向、加速度、角度等数据。
图4 嵌入式软件流程图
//-----------------------------------------------------------------------------
// Copyright (c) 2018 Semiconductor Components Industries LLC
// (d/b/a "ON Semiconductor"). All rights reserved.
// This software and/or documentation is licensed by ON Semiconductor under
// limited terms and conditions. The terms and conditions pertaining to the
// software and/or documentation are available at
// http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf ("ON Semiconductor Standard
// Terms and Conditions of Sale, Section 8 Software") and if applicable the
// software license agreement. Do not use this software and/or documentation
// unless you have carefully read and you agree to the limited terms and
// conditions. By using this software and/or documentation, you agree to the
// limited terms and conditions.
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <math.h>
#include <BDK.h>
#include <BSP_Components.h>
#include <BLE_Components.h>
#include <SoftwareTimer.h>
#include <bsec_integration.h>
uint8_t ble_data_tx[20];
/** Converts measured orientation data into degrees.
*
* GREEN LED will be turned on if board heading is within 10 degrees of
* magnetic north (<=10 or >=350).
*/
void ao_vector_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
float h = data->data_vector.x / 32768.0f * 360.0f;
float p = data->data_vector.y / 32768.0f * 360.0f;
float y = data->data_vector.z / 32768.0f * 360.0f;
if (h > 350.0f || h < 10.0f)
{
LED_On(LED_GREEN);
}
else
{
LED_Off(LED_GREEN);
}
ble_data_tx[1] = data->data_vector.x>>8;
ble_data_tx[2] = data->data_vector.x;
ble_data_tx[3] = data->data_vector.y>>8;
ble_data_tx[4] = data->data_vector.y;
ble_data_tx[5] = data->data_vector.z>>8;
ble_data_tx[6] = data->data_vector.z;
ble_data_tx[0]++;
BLE_ICS_Notify(ble_data_tx, 20);
printf("Orientation: h=%.1f� p=%.1f�, y=%.1f� (%d)\r\n", h, p, y, data->data_vector.status);
}
/** Converts measured linear acceleration data based on sensors dynamic range
* and prints it to debug terminal.
*
* Also turns on RED LED if total acceleration applied to the board is over 1g.
*/
void la_vector_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
/* Linear Acceleration sensor values are scaled using dynamic range. */
uint16_t dyn_range = BHI160_NDOF_GetAccelDynamicRange();
float x = data->data_vector.x / 32768.0f * dyn_range;
float y = data->data_vector.y / 32768.0f * dyn_range;
float z = data->data_vector.z / 32768.0f * dyn_range;
if (fabsf(x) + fabsf(y) + fabsf(z) >= 1.0f)
{
LED_On(LED_RED);
}
else
{
LED_Off(LED_RED);
}
ble_data_tx[7] = data->data_vector.x>>8;
ble_data_tx[8] = data->data_vector.x;
ble_data_tx[9] = data->data_vector.y>>8;
ble_data_tx[10] = data->data_vector.y;
ble_data_tx[11] = data->data_vector.z>>8;
ble_data_tx[12] = data->data_vector.z;
ble_data_tx[0]++;
BLE_ICS_Notify(ble_data_tx, 20);
printf("Linear Accel: x=%.2f g, y=%.2f g, z=%.2f g\r\n", x, y, z);
}
void gyro_vector_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
uint16_t dyn_range = BHI160_NDOF_GetGyroDynamicRange();
float x = data->data_vector.x / 32768.0f * dyn_range;
float y = data->data_vector.y / 32768.0f * dyn_range;
float z = data->data_vector.z / 32768.0f * dyn_range;
if (fabsf(z) > 45.0f)
{
LED_On(LED_BLUE);
}
else
{
LED_Off(LED_BLUE);
}
ble_data_tx[13] = data->data_vector.x>>8;
ble_data_tx[14] = data->data_vector.x;
ble_data_tx[15] = data->data_vector.y>>8;
ble_data_tx[16] = data->data_vector.y;
ble_data_tx[17] = data->data_vector.z>>8;
ble_data_tx[18] = data->data_vector.z;
ble_data_tx[0]++;
BLE_ICS_Notify(ble_data_tx, 20);
printf("Rate of Rotation: x=%.2f �/s, y=%.2f �/s, z=%.2f �/s\r\n", x, y, z);
}
void CustomService_WriteInd(struct BLE_ICS_RxIndData *ind)
{
/* Print at most ind->data_len characters from ind->data array. */
printf("APP: Received message \'%.*s\'\r\n", ind->data_len, ind->data);
/* Echo received message back to TX characteristic. */
//BLE_ICS_Notify(ind->data, ind->data_len);
}
int main(void)
{
int32_t retval;
/* Initialize all needed BDK components. */
BDK_Initialize();
BDK_BLE_Initialize();
BLE_BASS_Initialize(50,1);
BLE_ICS_Initialize(&CustomService_WriteInd);
/* Initialize all LEDs to eliminate any currents from disabled DIO pads. */
LED_Initialize(LED_RED);
LED_Initialize(LED_GREEN);
LED_Initialize(LED_BLUE);
/* Increase I2C bus speed to 400kHz. */
HAL_I2C_SetBusSpeed(HAL_I2C_BUS_SPEED_FAST);
/* Initialize BHI160.
* This may take a while depending on bus speed because RAM patch has to be
* uploaded into BHI160 to enable support for BMM150 magnetometer.
*
* Set temporary timer to see how long it took to initialize and load the
* RAM patch.
*/
LED_On(LED_GREEN);
{
printf("Initializing BHI160.\r\n");
struct SwTimer tim;
struct SwTimer_Duration tim_dur;
SwTimer_Initialize(&tim);
SwTimer_Start(&tim);
retval = BHI160_NDOF_Initialize();
ASSERT_DEBUG(retval == BHY_SUCCESS);
SwTimer_GetElapsed(&tim, &tim_dur);
SwTimer_Remove(&tim);
printf("BHI160 initialized in %lu seconds and %lu ns.\r\n",
tim_dur.seconds, tim_dur.nanoseconds);
}
LED_Off(LED_GREEN);
/* Enable desired virtual sensor outputs. */
retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_ORIENTATION, &ao_vector_cb, 5);
ASSERT_DEBUG(retval == BHY_SUCCESS);
retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_LINEAR_ACCELERATION, &la_vector_cb, 50);
ASSERT_DEBUG(retval == BHY_SUCCESS);
retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_RATE_OF_ROTATION, &gyro_vector_cb, 50);
ASSERT_DEBUG(retval == BHY_SUCCESS);
printf("APP: Entering main loop.\r\n");
while (1)
{
BDK_Schedule();
SYS_WAIT_FOR_INTERRUPT;
}
return 0;
}
数据处理算法主要对六轴原始数据进行特征提取,主要包括:
- 滤波:对原始数据用三阶低通滤波器滤波
- FFT:对原始数据快速傅里叶变换
- 分割数据:对原始数据进行区间分割(将每组20s长的数据 分割成多个2.56s长的小区间数据。为减小误差,分割区间时要求前后两区间具有50%重叠区,因此20s数据可以最多被分成 13 个2.56s的小区间)
- 特征提取:对上述每个小区间进行特征提取
- 保存特征:将提取特征后的特征数据进行存储,以便投入机器学习算法模型训练。
图5 设备实物图
微信小程序软件设计主要分行为识别与行为识别的技术统计等用户交互功能。
四、作品源码
justicegao.rar
(9.09 MB, 下载次数: 3)
数据处理算法不提供,涉及知识产权,见谅。
五、作品功能演示视频
https://training.eeworld.com.cn/course/6118/learn?preview=1#lesson/30684
六、项目总结
大赛分享一之RSL10蓝牙SoC之开发环境搭建
大赛分享二:RSL10蓝牙SoC之BHI160传感器数据采集
大赛分享三:RSL10蓝牙SoC之BMM150地磁传感器数据采集
大赛分享四:RSL10蓝牙SoC之BME680传感器数据采集
大赛分享五:RSL10蓝牙SoC之使用J-Scope调试语音信号
七、其他
感谢论坛举办这次大赛,感谢安森美和安富利能够提供开发板和赛前培训。
感谢各位!
基于RSL10可穿戴设备的人体行为识别系统.docx
(291.5 KB, 下载次数: 2)
|