前言
这几天学习了卡尔曼滤波器(Kalman Filter)相关的理论知识,并发现了一个非常仔细的推导过程,是在b站上发现的一个搞控制的博士DR_CAN:https://space.bilibili.com/230105574,看完他的卡尔曼滤波器相关的视频,加深了我对理论的理解,这里将视频中的推导过程加以梳理,以便日后查看。
数据融合
一个例子
首先,我们举一个简单的例子来理解一下测量中的递推,假设我们对某一物理量进行多次测量,并使用取平均值的方式来估计其真实值:
x^k=k1(z1+z2+...+zk)(1)
其中 x^k 是我们对真实值的估计,zi 是第 i 次测量的测量值。我们对上式进行简单变换称为递推形式:
x^k=k1(z1+z2+...+zk)=k1(z1+z2+...+zk−1)+k1zk=kk−1x^k−1+k1zk =x^k−1+k1(zk−x^k−1)(2)
上式的含义就是我们对该物理量进行 k 次测量之后的估计值 x^k 为第 k−1 次测量后估计值 x^k−1 和后面一项的,而后面那项受到第 k 次测量值的影响。且随着 k 不断增大,后面项趋于 0,估计值也就不在变化了。
我们可以把式 (2) 中后一项增益改写一下:
x^k=x^k−1+Kk(zk−x^k−1)(3)
这个 Kk 就相当于卡尔曼滤波器中的卡尔曼增益(Kalman Gain),在后面会进行详细推导。
数据融合的例子
下面举另一个测量的例子来加深对上述增益的理解。假设还是对一个物理量进行测量,我们有两种测量传感器,且两种传感器都存在测量误差,我们假设误差服从高斯分布。其中第一种传感器测量出来的值为 z1=30,它的误差标准差为 σ1=2;第二种传感器测量出来的值为 z2=32,它的误差标准差为 σ1=4。现在的问题是如何找到一个最优的估计值 z^ 来估计该物理量的真实值。
我们用上一个例子中思想进行融合,最终的测量估计值为第一个传感器的测量值和两者测量值差的加权和:
z^=z^1+K(z2−z1)(4)
我们需要找到这个增益 K 使得最终估计值的方差最小,也就是得到最优的估计值。这个方差计算如下:
σz^2=var(z1+K(z2−z1))=var((1−K)z1+Kz2)=(1−K)2var(z1)+K2var(z2)=(1−K)2σ12+K2σ22(5)
需要使得方差最小,我们将其对 K 求导并令其等于 0,求出相应的最小值点:
dKdσz^2=−2(1−K)σ12+2Kσ22=0K=σ12+σ22σ12(6)
带入上面的测量值和方差可以求出:K=0.2,σz^2=3.2,z^=30.4。最终的融合结果如下图:
卡尔曼增益
我们使用离散状态空间方程描述一个系统:
xk=Axk−1+Buk−1+wk−1zk=Hxk+vk(7)
其中,wk−1 是过程噪声,假设其服从高斯分布:p(w)∼(0,Q),其中 Q 为过程噪声的协方差矩阵;同样 vk 为测量噪声,假设也服从高斯分布:p(v)∼(0,R),R 为测量噪声的协方差矩阵。
在实际过程中,我们估计状态真实值时,无法知道过程噪声,于是我们的通过模型估计出的状态值(这里称为先验估计值)x^k− 为:
x^k−=Ax^k−1+Buk−1(8)
同样,我们也无法知道测量噪声,于是我们通过测量得到的估计值 x^kmea为:
x^kmea =H−zk(9)
这里同样使用上面数据融合的思想,将两种估计值进行加权融合得到最终的估计值 x^k:
x^k=x^k−+G(H−zk−x^k−)(10)
上式中的 G 为加权的增益参数,其范围为 [0,1],当 G 越接近于 0 时,最终的估计值更接近于模型算出来的先验估计值;当 G 越接近于 1 时,最终的估计值更接近于传感器测量出来的值。
对上式进行简单的变形(把增益区间变为了 [0,H−]),令 G=KkH,上式变为:
x^k=x^k−+Kk(zk−Hx^k−)(11)
和前文中数据融合中一样,我们现在的目标变为:如何找到一个增益 Kk 使得最终的估计值最接近真实值。
不难想到,这个增益的取值和模型中的过程噪声 wk−1 以及测量噪声 vk 有关系,当测量噪声很大时,我们希望最终的估计值更多的依赖于模型计算值(先验估计值),此时希望增益 Kk 很小;当模型中的过程噪声很大时,我们希望最终的估计值更多的依赖于传感器的测量值,此时希望增益 Kk 很大。
我们使用 ek 来衡量真实值和估计值之间的误差:
ek=xk−x^k(12)
这个 ek 也是服从均值为 0 的高斯分布的:p(ek)∼(0,P),这里的 P 为其协方差矩阵,它的值可以这样计算:P=E[ee⊤],也就是ee⊤的期望。且这个协方差矩阵的对角线元素为各个误差分量 ei 的方差(读者不妨令 e为二阶列向量 [e1,e2]⊤ 进行验证),我们需要使最终误差最小,也就是使其协方差矩阵的迹 tr(P) 最小。
我们首先计算协方差矩阵 P :
P=E[ee⊤]=E[(xk−x^k)(xk−x^k)⊤](13)
由式(11),我们知道:
xk−x^k=xk−(x^k−+Kk(zk−Hx^k−))=xk−x^k−−Kk(Hxk+vk)+KkHx^k−=xk−x^k−−KkH(xk−x^k−)−Kkvk=(I−KkH)(xk−x^k−)−Kkvk(14)
我们记上式中的 xk−x^k− 为先验误差ek−,并将式(14)代入(13),有:
Pk=E[(I−KkH)ek−−Kkvk][ek−⊤(I−KkH)⊤−vk⊤Kk⊤]=E(I−KkH)ek−ek−⊤(I−KkH)⊤−E(I−KkH)ek−vk⊤Kk⊤−EKkvkek−⊤(I−KkH)⊤+EKkvkvk⊤Kk⊤=(I−KkH)E(ek−ek−⊤)(I−KkH)⊤+KkE(vkvk⊤)Kk⊤(15)
上面四项中中间两项为 0,这是因为 ek− 和 vk⊤相互独立,且它们期望为0。在上面的式(15)中我们记 E(ek−ek−⊤) 为 Pk−,称为先验协方差矩阵;E(vkvk⊤) 又等于系统测量噪声的协方差矩阵 R 。
所以式(15)进一步写成:
Pk=(I−KkH)Pk−(I−KkH)⊤+KkRKk⊤=Pk−−KkHPk−−Pk−H⊤Kk⊤+KkHPk−H⊤Kk⊤+KkRKk⊤(16)
别忘了我们的目的是求出使 tr(Pk) 最小的 Kk,注意到上式第二项和第三项互为转置(Pk− 为对称矩阵),因而:
tr(Pk)=tr(Pk−)−2tr(KkHPk−)+tr(KkHPk−H⊤Kk⊤)+tr(KkRKk⊤)(17)
将上式(17)对 Kk 求导,并求出极值点:
dkkdtr(Pk)=−2(HPk−)⊤+2KkHPk−H⊤+2KkR=0(18)
可以得到:
Kk=HPk−H⊤+RPk−H⊤(19)
上式(19)就是卡尔曼滤波器中最重要的公式,卡尔曼增益的求法。实际上,从上式我们也能看出来卡尔曼增益和测量误差之间的简单关系,当测量误差很大(R很大)时,卡尔曼增益 Kk 趋近于 0,由式(11)最终估计值由模型先验值决定;当测量误差很小(R很小)时,卡尔曼增益 Kk 趋近于 H−,最终估计值由测量值决定。
至此,卡尔曼增益就推导完毕了。
卡尔曼滤波器
推导完卡尔曼增益之后,我们来看整个卡尔曼滤波器如何工作。
实际上,式(19)中的 Pk− 我们还没有推导如何计算得到,我们根据上面的约定有:
Pk−=E[ekek−⊤](20)
而:
ek−=xk−x^k−=Axk−1+Buk−1+wk−1−Ax^k−1−Buk−1=A(xk−1−x^k−1)+wk−1=Aek−1+wk−1(21)
将上式代入式(20):
Pk−=E[(Aek−1+wk−1)(ek−1⊤A⊤+wk−1⊤)]=E(Aek−1ek−1⊤A⊤)+E(wk−1wk−1⊤)=AE(ek−1ek−1⊤)A⊤+E(wk−1wk−1⊤)=APk−1A⊤+Q(22)
式(22)给出了误差协方差矩阵 Pk 的递推计算方法,根据上一时刻的误差协方差矩阵 Pk−1 和过程噪声协方差矩阵 Q 来计算。
那么至此,我们就能够得到卡尔曼滤波器的工作步骤了:
- 根据模型计算先验估计值:x^k−=Ax^k−1+Buk−1.
- 计算先验误差协方差矩阵:Pk−=APk−1A⊤+Q.
- 计算卡尔曼增益:Kk=HPk−H⊤+RPk−H⊤
- 得到最终估计值(后验估计):x^k=x^k−+Kk(zk−Hx^k−)
- 更新误差协方差矩阵:Pk=(I−KkH)Pk−
其中第5步更新 Pk 用于下一时刻计算 Pk− 。由于卡尔曼滤波器是不断递推工作的,所以第一次需要给 x^k−1 和 Pk−1 赋初值。
参考文献
- DR_CAN的精彩讲解