卡尔曼滤波器

欢迎访问我的博客首页


1. 滤波器思想


  卡尔曼滤波器是一种最优化递归数据处理算法 Optimal Recursive Data Processing Algorithm。

1.1 最优估计


  比较精确地测量某个距离的长度时,我们通常多次测量并取其平均值作为真实值的估计值。假设每次的测量值是 x i x_i xi,则第 k k k 次的估计值

x ^ k = 1 k ∑ i = 1 k x i = 1 k ⋅ k − 1 k − 1 ⋅ ∑ i = 1 k − 1 x i + 1 k ⋅ x k = k − 1 k ⋅ ( 1 k − 1 ⋅ ∑ i = 1 k − 1 x i ) + 1 k ⋅ x k = k − 1 k ⋅ x ^ k − 1 + 1 k ⋅ x k = x ^ k − 1 + 1 k ⋅ ( x k − x ^ k − 1 ) . \begin{aligned} \hat x_k &= \frac{1}{k} \sum_{i=1}^{k}x_i \\ &= \frac{1}{k} \cdot \frac{k-1}{k-1} \cdot \sum_{i=1}^{k - 1}x_i + \frac{1}{k} \cdot x_k \\ &= \frac{k - 1}{k} \cdot (\frac{1}{k - 1} \cdot \sum_{i=1}^{k - 1}x_i) + \frac{1}{k} \cdot x_k \\ &= \frac{k - 1}{k} \cdot \hat x_{k - 1} + \frac{1}{k} \cdot x_k \\ &= \hat x_{k - 1} + \frac{1}{k} \cdot (x_k - \hat x_{k - 1}). \end{aligned} x^k=k1i=1kxi=k1k1k1i=1k1xi+k1xk=kk1(k11i=1k1xi)+k1xk=kk1x^k1+k1xk=x^k1+k1(xkx^k1).

从上式可以看出,第 k k k 次的估计值 x ^ k \hat x_k x^k 有三个量决定:第 k − 1 k - 1 k1 次的估计值 x ^ k − 1 \hat x_{k - 1} x^k1、第 k k k 次的系数 1 k \frac{1}{k} k1、第 k k k 次的测量值 x k x_k xk。上式是一个递归算法,第 k k k 次的状态仅与第 k − 1 k - 1 k1 次有关,而与更前面的状态无关。这就是卡尔曼滤波器的思想。

  可以看出, k k k 越大,估计值越趋于稳定,即,与第 k k k 次的测量值相关性越小。

1.2 数据融合


  假设两个称的标准差分别是 σ 1 = 2 g \sigma_1 = 2g σ1=2g σ 2 = 4 g \sigma_2 = 4g σ2=4g,使用它们称得一个物体的质量分别是 z 1 = 30 g z_1 = 30g z1=30g z 2 = 32 g z_2 = 32g z2=32g。请估计这个物体的重量。

  题设包含的数学思想是:称对物体的真实质量估计满足正态分布 N ( z , σ 2 ) N(z, \sigma^2) N(z,σ2)。数据融合:令 z ^ = z 1 + k ( z 2 − z 1 ) \hat z = z_1 + k (z_2 - z_1) z^=z1+k(z2z1) z ^ \hat z z^ 是两个正态分布的线性组合,因此也是正态分布。下面,我们需要用 k k k 求出 σ z ^ \sigma_{\hat z} σz^,然后找出令 σ z ^ \sigma_{\hat z} σz^ 最小的 k k k,即可得出 z ^ \hat z z^ 的无偏估计。

  根据方差的定义

σ z ^ 2 = D ( z ^ ) = D [ z 1 + k ( z 2 − z 1 ) ] = D [ ( 1 − k ) z 1 + k z 2 ] = ( 1 − k ) 2 D ( z 1 ) + k 2 D ( z 2 ) . \sigma_{\hat z}^2 = D(\hat z) = D[z_1 + k(z_2 - z_1)] = D[(1 - k)z_1 + kz_2] = (1 - k)^2D(z_1) + k^2D(z_2). σz^2=D(z^)=D[z1+k(z2z1)]=D[(1k)z1+kz2]=(1k)2D(z1)+k2D(z2).

这是关于 k k k 的一元二次函数,极值点就是最值点,因此我们对 k k k 求导

d σ z ^ 2 d k = − 2 ( 1 − k ) D ( z 1 ) + 2 k D ( z 2 ) . \frac{{\rm d} \sigma_{\hat z}^2}{{\rm d} k} =-2(1 - k) D(z_1) + 2kD(z_2). dkdσz^2=2(1k)D(z1)+2kD(z2).

令导数为 0 得 k = D ( z 1 ) D ( z 1 ) + D ( z 2 ) = σ 1 2 σ 1 2 + σ 2 2 = 0.2 k = \frac{D(z_1)}{D(z_1) + D(z_2)} = \frac{\sigma_1^2}{\sigma_1^2 + \sigma_2^2} = 0.2 k=D(z1)+D(z2)D(z1)=σ12+σ22σ12=0.2。因此 z ^ = 30.4 g \hat z =30.4g z^=30.4g

2. 卡尔曼滤波器


  线性高斯系统可以用状态方程和观测方程表示为

{ x k = A k x k − 1 + B k u k + ε k , ε k ∼ N ( 0 , Q k ) , z k = C k x k + δ k , δ k ∼ N ( 0 , R k ) . (2.1) \left\{\begin{aligned} {\bm x}_k &= {\bm A}_k {\bm x}_{k - 1} + {\bm B}_k{\bm u}_{k} + {\bm \varepsilon}_k, &{\bm \varepsilon}_k \sim N({\bm 0}, {\bm Q}_k), \\ {\bm z}_k &= {\bm C}_k {\bm x}_{k} + {\bm \delta}_k, &{\bm \delta}_k \sim N({\bm 0}, {\bm R}_k). \end{aligned}\right. \tag{2.1} {xkzk=Akxk1+Bkuk+εk,=Ckxk+δk,εkN(0,Qk),δkN(0,Rk).(2.1)

其中,第一个公式称为状态方程或运动方程, x {\bm x} x 称为状态向量, A {\bm A} A 称为状态矩阵, B {\bm B} B 称为控制矩阵, u {\bm u} u 称为控制向量或读数向量, ε {\bm \varepsilon} ε 称为过程噪声。第二个公式称为观测方程, C {\bm C} C 称为观测矩阵, δ {\bm \delta} δ 称为观测噪声。

2.1 先验估计与后验估计


  我们可以分别根据状态方程和观测方程得到 k k k 时刻的状态

{ x ^ k − = A k x ^ k − 1 + B k u k , x ^ k M = C k − 1 z k . (2.2) \left\{\begin{aligned} \hat {\bm x}_k^- &= {\bm A}_k \hat {\bm x}_{k - 1} + {\bm B}_k{\bm u}_{k}, \\ \hat {\bm x}_k^M &= {\bm C}_k^{-1} {\bm z}_k. \end{aligned}\right. \tag{2.2} {x^kx^kM=Akx^k1+Bkuk,=Ck1zk.(2.2)

其中, x ^ k − \hat {\bm x}_k^- x^k 是先验估计, x ^ k M \hat {\bm x}_k^M x^kM 是测量值。计算这两个值时没有考虑噪声,因此它们是不准确的。所以我们进行数据融合

x ^ k = x ^ k − + G k ( C k − 1 z k − x ^ k − ) . (2.3a) \hat {\bm x}_k = \hat {\bm x}_k^- + {\bm G}_k({\bm C}_k^{-1} {\bm z}_k - \hat {\bm x}_k^-). \tag{2.3a} x^k=x^k+Gk(Ck1zkx^k).(2.3a)

现在,我们已经利用先验估计 x ^ k − \hat {\bm x}_k^- x^k 和测量值 C k − 1 z k {\bm C}_k^{-1} {\bm z}_k Ck1zk 求得后验估计 x ^ k \hat {\bm x}_k x^k

2.2 卡尔曼增益


  更常见的做法是令 G k = K k C k {\bm G}_k = {\bm K}_k {\bm C}_k Gk=KkCk,把上式写成

x ^ k = x ^ k − + K k ( z k − C k x ^ k − ) . (2.3b) \hat {\bm x}_k = \hat {\bm x}_k^- + {\bm K}_k({\bm z}_k - {\bm C}_k \hat {\bm x}_k^-). \tag{2.3b} x^k=x^k+Kk(zkCkx^k).(2.3b)

公式中的 K k \bm K_k Kk 称为卡尔曼增益矩阵(Kalman Gain Matrix)。

  现在求解 K k \bm K_k Kk。我们令 e k = x k − x ^ k {\bm e}_k = {\bm x}_k - \hat {\bm x}_k ek=xkx^k。因为 e k {\bm e}_k ek 是均值为 0 \bm 0 0 的正态分布的线性组合,所以它也是均值为 0 \bm 0 0 的正态分布,我们假设 e k ∼ N ( 0 , P k ) {\bm e}_k \sim N({\bm 0}, {\bm P}_k) ekN(0,Pk)。为了让 x ^ k \hat {\bm x}_k x^k 尽可能地接近 x k {\bm x}_k xk,我们需要让 e k {\bm e}_k ek 各维度的方差之和最小,也就是让其协方差矩阵 P k {\bm P}_k Pk 的迹最小。

  由

{ x k − x ^ k = x k − x ^ k − − K k z k + K k C k x ^ k − = x k − x ^ k − − K k ( C k x k + δ k ) + K k C k x ^ k − = x k − x ^ k − − K k C k x k − K k δ k + K k C k x ^ k − = ( x k − x ^ k − ) − K k C k ( x k − x ^ k − ) − K k δ k = ( I − K k C k ) ( x k − x ^ k − ) − K k δ k = ( I − K k C k ) e k − − K k δ k , ( x k − x ^ k ) T = e k − T ( I − C k T K k T ) − δ k T K k T . \left\{\begin{aligned} \bm x_k - \hat {\bm x}_k &= \bm x_k - \hat {\bm x}_k^- - {\bm K}_k {\bm z}_k + {\bm K}_k {\bm C}_k \hat {\bm x}_k^- \\ &= \bm x_k - \hat {\bm x}_k^- - {\bm K}_k ({\bm C}_k {\bm x}_{k} + {\bm \delta}_k) + {\bm K}_k {\bm C}_k \hat {\bm x}_k^- \\ &= \bm x_k - \hat {\bm x}_k^- - {\bm K}_k {\bm C}_k {\bm x}_{k} - {\bm K}_k {\bm \delta}_k + {\bm K}_k {\bm C}_k \hat {\bm x}_k^- \\ &= (\bm x_k - \hat {\bm x}_k^-) - {\bm K}_k {\bm C}_k (\bm x_k - \hat {\bm x}_k^-) - {\bm K}_k {\bm \delta}_k \\ &= ({\bm I} - {\bm K}_k {\bm C}_k) (\bm x_k - \hat {\bm x}_k^-) - {\bm K}_k {\bm \delta}_k \\ &= ({\bm I} - {\bm K}_k {\bm C}_k) {\bm e}_k^- - {\bm K}_k {\bm \delta}_k, \\ (\bm x_k - \hat {\bm x}_k)^{\rm T} &= {\bm e}_k^{-\rm T} (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) - {\bm \delta}_k^{\rm T} {\bm K}_k^{\rm T}. \end{aligned}\right. xkx^k(xkx^k)T=xkx^kKkzk+KkCkx^k=xkx^kKk(Ckxk+δk)+KkCkx^k=xkx^kKkCkxkKkδk+KkCkx^k=(xkx^k)KkCk(xkx^k)Kkδk=(IKkCk)(xkx^k)Kkδk=(IKkCk)ekKkδk,=ekT(ICkTKkT)δkTKkT.

e k ⋅ e k T = ( I − K k C k ) e k − ⋅ e k − T ( I − C k T K k T ) − ( I − K k C k ) e k − ⋅ δ k T K k T − K k δ k ⋅ e k − T ( I − C k T K k T ) + K k δ k ⋅ δ k T K k T . \begin{aligned} {\bm e}_k \cdot {\bm e}_k^{\rm T} &= ({\bm I} - {\bm K}_k {\bm C}_k) {\bm e}_k^- \cdot {\bm e}_k^{-\rm T} (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) \\ &- ({\bm I} - {\bm K}_k {\bm C}_k) {\bm e}_k^- \cdot {\bm \delta}_k^{\rm T} {\bm K}_k^{\rm T} \\ &- {\bm K}_k {\bm \delta}_k \cdot {\bm e}_k^{-\rm T} (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) \\ &+ {\bm K}_k {\bm \delta}_k \cdot {\bm \delta}_k^{\rm T} {\bm K}_k^{\rm T}. \end{aligned} ekekT=(IKkCk)ekekT(ICkTKkT)(IKkCk)ekδkTKkTKkδkekT(ICkTKkT)+KkδkδkTKkT.

在第一个公式中,我们记 x k − x ^ k − = e k − \bm x_k - \hat {\bm x}_k^- = {\bm e}_k^- xkx^k=ek

  为了求 P k \bm P_k Pk 的迹,我们先求 P k \bm P_k Pk。由附录 4.2 知

P k = E ( e k ⋅ e k T ) = ( I − K k C k ) E ( e k − ⋅ e k − T ) ( I − C k T K k T ) − ( I − K k C k ) E ( e k − ⋅ δ k T ) K k T − K k E ( δ k ⋅ e k − T ) ( I − C k T K k T ) + K k E ( δ k ⋅ δ k T ) K k T = ( I − K k C k ) P k − ( I − C k T K k T ) − 0 − 0 + K k R k K k T = ( P k − − K k C k P k − ) ( I − C k T K k T ) + K k R k K k T = P k − − P k − C k T K k T − K k C k P k − + K k C k P k − C k T K k T + K k R k K k T = P k − − P k − T C k T K k T − K k C k P k − + K k C k P k − C k T K k T + K k R k K k T = P k − − ( K k C k P k − ) T − K k C k P k − + K k C k P k − C k T K k T + K k R k K k T (2.4) \begin{aligned} {\bm P}_k &= E({\bm e}_k \cdot {\bm e}_k^{\rm T}) \\ &= ({\bm I} - {\bm K}_k {\bm C}_k) E({\bm e}_k^- \cdot {\bm e}_k^{-\rm T}) (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) \\ &- ({\bm I} - {\bm K}_k {\bm C}_k) E({\bm e}_k^- \cdot {\bm \delta}_k^{\rm T}) {\bm K}_k^{\rm T} \\ &- {\bm K}_k E({\bm \delta}_k \cdot {\bm e}_k^{-\rm T}) (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) \\ &+ {\bm K}_k E({\bm \delta}_k \cdot {\bm \delta}_k^{\rm T}) {\bm K}_k^{\rm T} \\ &= ({\bm I} - {\bm K}_k {\bm C}_k) \bm P_k^- (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) \\ &- 0 \\ &- 0 \\ &+ {\bm K}_k \bm R_k {\bm K}_k^{\rm T} \\ &= (\bm P_k^- - {\bm K}_k {\bm C}_k \bm P_k^-) (\bm I - \bm C_k^{\rm T} \bm K_k^{\rm T}) + {\bm K}_k \bm R_k {\bm K}_k^{\rm T} \\ &= \bm P_k^- - \bm P_k^- \bm C_k^{\rm T} \bm K_k^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + {\bm K}_k {\bm C}_k \bm P_k^- \bm C_k^{\rm T} \bm K_k^{\rm T} + {\bm K}_k \bm R_k {\bm K}_k^{\rm T} \\ &= \bm P_k^- - \bm P_k^{-\rm T} \bm C_k^{\rm T} \bm K_k^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + {\bm K}_k {\bm C}_k \bm P_k^- \bm C_k^{\rm T} \bm K_k^{\rm T} + {\bm K}_k \bm R_k {\bm K}_k^{\rm T} \\ &= \bm P_k^- - ({\bm K}_k {\bm C}_k \bm P_k^-)^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + {\bm K}_k {\bm C}_k \bm P_k^- \bm C_k^{\rm T} \bm K_k^{\rm T} + {\bm K}_k \bm R_k {\bm K}_k^{\rm T} \end{aligned} \tag{2.4} Pk=E(ekekT)=(IKkCk)E(ekekT)(ICkTKkT)(IKkCk)E(ekδkT)KkTKkE(δkekT)(ICkTKkT)+KkE(δkδkT)KkT=(IKkCk)Pk(ICkTKkT)00+KkRkKkT=(PkKkCkPk)(ICkTKkT)+KkRkKkT=PkPkCkTKkTKkCkPk+KkCkPkCkTKkT+KkRkKkT=PkPkTCkTKkTKkCkPk+KkCkPkCkTKkT+KkRkKkT=Pk(KkCkPk)TKkCkPk+KkCkPkCkTKkT+KkRkKkT(2.4)

于是

t r ( P k ) = t r ( P k − ) − 2 t r ( K k C k P k − ) + t r ( K k C k P k − C k T K k T ) + t r ( K k R k K k T ) . {\rm tr}(\bm P_k) = {\rm tr}(\bm P_k^-) - 2{\rm tr}({\bm K}_k {\bm C}_k \bm P_k^-) + {\rm tr}({\bm K}_k {\bm C}_k \bm P_k^-\bm C_k^{\rm T} \bm K_k^{\rm T}) + {\rm tr}({\bm K}_k \bm R_k {\bm K}_k^{\rm T}). tr(Pk)=tr(Pk)2tr(KkCkPk)+tr(KkCkPkCkTKkT)+tr(KkRkKkT).

这里用到的公式有:协方差矩阵 P k − \bm P_k^- Pk 是对称矩阵;对称矩阵的性质 ( A B ) T = B T A T (\bm A \bm B)^{\rm T} = \bm B^{\rm T} \bm A^{\rm T} (AB)T=BTAT;迹的性质 t r ( A ) = t r ( A T ) {\rm tr}(\bm A) = {\rm tr}(\bm A^{\rm T}) tr(A)=tr(AT)。在第一个公式中,我们令 P k − = E ( e k − ⋅ e k − T ) \bm P_k^- = E(\bm e_k^- \cdot \bm e_k^{-\rm T}) Pk=E(ekekT)

  接下来我们要找使 P k \bm P_k Pk 的迹 t r ( P k ) {\rm tr}(\bm P_k) tr(Pk) 最小的 K k \bm K_k Kk,于是我们求导并使之为 0 \bm 0 0

0 = d t r ( P k ) d K k = 0 − 2 P k − T C k T + 2 K k C k P k − C k T + 2 K k R k . \bm 0 = \begin{aligned} \frac{{\rm d} {\rm tr}(\bm P_k)}{{\rm d} \bm K_k} = \bm 0 - 2 \bm P_k^{- \rm T} \bm C_k^{\rm T} +2 \bm K_k \bm C_k \bm P_k^- \bm C_k^{\rm T} + 2 \bm K_k \bm R_k. \end{aligned} 0=dKkdtr(Pk)=02PkTCkT+2KkCkPkCkT+2KkRk.

K k = P k − T C k T C k P k − C k T + R k = P k − C k T C k P k − C k T + R k . (2.5) \bm K_k = \frac{\bm P_k^{-\rm T} \bm C_k^{\rm T}} {\bm C_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k} = \frac{\bm P_k^- \bm C_k^{\rm T}} {\bm C_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k}. \tag{2.5} Kk=CkPkCkT+RkPkTCkT=CkPkCkT+RkPkCkT.(2.5)

这里用到的公式有: d t r ( A X ) d X = d t r ( X A ) d X = A T \frac{{\rm d \rm tr}(\bm A \bm X)}{{\rm d} \bm X} = \frac{{\rm d \rm tr}(\bm X \bm A)}{{\rm d} \bm X} = \bm A^{\rm T} dXdtr(AX)=dXdtr(XA)=AT d t r ( A X B X T ) d X = A X B + A T X B T \frac{{\rm d \rm tr}(\bm A \bm X\bm B \bm X^{\rm T})}{{\rm d} \bm X} = \bm A \bm X \bm B + \bm A^{\rm T} \bm X \bm B^{\rm T} dXdtr(AXBXT)=AXB+ATXBT

2.3 先验误差的方差和误差的方差


  欲求 K k \bm K_k Kk 先求先验误差的方差 P k − \bm P_k^- Pk。我们求 P k \bm P_k Pk 时令 P k − = E ( e k − ⋅ e k − T ) \bm P_k^- = E(\bm e_k^- \cdot \bm e_k^{-\rm T}) Pk=E(ekekT),而

e k − = x k − x ^ k − = ( A k x k − 1 + B k u k + ε k ) − ( A k x ^ k − 1 + B k u k ) = A k ( x k − 1 − x ^ k − 1 ) + ε k = A k e k − 1 + ε k . \begin{aligned} \bm e_k^- &= \bm x_k - \hat {\bm x}_k^- \\ &= ({\bm A}_k {\bm x}_{k - 1} + {\bm B}_k{\bm u}_{k} + {\bm \varepsilon}_k) - ({\bm A}_k \hat {\bm x}_{k - 1} + {\bm B}_k{\bm u}_{k}) \\ &= \bm A_k (\bm x_{k - 1} - \hat {\bm x}_{k - 1}) + \bm \varepsilon_k \\ &= \bm A_k \bm e_{k - 1} + \bm \varepsilon_k. \end{aligned} ek=xkx^k=(Akxk1+Bkuk+εk)(Akx^k1+Bkuk)=Ak(xk1x^k1)+εk=Akek1+εk.

其中 ε k ∼ N ( 0 , Q k ) {\bm \varepsilon}_k \sim N({\bm 0}, {\bm Q}_k) εkN(0,Qk)。于是

P k − = E ( e k − ⋅ e k − T ) = E [ ( A k e k − 1 + ε k ) ( e k − 1 T A k T + ε k T ) ] = E ( A k e k − 1 e k − 1 T A k T + A k e k − 1 ε k T + ε k e k − 1 T A k T + ε k ε k T ) = E ( A k e k − 1 e k − 1 T A k T ) + E ( A k e k − 1 ε k T ) + E ( ε k e k − 1 T A k T ) + E ( ε k ε k T ) = A k E ( e k − 1 e k − 1 T ) A k T + 0 + 0 + E ( ε k ε k T ) = A k P k − 1 A k T + Q k . \begin{aligned} \bm P_k^- &= E(\bm e_k^- \cdot \bm e_k^{-\rm T}) \\ &= E[(\bm A_k \bm e_{k - 1} + \bm \varepsilon_k)(\bm e_{k - 1}^{\rm T} \bm A_k^{\rm T} + \bm \varepsilon_k^{\rm T})] \\ &= E(\bm A_k \bm e_{k - 1} \bm e_{k - 1}^{\rm T} \bm A_k^{\rm T} + \bm A_k \bm e_{k - 1} \bm \varepsilon_k^{\rm T} + \bm \varepsilon_k \bm e_{k - 1}^{\rm T} \bm A_k^{\rm T} + \bm \varepsilon_k \bm \varepsilon_k^{\rm T} ) \\ &= E(\bm A_k \bm e_{k - 1} \bm e_{k - 1}^{\rm T} \bm A_k^{\rm T}) + E(\bm A_k \bm e_{k - 1} \bm \varepsilon_k^{\rm T}) + E(\bm \varepsilon_k \bm e_{k - 1}^{\rm T} \bm A_k^{\rm T}) + E(\bm \varepsilon_k \bm \varepsilon_k^{\rm T}) \\ &= \bm A_k E(\bm e_{k - 1} \bm e_{k - 1}^{\rm T}) \bm A_k^{\rm T} + \bm 0 + \bm 0 + E(\bm \varepsilon_k \bm \varepsilon_k^{\rm T}) \\ &= \bm A_k \bm P_{k - 1} \bm A_k^{\rm T} + \bm Q_k. \end{aligned} Pk=E(ekekT)=E[(Akek1+εk)(ek1TAkT+εkT)]=E(Akek1ek1TAkT+Akek1εkT+εkek1TAkT+εkεkT)=E(Akek1ek1TAkT)+E(Akek1εkT)+E(εkek1TAkT)+E(εkεkT)=AkE(ek1ek1T)AkT+0+0+E(εkεkT)=AkPk1AkT+Qk.

  可以看出,欲求先验误差的方差 P k − \bm P_k^- Pk,需先求上一轮误差的方差 P k − 1 \bm P_{k - 1} Pk1。因此我们利用公式 (2.4) 给出求误差的方差的公式

P k = P k − − P k − T C k T K k T − K k C k P k − + K k C k P k − C k T K k T + K k R k K k T = P k − − P k − T C k T K k T − K k C k P k − + K k ( C k P k − C k T + R k ) K k T = P k − − P k − T C k T K k T − K k C k P k − + P k − C k T C k P k − C k T + R k ( C k P k − C k T + R k ) K k T = P k − − P k − T C k T K k T − K k C k P k − + P k − C k T K k T = P k − − K k C k P k − = ( I − K k C k ) P k − . \begin{aligned} {\bm P}_k &= \bm P_k^- - \bm P_k^{-\rm T} \bm C_k^{\rm T} \bm K_k^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + {\bm K}_k {\bm C}_k \bm P_k^- \bm C_k^{\rm T} \bm K_k^{\rm T} + {\bm K}_k \bm R_k {\bm K}_k^{\rm T} \\ &= \bm P_k^- - \bm P_k^{-\rm T} \bm C_k^{\rm T} \bm K_k^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + {\bm K}_k ({\bm C}_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k) \bm K_k^{\rm T} \\ &= \bm P_k^- - \bm P_k^{-\rm T} \bm C_k^{\rm T} \bm K_k^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + \frac{\bm P_k^- \bm C_k^{\rm T}} {\bm C_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k} ({\bm C}_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k) \bm K_k^{\rm T} \\ &= \bm P_k^- - \bm P_k^{-\rm T} \bm C_k^{\rm T} \bm K_k^{\rm T} - {\bm K}_k {\bm C}_k \bm P_k^- + \bm P_k^- \bm C_k^{\rm T} \bm K_k^{\rm T} \\ &= \bm P_k^- - {\bm K}_k {\bm C}_k \bm P_k^- \\ &= (\bm I - {\bm K}_k {\bm C}_k) \bm P_k^-. \end{aligned} Pk=PkPkTCkTKkTKkCkPk+KkCkPkCkTKkT+KkRkKkT=PkPkTCkTKkTKkCkPk+Kk(CkPkCkT+Rk)KkT=PkPkTCkTKkTKkCkPk+CkPkCkT+RkPkCkT(CkPkCkT+Rk)KkT=PkPkTCkTKkTKkCkPk+PkCkTKkT=PkKkCkPk=(IKkCk)Pk.

2.4 估计过程


  现在我们总结一下使用卡尔曼滤波器进行状态估计的过程。第一步求先验估计

x ^ k − = A k x ^ k − 1 + B k u k \hat {\bm x}_k^- = {\bm A}_k \hat {\bm x}_{k - 1} + {\bm B}_k{\bm u}_{k} x^k=Akx^k1+Bkuk

第二步求先验误差的方差(协方差矩阵)

P k − = A k P k − 1 A k T + Q k \bm P_k^- = \bm A_k \bm P_{k - 1} \bm A_k^{\rm T} + \bm Q_k Pk=AkPk1AkT+Qk

第三步计算卡尔曼增益

K k = P k − C k T C k P k − C k T + R k . \bm K_k = \frac{\bm P_k^- \bm C_k^{\rm T}} {\bm C_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k}. Kk=CkPkCkT+RkPkCkT.

第四步计算后验估计

x ^ k = x ^ k − + K k ( z k − C k x ^ k − ) . \hat {\bm x}_k = \hat {\bm x}_k^- + {\bm K}_k({\bm z}_k - {\bm C}_k \hat {\bm x}_k^-). x^k=x^k+Kk(zkCkx^k).

第五步求误差的方差(协方差矩阵)

P k = ( I − K k C k ) P k − . {\bm P}_k = (\bm I - {\bm K}_k {\bm C}_k) \bm P_k^-. Pk=(IKkCk)Pk.

这五个步骤的前两步称为预测,后三步称为校正。

3. 扩展卡尔曼滤波器


  非线性高斯系统可以用状态方程和观测方程表示为

{ x k = f ( x k − 1 , u k ) + ε k , ε k ∼ N ( 0 , Q k ) , z k = h ( x k ) + δ k , δ k ∼ N ( 0 , R k ) . (3.1) \left\{\begin{aligned} \bm x_k &= f(\bm x_{k - 1}, \bm u_k)+ \bm \varepsilon_k, &{\bm \varepsilon}_k \sim N({\bm 0}, {\bm Q}_k), \\ \bm z_k &= h(\bm x_k) + \bm \delta_k, &{\bm \delta}_k \sim N({\bm 0}, {\bm R}_k). \end{aligned}\right. \tag{3.1} {xkzk=f(xk1,uk)+εk,=h(xk)+δk,εkN(0,Qk),δkN(0,Rk).(3.1)

3.1 线性化


  使用泰勒公式展开成线性方程

{ x k = f ( x ^ k − 1 , u k ) + ε k + ∂ f ∂ x k − 1 ∣ x ^ k − 1 ⋅ ( x k − 1 − x ^ k − 1 ) , ε k ∼ N ( 0 , Q k ) , z k = h ( x ~ k ) + δ k + ∂ h ∂ x k ∣ x ~ k ⋅ ( x k − x ^ k ) , δ k ∼ N ( 0 , R k ) . (3.2a) \left\{\begin{aligned} \bm x_k &= f(\hat {\bm x}_{k - 1}, \bm u_k)+ \bm \varepsilon_k + \left. \frac{ \partial f}{ \partial x_{k - 1}} \right| _{\hat {\bm x}_{k - 1}} \cdot (\bm x_{k - 1} - \hat {\bm x}_{k - 1}) , &{\bm \varepsilon}_k \sim N({\bm 0}, {\bm Q}_k), \\ \bm z_k &= h(\tilde {\bm x}_k) + \bm \delta_k + \left. \frac{ \partial h}{ \partial x_k} \right| _{\tilde {\bm x}_k} \cdot (\bm x_k - \hat {\bm x}_k) , &{\bm \delta}_k \sim N({\bm 0}, {\bm R}_k). \end{aligned}\right. \tag{3.2a} xkzk=f(x^k1,uk)+εk+xk1f x^k1(xk1x^k1),=h(x~k)+δk+xkh x~k(xkx^k),εkN(0,Qk),δkN(0,Rk).(3.2a)

我们记

{ ∂ f ∂ x k − 1 ∣ x ^ k − 1 = A k ∂ h ∂ x k ∣ x ~ k = C k \left\{\begin{aligned} \left. \frac{ \partial f}{ \partial x_{k - 1}} \right| _{\hat {\bm x}_{k - 1}} &= A_k \\ \left. \frac{ \partial h}{ \partial x_k} \right| _{\tilde {\bm x}_k} &= C_k \end{aligned}\right. xk1f x^k1xkh x~k=Ak=Ck

则公式 (3.2a) 可以写成

{ x k = f ( x ^ k − 1 , u k ) + ε k + A k ⋅ ( x k − 1 − x ^ k − 1 ) , ε k ∼ N ( 0 , Q k ) , z k = h ( x ~ k ) + δ k + C k ⋅ ( x k − x ^ k ) , δ k ∼ N ( 0 , R k ) . (3.2b) \left\{\begin{aligned} \bm x_k &= f(\hat {\bm x}_{k - 1}, \bm u_k)+ \bm \varepsilon_k + \bm A_k \cdot (\bm x_{k - 1} - \hat {\bm x}_{k - 1}) , &{\bm \varepsilon}_k \sim N({\bm 0}, {\bm Q}_k), \\ \bm z_k &= h(\tilde {\bm x}_k) + \bm \delta_k + \bm C_k \cdot (\bm x_k - \hat {\bm x}_k) , &{\bm \delta}_k \sim N({\bm 0}, {\bm R}_k). \end{aligned}\right. \tag{3.2b} {xkzk=f(x^k1,uk)+εk+Ak(xk1x^k1),=h(x~k)+δk+Ck(xkx^k),εkN(0,Qk),δkN(0,Rk).(3.2b)

现在我们已经把非线性高斯系统转化成与公式 (2.2) 一样的线性高斯系统,因此估计过程可以直接使用第 2 节的推导结果。

3.2 估计过程


  类比卡尔曼滤波,我们可以写出扩展卡尔曼滤波的五个公式

{ x ^ k − = f ( x ^ k − 1 , u k ) P k − = A k P k − 1 A k T + Q k K k = P k − C k T C k P k − C k T + R k x ^ k = x ^ k − + K k [ z k − h ( x ^ k − ) ] P k = ( I − K k C k ) P k − . \left\{\begin{aligned} \hat {\bm x}_k^- &= f(\hat {\bm x}_{k - 1}, \bm u_k) \\ \bm P_k^- &= \bm A_k \bm P_{k - 1} \bm A_k^{\rm T} + \bm Q_k \\ \bm K_k &= \frac{\bm P_k^- \bm C_k^{\rm T}} {\bm C_k \bm P_k^- \bm C_k^{\rm T} + \bm R_k} \\ \hat {\bm x}_k &= \hat {\bm x}_k^- + {\bm K}_k[{\bm z}_k - h(\hat {\bm x}_k^-)] \\ {\bm P}_k &= (\bm I - {\bm K}_k {\bm C}_k) \bm P_k^-. \end{aligned}\right. x^kPkKkx^kPk=f(x^k1,uk)=AkPk1AkT+Qk=CkPkCkT+RkPkCkT=x^k+Kk[zkh(x^k)]=(IKkCk)Pk.

3.3 例子


# encoding=utf-8
import math
import numpy as np
import matplotlib.pyplot as plt


# 运动方程。
def motion_model(x, u):
    B = np.array([[DT * math.cos(x[2, 0]), 0],
                  [DT * math.sin(x[2, 0]), 0],
                  [0.0, DT],
                  [0.0, 0.0]])
    x = x + B @ u
    return x


# 观测方程。
def observation_model(x):
    H = np.array([
        [1, 0, 0, 0],
        [0, 1, 0, 0]
    ])
    z = H @ x
    return z


# 运动学方程中的雅克比矩阵。
def jacob_f(x, u):
    yaw = x[2, 0]
    v = u[0, 0]
    jF = np.array([
        [1.0, 0.0, -DT * v * math.sin(yaw), DT * math.cos(yaw)],
        [0.0, 1.0, DT * v * math.cos(yaw), DT * math.sin(yaw)],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0]])
    return jF


# 观测方程中的雅克比矩阵。
def jacob_h():
    jH = np.array([
        [1, 0, 0, 0],
        [0, 1, 0, 0]
    ])
    return jH


def observation(xTrue, xd, u):
    # 计算无噪声的五元状态,仅用于绘图。
    xTrue = motion_model(xTrue, u)
    # 观测值。
    z = observation_model(xTrue) + GPS_NOISE @ np.random.randn(2, 1)
    # add noise to input
    ud = u + INPUT_NOISE @ np.random.randn(2, 1)
    xd = motion_model(xd, ud)
    return xTrue, z, xd, ud


# 扩展卡尔曼滤波过程
def ekf_estimation(xEst, PEst, z, u):
    """
    滤波的五个公式。
    :param xEst: 上一轮的估计值 hat x_{k - 1}.
    :param PEst: 误差的方差 P_{k - 1}。
    :param z:    观测值 z_k。
    :param u:    带噪声的控制向量 u_k。
    :return:     估计值 hat x_k 和误差的方差 P_k。
    """

    # 1.预测。
    # hat x_k^- = f(hat x_{k - 1}, u_k)
    xPred = motion_model(xEst, u)
    # P_k^- = A_k P_{k - 1} A_k^T + Q_k
    jF = jacob_f(xEst, u)
    PPred = jF @ PEst @ jF.T + Q  # 预测方差
    # 2.更新。
    # K_k = P_k^- H_k^T / (H_k P_k^- H_k^T + R_k)
    jH = jacob_h()
    K = PPred @ jH.T @ np.linalg.inv(jH @ PPred @ jH.T + R)
    # hat x_k = hat x_k^- + K_k(z_k - h(hat x_k^-))
    xEst = xPred + K @ (z - observation_model(xPred))
    # P_k = (I - K_k H_k) P_k^-
    PEst = (np.eye(len(xEst)) - K @ jH) @ PPred
    # 3.。
    return xEst, PEst


# 绘制协方差的椭圆
def plot_covariance_ellipse(xEst, PEst):
    # 从 4x4 的 PEst 矩阵取左上角的 2x2 矩阵。
    Pxy = PEst[0:2, 0:2]
    # 计算特征值和特征向量。
    eigval, eigvec = np.linalg.eig(Pxy)

    if eigval[0] >= eigval[1]:
        bigind = 0
        smallind = 1
    else:
        bigind = 1
        smallind = 0

    t = np.arange(0, 2 * math.pi + 0.1, 0.1)
    a = math.sqrt(eigval[bigind])
    b = math.sqrt(eigval[smallind])
    x = [a * math.cos(it) for it in t]
    y = [b * math.sin(it) for it in t]
    angle = math.atan2(eigvec[bigind, 1], eigvec[bigind, 0])
    rot = np.array([[math.cos(angle), math.sin(angle)],
                    [-math.sin(angle), math.cos(angle)]])
    fx = rot @ (np.array([x, y]))
    px = np.array(fx[0, :] + xEst[0, 0]).flatten()
    py = np.array(fx[1, :] + xEst[1, 0]).flatten()
    plt.plot(px, py, "--r")


def main():
    print(__file__ + " start!!")

    time = 0.0

    # State Vector [x y yaw v]'
    xEst = np.zeros((4, 1))
    xTrue = np.zeros((4, 1))
    PEst = np.eye(4)

    xDR = np.zeros((4, 1))  # Dead reckoning

    # history
    hxEst = xEst
    hxTrue = xTrue
    hxDR = xTrue
    hz = np.zeros((2, 1))

    while SIM_TIME >= time:
        time += DT
        # 线速度 m/s,角速度 rad/s。
        u = np.array([[1], [0.1]])

        xTrue, z, xDR, ud = observation(xTrue, xDR, u)
        # 扩展卡尔曼滤波器的五个方程。
        xEst, PEst = ekf_estimation(xEst, PEst, z, ud)

        # store data history
        hxEst = np.hstack((hxEst, xEst))
        hxDR = np.hstack((hxDR, xDR))
        hxTrue = np.hstack((hxTrue, xTrue))
        hz = np.hstack((hz, z))

        plt.cla()
        # for stopping simulation with the esc key.
        plt.gcf().canvas.mpl_connect('key_release_event',
                                     lambda event: [exit(0) if event.key == 'escape' else None])
        plt.plot(hz[0, :], hz[1, :], ".g")  # 观测数据
        plt.plot(hxTrue[0, :].flatten(), hxTrue[1, :].flatten(), "-y")  # 真实
        plt.plot(hxDR[0, :].flatten(), hxDR[1, :].flatten(), "-k")  # 黑色
        plt.plot(hxEst[0, :].flatten(), hxEst[1, :].flatten(), "-r")  # 红色
        plot_covariance_ellipse(xEst, PEst)
        plt.axis("equal")
        plt.grid(True)
        plt.pause(0.001)


if __name__ == '__main__':
    # EKF 状态方程的协方差矩阵
    Q = np.diag([
        0.1,  # variance of location on x-axis
        0.1,  # variance of location on y-axis
        np.deg2rad(1.0),  # variance of yaw angle
        1.0  # variance of velocity
    ]) ** 2  # predict state covariance

    # 观测方程的协方差矩阵
    R = np.diag([1.0, 1.0]) ** 2  # Observation x,y position covariance

    # 仿真参数
    INPUT_NOISE = np.diag([1.0, np.deg2rad(30.0)]) ** 2
    GPS_NOISE = np.diag([0.5, 0.5]) ** 2

    DT = 0.1  # time tick [s]
    SIM_TIME = 100.0  # simulation time [s]
    main()

4. 附录


4.1 正态分布


  正态分布又叫高斯分布。均值为 μ \mu μ 方差为 σ 2 \sigma^2 σ2 的一维正态分布的概率密度函数是

p ( x ) = ( 2 π σ 2 ) − 1 2 e x p [ − 1 2 ( x − μ 2 ) σ 2 ] . p(x) = (2 \pi \sigma^2)^{-\frac{1}{2}} {\rm exp}[ -\frac{1}{2} \frac{(x - \mu^2)}{\sigma^2} ]. p(x)=(2πσ2)21exp[21σ2(xμ2)].

当随机变量 x \bm x x 是多维矢量时,称为多元正态分布。多元正态分布的概率密度函数是

p ( x ) = d e t ( 2 π Σ ) − 1 2 e x p [ − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ] . p(\bm x) = {\rm det}(2 \pi \bm \Sigma)^{-\frac{1}{2}} {\rm exp}[ -\frac{1}{2} (\bm x - \bm \mu)^{\rm T} \bm \Sigma^{-1} (\bm x - \bm \mu) ]. p(x)=det(2πΣ)21exp[21(xμ)TΣ1(xμ)].

其中,方差 Σ \bm \Sigma Σ 由随机变量 x \bm x x 各分量的协方差组成

Σ = [ C o v ( x 1 , x 1 ) C o v ( x 1 , x 2 ) ⋯ C o v ( x 1 , x n ) C o v ( x 2 , x 1 ) C o v ( x 2 , x 2 ) ⋯ C o v ( x 2 , x n ) ⋮ ⋮ ⋱ ⋮ C o v ( x n , x 1 ) C o v ( x n , x 2 ) ⋯ C o v ( x n , x n ) ] . \bm \Sigma = \begin{bmatrix} {\rm Cov}(x_1, x_1) & {\rm Cov}(x_1, x_2) & \cdots & {\rm Cov}(x_1, x_n) \\ {\rm Cov}(x_2, x_1) & {\rm Cov}(x_2, x_2) & \cdots & {\rm Cov}(x_2, x_n) \\ \vdots & \vdots & \ddots & \vdots \\ {\rm Cov}(x_n, x_1) & {\rm Cov}(x_n, x_2) & \cdots & {\rm Cov}(x_n, x_n) \\ \end{bmatrix}. Σ= Cov(x1,x1)Cov(x2,x1)Cov(xn,x1)Cov(x1,x2)Cov(x2,x2)Cov(xn,x2)Cov(x1,xn)Cov(x2,xn)Cov(xn,xn) .

4.2 均值为零的随机变量的方差


  均值为零的一维随机变量 x ∼ N ( 0 , σ 2 ) x \sim N(0, \sigma^2) xN(0,σ2) 的方差

σ 2 = D ( x ) = E [ x − E ( x ) ] 2 = E ( x 2 ) . \sigma^2 = D(x) = E{[x - E(x)]^2} = E(x^2). σ2=D(x)=E[xE(x)]2=E(x2).

  均值为零的多维随机变量 x ∼ N ( 0 , Σ ) {\bm x} \sim N({\bm 0}, {\bm \Sigma}) xN(0,Σ) 的协方差矩阵

Σ = E ( x x T ) . {\bm \Sigma} = E({\bm x} {\bm x}^{\rm T}). Σ=E(xxT).

证明:因为 x \bm x x 的各分量相互独立,所以

C o v ( x i , x j ) = E ( x i x j ) − E ( x i ) E ( x j ) = E ( x i x j ) = x i x j . {\rm Cov}(x_i, x_j) = E(x_i x_j) - E(x_i)E(x_j) = E(x_i x_j) = x_i x_j. Cov(xi,xj)=E(xixj)E(xi)E(xj)=E(xixj)=xixj.

于是

Σ = [ x 1 x 1 x 1 x 2 ⋯ x 1 x n x 2 x 1 x 2 x 2 ⋯ x 2 x n ⋮ ⋮ ⋱ ⋮ x n x 1 x n x 2 ⋯ x n x n ] = E ( x x T ) . {\bm \Sigma} = \begin{bmatrix} x_1x_1 & x_1x_2 & \cdots & x_1x_n \\ x_2x_1 & x_2x_2 & \cdots & x_2x_n \\ \vdots & \vdots & \ddots & \vdots \\ x_nx_1 & x_nx_2 & \cdots & x_nx_n \\ \end{bmatrix} = E({\bm x} {\bm x}^{\rm T}). Σ= x1x1x2x1xnx1x1x2x2x2xnx2x1xnx2xnxnxn =E(xxT).

5. 参考


  1. 卡尔曼滤波器,B 站,2020。
  2. 扩展卡尔曼滤波器,CSDN,2023。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值