由于工作需要,最近需要用到一种数字滤波算法,经过与高手的交流,研究了高斯滤波算法和卡尔曼滤波算法;后来还是选择卡尔曼算法;因为他的思想比较简单,也是比较稳定的;他可以不断校正,不断更新;但是有一定的弊端;比如我们在测量之前还要测量一些数据作为他的Q因子(即过程激励方差)和R因子;
上面是他基本思想,我们可以把他简化为下面几个步骤:
/* * Kalman Filter Algorithm * ---------------------------------------------------------- * Time Update Equation * [1] Xk = X[k-1]; * [2] Pk = P[k-1] + Q; * PS : Q Factor is As Incentive Noise Variance; * ---------------------------------------------------------- * Measurement Update Equation * [3] Kk = Pk / (Pk + R); * [4] X[k] = Xk + Kk * (Zm - Xk); * [5] P[k] = (1 - Kk) * Pk; * PS : R Factor is As The process covariance noise; * Zm : Measure Value or True Value * ---------------------------------------------------------- * Update Next X[*] And P[*] * [6] X[k-1] = X[k]; * [7] P[k-1] = P[k]; * ---------------------------------------------------------- * Author : -Rain * E-mail : ieczw@qq.com */ #define __DEBUGM__ //#define __DEBUG__ #ifdef __DEBUGM__ #include <stdio.h> #endif #define QVALUE 0.005 // Incentive noise variance #define RVALUE 15.0 // The process covariance noise double KalmanUpdata(double TrueValue) { char k = 1; // Just As a Scalar static double X[2],Xk; static double P[2],Pk; static double Kk; /* * Time Update */ Xk = X[k-1]; Pk = P[k-1] + QVALUE; #ifdef __DEBUG__ printf( "Time Update : Q = %f\n" "Xk = %f\n" "Pk = %f\n", QVALUE,Xk,Pk); #endif /* * Measurement Update Equation */ Kk = Pk / (Pk + RVALUE); X[k] = Xk + Kk * (TrueValue - Xk); P[k] = (1 - Kk) * Pk; #ifdef __DEBUG__ printf( "Measurement Update : R = %f\n" "Kk = %f\n" "X[k] = %f\n" "P[k] = %f\n" ,RVALUE,Kk,X[k],P[k]); #endif /* * Update Next X[*] And P[*] */ X[k-1] = X[k]; P[k-1] = P[k]; return X[k]; } #ifdef __DEBUGM__ #define INC 0.01 #define IDEAL 0.0 int main(void) { /* * Rand Value : rand_value : -15 ~ 15 ; * average value of rand_value EQU 0; * Noise Value -15 ~ 15; So We Should Set R = 15.0 * Increment : inn += INC; INC = 0.01 * Noise Value -0.005 ~ 0.005; So Set Q = 0.005 */ int i = 0; double rand_value; double inn = 0.0; for(i=0; i<100000; i++){ /* * Increment : INC = 0.01 * Noise Value : 0.001*(5 - rand()%11) = -0.005 ~ 0.005 */ inn += INC + 0.001*(5 - rand()%11); /* * Ideal Value : IDEAL = 0.0 * Noise Value : 15.0 - rand() % 31 = -15 ~ 15 */ rand_value = IDEAL + inn + 15.0 - rand() % 31; printf("True Value : %f\n",rand_value); printf("Kalman Update Value : %f\n",KalmanUpdata(rand_value)); } return 0; } #endif
原文:http://blog.csdn.net/ieczw/article/details/21627771