【滤波算法】卡尔曼滤波手撕版本(推导+案例解释)

卡尔曼滤波(Kalman Filter, KF)是一种递归最小均方误差估计算法,适用于线性动态系统。它分为预测(Prediction)更新(Update)两个阶段。其中预测也就是所谓的先验,更新实际上就是后验


先理解基础的概念,以及每一个变量的定义,理解了这些才能理解接下来的公式代表的含义:

1. Kalman 方程的理解

Kalman 滤波是一种递归最小均方误差(MMSE)估计算法,它能在噪声环境下从不完美的观测数据中估计系统状态。它常用于导航、信号处理、控制系统、目标跟踪等场景,尤其适用于线性动态系统。

1. Kalman 滤波的基本数学模型

Kalman 滤波的核心是基于状态空间模型的递归估计,它由主要由2组5个方程组成:

(1) 预测步骤 (Prediction)

预测当前时刻的状态:
x ^ k − = F k x ^ k − 1 + B k u k \hat{x}_k^- = F_k \hat{x}_{k-1} + B_k u_k x^k=Fkx^k1+Bkuk
预测协方差:
P k − = F k P k − 1 F k T + Q k P_k^- = F_k P_{k-1} F_k^T + Q_k Pk=FkPk1FkT+Qk

(2) 更新步骤 (Correction/Update)

计算卡尔曼增益:
K k = P k − H k T ( H k P k − H k T + R k ) − 1 K_k = P_k^- H_k^T (H_k P_k^- H_k^T + R_k)^{-1} Kk=PkHkT(HkPkHkT+Rk)1
更新状态估计:
x ^ k = x ^ k − + K k ( z k − H k x ^ k − ) \hat{x}_k = \hat{x}_k^- + K_k (z_k - H_k \hat{x}_k^-) x^k=x^k+Kk(zkHkx^k)
更新协方差:
P k = ( I − K k H k ) P k − P_k = (I - K_k H_k) P_k^- Pk=(IKkHk)Pk

其中:

  • x k x_k xk 是系统的状态变量(如位置、速度等)
  • F k F_k Fk 是状态转移矩阵,描述系统的运动
  • u k u_k uk 是控制输入
  • B k B_k Bk 是控制输入矩阵
  • P k P_k Pk 是状态估计误差的协方差矩阵
  • Q k Q_k Qk 是过程噪声协方差矩阵,可能和时间有关,但是可以简化为定值,比如下面的例子过程噪声是高斯白噪声
  • H k H_k Hk 是观测矩阵,将状态映射到测量值
  • R k R_k Rk 是测量噪声协方差矩阵,这个和传感器的噪声相关,一般可以看作服从高斯分布
  • K k K_k Kk 是卡尔曼增益
  • z k z_k zk 是观测数据

我们先不着急强行理解,先看一下简单的例子

2. 具体实例:目标跟踪(1D 位置估计)

假设我们要估计一个物体的 1D 位置,目标运动服从匀速模型:

x k = [ p o s k v e l k ] x_k = \begin{bmatrix} pos_k \\ vel_k \end{bmatrix} xk=[poskvelk]

其中:

  • p o s k pos_k posk 是目标的当前位置
  • v e l k vel_k velk 是目标的速度
(1) 定义状态转移模型

假设时间间隔 Δ t \Delta t Δt ,状态转移矩阵 F F F 为:
F = [ 1 Δ t 0 1 ] F = \begin{bmatrix} 1 & \Delta t \\ 0 & 1 \end{bmatrix} F=[10Δt1]

这里:

  • 位置更新公式 p o s k = p o s k − 1 + v e l k − 1 ⋅ Δ t pos_k = pos_{k-1} + vel_{k-1} \cdot \Delta t posk=posk1+velk1Δt
  • 速度保持不变 v e l k = v e l k − 1 vel_k = vel_{k-1} velk=velk1

假设没有外部控制输入,则 B = 0 B = 0 B=0

(2) 定义观测模型

假设我们只能测量位置,这里观测量就是状态量,所以直接相等:
H = [ 1 0 ] H = \begin{bmatrix} 1 & 0 \end{bmatrix} H=[10]
观测噪声 R R R 服从高斯分布。

(3) 过程噪声

假设加速度变化的标准差是 σ a \sigma_a σa,那么过程噪声协方差矩阵:
Q = [ 1 4 Δ t 4 σ a 2 1 2 Δ t 3 σ a 2 1 2 Δ t 3 σ a 2 Δ t 2 σ a 2 ] Q = \begin{bmatrix} \frac{1}{4} \Delta t^4 \sigma_a^2 & \frac{1}{2} \Delta t^3 \sigma_a^2 \\ \frac{1}{2} \Delta t^3 \sigma_a^2 & \Delta t^2 \sigma_a^2 \end{bmatrix} Q=[41Δt4σa221Δt3σa221Δt3σa2Δt2σa2]

(4) 预测和更新
  • 用预测方程计算 p o s pos pos v e l vel vel
  • 结合测量值更新状态

3. Python 实现

import numpy as np
import matplotlib.pyplot as plt

# 初始化
dt = 1  # 采样时间间隔
F = np.array([[1, dt], [0, 1]])  # 状态转移矩阵
H = np.array([[1, 0]])  # 观测矩阵
Q = np.array([[0.01, 0.01], [0.01, 0.1]])  # 过程噪声
R = np.array([[1]])  # 观测噪声,1x1 的矩阵,服从高斯分布,均值为0, 方差为1, 没有协方差部分
P = np.eye(2)  # 误差协方差

# 初始状态
x = np.array([[0], [1]])  # 初始位置0,速度1

# 真实轨迹(加随机噪声)
np.random.seed(42)
real_positions = []
measurements = []
for i in range(50):
    x_true = i + np.random.randn() * 0.5  # 真实位置
    z = x_true + np.random.randn()  # 观测值
    real_positions.append(x_true)
    measurements.append(z)

# 进行Kalman滤波
filtered_positions = []
for z in measurements:
    # 预测
    x_pred = F @ x
    P_pred = F @ P @ F.T + Q
    
    # 计算卡尔曼增益
    K = P_pred @ H.T @ np.linalg.inv(H @ P_pred @ H.T + R)
    
    # 更新
    x = x_pred + K @ (z - H @ x_pred)
    P = (np.eye(2) - K @ H) @ P_pred
    
    filtered_positions.append(x[0, 0])

# 画图
plt.plot(real_positions, label="真实轨迹")
plt.plot(measurements, 'o', label="测量值", alpha=0.5)
plt.plot(filtered_positions, label="Kalman滤波估计")
plt.legend()
plt.show()

4. 结果分析

  • 原始测量值(带噪声):观测值抖动较大。
  • 真实轨迹:理想状态下的轨迹。
  • Kalman 估计结果:经过滤波后,轨迹更加平滑,误差减小。

结果如下:
在这里插入图片描述

推导相关内容

如果想深度的理解卡尔曼滤波,最好能进行相关公式的推导,我整理了如下的内容,可以帮助大家理解一下,这5个公式怎么来的。

1. 预测步骤(Prediction Step)

预测步骤的目的是利用系统的状态转移模型,从上一时刻的状态预测当前时刻的状态,并对不确定性进行传播。

(1) 预测状态方程

x ^ k − = F k x ^ k − 1 + B k u k \hat{x}_k^- = F_k \hat{x}_{k-1} + B_k u_k x^k=Fkx^k1+Bkuk
物理意义:

  • 上一时刻的估计状态 ( \hat{x}_{k-1} ) 通过系统模型 ( F_k ) 预测当前状态 ( \hat{x}_k^- )。
  • 若系统受到控制输入 ( u_k )(例如加速度控制车辆),则通过 ( B_k u_k ) 对状态进行修正。

注: 这里的 x ^ \hat{x} x^上的帽子代表估计的意思, x k − x_k^- xk这里的右上角的负号代表先验的意思,所以 x ^ k − \hat{x}_k^- x^k代表的意思就是先验估计值。

还是以匀速运动模型为例:
如果我们估计一个物体的 1D 位置和速度:
x k = [ pos k vel k ] x_k = \begin{bmatrix} \text{pos}_k \\ \text{vel}_k \end{bmatrix} xk=[poskvelk]
假设物体遵循 匀速运动模型,状态转移矩阵为:
F = [ 1 Δ t 0 1 ] F = \begin{bmatrix} 1 & \Delta t \\ 0 & 1 \end{bmatrix} F=[10Δt1]
则:
x ^ k − = [ 1 Δ t 0 1 ] [ pos k − 1 vel k − 1 ] = [ pos k − 1 + vel k − 1 ⋅ Δ t vel k − 1 ] \hat{x}_k^- = \begin{bmatrix} 1 & \Delta t \\ 0 & 1 \end{bmatrix} \begin{bmatrix} \text{pos}_{k-1} \\ \text{vel}_{k-1} \end{bmatrix}= \begin{bmatrix} \text{pos}_{k-1} + \text{vel}_{k-1} \cdot \Delta t \\ \text{vel}_{k-1} \end{bmatrix} x^k=[10Δt1][posk1velk1]=[posk1+velk1Δtvelk1]
即:

  • 位置 = 旧位置 + 速度 × 时间
  • 速度保持不变(没有加速度输入)

(2) 预测协方差方程

P k − = F k P k − 1 F k T + Q k P_k^- = F_k P_{k-1} F_k^T + Q_k Pk=FkPk1FkT+Qk
物理意义:

  • P k − P_k^- Pk 代表状态估计的不确定性(协方差矩阵)
  • 误差随着时间传播,乘上 F k F_k Fk 是因为状态自身的演化会影响不确定性
  • 加上 Q k Q_k Qk(过程噪声),表示系统在运动过程中可能会受到外界干扰(如风、摩擦、控制误差)。

推导思路:
由状态转移:
x k = F k x k − 1 + w k x_k = F_k x_{k-1} + w_k xk=Fkxk1+wk
其中 w k w_k wk过程噪声,其协方差为 Q k Q_k Qk,即:
E [ w k w k T ] = Q k E[w_k w_k^T] = Q_k E[wkwkT]=Qk
对误差协方差 P k − P_k^- Pk 计算:
P k − = E [ ( x k − x ^ k − ) ( x k − x ^ k − ) T ] P_k^- = E[(x_k - \hat{x}_k^-)(x_k - \hat{x}_k^-)^T] Pk=E[(xkx^k)(xkx^k)T]
代入 x k = F k x k − 1 + w k x_k = F_k x_{k-1} + w_k xk=Fkxk1+wk
P k − = E [ ( F k x k − 1 + w k − F k x ^ k − 1 ) ( F k x k − 1 + w k − F k x ^ k − 1 ) T ] P_k^- = E[(F_k x_{k-1} + w_k - F_k \hat{x}_{k-1})(F_k x_{k-1} + w_k - F_k \hat{x}_{k-1})^T] Pk=E[(Fkxk1+wkFkx^k1)(Fkxk1+wkFkx^k1)T]
展开,假设过程噪声 w k w_k wk x k − 1 x_{k-1} xk1 无关(独立),去掉交叉项:

E [ ( x k − 1 − x ^ k − 1 ) w k T ] = 0 , E [ w k ( x k − 1 − x ^ k − 1 ) T ] = 0 E[(x_{k-1} - \hat{x}_{k-1}) w_k^T] = 0, \quad E[w_k (x_{k-1} - \hat{x}_{k-1})^T] = 0 E[(xk1x^k1)wkT]=0,E[wk(xk1x^k1)T]=0
等到:
P k − = F k E [ ( x k − 1 − x ^ k − 1 ) ( x k − 1 − x ^ k − 1 ) T ] F k T + E [ w k w k T ] P_k^- = F_k E[(x_{k-1} - \hat{x}_{k-1})(x_{k-1} - \hat{x}_{k-1})^T] F_k^T + E[w_k w_k^T] Pk=FkE[(xk1x^k1)(xk1x^k1)T]FkT+E[wkwkT]
即:
P k − = F k P k − 1 F k T + Q k P_k^- = F_k P_{k-1} F_k^T + Q_k Pk=FkPk1FkT+Qk


2. 更新步骤(Update Step)

更新步骤的目的是结合测量值,修正预测值,使估计更接近真实值。

(3) 计算 Kalman 增益

K k = P k − H k T ( H k P k − H k T + R k ) − 1 K_k = P_k^- H_k^T (H_k P_k^- H_k^T + R_k)^{-1} Kk=PkHkT(HkPkHkT+Rk)1
物理意义:

  • K k K_k Kk 控制测量值对估计的影响程度
  • R k R_k Rk(测量噪声协方差)较大,说明测量不可靠,则 K k K_k Kk 会降低测量值的权重,使系统更依赖模型预测。
  • P k − P_k^- Pk(先验误差协方差)较大,说明预测不确定性高,则 K k K_k Kk 会增加测量值的权重。

推导思路(最小均方误差估计):
观测方程:
z k = H k x k + v k z_k = H_k x_k + v_k zk=Hkxk+vk
其中 v k ∼ N ( 0 , R k ) v_k \sim \mathcal{N}(0, R_k) vkN(0,Rk) 是观测噪声。

观测残差(创新量):
y k = z k − H k x ^ k − y_k = z_k - H_k \hat{x}_k^- yk=zkHkx^k

使用卡尔曼增益 K k K_k Kk 进行修正
x ^ k = x ^ k − + K k y k \hat{x}_k = \hat{x}_k^- + K_k y_k x^k=x^k+Kkyk

误差更新:
e k = x k − x ^ k = x k − x ^ k − − K k y k e_k = x_k - \hat{x}_k = x_k - \hat{x}_k^- - K_k y_k ek=xkx^k=xkx^kKkyk

代入 y k = z k − H k x ^ k − y_k = z_k - H_k \hat{x}_k^- yk=zkHkx^k
e k = x k − x ^ k − − K k ( H k x k + v k − H k x ^ k − ) e_k = x_k - \hat{x}_k^- - K_k (H_k x_k + v_k - H_k \hat{x}_k^-) ek=xkx^kKk(Hkxk+vkHkx^k)

整理:
e k = ( I − K k H k ) ( x k − x ^ k − ) − K k v k e_k = (I - K_k H_k)(x_k - \hat{x}_k^-) - K_k v_k ek=(IKkHk)(xkx^k)Kkvk
目标是最小化更新后的估计误差:
x k = x ^ k − + K k ( z k − H k x ^ k − ) x_k = \hat{x}_k^- + K_k (z_k - H_k \hat{x}_k^-) xk=x^k+Kk(zkHkx^k)
e k = x k − x ^ k e_k = x_k - \hat{x}_k ek=xkx^k 为更新后的误差,最小化其均方误差:
E [ e k e k T ] = E [ ( x k − x ^ k ) ( x k − x ^ k ) T ] E[e_k e_k^T] = E[(x_k - \hat{x}_k)(x_k - \hat{x}_k)^T] E[ekekT]=E[(xkx^k)(xkx^k)T]

这个就相当于计算误差协方差:
P k = E [ e k e k T ] P_k = E[e_k e_k^T] Pk=E[ekekT]

展开:
P k = E [ ( I − K k H k ) ( x k − x ^ k − ) ( x k − x ^ k − ) T ( I − K k H k ) T + K k v k v k T K k T ] P_k = E[(I - K_k H_k)(x_k - \hat{x}_k^-)(x_k - \hat{x}_k^-)^T (I - K_k H_k)^T + K_k v_k v_k^T K_k^T] Pk=E[(IKkHk)(xkx^k)(xkx^k)T(IKkHk)T+KkvkvkTKkT]
由于预测误差协方差 P k − = E [ ( x k − x ^ k − ) ( x k − x ^ k − ) T ] P_k^- = E[(x_k - \hat{x}_k^-)(x_k - \hat{x}_k^-)^T] Pk=E[(xkx^k)(xkx^k)T],且测量噪声协方差 R k = E [ v k v k T ] R_k = E[v_k v_k^T] Rk=E[vkvkT],有:
P k = ( I − K k H k ) P k − ( I − K k H k ) T + K k R k K k T P_k = (I - K_k H_k) P_k^- (I - K_k H_k)^T + K_k R_k K_k^T Pk=(IKkHk)Pk(IKkHk)T+KkRkKkT

K k K_k Kk 使 P k P_k Pk 最小, 令 P k P_k Pk K k K_k Kk 求导,令其梯度为 0:

∂ P k ∂ K k = − H k P k − ( I − K k H k ) T + K k R k = 0 \frac{\partial P_k}{\partial K_k} = -H_k P_k^- (I - K_k H_k)^T + K_k R_k = 0 KkPk=HkPk(IKkHk)T+KkRk=0

整理得:
K k ( H k P k − H k T + R k ) = P k − H k T K_k (H_k P_k^- H_k^T + R_k) = P_k^- H_k^T Kk(HkPkHkT+Rk)=PkHkT

解得:

K k = P k − H k T ( H k P k − H k T + R k ) − 1 K_k = P_k^- H_k^T (H_k P_k^- H_k^T + R_k)^{-1} Kk=PkHkT(HkPkHkT+Rk)1


(4) 更新状态估计

x ^ k = x ^ k − + K k ( z k − H k x ^ k − ) \hat{x}_k = \hat{x}_k^- + K_k (z_k - H_k \hat{x}_k^-) x^k=x^k+Kk(zkHkx^k)
物理意义:

  • z k − H k x ^ k − z_k - H_k \hat{x}_k^- zkHkx^k 代表测量残差(创新),即测量值和预测值的偏差。
  • K k K_k Kk 控制更新幅度,若测量可靠,则 K k K_k Kk 增大,状态更倾向于测量值。

(5) 更新协方差矩阵

P k = ( I − K k H k ) P k − P_k = (I - K_k H_k) P_k^- Pk=(IKkHk)Pk
物理意义:

  • 误差协方差减少,说明对状态的不确定性降低。
  • ( I − K k H k ) (I - K_k H_k) (IKkHk) 作用是削弱测量维度的不确定性,即:
    • K k K_k Kk 很大(测量可靠),则 P k P_k Pk 明显减小。
    • K k K_k Kk 很小(预测更可靠),则 P k P_k Pk 变化不大。

推导思路:
假设新误差:
e k = x k − x ^ k = x k − x ^ k − − K k ( z k − H k x k − ) e_k = x_k - \hat{x}_k = x_k - \hat{x}_k^- - K_k (z_k - H_k x_k^-) ek=xkx^k=xkx^kKk(zkHkxk)
带入 z k = H k x k + v k z_k = H_k x_k + v_k zk=Hkxk+vk,其中 v k v_k vk 是测量噪声:
e k = x k − x ^ k − − K k ( H k x k + v k − H k x k − ) e_k = x_k - \hat{x}_k^- - K_k (H_k x_k + v_k - H_k x_k^-) ek=xkx^kKk(Hkxk+vkHkxk)
= ( I − K k H k ) ( x k − x ^ k − ) − K k v k = (I - K_k H_k)(x_k - \hat{x}_k^-) - K_k v_k =(IKkHk)(xkx^k)Kkvk
计算误差协方差:
P k = E [ e k e k T ] = ( I − K k H k ) P k − ( I − K k H k ) T + K k R k K k T P_k = E[e_k e_k^T] = (I - K_k H_k) P_k^- (I - K_k H_k)^T + K_k R_k K_k^T Pk=E[ekekT]=(IKkHk)Pk(IKkHk)T+KkRkKkT
可近似为:
P k = ( I − K k H k ) P k − P_k = (I - K_k H_k) P_k^- Pk=(IKkHk)Pk


总结

请记住以下5个方程, 5个方程共同作用,使得 Kalman 滤波可以高效、精准地估计系统状态。

步骤公式物理意义
预测状态 x ^ k − = F k x ^ k − 1 + B k u k \hat{x}_k^- = F_k \hat{x}_{k-1} + B_k u_k x^k=Fkx^k1+Bkuk由上一时刻推测当前状态
预测协方差 P k − = F k P k − 1 F k T + Q k P_k^- = F_k P_{k-1} F_k^T + Q_k Pk=FkPk1FkT+Qk传播误差
计算增益 K k = P k − H k T ( H k P k − H k T + R k ) − 1 K_k = P_k^- H_k^T (H_k P_k^- H_k^T + R_k)^{-1} Kk=PkHkT(HkPkHkT+Rk)1平衡预测和测量的权重
更新状态 x ^ k = x ^ k − + K k ( z k − H k x ^ k − ) \hat{x}_k = \hat{x}_k^- + K_k (z_k - H_k \hat{x}_k^-) x^k=x^k+Kk(zkHkx^k)融合测量数据
更新协方差 P k = ( I − K k H k ) P k − P_k = (I - K_k H_k) P_k^- Pk=(IKkHk)Pk误差减少

Kalman 滤波的优势

  • 适用于动态系统的状态估计
  • 能够处理测量噪声和过程噪声
  • 计算复杂度低,适合实时应用

适用条件

  • 线性系统(非线性系统需扩展到 EKF/UKF)
  • 过程噪声和观测噪声服从高斯分布

对于更复杂的应用,如非线性系统、IMU 传感器融合等,可考虑 扩展 Kalman 滤波(EKF)或无迹 Kalman 滤波(UKF)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

白码思

您的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值