花了一天的时间利用常用数字滤波算法对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_1(short *value_buf) { unsigned char i,j,count; int sum=0; short temp; short arrary_temp[N]; for(i=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; } } } for(count=1;count<N-1;count++) //这里做了修改 sum += arrary_temp[count]; //去掉最大值和最小值 return (short)(sum/(N-2)); }
说明:相当于“中位值滤波法”+“算术平均滤波法”.连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均值N值的选取:3~14
下图三种滤波算法的效果对比图(滑动平均滤波法(黄线) 和 中位值平均滤波法分析(蓝) 和 中位值滤波法(粉红)):
从图中可以看出前两种滤波算法较平滑,滤波都会有一定的滞后性,滑动平均滤波滞后较不明显,中位值平均滤波法较为平滑.
优美的波形,单效果
中位值平均滤波
滑动平均滤波:
博文为本人所写,转载请表明出处,滑动平均滤波法和中位值平均滤波法分析