花了一天的時間利用常用數字濾波算法對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
下圖三種濾波算法的效果對比圖(滑動平均濾波法(黃線) 和 中位值平均濾波法分析(藍) 和 中位值濾波法(粉紅)):
從圖中可以看出前兩種濾波算法較平滑,濾波都會有一定的滯后性,滑動平均濾波滯后較不明顯,中位值平均濾波法較為平滑.
優美的波形,單效果
中位值平均濾波
滑動平均濾波:
博文為本人所寫,轉載請表明出處,滑動平均濾波法和中位值平均濾波法分析