PX4中的卡尔曼滤波——代码公式对照解释


这篇博客以PX4中速度和位置估计来分析卡尔曼滤波过程,将枯燥的公式和鲜活的代码联系起来。
版本:v1.9.0
源码位置:

  1. ~src/lib/ecl/EKF/vel_pos_fusion.cpp
  2. ~src/lib/ecl/EKF/ekf_helper.cpp
  3. ~src/lib/ecl/EKF/control.cpp

能力有限,出现错误欢迎指正讨论!

1. 变量解释

bool fuse_map[6] = {}; // map of booleans true when [VN,VE,VD,PN,PE,PD] observations are available
	bool innov_check_pass_map[6] = {}; // true when innovations consistency checks pass for [VN,VE,VD,PN,PE,PD] observations
	float R[6] = {}; // observation variances for [VN,VE,VD,PN,PE,PD]
	float gate_size[6] = {}; // innovation consistency check gate sizes for [VN,VE,VD,PN,PE,PD] observations
	float Kfusion[24] = {}; // Kalman gain vector for any single observation - sequential fusion is used
	float innovation[6]; // local copy of innovations for  [VN,VE,VD,PN,PE,PD]
  • fuse_map: 判断数据是否有效的标志位
  • innov_check_pass_map[6]: 判断数据更新是否有效的标志位
  • R[6]:六个变量观测的噪音
  • Kfusion[24]:卡尔曼增益
  • innovation[6]:六个状态变量

2. 代码和公式对应

2.1卡尔曼滤波公式

S = H P k + 1 ∣ k H T + R K = P k + 1 ∣ k H T S − 1 x k + 1 ∣ k + 1 = x k + 1 ∣ k + K ( Z − H ∗ x k + 1 ∣ k ) P k + 1 ∣ k + 1 = [ I − K H ] ∗ P k + 1 ∣ k S=HP_{k+1|k}H^T+R\\ K=P_{k+1|k}H^TS^{-1}\\ x_{k+1|k+1}=x_{k+1|k}+K(Z-H*x_{k+1|k})\\ P_{k+1|k+1}=[I-KH]*P_{k+1|k} S=HPk+1kHT+RK=Pk+1kHTS1xk+1k+1=xk+1k+K(ZHxk+1k)Pk+1k+1=[IKH]Pk+1k
其中 P P P是协方差, R R R是传感器观测噪音, Z Z Z是传感器观测值。

2.2 对应代码

说明:这里矩阵 H = I H=I H=I,因此公式会变得简单
这一小结代码在vel_pos_fusion.cpp

_vel_pos_innov_var[obs_index] = P[state_index][state_index] + R[obs_index];

对应第一个公式,_vel_pos_innov_var就是 S S S

Kfusion[row] = P[row][state_index] / _vel_pos_innov_var[obs_index];

对应第二个公式,Kfusion对应 K K K

KHP[row][column] = Kfusion[row] * P[state_index][column];
P[row][column] = P[row][column] - KHP[row][column];

对应第四个公式

2.2 状态更新公式说明

这行代码在ekf_helper.cpp

_state.vel(i) = _state.vel(i) - K[i + 4] * innovation;

对应第三个公式

重点说下第三个,和公式对比好像是错误的,因为这个代码表示的公式应该是
x k + 1 ∣ k + 1 = x k + 1 ∣ k − K ∗ x x_{k+1|k+1}=x_{k+1|k}-K*x xk+1k+1=xk+1kKx

重点是我们需要知道_state.vel这个变量怎么来的,在GPS数据融合预处理中,有这么一段代码
这行代码在control.cpp

_vel_pos_innov[0] = _state.vel(0) - _gps_sample_delayed.vel(0);

这里的_gps_sample_delayed.vel(0)就是代码里面 Z Z Z,因此这个公式对应的是
x = x k + 1 ∣ k − Z x=x_{k+1|k}-Z x=xk+1kZ
将这个公式带入上式就可以得到
x k + 1 ∣ k + 1 = x k + 1 ∣ k − K ∗ ( x k + 1 ∣ k − Z ) = x k + 1 ∣ k + K ( Z − H ∗ x k + 1 ∣ k ) x_{k+1|k+1}=x_{k+1|k}-K*(x_{k+1|k}-Z)\\ =x_{k+1|k}+K(Z-H*x_{k+1|k}) xk+1k+1=xk+1kK(xk+1kZ)=xk+1k+K(ZHxk+1k)

3. 总结

PX4中卡尔曼滤波看起来很复杂,简而言之就是IMU做状态变量的更新,其他传感器纠正IMU估计出来的状态变量。复杂就复杂在不同传感器之间的处理,里面会出现各种情况(GPS可用但是气压计不可用,磁力计测得的数据不可信,等等…),因此要对这些情况做处理并且给出对应的协方差传播的公式和观测噪声矩阵。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhao23333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值