四轴mpu6050姿态角卡尔曼滤波代码分析

本文详细分析了针对MPU6050四轴飞行器姿态角的卡尔曼滤波代码,纠正了网上常见错误。内容包括过程方程、量测方程以及卡尔曼滤波的五个关键公式,并对代码中的矩阵运算和噪声模型进行了讨论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

卡尔曼滤波理解及代码分析

鉴于网上的代码以及分析的各种错误,所以写一个正确的详细的分析。

过程方程以及量测方程

X(K)=AX(K-1)+BU(K-1)+W(K-1)

Z(K)=HX(K)+V(K)

说明,下面带T的表示转置。

  • 卡尔曼滤波的黄金五条公式
    1. X(k|k-1)=AX(k-1|k-1)+BU(k)……….先验估计
    2. P(k|k-1)=A P(k-1| k-1) AT+Q……….误差协方差
    3. Kg(k)= P(k|k-1) HT / (H P(k|k-1) HT + R)……….计算卡尔曼增益
    4. X(k|k)= X(k|k-1) + Kg(k)(Z(k) - H X(k|k-1))……….修正估计
    5. P(k|k)=( I-Kg(k) H) P(k|k-1)……….更新误差协方差

下面的程序主要针对MPU6050的姿态角的滤波。

float  Q_angle=0.001;    //陀螺仪噪声的协方差
float  Q_gyro=0.003;    //陀螺仪漂移噪声的协方差
float  R_angle=0.5;      // 加速度计的协方差
float  dt=0.005;      
char   C_0 = 1;
float  Q_bias=0, Angle_err=0;  //Q_bias为陀螺仪漂移
float  PCt_0=0, PCt_1=0, E=0;
float  K_0=0, K_1=0, t_0=0, t_1=0;
float  Pdot[4] ={
  
  0,0,0,0};
float  PP[2][2] = { { 1, 0 },{ 0, 1 } };

首先建立的是过程方程,这里的状态变量是angle以及Q_bias,角度以及陀螺仪的漂移。

img

那么已经建立了这里的预测方程,没有加上噪声。

void Kalman_Filter(float Gyro,float Accel)    
{    //Gyro陀螺仪的测量值,Accel加速度计的角度计算值

     Angle+=(Gyro - Q_bias) * dt;  
    //角度测量模型方程
    //就漂移来说认为每次都是相同的Q_bias=Q_bias;
    //由此得到矩阵

上面的代码就对应着预测方程。对应着卡尔曼滤波的五个公式的第一条:X(k|k-1)=AX(k-1|k-1)+BU(k)

这里再分析第二条公式,P(k|k-1)=A P(k-1| k-1) AT+Q。可以在之前看出,A=[1,-dt;0,1]。而Q的定义如下:

img

因为角度噪声和陀螺仪的角速度的漂移噪声相互独立,所以为一个对角矩阵。然后,Q_angle,Q_gyro再程序开头已经给出。所以设P=[a,b;c,d]

的出一个更新的式子,

[acbd]=[10d
### MPU6050姿态解算的卡尔曼滤波原理 卡尔曼滤波是一种递归的状态估计方法,适用于线性和非线性系统的状态预测和校正。在MPU6050的姿态解算中,卡尔曼滤波被用来融合加速度计和陀螺仪的数据,从而提高姿态角(如俯仰角、横滚角)的精度[^1]。 #### 卡尔曼滤波的核心概念 卡尔曼滤波的主要目标是通过最小化均方误差来估算系统的实际状态。其核心过程分为两个阶段:**时间更新**(预测)和**测量更新**(校正)。以下是关键参数及其作用: - **X_k**: 当前时刻的状态向量。 - **P_k**: 先验误差协方差矩阵,表示当前状态估计的不确定性。 - **K_k**: 卡尔曼增益矩阵,用于权衡预测值和测量值的重要性。 - **H**: 观测矩阵,描述测量值与真实状态之间的关系。 - **R**: 测量噪声协方差矩阵,反映测量数据的可靠性。 - **Q**: 过程噪声协方差矩阵,表征模型预测中的不确定度。 卡尔曼滤波的时间更新和测量更新公式如下: $$ \hat{X}_{k|k-1} = F \cdot \hat{X}_{k-1} $$ $$ P_{k|k-1} = F \cdot P_{k-1} \cdot F^T + Q $$ $$ K_k = P_{k|k-1} \cdot H^T \cdot (H \cdot P_{k|k-1} \cdot H^T + R)^{-1} $$ $$ \hat{X}_k = \hat{X}_{k|k-1} + K_k \cdot (Z_k - H \cdot \hat{X}_{k|k-1}) $$ $$ P_k = (I - K_k \cdot H) \cdot P_{k|k-1} $$ 其中,$\hat{X}$ 表示状态估计值,$F$ 是状态转移矩阵,$Z_k$ 是测量值[^4]。 --- ### 示例代码实现 以下是一个基于Arduino平台的简单二维卡尔曼滤波器实现,用于处理MPU6050的加速度计和陀螺仪数据。 ```cpp #include <Wire.h> #include "MPU6050_tockn.h" #define DT 0.01 // 时间间隔(秒) // 定义卡尔曼滤波变量 float kalman_gain_roll, kalman_gain_pitch; float error_estimate_roll = 0.01; // 初始估计误差 float error_estimate_pitch = 0.01; float q_angle = 0.001; // 加速度计角度变化率的标准偏差平方 float r_measure = 0.03; // 陀螺仪测量噪声标准偏差平方 MPU6050 mpu; void setup() { Wire.begin(); Serial.begin(9600); while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { Serial.println("Failed to initialize MPU6050"); delay(500); } } void loop() { float ax, ay, az, gx, gy, gz; float roll_acc, pitch_acc; static float angle_roll = 0, angle_pitch = 0; static float p_est_roll = error_estimate_roll, p_est_pitch = error_estimate_pitch; mpu.update(); ax = mpu.getAccX(); ay = mpu.getAccY(); az = mpu.getAccZ(); gx = mpu.getGyroX(); gy = mpu.getGyroY(); gz = mpu.getGyroZ(); // 计算加速度计的角度 roll_acc = atan2(ay, sqrt(ax * ax + az * az)) * RAD_TO_DEG; pitch_acc = atan2(-ax, sqrt(ay * ay + az * az)) * RAD_TO_DEG; // 预测步 angle_roll += gx * DT; angle_pitch += gy * DT; // 更新先验误差协方差 p_est_roll += q_angle; p_est_pitch += q_angle; // 校正步 kalman_gain_roll = p_est_roll / (p_est_roll + r_measure); kalman_gain_pitch = p_est_pitch / (p_est_pitch + r_measure); angle_roll = angle_roll + kalman_gain_roll * (roll_acc - angle_roll); angle_pitch = angle_pitch + kalman_gain_pitch * (pitch_acc - angle_pitch); // 更新后验误差协方差 p_est_roll -= kalman_gain_roll * p_est_roll; p_est_pitch -= kalman_gain_pitch * p_est_pitch; // 输出结果 Serial.print(angle_roll); Serial.print(", "); Serial.println(angle_pitch); delay(10); } ``` 上述代码实现了简单的二维卡尔曼滤波器,分别对俯仰角和横滚角进行了独立计算。它利用了加速度计提供绝对方向的信息以及陀螺仪提供高频率旋转速率的优点[^2]。 --- ### 实现要点总结 1. **初始化设置** 初始化过程中需定义卡尔曼滤波的关键参数,例如初始估计误差、过程噪声协方差 $q\_angle$ 和测量噪声协方差 $r\_measure$[^3]。 2. **时间更新(预测)** 使用陀螺仪数据推导出新的角度估计值,并更新先验误差协方差矩阵。 3. **测量更新(校正)** 结合加速度计提供的角度信息调整预测值,最终得到更精确的姿态角估计。 4. **性能优化** 调整 $q\_angle$ 和 $r\_measure$ 参数可显著影响滤波效果。通常需要根据具体应用场景进行微调。 ---
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值