基于三轴加速度传感器的计步算法

基于三轴加速度传感器计步算法

By Sky.J 2018.08.08

概述

今天主要是想要分享利用三轴加速度传感器计步的一个算法步骤。

 

数据分析--->模型

这里拿到的是ADI公司的测试数据,可以看到不管如何佩戴计步器,总有至少一个轴具有相对较大的周期性加速度变化。那么我们就可以从这里着手,进行数据分析,判断步伐。

算法

1,均值滤波器---滤波

均值滤波器实现均值滤波,其实很简单就是拿到多组x,y,z三轴数据,求平均值。最后的平均值作为输出结果,使输出结果更加平滑。完成初步滤波。

下面是伪代码

#define FILTER_CNT			4

typedef struct {
  short x;
  short y;
  short z;
}axis_info_t;

typedef struct filter_avg{
	axis_info_t info[FILTER_CNT];
	unsigned char count;
}filter_avg_t;

//读取xyz数据存入均值滤波器,存满进行计算,滤波后样本存入sample,如何读取存满就不多说了。
static void filter_calculate(filter_avg_t *filter, axis_info_t *sample)
{
	unsigned int i;
	short x_sum = 0, y_sum = 0, z_sum = 0;
	for (i = 0; i < FILTER_CNT; i++) {
		x_sum += filter->info[i].x;
		y_sum += filter->info[i].y;
		z_sum += filter->info[i].z;
	}
	sample->x = x_sum / FILTER_CNT;
	sample->y = y_sum / FILTER_CNT;
	sample->z = z_sum / FILTER_CNT;
}

2,动态阈值

动态阈值: 系统持续更新3轴加速度的最大值和最小值,每采样50次更新一次。平均值(Max + Min)/2称为"动态阈值"。

对于动态阈值其实就是我们在采样过程中拿到的每个轴的最大值和最小值的平均值,它是每取50个样本就更新一次&#x

数的算法通常有很多种,以下是一种简单的基于加速度计步算法的 C 语言程序: ```c #include <stdio.h> #include <math.h> #define FILTER_ALPHA 0.3 // 低通滤波器的 alpha 值 #define PEAK_THRESHOLD 1.5 // 数峰值的阈值 #define WINDOW_SIZE 20 // 数峰值检测的窗口大小 int main() { // 初始化 int step_count = 0; // 数器 float x_acc, y_acc, z_acc; // 加速度 float x_acc_filtered = 0, y_acc_filtered = 0, z_acc_filtered = 0; // 低通滤波后的加速度 float acc_magnitude = 0, acc_magnitude_filtered = 0; // 加速度模和滤波后的加速度模 float acc_magnitude_max = -INFINITY; // 数峰值检测的最大加速度模 int peak_detected = 0; // 数峰值是否被检测到的标志 int window[WINDOW_SIZE] = {0}; // 数峰值检测的滑动窗口 // 循环读取加速度数据并数 while (1) { // 读取加速度数据(这里假设已经有相应的函数) read_acc_data(&x_acc, &y_acc, &z_acc); // 低通滤波 x_acc_filtered = FILTER_ALPHA * x_acc + (1 - FILTER_ALPHA) * x_acc_filtered; y_acc_filtered = FILTER_ALPHA * y_acc + (1 - FILTER_ALPHA) * y_acc_filtered; z_acc_filtered = FILTER_ALPHA * z_acc + (1 - FILTER_ALPHA) * z_acc_filtered; // 加速度模 acc_magnitude = sqrt(x_acc * x_acc + y_acc * y_acc + z_acc * z_acc); acc_magnitude_filtered = sqrt(x_acc_filtered * x_acc_filtered + y_acc_filtered * y_acc_filtered + z_acc_filtered * z_acc_filtered); // 数峰值检测 if (!peak_detected) { // 把当前的加速度模放入滑动窗口 for (int i = WINDOW_SIZE - 1; i > 0; i--) { window[i] = window[i - 1]; } window[0] = acc_magnitude_filtered; // 检查滑动窗口的最大值是否超过阈值 if (acc_magnitude_filtered > acc_magnitude_max) { acc_magnitude_max = acc_magnitude_filtered; } if (window[WINDOW_SIZE - 1] >= acc_magnitude_max * PEAK_THRESHOLD) { peak_detected = 1; acc_magnitude_max = -INFINITY; } } else { // 数峰值检测到之后,等待加速度模回落到一定程度 if (acc_magnitude_filtered < 0.5 * acc_magnitude_max) { // 数加一 step_count++; peak_detected = 0; acc_magnitude_max = -INFINITY; } } // 输出数 printf("Step count: %d\n", step_count); } return 0; } ``` 该算法的基本思路是,首先通过低通滤波器去除高频噪声,然后加速度模,接着利用滑动窗口和阈值检测找出数峰值,最后在数峰值检测到之后等待加速度模回落到一定程度,就可以将数器加一。需要注意的是,该算法仅供参考,实际应用中还需要根据具体情况进行调整和优化。
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值