一、研究背景

2020年全国大学生电子设计大赛中,A题中有一个小项目为步数检测,这让我开始了计步算法的探究。通过查阅文献,最后选择陈国良团队《一种基于自适应波峰检测的MEMS计步算法》一文中提及的波峰检测算法为基础思路,编写了基础的步数检测代码。

二、算法实现

1. 基础思路

通过对人体行走特征进行分析,人行走频率一般在 1~2.5 Hz 范围内,跑步时频率不超过 5 Hz,加速度在 0.2g~2g 之间。由于跑动时步频较大, 15 Hz 和20 Hz 的加速度采样频率无法完整地记录步态信息,本算法选取 50 Hz 采样频率采集加速度数据 。由于人在行走时,空间加速度会有明显的波峰出现,则可以通过波峰检测来读取步数。

首先选取一定范围的采样点,如20个采样点来取最大值,找出潜在波峰。

而真实波峰检测上为避免伪波峰被误检测,需要经过3次滤波:

  1. 行走时,总加速度值会大于某个数值。大于该数值则有可能为真实波峰。当然,考虑到算法可移植性,不同的加速度传感器的加速度值可能不同,则移植到新的硬件平台上需要重新标定阈值。
  2. 人正常行走的时间是在一定频率范围内的,论文中指出时间差满足时间阈值[0.3 s, 0.8 s]为正常态。则将潜在峰值与前一波峰比较,如果时间在该范围内,则为正常行走时间间隔。
  3. 将潜在波峰与前后相邻10个数据点进行比较,若潜在波峰仍为最大值,则该波峰为真实波峰,否则,退出检测。

2. 算法难点及注意事项

(1)不同传感器因为自身性能原因,需要解决陀螺仪传感器的数据漂移。
解决方案:将传感器传回来的x,y,z轴加速度数据平方求和,减小单个方向加速度数据产生的误差。

(2)要进行波峰检测,需要确保数据实时传入且存储,需要用队列这一数据结构来存储数据,确保数据的时间顺序不出差错。
解决方案:构建队列存储、读取数据,实现FIFO(先进先出)功能。

3.总体代码思路

uint16_t WALK_COUNT=0;//初始步数记为0
//uint16_t Real_Peak_position=0;//真实波峰的时间节点
struct max_info maxvalue[2];//至少要3个最大值,最大值均需与前后两个波峰比较,人为设置0为前一值,1为现在值,2为后一值
uint8_t value_right=0,time_right=0,before_after_right=0;
float walk_distance=0;
void walk_step(void)
{
	data_get_once();

    maxvalue[1]=find_max(a,20);//找到20个历元的滑动窗口中的潜在峰值
    if((maxvalue[1].value>MIN_G_SPEED)&&(maxvalue[1].value<MAX_G_SPEED))
    {
        value_right=1;
    }
    if(time_judge(maxvalue[1].position,maxvalue[0].position))
    {
        time_right=1;
    }
    if(before_after_judge(maxvalue[1].value,before,after))
    {
        before_after_right=1;
    }
		
		time_right=1;//我的算法中未采用时间间隔滤波,因为实际测量可能会出现丢步的情况
    if(value_right&&time_right&&before_after_right)
    {
        WALK_COUNT++;
        maxvalue[0].value=maxvalue[1].value;//更新上一波峰值,为下一次波峰比对做准备
        maxvalue[0].position=maxvalue[1].position;
    }else//如果不符合要求
    {
        maxvalue[1].position+=20;//上一个波峰位置加20
    }
		
		value_right=0;
		time_right=0;
		before_after_right=0;
		
		walk_distance=WALK_COUNT*0.60;
}

4. 硬件传感器

加速度传感器选用正点原子ATK-IMU901模块,设置采样频率为50hz。

三、总结

算法总体思路清晰简介,能实际应用再测算步数的最主要原因是,硬件结构即陀螺仪的数据稳定。若使用噪声大,数据易漂移传感器,如MPU6050,应进行数据滤波使数据保持稳定再来考虑算法实现。如采用进行DMP结算或者原始数据读取卡尔曼滤波等。