4500 字
23 分钟
【卡尔曼滤波】01 - 理论基础入门
2024-12-03
2026-02-25

1. 状态空间表达式#

WkW_k:过程噪声

VkV_k:观测噪声

2. 系统框图#

3. 高斯分布#

卡尔曼滤波的噪声分布为高斯分布

WkW_k, QkQ_k 的定义:

举个栗子:

一辆以大约5m/s行驶的小车,收到各种阻力的影响,运动速度为 V+VrV + V_r

实际速度为:5+δ5 + \delta (m/s)

Wk=δW_k = \delta m/s

δN(0,1)\delta \in N(0, 1) 的高斯分布,Qk=1Q_k = 1

4. 协方差#

Δ11\Delta_{11} 就是 Cov(x1,x2)\text{Cov}(x_1, x_2) 的简化形式

二维协方差#

二维协方差(或称为协方差矩阵)是一个扩展了标准协方差概念的工具,适用于多维数据,特别是用于描述两个或更多变量之间的关系。在二维情况下,协方差矩阵可以用于表示两个随机变量 XXYY 的联合分布中的协方差。

协方差矩阵的表示#

对于二维数据 (X,Y)(X, Y),协方差矩阵表示为:

其中:

  • Cov(X,X)\text{Cov}(X, X)XX 的方差,表示 XX 自身的波动程度。
  • Cov(Y,Y)\text{Cov}(Y, Y)YY 的方差,表示 YY 自身的波动程度。
  • Cov(X,Y)\text{Cov}(X, Y)XXYY 之间的协方差,表示它们之间的线性关系。
  • Cov(Y,X)\text{Cov}(Y, X)Cov(X,Y)\text{Cov}(X, Y) 相等,因为协方差是对称的。

因此,二维协方差矩阵包含了两个变量的方差和它们之间的协方差。协方差矩阵的对角线元素是方差,非对角线元素是协方差。

二维协方差矩阵的计算#

假设有数据集 X=[x1,x2,,xn]X = [x_1, x_2, \ldots, x_n]Y=[y1,y2,,yn]Y = [y_1, y_2, \ldots, y_n],则计算步骤:

  1. 计算每个变量的均值 X\overline{X}Y\overline{Y}

  2. 计算每对变量之间的协方差:

    Cov(X,Y)=1ni=1n(XiX)(YiY)\text{Cov}(X, Y) = \frac{1}{n} \sum_{i=1}^{n} (X_i - \overline{X})(Y_i - \overline{Y})

  3. 构建协方差矩阵。

应用#

二维协方差矩阵在以下领域有广泛应用:

  • 多元统计分析
  • 机器学习算法(如主成分分析)
  • 金融分析

5. 超参数#

卡尔曼滤波器主要调节两个参数:

QQ:过程噪声的方差

RR:观测噪声的方差

卡尔曼滤波#

Xk1X_{k-1}:最优估计值,后验,就是卡尔曼滤波器的输出值

XkX_k^{-}:基于 Xk1X_{k-1} 的估计值,先验估计值

yky_k:传感器的测量值,当前时刻的观测值

XkX_k:当前的最优估计值

当前的最优估计值可以理解为先验估计值测量值重合相关得到的结果。

卡尔曼滤波#

一、实现过程#

使用上一次的最优结果,预测当前的值,同时用观测值修正当前值,得到最优结果。


# -*- coding: utf-8 -*-
"""
@对理想的一维匀加速直线运动模型,配有不精确的imu和不精确的gps,进行位置观测,协方差均使用矩阵的方式表示,以适配多维特征
"""
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(1,100,100) # 在1~100s内采样100次
u = 0.6 # 加速度值,匀加速直线运动模型
v0 = 5 # 初始速度
s0 = 0 # 初始位置
X_true = np.array([[s0], [v0]])
size = t.shape[0] + 1
dims = 2 # x, v, [位置, 速度]
# 这两个参数可以理解为Q:对测量器的信任度 R:对系统模型的信任度
Q = np.array([[1e1,0], [0,1e1]]) # 过程噪声的协方差矩阵,这是一个超参数
R = np.array([[1e10,0], [0,1e10]]) # 观测噪声的协方差矩阵,也是一个超参数。
# R_var = R.trace()
# 初始化
X = np.array([[0], [0]]) # 估计的初始状态,[位置, 速度],就是我们要估计的内容,可以用v0,s0填入,也可以默认为0,相差越大,收敛时间越长
P = np.array([[0.1, 0], [0, 0.1]]) # 先验误差协方差矩阵的初始值,根据经验给出
# 已知的线性变换矩阵
F = np.array([[1, 1], [0, 1]]) # 状态转移矩阵
B = np.array([[1/2], [1]]) # 控制矩阵
H = np.array([[1,0],[0,1]]) # 观测矩阵
# 根据理想模型推导出来的真实位置值,实际生活中不会存在如此简单的运动模型,真实位置也不可知,本程序中使用真值的目的是模拟观测噪声数据和测量噪声数据
# 对于实际应用的卡尔曼滤波而言,并不需要知道真实值,而是通过预测值和观测值,来求解最优估计值,从而不断逼近该真值
real_positions = np.array([0] * size) # 这样写的目的是为了创建长序列,用于绘制整个运动过程的图像
real_speeds = np.array([0] * size) # 后面要使用for循环,而for循环中需要用到i,而i是索引,所以需要创建一个长度为size的数组,用于存储每个时刻的位置和速度
real_positions[0] = s0 # 初始时刻的位置
# 实际观测值,通过理论值加上观测噪声模拟获得,初值即理论初始点加上观测噪声
measure_positions = np.array([0] * size)
measure_speeds = np.array([0] * size)
measure_positions[0] = real_positions[0] + np.random.normal(0, R[0][0]**0.5)
# 最优估计值,也就是卡尔曼滤波输出的真实值的近似逼近,同样地,初始值由观测值决定
optim_positions = np.array([0] * size)
optim_positions[0] = measure_positions[0]
optim_speeds = np.array([0] * size)
for i in range(1,t.shape[0]+1):
# 根据理想模型获得当前的速度、位置真实值(实际应用中不需要),程序中只是为了模拟测试值和比较
w = np.array([[np.random.normal(0, Q[0][0]**0.5)], [np.random.normal(0, Q[1][1]**0.5)]]) # 过程噪声协方差矩阵
X_true = F @ X_true + B * u + w
real_positions[i] = X_true[0]
real_speeds[i] = X_true[1]
v = np.array([[np.random.normal(0, R[0][0]**0.5)], [np.random.normal(0, R[1][1]**0.5)]]) # 观测噪声协方差矩阵
# 观测矩阵用于产生真实的观测数据,注意各量之间的关联
Z = H @ X_true + v
# 以下是卡尔曼滤波的整个过程
# 预测
X_ = F @ X + B * u # 预测方程
P_ = F @ P @ F.T + Q # 预测协方差矩阵
# 更新
# 注意矩阵运算的顺序
K = P_@ H.T @ np.linalg.inv(H @ P_@ H.T + R) # 计算卡尔曼滤波增益系数
X = X_ + K @ (Z - H @ X_) # 计算最优估计值
P = (np.eye(2) - K @ H ) @ P_ # 更新最优估计协方差矩阵
# 记录结果
optim_positions[i] = X[0][0]
optim_speeds[i] = X[1][0]
measure_positions[i] = Z[0]
measure_speeds[i] = Z[1]
t = np.concatenate((np.array([0]), t))
plt.plot(t,real_positions,label='real positions')
plt.plot(t,measure_positions,label='measured positions')
plt.plot(t,optim_positions,label='kalman filtered positions')
plt.legend()
plt.show()
plt.plot(t,real_speeds,label='real speeds')
plt.plot(t,measure_speeds,label='measured speeds')
plt.plot(t,optim_speeds,label='kalman filtered speeds')
plt.legend()
plt.show()

这段代码实现了一个一维匀加速运动中的卡尔曼滤波,用于估计物体的真实位置和速度。下面我们详细解释一下代码中每部分的含义,帮助你理解卡尔曼滤波的工作原理:


1. 问题背景#

  • 模拟的是一个匀加速直线运动的物体,其真实的运动受过程噪声(比如发动机噪声、风阻等)影响。
  • 同时,测量设备(如 GPS 和 IMU)也会引入观测噪声,导致测量的位置和速度不够准确。
  • 我们希望使用卡尔曼滤波方法,通过结合运动模型(预测值)和观测值,逐步估计物体的真实位置和速度。

2. 状态定义#

状态包含两个变量:位置 xx 和速度 vv

X=[xv]X = \begin{bmatrix} x \\ v \end{bmatrix}


3. 系统模型#

  1. 状态转移模型 Xk+1=FXk+Bu+wX_{k+1} = F \cdot X_k + B \cdot u + w

    • F=[1101]F = \begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix}:描述如何从当前的状态 XkX_k 预测下一时刻的状态。

      • 假设一个单位时间 Δt=1\Delta t = 1,位置通过公式 xk+1=xk+vkΔtx_{k+1} = x_k + v_k \cdot \Delta t 预测。
      • 速度保持不变:vk+1=vkv_{k+1} = v_k
    • B=[1/21]B = \begin{bmatrix} 1/2 \\ 1 \end{bmatrix}:控制矩阵,用于描述加速度对系统状态的影响。

      • 加速度 uu 对位置的影响是 12uΔt2\frac{1}{2} u \Delta t^2,对速度是 uΔtu \Delta t
    • ww:过程噪声,用于模拟运动模型中的不确定性。

  2. 观测模型 Zk=HXk+vZ_k = H \cdot X_k + v

    • H=[1001]H = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}:观测矩阵,表示测量设备直接观测位置和速度。
    • vv:观测噪声,模拟测量设备的误差。

4. 噪声和协方差矩阵#

  • 过程噪声协方差矩阵 QQ:描述运动模型中的不确定性。

    • Q=[100010]Q = \begin{bmatrix} 10 & 0 \\ 0 & 10 \end{bmatrix}:这里假设位置和速度上的过程噪声是独立的。
  • 观测噪声协方差矩阵 RR:描述测量设备的不准确性。

    • R=[100000010000]R = \begin{bmatrix} 10000 & 0 \\ 0 & 10000 \end{bmatrix}:这里假设位置和速度测量噪声也是独立的。

5. 卡尔曼滤波的步骤#

卡尔曼滤波由两步组成:预测更新

(1) 预测步骤#

  • 状态预测

    Xkk1=FXk1k1+BuX_{k|k-1} = F \cdot X_{k-1|k-1} + B \cdot u

    • 利用状态转移方程,预测当前位置和速度。
  • 协方差预测

    Pkk1=FPk1k1FT+QP_{k|k-1} = F \cdot P_{k-1|k-1} \cdot F^T + Q

    • 协方差矩阵的预测,反映噪声和不确定性的传播。

(2) 更新步骤#

  • 卡尔曼增益

    Kk=Pkk1HT(HPkk1HT+R)1K_k = P_{k|k-1} \cdot H^T \cdot (H \cdot P_{k|k-1} \cdot H^T + R)^{-1}

    • 卡尔曼增益决定了如何平衡预测值和观测值的权重。
  • 状态更新

    Xkk=Xkk1+Kk(ZkHXkk1)X_{k|k} = X_{k|k-1} + K_k \cdot (Z_k - H \cdot X_{k|k-1})

    • 利用测量值 ZkZ_k,修正预测值。
  • 协方差更新

    Pkk=(IKkH)Pkk1P_{k|k} = (I - K_k \cdot H) \cdot P_{k|k-1}

    • 更新后的协方差矩阵,用于描述估计值的不确定性。

6. 代码的具体实现#

  1. 生成真实值和观测值
    • X_true:用运动模型生成真实位置和速度。
    • Z:观测值通过添加观测噪声模拟。
  2. 卡尔曼滤波的预测和更新
    • X_P_:预测状态和协方差矩阵。
    • K:计算卡尔曼增益。
    • XP:更新状态和协方差矩阵。
  3. 记录结果
    • optim_positionsoptim_speeds 存储卡尔曼滤波的估计值。

7. 图示结果#

  • 位置图
    • 蓝色:真实位置(real_positions)。
    • 橙色:观测位置(measure_positions,带噪声)。
    • 绿色:卡尔曼滤波估计的最优位置(optim_positions)。
  • 速度图
    • 蓝色:真实速度(real_speeds)。
    • 橙色:观测速度(measure_speeds,带噪声)。
    • 绿色:卡尔曼滤波估计的最优速度(optim_speeds)。

8. 关键理解#

  1. 噪声影响
    • 观测值受噪声影响波动较大。
    • 卡尔曼滤波通过结合模型预测和观测值,显著减小噪声的影响。
  2. 滤波过程
    • 早期估计可能与真实值偏差较大,但随着时间推移,滤波器逐渐收敛。
  3. 卡尔曼增益的作用
    • 决定了如何在观测值和预测值之间取权重,观测噪声越大,越依赖模型预测。

二、补充说明#

为什么 H 是 2×2 的矩阵#

在卡尔曼滤波中,观测矩阵 HH 的维度是由状态向量 XX 和观测向量 ZZ 决定的,其大小为 m×nm \times n,其中:

  • nn 是状态向量的维度(这里是 2,因为状态 XX 包括 [位置, 速度])。
  • mm 是观测向量的维度(这里是 2,因为观测值 ZZ 包括 [位置, 速度])。

代码中定义的状态向量和观测向量为:

  • 状态向量 XX

    X=[xv]X = \begin{bmatrix} x \\ v \end{bmatrix}

    包含两个变量:位置 xx 和速度 vv

  • 观测向量 ZZ

    Z=[zxzv]Z = \begin{bmatrix} z_x \\ z_v \end{bmatrix}

    包含两个变量:测量的”位置” zxz_x 和测量的”速度” zvz_v

因此,观测矩阵 HH 是一个 2×22 \times 2 的矩阵,用于从状态 XX 映射到观测 ZZ。形式为:

Z=HX+vZ = H \cdot X + v


为什么 H 是 2×2 的单位矩阵?#

在这个例子中,观测矩阵 HH 被定义为:

H=[1001]H = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}

这表示观测值直接测量了状态中的位置和速度,且没有任何变换。具体来说:

  1. 第一行 [1,0][1, 0]

    • 表示观测值的第一个分量 zxz_x 对应状态中的位置 xx,并且它与速度 vv 无关。

    zx=1x+0vz_x = 1 \cdot x + 0 \cdot v

  2. 第二行 [0,1][0, 1]

    • 表示观测值的第二个分量 zvz_v 对应状态中的速度 vv,并且它与位置 xx 无关。

    zv=0x+1vz_v = 0 \cdot x + 1 \cdot v

这就说明测量设备可以分别直接得到位置和速度,且观测值和状态是一一对应的。


如果 H 不是单位矩阵怎么办?#

在实际应用中,观测值可能与状态变量不是一一对应的,比如:

  1. 观测值只有位置(没有速度)

    H=[10]H = \begin{bmatrix} 1 & 0 \end{bmatrix}

    这里,观测值只包含位置 xx,不包含速度 vv

  2. 观测值是状态变量的某种线性组合

    H=[0.50.501]H = \begin{bmatrix} 0.5 & 0.5 \\ 0 & 1 \end{bmatrix}

    这里,观测值的第一个分量是 0.5x+0.5v0.5 \cdot x + 0.5 \cdot v,第二个分量是速度 vv

  3. 非线性观测:如果观测值和状态的关系是非线性的,可能需要使用扩展卡尔曼滤波(EKF)或无迹卡尔曼滤波(UKF)来处理。


为什么 Q=10 和 R=10000#

在卡尔曼滤波中,过程噪声协方差矩阵 QQ观测噪声协方差矩阵 RR 是滤波器的重要参数,它们用来描述系统模型和测量设备的不确定性。

Q=[100010],R=[100000010000]Q = \begin{bmatrix} 10 & 0 \\ 0 & 10 \end{bmatrix}, \quad R = \begin{bmatrix} 10000 & 0 \\ 0 & 10000 \end{bmatrix}

是人为设定的超参数,代表对过程噪声和观测噪声强度的假设。

Q 为什么是 10#

  • 含义QQ过程噪声协方差矩阵,用于描述系统动态模型中的不确定性。它反映了模型对自身预测的信任程度。
  • 设置为 10 表示每秒钟,位置和速度的预测值可能会受到方差为 10 的噪声影响。假设运动模型存在较小的不确定性(与观测噪声相比)。
  • 如果 QQ 设得太小(接近 0),滤波器会过于相信模型而忽视观测值;如果设得太大,滤波器会对模型预测缺乏信任,可能过度依赖观测值。

R 为什么是 10000#

  • 含义RR观测噪声协方差矩阵,用于描述测量设备的不准确性。
  • 设置为 10000 表示测量设备(比如 GPS 或 IMU)在每次测量时的噪声方差为 10000,意味着测量设备相对不精确,观测数据波动较大。
  • 通常,测量设备引入的噪声比运动模型的内在不确定性大得多。将观测噪声方差设为远大于过程噪声方差,表示测量数据不太可信,卡尔曼滤波器会更多地依赖运动模型预测。

两者的相对大小#

  • 如果 QRQ \ll R(过程噪声远小于观测噪声):滤波器更相信运动模型的预测值。
  • 如果 QRQ \gg R(过程噪声远大于观测噪声):滤波器更依赖观测值,而弱化对模型的信任。

状态更新公式 X_true = F @ X_true + B * u + w 的结果#

公式 Xtrue=FXtrue+Bu+wX_{\text{true}} = F \cdot X_{\text{true}} + B \cdot u + w 是用来模拟系统的真实状态更新的。

符号解释#

  • Xtrue=[xv]X_{\text{true}} = \begin{bmatrix} x \\ v \end{bmatrix}:系统的真实状态向量,包括位置 xx 和速度 vv
  • F=[1101]F = \begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix}:状态转移矩阵。
  • B=[1/21]B = \begin{bmatrix} 1/2 \\ 1 \end{bmatrix}:控制矩阵。
  • uu:加速度(设定为 0.6)。
  • w=[wxwv]w = \begin{bmatrix} w_x \\ w_v \end{bmatrix}:过程噪声,其中 wxN(0,Q[0,0])w_x \sim \mathcal{N}(0, Q[0,0])wvN(0,Q[1,1])w_v \sim \mathcal{N}(0, Q[1,1])

更新过程#

逐项展开公式:

  1. 位置更新

    xtrue,new=xtrue+vtrue+12u+wxx_{\text{true,new}} = x_{\text{true}} + v_{\text{true}} + \frac{1}{2} u + w_x

  2. 速度更新

    vtrue,new=vtrue+u+wvv_{\text{true,new}} = v_{\text{true}} + u + w_v

示例计算#

假设当前 Xtrue=[05]X_{\text{true}} = \begin{bmatrix} 0 \\ 5 \end{bmatrix},加速度 u=0.6u = 0.6,噪声 wx=2.0w_x = 2.0wv=1.0w_v = -1.0

  1. 位置更新:xtrue,new=0+5+120.6+2.0=7.3x_{\text{true,new}} = 0 + 5 + \frac{1}{2} \cdot 0.6 + 2.0 = 7.3
  2. 速度更新:vtrue,new=5+0.61.0=4.6v_{\text{true,new}} = 5 + 0.6 - 1.0 = 4.6

最终结果:Xtrue,new=[7.34.6]X_{\text{true,new}} = \begin{bmatrix} 7.3 \\ 4.6 \end{bmatrix}


卡尔曼滤波常见术语(中英对照)#

中文英文
卡尔曼滤波Kalman Filter
状态向量State Vector
状态转移矩阵State Transition Matrix (FF)
观测矩阵Observation Matrix (HH)
过程噪声Process Noise (ww)
观测噪声Measurement Noise (vv)
过程噪声协方差矩阵Process Noise Covariance Matrix (QQ)
观测噪声协方差矩阵Measurement Noise Covariance Matrix (RR)
卡尔曼增益Kalman Gain (KK)
预测步骤Prediction Step
更新步骤Update Step

需要手动调节的参数#

1. 过程噪声协方差矩阵 QQ#

  • 反映对系统模型中随机性的假设。
  • 增大 QQ:滤波器更不信任模型预测,更依赖观测值,结果波动增大。
  • 减小 QQ:滤波器更信任模型预测,结果更平滑但可能响应迟钝。

2. 观测噪声协方差矩阵 RR#

  • 反映对测量设备精度的假设。
  • 增大 RR:滤波器更不信任观测值,更依赖模型预测,结果更平滑。
  • 减小 RR:滤波器更信任观测值,结果更接近测量但波动增大。

3. 初始状态协方差矩阵 PP#

  • 描述对系统初始状态的不确定性。
  • 增大 PP:对初始状态不确定性高,收敛速度可能较慢。
  • 减小 PP:对初始状态较自信,滤波器可能更快收敛。

4. 控制输入 uu 和控制矩阵 BB#

  • 如果系统中的加速度已知,设置精确的 uu 值。
  • 如果没有加速度信息,直接将 BuB \cdot u 设置为 0。

5. 时间步长 Δt\Delta t#

  • 影响状态转移矩阵 FF 和控制矩阵 BB 的数值。

  • 如果时间步长为 Δt\Delta t,矩阵调整为:

    F=[1Δt01],B=[Δt22Δt]F = \begin{bmatrix} 1 & \Delta t \\ 0 & 1 \end{bmatrix}, \quad B = \begin{bmatrix} \frac{\Delta t^2}{2} \\ \Delta t \end{bmatrix}

调节顺序建议#

  1. 确定初始状态和协方差矩阵 PP
  2. 根据传感器噪声水平调整 RR
  3. 根据运动模型复杂性调整 QQ
  4. 根据实际情况调整 uuΔt\Delta t

调节效果总结#

  • 增加 QQ:结果更接近观测值,波动性增加
  • 增加 RR:结果更平滑,但与真实值偏差可能增加
  • QQRR 都变小:更快收敛,但对噪声鲁棒性降低
  • QQRR 都变大:估计值可能迟钝且收敛速度降低
【卡尔曼滤波】01 - 理论基础入门
http://www.turinblog.cn/posts/卡尔曼滤波01---理论基础入门/
作者
Szturin
发布于
2024-12-03
许可协议
CC BY-NC-SA 4.0