久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 915|回復: 0
收起左側

mpu6050卡爾曼濾波STM32單片機程序 詳細注釋說明

[復制鏈接]
ID:583948 發表于 2024-11-29 12:10 | 顯示全部樓層 |閱讀模式
基于STM32F103 MPU6050卡爾曼濾波算法,詳細注釋說明!
  1. #include "kalman.h"
  2. #include "mpu6050.h"
  3. #include "math.h"


  4. short aacx,aacy,aacz;                /*加速度傳感器原始數據*/
  5. short gyrox,gyroy,gyroz;        /*陀螺儀原始數據*/
  6. short temperature;                        /*陀螺儀溫度數據*/
  7. float Accel_x;                             /*X軸加速度值暫存*/
  8. float Accel_y;                            /*Y軸加速度值暫存*/
  9. float Accel_z;                             /*Z軸加速度值暫存*/
  10. float Gyro_x;                                /*X軸陀螺儀數據暫存*/
  11. float Gyro_y;                        /*Y軸陀螺儀數據暫存*/
  12. float Gyro_z;                                 /*Z軸陀螺儀數據暫存*/
  13. float Angle_x_temp;                  /*由加速度計算的x傾斜角度*/
  14. float Angle_y_temp;                  /*由加速度計算的y傾斜角度*/
  15. float Angle_X_Final;                 /*X最終傾斜角度*/
  16. float Angle_Y_Final;                 /*Y最終傾斜角度*/

  17. /**
  18.   * @brief  讀取數據預處理
  19.   *         
  20.   * @param  NULL
  21.   *
  22.   * @retval NULL
  23.   */
  24. void Angle_Calcu(void)         
  25. {
  26.         /*1.原始數據讀取*/
  27.         float accx,accy,accz;                                                /*三方向角加速度值*/
  28.         MPU_Get_Accelerometer(&aacx,&aacy,&aacz);        /*得到加速度傳感器數據*/
  29.         MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);        /*得到陀螺儀數據*/
  30.         temperature = MPU_Get_Temperature();                /*得到溫度值*/
  31.         Accel_x = aacx;
  32.         Accel_y = aacy;
  33.         Accel_z = aacz;
  34.         Gyro_x  = gyrox;
  35.         Gyro_y  = gyroy;
  36.         Gyro_z  = gyroz;
  37.         
  38.         /*2.角加速度原始值處理過程*/        
  39.         /*加速度傳感器配置寄存器0X1C內寫入0x01,設置范圍為±2g。換算關系:2^16/4 = 16384LSB/g*/
  40.         if(Accel_x<32764) accx=Accel_x/16384;
  41.         else              accx=1-(Accel_x-49152)/16384;
  42.         if(Accel_y<32764) accy=Accel_y/16384;
  43.         else              accy=1-(Accel_y-49152)/16384;
  44.         if(Accel_z<32764) accz=Accel_z/16384;
  45.         else              accz=(Accel_z-49152)/16384;
  46.         /*加速度反正切公式計算三個軸和水平面坐標系之間的夾角*/
  47.         Angle_x_temp=(atan(accy/accz))*180/3.14;
  48.         Angle_y_temp=(atan(accx/accz))*180/3.14;
  49.         /*判斷計算后角度的正負號*/                                                                                       
  50.         if(Accel_x<32764) Angle_y_temp = +Angle_y_temp;
  51.         if(Accel_x>32764) Angle_y_temp = -Angle_y_temp;
  52.         if(Accel_y<32764) Angle_x_temp = +Angle_x_temp;
  53.         if(Accel_y>32764) Angle_x_temp = -Angle_x_temp;
  54.         
  55.         /*3.角速度原始值處理過程*/
  56.         /*陀螺儀配置寄存器0X1B內寫入0x18,設置范圍為±2000deg/s。換算關系:2^16/4000=16.4LSB/(°/S)*/
  57.         /*計算角速度*/
  58.         if(Gyro_x<32768) Gyro_x=-(Gyro_x/16.4);
  59.         if(Gyro_x>32768) Gyro_x=+(65535-Gyro_x)/16.4;
  60.         if(Gyro_y<32768) Gyro_y=-(Gyro_y/16.4);
  61.         if(Gyro_y>32768) Gyro_y=+(65535-Gyro_y)/16.4;
  62.         if(Gyro_z<32768) Gyro_z=-(Gyro_z/16.4);
  63.         if(Gyro_z>32768) Gyro_z=+(65535-Gyro_z)/16.4;
  64.         
  65.         /*4.調用卡爾曼函數*/
  66.         Kalman_Filter_X(Angle_x_temp,Gyro_x);  /*卡爾曼濾波計算X傾角*/
  67.         Kalman_Filter_Y(Angle_y_temp,Gyro_y);  /*卡爾曼濾波計算Y傾角*/                                                                                                                          
  68. }


  69. /************************ 卡爾曼參數 ****************************/               
  70. float Q_angle = 0.001;                /*角度數據置信度,角度噪聲的協方差*/
  71. float Q_gyro  = 0.003;                /*角速度數據置信度,角速度噪聲的協方差*/
  72. float R_angle = 0.5;                /*加速度計測量噪聲的協方差*/
  73. float dt      = 0.02;                /*濾波算法計算周期,由定時器定時20ms*/
  74. char  C_0     = 1;                        /*H矩陣值*/
  75. float Q_bias, Angle_err;        /*Q_bias:陀螺儀的偏差  Angle_err:角度偏量*/
  76. float PCt_0, PCt_1, E;                /*計算的過程量*/
  77. float K_0, K_1, t_0, t_1;        /*卡爾曼增益  K_0:用于計算最優估計值  K_1:用于計算最優估計值的偏差 t_0/1:中間變量*/
  78. float P[4] ={0,0,0,0};                /*過程協方差矩陣的微分矩陣,中間變量*/
  79. float PP[2][2] = { { 1, 0 },{ 0, 1 } };/*過程協方差矩陣P*/

  80. /**
  81.   * @brief  卡爾曼函數
  82.   *         
  83.   * @param  Accel
  84.   * @param  Gyro
  85.   *
  86.   * @retval NULL
  87.   */
  88. void Kalman_Filter_X(float Accel,float Gyro)               
  89. {
  90.         /*
  91.                 步驟一,先驗估計
  92.                 公式:X(k|k-1) = AX(k-1|k-1) + BU(k)
  93.                 X = (Angle,Q_bias)
  94.                 A(1,1) = 1,A(1,2) = -dt
  95.                 A(2,1) = 0,A(2,2) = 1
  96.         */        
  97.         Angle_X_Final += (Gyro - Q_bias) * dt;         /*狀態方程,角度值等于上次最優角度加角速度減零漂后積分*/
  98.         
  99.         /*
  100.                 步驟二,計算過程協方差矩陣的微分矩陣
  101.                 公式:P(k|k-1)=AP(k-1|k-1)A^T + Q
  102.                 Q(1,1) = cov(Angle,Angle)        Q(1,2) = cov(Q_bias,Angle)
  103.                 Q(2,1) = cov(Angle,Q_bias)        Q(2,2) = cov(Q_bias,Q_bias)
  104.         */
  105.         P[0]= Q_angle - PP[0][1] - PP[1][0];
  106.         P[1]= -PP[1][1];                                                /*先驗估計誤差協方差*/
  107.         P[2]= -PP[1][1];
  108.         P[3]= Q_gyro;
  109.         PP[0][0] += P[0] * dt;   
  110.         PP[0][1] += P[1] * dt;   
  111.         PP[1][0] += P[2] * dt;
  112.         PP[1][1] += P[3] * dt;        
  113.         
  114.         /*
  115.                 步驟三,計算卡爾曼增益
  116.                 公式:Kg(k)= P(k|k-1)H^T/(HP(k|k-1)H^T+R)
  117.                 Kg = (K_0,K_1) 對應Angle,Q_bias增益
  118.                 H = (1,0)        可由z=HX+v求出z:Accel
  119.         */
  120.         PCt_0 = C_0 * PP[0][0];
  121.         PCt_1 = C_0 * PP[1][0];
  122.         E = R_angle + C_0 * PCt_0;
  123.         K_0 = PCt_0 / E;
  124.         K_1 = PCt_1 / E;
  125.         
  126.         /*
  127.                 步驟四,后驗估計誤差協方差
  128.                 公式:P(k|k)=(I-Kg(k)H)P(k|k-1)
  129.                 也可寫為:P(k|k)=P(k|k-1)-Kg(k)HP(k|k-1)
  130.         */
  131.         t_0 = PCt_0;
  132.         t_1 = C_0 * PP[0][1];
  133.         PP[0][0] -= K_0 * t_0;               
  134.         PP[0][1] -= K_0 * t_1;
  135.         PP[1][0] -= K_1 * t_0;
  136.         PP[1][1] -= K_1 * t_1;
  137.         
  138.         /*
  139.                 步驟五,計算最優角速度值
  140.                 公式:X(k|k)= X(k|k-1)+Kg(k)(Z(k)-X(k|k-1))
  141.         */
  142.         Angle_err = Accel - Angle_X_Final;                /*Z(k)先驗估計 計算角度偏差*/
  143.         Angle_X_Final += K_0 * Angle_err;                 /*后驗估計,給出最優估計值*/
  144.         Q_bias        += K_1 * Angle_err;                 /*后驗估計,跟新最優估計值偏差*/
  145.         Gyro_x         = Gyro - Q_bias;         
  146. }

  147. void Kalman_Filter_Y(float Accel,float Gyro)                 
  148. {
  149.         Angle_Y_Final += (Gyro - Q_bias) * dt;
  150.         P[0]=Q_angle - PP[0][1] - PP[1][0];
  151.         P[1]=-PP[1][1];
  152.         P[2]=-PP[1][1];
  153.         P[3]=Q_gyro;        
  154.         PP[0][0] += P[0] * dt;
  155.         PP[0][1] += P[1] * dt;  
  156.         PP[1][0] += P[2] * dt;
  157.         PP[1][1] += P[3] * dt;        
  158.         Angle_err = Accel - Angle_Y_Final;               
  159.         PCt_0 = C_0 * PP[0][0];
  160.         PCt_1 = C_0 * PP[1][0];        
  161.         E = R_angle + C_0 * PCt_0;        
  162.         K_0 = PCt_0 / E;
  163.         K_1 = PCt_1 / E;        
  164.         t_0 = PCt_0;
  165.         t_1 = C_0 * PP[0][1];
  166.         PP[0][0] -= K_0 * t_0;               
  167.         PP[0][1] -= K_0 * t_1;
  168.         PP[1][0] -= K_1 * t_0;
  169.         PP[1][1] -= K_1 * t_1;               
  170.         Angle_Y_Final        += K_0 * Angle_err;
  171.         Q_bias        += K_1 * Angle_err;         
  172.         Gyro_y   = Gyro - Q_bias;         
  173. }

復制代碼


  1. /**
  2.   ******************************************************************************
  3.   * @file    main.c
  4.   * @author  
  5.   * @version V1.0
  6.   * @date    2023-4-7
  7.   * @brief   MPU6050陀螺儀數據解算(卡爾曼濾波)
  8.   ******************************************************************************
  9.   *
  10.   *
  11.   *
  12.   ******************************************************************************
  13.   */
  14. #include "main.h"
  15. /**
  16.   * @brief  主函數
  17.   * @param  無
  18.   * @retval 無
  19.   */
  20. int main(void)
  21. {        
  22.         SYS_Init();
  23.         while(1)
  24.         {               
  25.                 /*MPU6050數據上報*/
  26.                 DATA_Report();
  27.         }
  28. }
  29. /**
  30.   * @brief  系統初始化總函數
  31.   * @param  無
  32.   * @retval 無
  33.   */
  34. void SYS_Init(void)
  35. {
  36.         delay_init();  
  37.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  38.         uart_init(115200);
  39.         LED_Init();
  40.         MPU_Init();
  41.         /*10Khz的計數頻率,計數到200為20ms*/
  42.         TIM4_Int_Init(199,7199);
  43. }
  44. /**
  45.   * @brief  MPU6050數據上報
  46.   * @param  無
  47.   * @retval 無
  48.   */
  49. void DATA_Report(void)
  50. {
  51.         /*串口發送實時俯仰角,橫滾角,XYZ三軸角加速度原始值,XYZ三軸角速度原始值*/
  52.         printf("俯仰角:%.4f 橫滾角:%.4f \
  53.         X加速度:%5d y加速度:%5d z加速度:%5d \
  54.         x速度:%5d y速度:%5d z速度:%5d\r\n",\
  55.         Angle_X_Final,Angle_Y_Final,aacx,aacy,aacz,\
  56.         gyrox,gyroy,gyroz);
  57.         
  58.         
  59. }
復制代碼

原理圖: 無
仿真: 無
代碼: STM32F103C8T6驅動MPU6050程序(卡爾曼濾波_軟件IIC_OLED顯示_串口上傳).7z (236.32 KB, 下載次數: 0)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品日本久久久久久久久久 | 国产精品成人一区二区三区夜夜夜 | 欧美成人一区二区三区 | 激情小视频| 毛片软件 | 国产欧美精品一区 | 亚洲日韩欧美一区二区在线 | 欧美中文字幕一区二区 | 在线观看亚洲专区 | 精品久久国产 | 欧美在线视频一区 | 日韩在线 | 欧美综合在线观看 | 91资源在线 | 黄色永久免费 | 欧美无乱码久久久免费午夜一区 | 日韩精品一区二区三区视频播放 | 久久精品免费一区二区三 | 欧美伊人久久久久久久久影院 | 国产在线中文字幕 | 久久精品国产一区二区电影 | 在线午夜 | 欧美不卡在线 | 日韩在线免费视频 | 播放一级毛片 | 日韩在线视频一区 | 久久国产一区二区 | 亚洲精品1区2区3区 91免费看片 | 欧美 中文字幕 | 国产精品久久久久免费 | 欧美精品一区二区三 | av乱码 | 欧美精品一区在线发布 | 一级做受毛片免费大片 | 视频三区 | 久久国产福利 | 狠狠入ady亚洲精品经典电影 | 国产成人精品一区二区三区在线 | 伊人精品视频 | 欧美美乳 | 欧美一级久久 |