以NASA之名: 卡尔曼滤波器
'That's one small step for man,one giant leap for mankind.' — Neil Alden Armstron
[TOC]
引言
二十世纪的阿波罗登月计划在人类历史上是浓墨重彩的一笔, 是人类科学发展极其重要的里程碑. 在此计划中, 阿姆斯特朗在月球上说出了上面的一句话,是对此计划最最恰当的注释. 说起来这个计划很''简单'': 送人到月球转一圈,然后再回来. 这么一个'简单'的计划实施起来得有多困难大家心中早有尺度.而卡尔曼滤波器(Kalman filter)就是其中的功臣.
荣耀骑士
卡尔曼滤波(器)是以其主要贡献者 Rudolf Emil Kalman 命名的. 这个滤波器做什么的呢?
现在,时间闪回到 1969年 七月, 当时 Armstrong 正坐在阿波罗11号中,飞向月球. 在此期间掌握飞船的位置及其速度是非常重要的.因为只要偏差超过一定阈值, 飞船的超高速就会将这偏差迅速放大,进而飞船就会偏离预定轨道,最终,极有可能飞向太空就再也回不来了.
那要如何得到飞船在某个时间点的位置与速度呢?
我们知道地面上的科学家在将阿波罗11号发射升空之前肯定会预先计算飞船每个点的位置,或者一定有一个计算精确的计算公式.但, 无论多么精确的公式都无法包含所有因素,不确定性是无法避免的. 而阿波罗上面肯定会有一套复杂的传感系统来测算飞船的位置与速度, 然而, 传感觉器必然地会有偏差. 也就是说我们会从两种不同的途径获得两套参数(位置与速度), 这两套参数一般是不同的,却又都是不准确的.
我们当然会想到:能不能综合地考虑这两套参数,从而获得一套靠谱的参数,来指导飞船航行? 那这两个参数如何综合考虑呢? 在此关键时刻,荣耀骑士 — 卡尔曼滤波器登场了.它的出现就是解决此等棘手问题的.
卡尔曼滤波器是如何工作的呢? 我们知道科学家的公式是不会错的,只不过外界因素干扰,才使其失准的.因此我们以其为基准,用传感器的参数来对基校准. 传感器的参数也有不确定性. 我们的目的是获得更精准的参数, 故需要在传感参数校正公式参数时,首要任务即是在当前所有信息面前最小化不确定性.这就是卡尔曼滤波器的作用. 至于它是如何最小化不确定性的,就要涉及公式了, 你确定要上吗? 如果是,请继续~
卡尔曼滤波器*
卡尔曼滤波(器)基于线性动态系统,是建立在线性模型上的带有白噪声的马氏链. 其与隐马尔可夫模型(HMM)很相像,最主要的不同点在其隐状态是连续的,而HMM是离散的.
模型:
{xk=Akxk−1+Bkuk+wkyk=Ckxk+vk
其中所有变量均为矩阵(或向量),
xk
: k 时刻的状态向量;
Ak
: 状态转移矩阵;
Bk
: 控制矩阵,
uk
: 控制向量; 一般,将此控制部分当作确定部分而不包含在模型中,因此上式可简化为:
{xk=Akxk−1+wkyk=Ckxk+vk
yk
: k时刻的观测向量;
Ck
: 观测矩阵;
wk,vk
均为零均值白噪声,方差分别为
Qk,Rk
, 其互不相关,并与初始状态亦不相关:
wk:E[wk]=0,σ2k=Qk;vk:E[vk]=0,σ2k=Rk;cov[x0,wk]=0;cov(x0,vk)=0;E[wkvTk]=0.
卡尔曼滤波器即是利用递推方法及状态方程(式1或式2) 寻找最小均方误差状态变量
xk
的估计值
x^k
:
x~k=xk−x^kminE[x~kx~Tk]→x^k
当不考虑白噪声时:
x^′k=Akx^k−1y^k=Ckx^′k=CkAkx^k−1
其中
x^′k
为 k 时刻状态的估计值(由上一时刻状态经转移矩阵得到),
y^k
为测量值的估计值(由状态估计值推出), 而
x^k
现在称为状态校正后的估计值.
观测向量的误差(也即新息):
y~k=yk−y^k
用观测值来校正状态变量:
x^k==Akx^k−1+Hk(yk−y^k)Akx^k−1+Hk(yk− CkAkx^k−1)
其中,
Hk
称为增益矩阵,即为一新息加权矩阵.
新息(Innovation)y~k
即是在 k 时刻之前没有但在 t 时刻产生的新的新信息. 用代数的语言即是 新息与过去的信息是正交的:
E[y~kyTj]=O,1≤j<k
而且可以容易的推论出, 新息之间也是正交的:
E[y~iy~Tj]=O,i≠j,and1≤i,j≤k
从而可知, 新息
y~k
是一个与k 之前时刻的数据不相关,且有白噪声性质的随机过程.
校正后的状态变量估计误差及其均方值 (Pk
) 还有未经校正的状态变量估计误差的均方值 (
P′k
):
x~kPkP′k===xk−x^kE[x~kx~Tk]=E[(xk−x^k)(xk−x^k)T]E[(xk−x^′k)(xk−x^′k)T]
卡尔曼滤波器即是最小化
Pk
(不确定性) 的方式来得到
Hk
,最终得到
x^k
:
minPk→Hk→x^k
x~k====xk−x^kAkxk−1+wk−(Akx^k−1+Hk(yk− CkAkx^k−1))Akxk−1+wk−(Akx^k−1+Hk( Ck(Akxk−1+wk)+vk− CkAkx^k−1))(Ak−HkCkAk)(xk−1−x^k−1)+(I−HkCk)wk−Hkvk
偷个懒吧, 接着就是'暴力'推导, 没有什么技术含量, 只看你有没有仔细,否则结果一定会出来.
经过几张A4
纸的推导, 你可以得到以下几个重要公式:
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪x^kHkP′kPk====Akx^k−1+Hk(yk−CkAkx^k−1)P′kCTk(CkP′kCTk+Rk)−1AkPk−1ATk+Qk−1(I−HkCk)P′k
这就是卡尔曼滤波器的递推公式了.
假设我们要研究的对象是一个房间的温度。根据你的经验判断,这个房间的温度是恒定的,也就是下一分钟的温度等于现在这一分钟的温度(假设我们用一分钟来做时间单位)。假设你对你的经验不是100%的相信,可能会有上下偏差几度。我们把这些偏差看成是高斯白噪声(White Gaussian Noise),也就是这些偏差跟前后时间是没有关系的而且符合高斯分布(Gaussian Distribution)。另外,我们在房间里放一个温度计,但是这个温度计也不准确的,测量值会比实际值偏差。我们也把这些偏差看成是高斯白噪声。
好了,现在对于某一分钟我们有两个有关于该房间的温度值:你根据经验的预测值(系统的预测值)和温度计的值(测量值)。下面我们要用这两个值结合他们各自的噪声来估算出房间的实际温度值。
假如我们要估算k时刻的实际温度值。首先你要根据k-1时刻的温度值,来预测k时刻的温度。因为你相信温度是恒定的,所以你会得到k时刻的温度预测值是跟k-1时刻一样的,假设是23度,同时该值的高斯噪声的偏差是5度(5是这样得到的:如果k-1时刻估算出的最优温度值的偏差是3,你对自己预测的 不确定度是4度,他们平方相加再开方,就是5)。然后,你从温度计那里得到了k时刻的温度值,假设是25度,同时该值的偏差是4度。
由于我们用于估算k时刻的实际温度有两个温度值,分别是23度和25度。究竟实际温度是多少呢?相信自己还是相信温度计呢?究竟相信谁多一点,我们可以用他们的协方差(covariance)来判断。因为Kg=5^2/(5^2+4^2),所以Kg=0.61,我们可以估算出k时刻的实际温度值是:23+0.61*(25-23)=24.22度。可以看出,因为温度计的协方差(covariance)比较小(比较相信温度计),所以估算出的最优温度值偏向温度计的值。
现在我们已经得到k时刻的最优温度值了,下一步就是要进入k+1时刻,进行新的最优估算。到现在为止,好像还没看到什么自回归的东西出现。对了,在进入k+1时刻之前,我们还要算出k时刻那个最优值(24.22度)的偏差。算法如下:((1-Kg)*5^2)^0.5=3.12。这里的5就是上面的k时刻你预测的那个23度温度值的偏差,得出的3.12就是进入k+1时刻以后k时刻估算出的最优温度值的偏差(对应于上面的3)。
就是这样,卡尔曼滤波器就不断的把(协方差(covariance)递归,从而估算出最优的温度值。他运行的很快,而且它只保留了上一时刻的协方差(covariance)。上面的Kg,就是卡尔曼增益(Kalman Gain)。他可以随不同的时刻而改变他自己的值,是不是很神奇!