標(biāo)題: STM32單片機(jī)卡爾曼濾波程序分享 [打印本頁]

作者: 23123的    時(shí)間: 2019-8-6 17:42
標(biāo)題: STM32單片機(jī)卡爾曼濾波程序分享
在網(wǎng)上找的卡爾曼濾波在自己理解的基礎(chǔ)上更改了一下代碼!實(shí)測(cè)有用

單片機(jī)源程序如下:
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "stm32f10x.h"       
  3. #include "kalman.h"       
  4. #include "matrix.h"                                                                                 

  5. /*==============================================================================
  6. 1.預(yù)估計(jì)
  7.    X(k|k-1) = F(k,k-1)*X(k-1|k-1)        //控制量為0


  8. 2.計(jì)算預(yù)估計(jì)協(xié)方差矩陣
  9.    P(k|k-1) = F(k,k-1)*P(k-1|k-1)*F(k,k-1)'+Q(k)
  10.    Q(k) = U(k)×U(k)'


  11. 3.計(jì)算卡爾曼增益矩陣
  12.    Kg(k) = P(k|k-1)*H' / (H*P(k|k-1)*H' + R(k))
  13.    R(k) = N(k)×N(k)'


  14. 4.更新估計(jì)
  15.    X(k|k) = X(k|k-1)+Kg(k)*(Z(k)-H*X(k|k-1))


  16. 5.計(jì)算更新后估計(jì)協(xié)防差矩陣
  17.    P(k|k) =(I-Kg(k)*H)*P(k|k-1)


  18. 6. 更新最優(yōu)值


  19. F(k,k-1):     狀態(tài)轉(zhuǎn)移矩陣
  20. X(k|k-1):     根據(jù)k-1時(shí)刻的最優(yōu)值估計(jì)k時(shí)刻的值
  21. X(k-1|k-1):   k-1時(shí)刻的最優(yōu)值
  22. P(k|k-1):     X(k|k-1)對(duì)應(yīng)的covariance
  23. P(k-1|k-1):   X(k-1|k-1)對(duì)應(yīng)的covariance
  24. Q(k):         系統(tǒng)過程的covariance
  25. R(k):         測(cè)量過程的協(xié)方差
  26. H(k):         觀測(cè)矩陣轉(zhuǎn)移矩陣
  27. Z(k):         k時(shí)刻的測(cè)量值


  28. 基本思路: 首先根據(jù)上一次(如果是第一次則根據(jù)預(yù)賦值計(jì)算)的數(shù)據(jù)計(jì)算出本次的估計(jì)值,
  29.           同理,根據(jù)上一次的數(shù)據(jù)計(jì)算出本次估計(jì)值的協(xié)方差;  接著,由本次估計(jì)值的協(xié)
  30.           方差計(jì)算出卡爾曼增益;  最后,根據(jù)估測(cè)值和測(cè)量值計(jì)算當(dāng)前最優(yōu)值及其協(xié)方差
  31. ==============================================================================*/



  32. //================================================//
  33. //==             最優(yōu)值方差結(jié)構(gòu)體               ==//
  34. //================================================//
  35. typedef struct  _tCovariance
  36. {
  37.   float PNowOpt[LENGTH];
  38.   float PPreOpt[LENGTH];
  39. }tCovariance;







  40. static tOptimal      tOpt;
  41. static tCovariance   tCov;
  42. //float         Z[LENGTH]  = {4000};           //  測(cè)量值(每次測(cè)量的數(shù)據(jù)需要存入該數(shù)組)
  43. static float         I[LENGTH]  = {1};              //  單位矩陣
  44. static float         X[LENGTH]  = {9.8};              //  當(dāng)前狀態(tài)的預(yù)測(cè)值
  45. static float         P[LENGTH]  = {0};              //  當(dāng)前狀態(tài)的預(yù)測(cè)值的協(xié)方差
  46. static float         K[LENGTH]  = {0};              //  卡爾曼增益
  47. static float         Temp3[LENGTH] = {0};           //  輔助變量
  48. //============================================================================//
  49. //==                    卡爾曼濾波需要配置的變量                            ==//
  50. //============================================================================//
  51. static float         F[LENGTH]  = {1};              //  狀態(tài)轉(zhuǎn)移矩陣   即:堅(jiān)信當(dāng)前的狀態(tài)與上一次狀態(tài)的關(guān)系,如果堅(jiān)信是一樣的,則狀態(tài)轉(zhuǎn)移矩陣就為單位矩陣
  52. static float         Q[LENGTH]  = {0.0001f};//0.0001f              //  系統(tǒng)過程的協(xié)方差        協(xié)方差的定義:真實(shí)值與期望值之差的平方的期望值
  53. static float         R[LENGTH]  = {2};              //  測(cè)量過程的協(xié)方差        協(xié)方差的定義:真實(shí)值與期望值之差的平方的期望值   
  54. //如果你需要濾波結(jié)果更依賴于觀測(cè)量,那就調(diào)小R,增大Q;反之,調(diào)大R,調(diào)小Q,這樣估計(jì)值就取決于系統(tǒng)。
  55. //如果R大Q小,就是說,狀態(tài)估計(jì)值比測(cè)量值要可靠,這時(shí),所得出的結(jié)果就是更接近估計(jì)值;
  56. //如果R小Q大,這時(shí),計(jì)算出來的結(jié)果就會(huì)更接近測(cè)量值。
  57. static float         H[LENGTH]  = {1};              //  觀測(cè)矩陣轉(zhuǎn)移矩陣        測(cè)量值與狀態(tài)預(yù)測(cè)值之間的單位換算關(guān)系,即把預(yù)測(cè)值單位換算成測(cè)量值單位
  58. static float         Temp1[LENGTH] = {1};           //  輔助變量, 同時(shí)保存tOpt.XPreOpt[]的初始化值
  59. static float         Temp2[LENGTH] = {10000};       //  輔助變量, 同時(shí)保存tCov.PPreOpt[]的初始化值


  60. void KalMan_PramInit(void)
  61. {
  62.   unsigned char   i;
  63.   
  64.   for (i=0; i<LENGTH; i++)
  65.   {
  66.     tOpt.XPreOpt[i] = Temp1[i];           //零值初始化
  67.   }
  68.   for (i=0; i<LENGTH; i++)
  69.   {
  70.     tCov.PPreOpt[i] = Temp2[i];           //零值初始化
  71.   }
  72. }


  73. //============================================================================//
  74. //==                          卡爾曼濾波                                    ==//
  75. //============================================================================//
  76. //==入口參數(shù): 當(dāng)前時(shí)刻的測(cè)量值                                                            ==//
  77. //==出口參數(shù): 當(dāng)前時(shí)刻的最優(yōu)值                                                            ==//
  78. //==返回值:   當(dāng)前時(shí)刻的最優(yōu)值                                                            ==//
  79. //============================================================================//
  80. float KalMan_Update(float *Z)
  81. {
  82.         u8 i;  
  83.         MatrixMul(F, tOpt.XPreOpt, X, ORDER, ORDER, ORDER);       //  基于系統(tǒng)的上一狀態(tài)而預(yù)測(cè)現(xiàn)在狀態(tài); X(k|k-1) = F(k,k-1)*X(k-1|k-1)

  84.         MatrixCal(F, tCov.PPreOpt, Temp1, ORDER);
  85.         MatrixAdd(Temp1, Q, P, ORDER, ORDER);                     //  預(yù)測(cè)數(shù)據(jù)的協(xié)方差矩陣; P(k|k-1) = F(k,k-1)*P(k-1|k-1)*F(k,k-1)'+Q

  86.         MatrixCal(H, P, Temp1, ORDER);
  87.         MatrixAdd(Temp1, R, Temp1, ORDER, ORDER);
  88.         Gauss_Jordan(Temp1, ORDER);
  89.         MatrixTrans(H, Temp2, ORDER, ORDER);
  90.         MatrixMul(P, Temp2, Temp3, ORDER, ORDER, ORDER);
  91.         MatrixMul(Temp1, Temp3, K, ORDER, ORDER, ORDER);          //  計(jì)算卡爾曼增益; Kg(k) = P(k|k-1)*H' / (H*P(k|k-1)*H' + R)

  92.         MatrixMul(H, X, Temp1, ORDER, ORDER, ORDER);
  93.         MatrixMinus(Z, Temp1, Temp1, ORDER, ORDER);
  94.         MatrixMul(K, Temp1, Temp2, ORDER, ORDER, ORDER);
  95.         MatrixAdd(X, Temp2, tOpt.XNowOpt, ORDER, ORDER);          //  根據(jù)估測(cè)值和測(cè)量值計(jì)算當(dāng)前最優(yōu)值; X(k|k) = X(k|k-1)+Kg(k)*(Z(k)-H*X(k|k-1))

  96.         MatrixMul(K, H, Temp1, ORDER, ORDER, ORDER);
  97.         MatrixMinus(I, Temp1, Temp1, ORDER, ORDER);
  98.         MatrixMul(Temp1, P, tCov.PNowOpt, ORDER, ORDER, ORDER);   //  計(jì)算更新后估計(jì)協(xié)防差矩陣; P(k|k) =(I-Kg(k)*H)*P(k|k-1)

  99.         for (i=0; i<LENGTH; i++)
  100.         {
  101.           tOpt.XPreOpt[i] = tOpt.XNowOpt[i];
  102.           tCov.PPreOpt[i] = tCov.PNowOpt[i];
  103.         }
  104.        
  105.         return tOpt.XNowOpt[0];
  106. }
復(fù)制代碼

所有資料51hei提供下載:
kalman.7z (3.71 KB, 下載次數(shù): 252)



作者: xlw415    時(shí)間: 2020-3-23 15:24
謝謝分享,比較容易理解.
作者: 484    時(shí)間: 2020-4-2 20:14
首先感謝樓主分享!然后小白想問下卡爾曼濾波返回值不應(yīng)該是下一時(shí)刻的最優(yōu)值嗎
作者: 夯昆斯密達(dá)    時(shí)間: 2021-5-13 09:52
tOptimal 這個(gè)結(jié)構(gòu)體的定義在哪兒?
作者: liesnake    時(shí)間: 2021-5-13 17:38
這個(gè)不錯(cuò),感覺論壇代碼的質(zhì)量越來越高了。
作者: 龍晨天    時(shí)間: 2021-7-21 16:07
6啊 樓主




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1