本文已参与「新人创作礼」活动,一起开启掘金创作之路。
声明: 本文图文均来源于www.kalmanfilter.net/,如有侵权请联系删除。
本文由微信公众号【DeepDriving】整理,由于全文内容较多所以分成3部分发出来。关注公众号【DeepDriving】,后台回复关键字【卡尔曼滤波器】可获取全文PDF。
多维卡尔曼滤波器
前面介绍了一维卡尔曼滤波器,相信大家已经对卡尔曼滤波器有了一定的认识,但是在实际应用中,我们通常需要处理有多维状态数据的系统。比如,对于一个三维空间中的飞机,我们需要一个9维向量来描述其位置、速度和加速度:
[xyzx˙y˙z˙x¨y¨z¨]T

假设我们采用恒加速度(constant acceleration)动态模型,那么在n时刻飞机的状态可以写为
⎩⎨⎧xn=xn−1+x˙n−1Δt+21x¨n−1Δt2yn=yn−1+y˙n−1Δt+21y¨n−1Δt2zn=zn−1+z˙n−1Δt+21z¨n−1Δt2x˙n=x˙n−1+x¨n−1Δty˙n=y˙n−1+y¨n−1Δtz˙n=z˙n−1+z¨n−1Δtx¨n=x¨n−1y¨n=y¨n−1z¨n=z¨n−1
在实际应用中,我们通常会使用矩阵的方式来描述多维数据处理的过程。接下来,我们将用矩阵的方式来介绍多维卡尔曼滤波器的几个方程。
状态外推方程
状态外推方程的作用是在当前时刻n基于现有的知识去预测n+1时刻系统的状态,所以也叫状态预测方程或者状态转移方程,其矩阵形式的公式如下:
x^n+1,n=Fx^n,n+Gun+wn
其中,x^n+1,n是预测的n+1时刻的系统状态向量;x^n,n是估计的n时刻的系统状态向量;un是控制变量(输入变量),对系统来说是一个可测量的(确定性的)输入;wn是过程噪声,是会影响系统状态的不可测量的输入量;F是状态转移矩阵;G是控制矩阵,也叫输入转移矩阵,用于将控制变量映射为状态变量。
以前面的飞机为例,用状态向量xn^描述其在三维空间中的位置、速度和加速度
x^n=[x^ny^nz^nx˙^ny˙^nz˙^nx¨^ny¨^nz¨^n]T
假如采用恒加速模型,如果不考虑有控制变量输入,那么状态外推方程为
x^n+1,n=Fx^n,n
状态转移方程为
F=⎣⎡100000000010000000001000000Δt001000000Δt001000000Δt0010000.5Δt200Δt0010000.5Δt200Δt0010000.5Δt200Δt001⎦⎤
那么
⎣⎡x^n+1,ny^n+1,nz^n+1,nx˙^n+1,ny˙^n+1,nz˙^n+1,nx¨^n+1,ny¨^n+1,nz¨^n+1,n⎦⎤=⎣⎡100000000010000000001000000Δt001000000Δt001000000Δt0010000.5Δt200Δt0010000.5Δt200Δt0010000.5Δt200Δt001⎦⎤⎣⎡x^n,ny^n,nz^n,nx˙^n,ny˙^n,nz˙^n,nx¨^n,ny¨^n,nz¨^n,n⎦⎤
算得结果
⎩⎨⎧x^n+1,n=x^n,n+x˙^n,nΔt+21x¨^n,nΔt2y^n+1,n=y^n,n+y˙^n,nΔt+21y¨^n,nΔt2z^n+1,n=z^n,n+z˙^n,nΔt+21z¨^n,nΔt2x˙^n+1,n=x˙^n,n+x¨^n,nΔty˙^n+1,n=y˙^n,n+y¨^n,nΔtz˙^n+1,n=z˙^n,n+z¨^n,nΔtx¨^n+1,n=x¨^n,ny¨^n+1,n=y¨^n,nz¨^n+1,n=z¨^n,n
假如我们有加速度传感器可以提供飞机的加速度信息作为系统的输入,所提供的加速度测量值un为
un=⎣⎡x¨ny¨nz¨n⎦⎤
那么状态外推方程为
x^n+1,n=Fx^n,n+Gun,n
转移矩阵F和控制矩阵G分别如下:
F=⎣⎡100000010000001000Δt001000Δt001000Δt001⎦⎤
G=⎣⎡0.5Δt200Δt0000.5Δt200Δt0000.5Δt200Δt⎦⎤
那么
⎣⎡x^n+1,ny^n+1,nz^n+1,nx˙^n+1,ny˙^n+1,nz˙^n+1,n⎦⎤=⎣⎡100000010000001000Δt001000Δt001000Δt001⎦⎤⎣⎡x^n,ny^n,nz^n,nx˙^n,ny˙^n,nz˙^n,n⎦⎤+⎣⎡0.5Δt200Δt0000.5Δt200Δt0000.5Δt200Δt⎦⎤⎣⎡x¨ny¨nz¨n⎦⎤
协方差外推方程
协方差外推方程如下:
Pn+1,n=FPn,nFT+Q
其中,Pn,n描述了当前估计值的不确定度,是当前系统状态的协方差矩阵;Pn+1,n描述了当前预测值的不确定度,是预测的系统状态的协方差矩阵;F是状态转移矩阵;Q是过程噪声协方差矩阵。
现在我们从头来推导一下这个方程。
假设过程噪声为零(Q=0),那么
Pn+1,n=FPn,nFT
由前面的背景知识我们知道系统状态向量x的协方差矩阵为
COV(x)=E((x−μx)(x−μx)T)
因此
Pn,n=E((x^n,n−μxn,n)(x^n,n−μxn,n)T)
根据状态外推方程
x^n+1,n=Fx^n,n+Gu^n,n
可得
Pn+1,n=E((x^n+1,n−μxn+1,n)(x^n+1,n−μxn+1,n)T)=E((Fx^n,n+Gu^n,n−Fμxn,n−Gu^n,n)(Fx^n,n+Gu^n,n−Fμxn,n−Gu^n,n)T)=E(F(x^n,n−μxn,n)(F(x^n,n−μxn,n))T)=E(F(x^n,n−μxn,n)(x^n,n−μxn,n)TFT)=FE((x^n,n−μxn,n)(x^n,n−μxn,n)T)FT=FPn,nFT
该如何构建过程噪声协方差矩阵Q呢?
假设系统的状态为位置、速度和加速度,分别用x,v和a来表示。对于恒速模型来说,过程噪声的协方差矩阵为
Q=[V(x)COV(v,x)COV(x,v)V(v)]
我们将用随机加速度方差σa2来表示位置、速度的方差和协方差。由前面的背景知识可以知道
V(v)=σv2=E(v2)−μv2=E((aΔt)2)−(μaΔt)2=Δt2(E(a2)−μa2)=Δt2σa2
V(x)=σx2=E(x2)−μx2=E((21aΔt2)2)−(21μaΔt2)2=4Δt4(E(a2)−μa2)=4Δt4σa2
COV(x,v)=COV(v,x)=E(xv)−μxμv=E(21aΔt2aΔt)−(21μaΔt2μaΔt)=2Δt3(E(a2)−μa2)=2Δt3σa2
那么
Q=σa2[4Δt42Δt32Δt3Δt2]
这样求矩阵Q比较麻烦,我们可以通过下面的方式快速求出来。
如果动态模型不包含控制输入,那么我们可以直接通过状态转移矩阵将加速度的随机方差σa2映射到动态模型中。定义矩阵Qa为:
Qa=⎣⎡000000001⎦⎤σa2
那么过程噪声协方差矩阵Q可由下面的公式得到
Q=FQaFT
由运动模型可知状态转移矩阵为
F=⎣⎡100Δt102Δt2Δt1⎦⎤
则
Q=FQaFT=⎣⎡100Δt102Δt2Δt1⎦⎤⎣⎡000000001⎦⎤⎣⎡1Δt2Δt201Δt001⎦⎤σa2=⎣⎡0000002Δt2Δt1⎦⎤⎣⎡1Δt2Δt201Δt001⎦⎤σa2=⎣⎡4Δt42Δt32Δt22Δt3Δt2Δt2Δt2Δt1⎦⎤σa2
如果动态模型包含控制输入,那么过程噪声协方差矩阵Q可由下面的公式得到:
Q=Gσa2GT
其中G为控制矩阵(或者叫输入转移矩阵)。由运动模型可知
G=[2Δt2Δt]
那么
Q=Gσa2GT=σa2GGT=σa2[2Δt2Δt][2Δt2Δt]=σa2[4Δt42Δt32Δt3Δt2]
状态更新方程
状态更新方程的表达式如下所示:
x^n,n=x^n,n−1+Kn(zn−Hx^n,n−1)
其中x^n,n是n时刻估计的系统状态向量;x^n,n−1是在n−1时刻预测的系统状态向量;Kn是卡尔曼增益;zn是测量值;H为观测矩阵。
在前面测量金条重量的例子中我们已经介绍了状态更新方程,在这里就不做更多介绍了。在多维的情况下,我们需要注意的是矩阵的维度。举个例子,假如系统的状态是一个5维的向量,但是只有第1、3、5维是可测量的:
x(n)=⎣⎡x1x2x3x4x5⎦⎤z(n)=⎣⎡z1z3z5⎦⎤
那么观测矩阵应该是一个3×5的矩阵:
H=⎣⎡100000010000001⎦⎤
那么观测残差(zn−Hx^n,n−1)为
(zn−Hx^n,n−1)=⎣⎡z1z3z5⎦⎤−⎣⎡100000010000001⎦⎤⎣⎡x^1x^2x^3x^4x^5⎦⎤=⎣⎡(z1−x^1)(z3−x^3)(z5−x^5)⎦⎤
此时卡尔曼增益的维度应该是5×3。
协方差更新方程
协方差更新方程的表达式如下:
Pn,n=(I−KnH)Pn,n−1(I−KnH)T+KnRnKnT
其中,Pn,n为当前状态估计值的协方差矩阵;Pn,n−1是当前状态的先验估计(基于前一个状态的预测)的协方差矩阵;Kn为卡尔曼增益;H为观测矩阵;Rn为测量噪声的协方差矩阵。
接下来,我们将对这个公式进行详细推导。推导过程中会用到下面几个公式:
| 方程 | 说明 |
|---|
| x^n,n=x^n,n−1+Kn(zn−Hx^n,n−1) | 状态更新方程 |
| zn=Hxn+vn | 测量方程,vn为测量噪声 |
| Pn,n=E(enenT)=E((xn−x^n,n)(xn−x^n,n)T) | 状态协方差矩阵 |
| Rn=E(vnvnT) | 测量噪声协方差矩阵 |
对于每一个估计,估计误差en为
en=xn−x^n,n=xn−x^n,n−1−Kn(zn−Hx^n,n−1)=xn−x^n,n−1−Kn(Hxn+vn−Hx^n,n−1)=xn−x^n,n−1−KnHxn−Knvn+KnHx^n,n−1=xn−x^n,n−1−KnH(xn−x^n,n−1)−Knvn=(I−KnH)(xn−x^n,n−1)−Knvn
再由上式来推导估计值的协方差矩阵Pn,n
Pn,n=E(enenT)=E((xn−x^n,n)(xn−x^n,n)T)=E(((I−KnH)(xn−x^n,n−1)−Knvn)×((I−KnH)(xn−x^n,n−1)−Knvn)T)=E(((I−KnH)(xn−x^n,n−1)−Knvn)×(((I−KnH)(xn−x^n,n−1))T−(Knvn)T))=E(((I−KnH)(xn−x^n,n−1)−Knvn)×((xn−x^n,n−1)T(I−KnH)T−(Knvn)T))=E((I−KnH)(xn−x^n,n−1)(xn−x^n,n−1)T(I−KnH)T)−E((I−KnH)(xn−x^n,n−1)(Knvn)T)−E(Knvn(xn−x^n,n−1)T(I−KnH)T)+E(Knvn(Knvn)T)
(xn−x^n,n−1)是先验估计与真实值之间的误差,它与当前时刻的测量噪声vn是不相关的。有前面的背景知识我们知道,两个相互独立变量乘积的期望值为零,所以
E((I−KnH)(xn−x^n,n−1)(Knvn)T)=0E(Knvn(xn−x^n,n−1)T(I−KnH)T)=0
那么
Pn,n=E((I−KnH)(xn−x^n,n−1)(xn−x^n,n−1)T(I−KnH)T)+E(KnvnvnTKnT)=(I−KnH)E((xn−x^n,n−1)(xn−x^n,n−1)T)(I−KnH)T+KnE(vnvnT)KnT
由
E((xn−x^n,n−1)(xn−x^n,n−1)T)=Pn,n−1E(vnvnT)=Rn
可得
Pn,n=(I−KnH)Pn,n−1(I−KnH)T+KnRnKnT
好了,终于把这个公式推导完了。
卡尔曼增益
卡尔曼增益的表达式如下:
Kn=Pn,n−1HT(HPn,n−1HT+Rn)−1
其中,Kn为卡尔曼增益;Pn,n−1是当前状态的先验估计(基于前一个状态的预测)的协方差矩阵;H为观测矩阵;Rn为测量噪声的协方差矩阵。
在开始推导卡尔曼增益之前,让我们先对协方差更新公式再做一些变换:
Pn,n=(I−KnH)Pn,n−1(I−KnH)T+KnRnKnT=(I−KnH)Pn,n−1(I−(KnH)T)+KnRnKnT=(I−KnH)Pn,n−1(I−HTKnT)+KnRnKnT=(Pn,n−1−KnHPn,n−1)(I−HTKnT)+KnRnKnT=Pn,n−1−Pn,n−1HTKnT−KnHPn,n−1+KnHPn,n−1HTKnT+KnRnKnT=Pn,n−1−Pn,n−1HTKnT−KnHPn,n−1+Kn(HPn,n−1HT+Rn)KnT
卡尔曼滤波器是最优滤波器,因此我们需要寻求能最小化估计方差的卡尔曼增益。为了最小化估计方差,我们需要最小化状态协方差矩阵Pn,n的主对角线,也就是最小化它的迹tr(Pn,n)。为了求得tr(Pn,n)的极小值,我们需要求迹tr(Pn,n)关于卡尔曼增益Kn的导数,并设导数为零。
tr(Pn,n)=tr(Pn,n−1)−tr(Pn,n−1HTKnT)−tr(KnHPn,n−1)+tr(Kn(HPn,n−1HT+Rn)KnT)=tr(Pn,n−1)−2tr(KnHPn,n−1)+tr(Kn(HPn,n−1HT+Rn)KnT)
求导数并令其为零:
dKnd(tr(Pn,n))=dKnd(tr(Pn,n−1))−dKnd(2tr(KnHPn,n−1))+dKnd(tr(Kn(HPn,n−1HT+Rn)KnT))=0−2(HPn,n−1)T+2Kn(HPn,n−1HT+Rn)=0
这里用到了两个计算公式:
{\frac{d}{d\boldsymbol{A}} \left( tr\left( \boldsymbol{ABA^{T}} \right) \right) = 2\boldsymbol{AB} }$$
由上面的导数为零,可得
(HPn,n−1)T=Kn(HPn,n−1HT+Rn)
因此可求得卡尔曼增益Kn:
Kn=(HPn,n−1)T(HPn,n−1HT+Rn)−1=Pn,n−1THT(HPn,n−1HT+Rn)−1=Pn,n−1HT(HPn,n−1HT+Rn)−1
因为协方差矩阵是对称矩阵,所以Pn,n−1T=Pn,n−1。
简化的协方差更新方程
在很多资料中,协方差更新方程并不是前面我们推导出来的那样,而是将卡尔曼增益公式代入后再化简得到的。
Pn,n=(I−KnH)Pn,n−1(I−KnH)T+KnRnKnT=Pn,n−1−Pn,n−1HTKnT−KnHPn,n−1+Kn(HPn,n−1HT+Rn)KnT=Pn,n−1−Pn,n−1HTKnT−KnHPn,n−1+Pn,n−1HT(HPn,n−1HT+Rn)−1(HPn,n−1HT+Rn)KnT=Pn,n−1−Pn,n−1HTKnT−KnHPn,n−1+Pn,n−1HTKnT=Pn,n−1−KnHPn,n−1=(I−KnH)Pn,n−1
化简后的式子显得更加优雅而且方便记忆。然而需要注意的是,即使是计算卡尔曼增益时由于四舍五入引起的一点小误差也可能会导致巨大的计算误差,因为相减项(I−KnH)会因为浮点数精度误差而导致出现非对称矩阵。因此,这个方程是数值不稳定的!
总结
前面已经用矩阵形式详细推导了卡尔曼滤波器的5个方程,把这5个方程联系到一起可以知道,卡尔曼滤波器执行的操作就是一个不断“预测-更新”的迭代过程,如下图所示:

在初始化之后,卡尔曼滤波器将会预测系统在下一个时刻的状态,同时提供预测的不确定度。在得到测量值之后,卡尔曼滤波器会根据测量值对预测值进行更新(校正)从而估计出一个相对准确的当前状态及其不确定度。然后,卡尔曼滤波器将基于当前状态去预测下一时刻的系统状态,如此循环迭代下去......
下图展示了卡尔曼滤波器在执行”预测-更新“操作过程中所使用的5个方程:

下表对卡尔曼滤波器的5个方程进行了总结:
| 操作 | 方程 | 方程名 |
|---|
| 预测 | x^n+1,n=Fx^n,n+Gun | 状态外推方程 |
| 预测 | Pn+1,n=FPn,nFT+Q | 协方差外推方程 |
| 更新 | x^n,n=x^n,n−1+Kn(zn−Hx^n,n−1) | 状态更新方程 |
| 更新 | Pn,n=(I−KnH)Pn,n−1(I−KnH)T+KnRnKnT | 协方差更新方程 |
| 更新 | Kn=Pn,n−1HT(HPn,n−1HT+Rn)−1 | 卡尔曼增益 |
其中
| 方程 | 说明 |
|---|
| zn=Hxn | 测量方程 |
| Rn=E(vnvnT) | 测量噪声协方差矩阵 |
| Qn=E(wnwnT) | 过程噪声协方差矩阵 |
| Pn,n=E(enenT)=E((xn−x^n,n)(xn−x^n,n)T) | 状态协方差矩阵 |
下标是对5个方程中所用到的符号的说明:
| 符号 | 说明 |
|---|
| x | 状态向量 |
| z | 观测向量 |
| F | 状态转移矩阵 |
| u | 输入向量 |
| G | 控制矩阵 |
| P | 状态协方差矩阵 |
| Q | 过程噪声协方差矩阵 |
| R | 测量噪声协方差矩阵 |
| w | 过程噪声向量 |
| v | 测量噪声向量 |
| H | 观测矩阵 |
| K | 卡尔曼增益 |
| n | 离散时间索引 |