花了一天的时间利用常用数字滤波算法对AHRS传感器的数据进行滤波,同时也查找了一些网络资料.网络上的资料基本上都是crtl+c crtl+v 而来的,有很多都有错误,所以说只能简单的借鉴 .这里我选用的滑动平均滤波法和中位值平均滤波法这两种算法.滤波效果如图,黄
色为原始数据,红色为滤波之后的数据.
角速度计N =15的效果
滑动平均滤波法代码:
#define N 15 short value_buf[N]; char i=0; //递推平均滤波法滑动平均滤波法) short filter_0 ) { char count; int sum=0; //这里修改成 int short temp=0; value_buf[i++] = get_ad); if i == N) i = 0; for count=0;count<N;count++) { sum += value_buf[count]; } temp=short)sum/N); return temp; }
说明:这里只是描述一种算法, 程序的编写需要结合自己的情况修改.对于AHRS传感器输出的数据是补码的形式,比方说是16位必须赋值给short类型,且参与的变量为有符号数,否则在接收于零时波形会畸变.
对于滑动平均滤波法,其缺点:灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差,不易消除由于脉冲干扰所引起的采样值偏差,不适用于脉冲干扰比较严重的场合,比较浪费RAM,同时滤波有一定的滞后后性.
中值平均滤波算法 代码:
//中位值平均滤波法防脉冲干扰平均滤波法) short filter_1short *value_buf) { unsigned char i,j,count; int sum=0; short temp; short arrary_temp[N]; fori=0;i<N;i++) { arrary_temp[i]=value_buf[i]; //把数组中的值给临时数组.对临时数组进行排序. } /*问题分析,这里如果对原始数据进行排序的话,因为数组是先入先出.所以新来的数据会把 最小的值给覆盖掉.这里排序算法是没有问题的.也就是说每取一个数都要进行排序,计算量比较 大! 有没有办法减少计算量? */ for j=0;j<N-1;j++) { for i=0;i<N-j;i++) { if arrary_temp[i]>arrary_temp[i+1]) { temp = arrary_temp[i]; arrary_temp[i] = arrary_temp[i+1]; arrary_temp[i+1] = temp; } } } forcount=1;count<N-1;count++) //这里做了修改 sum += arrary_temp[count]; //去掉最大值和最小值 return short)sum/N-2)); }
说明:相当于“中位值滤波法”+“算术平均滤波法”.连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均值N值的选取:3~14
下图三种滤波算法的效果对比图滑动平均滤波法黄线) 和 中位值平均滤波法分析蓝) 和 中位值滤波法粉红)):
从图中可以看出前两种滤波算法较平滑,滤波都会有一定的滞后性,滑动平均滤波滞后较不明显,中位值平均滤波法较为平滑.
优美的波形,单效果
中位值平均滤波
滑动平均滤波:
博文为本人所写,转载请表明出处,滑动平均滤波法和中位值平均滤波法分析