当前位置:   article > 正文

Arduino MPU6050加速度传感器 卡尔曼滤波求解姿态角_如何通过mpu6050获得角度 卡尔曼滤波

如何通过mpu6050获得角度 卡尔曼滤波

1、mpu6050与单片机的连接

①使用uno和nano:VCC-5V  GND-GND  SDA-A4  SCL-A5

②使用esp8266:VCC-3V  GND-GND   SDA-D2  SCL-D1

2、代码

  1. #include <Adafruit_MPU6050.h>
  2. #include <Adafruit_Sensor.h>
  3. #include <Wire.h>
  4. // 卡尔曼滤波器参数
  5. float dt = 0.01; // 时间步长
  6. float Q_angle = 0.001; // 过程噪声方差
  7. float Q_gyro = 0.003; // 过程噪声方差
  8. float R_angle = 0.5; // 测量噪声方差
  9. // 状态变量
  10. float pitch = 0;
  11. float roll = 0;
  12. float gyro_x_bias = 0;
  13. float gyro_y_bias = 0;
  14. // 卡尔曼滤波器矩阵
  15. float Xk[4][1] = {{0},
  16. {0},
  17. {0},
  18. {0}};
  19. float Pk[4][4] = {{1, 1, 0, 0},
  20. {1, 1, 0, 0},
  21. {0, 0, 1, 1},
  22. {0, 0, 1, 1}};
  23. const float Ak[4][4] = {{1, -dt, 0, 0},
  24. {0, 1, 0, 0},
  25. {0, 0, 1, -dt},
  26. {0, 0, 0, 1}};
  27. const float Hk[2][4] = {{1, 0, 0, 0},
  28. {0, 0, 1, 0}};
  29. const float Qk[4][4] = {{Q_angle, 0, 0, 0},
  30. {0, Q_gyro, 0, 0},
  31. {0, 0, Q_angle, 0},
  32. {0, 0, 0, Q_gyro}};
  33. const float Rk[2][2] = {{R_angle, 0},
  34. {0, R_angle}};
  35. Adafruit_MPU6050 mpu;
  36. void setup() {
  37. Serial.begin(115200);
  38. // Try to initialize!
  39. if (!mpu.begin()) {
  40. Serial.println("Failed to find MPU6050 chip");
  41. while (1) {
  42. delay(10);
  43. }
  44. }
  45. Serial.println("MPU6050 Found!");
  46. // 设置加速计范围为 +-8G
  47. mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  48. // 设置陀螺仪范围为 +- 500 deg/s
  49. mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  50. // 设置滤波器带宽为21 Hz
  51. mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  52. delay(100);
  53. }
  54. /* 计算姿态角度 */
  55. void calculateAttitude(sensors_event_t a, sensors_event_t g) {
  56. /* 获取传感器读数 */
  57. float gyro_x = g.gyro.x / 57.296 - gyro_x_bias; // 将陀螺仪读数转换为弧度并减去静态偏差
  58. float gyro_y = g.gyro.y / 57.296 - gyro_y_bias;
  59. /* 计算加速度计测得的姿态角度 */
  60. float accel_pitch = atan2(a.acceleration.x, sqrt(pow(a.acceleration.y, 2) + pow(a.acceleration.z, 2)));
  61. float accel_roll = atan2(a.acceleration.y, sqrt(pow(a.acceleration.x, 2) + pow(a.acceleration.z, 2)));
  62. /* 融合加速度计和陀螺仪数据 */
  63. float alpha = 0.96; // 加速度计和陀螺仪融合的权重因子
  64. pitch = alpha * (pitch + dt * gyro_x) + (1 - alpha) * accel_pitch;
  65. roll = alpha * (roll + dt * gyro_y) + (1 - alpha) * accel_roll;
  66. }
  67. /* 使用卡尔曼滤波器进行姿态角度滤波 */
  68. void kalmanFilter() {
  69. float Yk[2][1] = {{pitch},
  70. {roll}};
  71. // 卡尔曼滤波器预测
  72. float Xk_1[4][1] = {{0},
  73. {0},
  74. {0},
  75. {0}};
  76. for (int i = 0; i < 4; i++) {
  77. for (int j = 0; j < 4; j++) {
  78. Xk_1[i][0] += Ak[i][j] * Xk[j][0];
  79. }
  80. }
  81. float Pk_1[4][4] = {{0, 0, 0, 0},
  82. {0, 0, 0, 0},
  83. {0, 0, 0, 0},
  84. {0, 0, 0, 0}};
  85. for (int i = 0; i < 4; i++) {
  86. for (int j = 0; j < 4; j++) {
  87. for (int k = 0; k < 4; k++) {
  88. Pk_1[i][j] += Ak[i][k] * Pk[k][j];
  89. }
  90. }
  91. }
  92. for (int i = 0; i < 4; i++) {
  93. Pk_1[i][i] += Qk[i][i];
  94. }
  95. // 卡尔曼滤波器更新
  96. float temp1[2][4];
  97. float temp2[4][4];
  98. float S[2][2];
  99. for (int i = 0; i < 2; i++) {
  100. for (int j = 0; j < 4; j++) {
  101. temp1[i][j] = 0;
  102. for (int k = 0; k < 4; k++) {
  103. temp1[i][j] += Hk[i][k] * Pk_1[k][j];
  104. }
  105. }
  106. }
  107. for (int i = 0; i < 4; i++) {
  108. for (int j = 0; j < 4; j++) {
  109. temp2[i][j] = 0;
  110. for (int k = 0; k < 4; k++) {
  111. temp2[i][j] += Pk_1[i][k] * Hk[k][j];
  112. }
  113. }
  114. }
  115. for (int i = 0; i < 2; i++) {
  116. for (int j = 0; j < 2; j++) {
  117. float temp3 = 0;
  118. for (int k = 0; k < 4; k++) {
  119. temp3 += Hk[i][k] * temp1[k][j];
  120. }
  121. S[i][j] = Rk[i][j] + temp3;
  122. }
  123. }
  124. float K[4][2];
  125. for (int i = 0; i < 4; i++) {
  126. for (int j = 0; j < 2; j++) {
  127. float temp3 = 0;
  128. for (int k = 0; k < 4; k++) {
  129. temp3 += temp2[i][k] * Hk[j][k];
  130. }
  131. K[i][j] = temp1[j][i] / S[j][j];
  132. }
  133. }
  134. for (int i = 0; i < 4; i++) {
  135. Xk[i][0] = Xk_1[i][0] + K[i][0] * (Yk[0][0] - Hk[0][i] * Xk_1[i][0] + Yk[1][0] - Hk[1][i] * Xk_1[i][0]);
  136. for (int j = 0; j < 4; j++) {
  137. Pk[i][j] = (1 - K[i][0] * Hk[0][j] - K[i][1] * Hk[1][j]) * Pk_1[i][j];
  138. }
  139. }
  140. }
  141. void loop() {
  142. /* 获取新的传感器读数 */
  143. sensors_event_t a, g, temp;
  144. mpu.getEvent(&a, &g, &temp);
  145. /* 计算姿态角度 */
  146. calculateAttitude(a, g);
  147. /* 使用卡尔曼滤波器进行姿态角度滤波 */
  148. kalmanFilter();
  149. /* 打印输出姿态角度 */
  150. Serial.print("Pitch: ");
  151. Serial.print(pitch*180/PI, 2);
  152. Serial.print(" Roll: ");
  153. Serial.println(roll*180/PI, 2);
  154. delay(10);
  155. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/512923
推荐阅读
相关标签
  

闽ICP备14008679号