工作中需要用到卡尔曼滤波,这里记录一下自己的学习心得,便于以后复习。我是一个程序员,不是搞数学或双控的,所以叙述中难免有不精确的地方,但一定是对于普通人来说好理解的表达方式。
当然,学习卡尔曼滤波免不了要了解一些矩阵运算的知识,这方面是真没办法,去看线性代数吧,我就不在文章里介绍了。
另外,学习卡尔曼滤波还要弄明白一些很重要的统计学概念,比如期望、协方差、高斯分布等等,至于它们的定义也请参考其他资料吧。
虽然题目叫哲学问题,但实际上想介绍清楚几个名词的含义,分别是 “真实值”、“估计值”、“测量值”、“最优估计值”
第一个概念:现实世界中,“真实值”不可知。
这里我不免俗的用一个房间的温度来举例子,那么“真实值”指的就是“房间的真实温度"。根据物理学知识我们可以知道,”房间的真实温度“是由房间中所有微观粒子的运动状态决定的,它是客观的,不会受到人的主观意识或者使用的测量工具的影响(此处请忘记量子力学)。
那么这个”真实的温度“是多少呢?这个问题可能永远也没有答案,因为你无法统计所有粒子的状态。即使你有办法统计,也是不行的,因为统计必然要用到仪器,没有什么仪器是100%准确的,你统计的结果一定是有误差的。
第二个概念:“真实值”可以被估计和测量。
先说测量。“真实值”虽然不可知道,但是我们可以利用仪器对真实值进行测量。比如房间的温度,我们可以用一个温度计测量,但我们知道仪器不可能绝对准确,一定是有误差的。所以,可得:
测 量 值 = 真 实 值 + 测 量 误 差 测量值 = 真实值 + 测量误差 测量值=真实值+测量误差
再说说估计。其实,更准确的说,这里的估计应该是指利用模型进行推测。为了推断当前房间的温度,我首先需要对房间温度变化建立一个数学模型,比如:
房 间 温 度 = 房 间 初 始 温 度 + K ∗ 光 照 时 间 , 其 中 K 为 常 数 房间温度 =房间初始温度+K * \sqrt{光照时间},其中K 为常数 房间温度=房间初始温度+K∗光照时间,其中K为常数
然后,我就可以根据这个数学模型去推测当前房间的温度。当然这个模型显然不能准确得到房间的温度,但通过这个例子我看可以得到如下的要点:
但是,由于现实世界太复杂,建立的任何数学模型都不可能丝毫不差的反应一个物理过程。因此任何数学模型都是一个有误差模型,我们将这个误差,叫做“过程误差”(也有叫其他名字的,我个人习惯这个名字,所以就使用了这个)。所以,通过模型推测出的估计值满足如下公式:
估 计 值 = 真 实 值 + 过 程 误 差 估计值 = 真实值 + 过程误差 估计值=真实值+过程误差
第三个概念:最优估计值为测量值与估计值得加权平均
有了估计值和测量值,但我们还面临一个问题,估计值和测量值那一个更接近真实值呢?
我们的直观感受是测量值更接近真实值,买菜用称,看时间用表,冷热用温度计,测量值在我们生活中应用的更为普遍,所以我们似乎更容易接受测量值作为真实值的代表。
但实时并非如此,以在市场买西红柿为例,当你挑选完5个西红柿后,你会首先估计一个重量,比如2斤;然后,你将西红柿交给摊主去称重,显示是2斤3两,这与你的估计偏差不大,所以你相信了测量值。但是,如果此时显示为10斤,你就会相信你的估计值,当场拒绝这笔买卖。
所以,在推测真实值的过程中,估计值和测量值是都会用到的。上文买菜的例子,使用的推测方法可总结为:
卡尔曼滤波将上述方法总结为如下公式:
最 优 估 计 值 = 估 计 值 + G ∗ ( 测 量 值 − 估 计 值 ) 最优估计值 = 估计值+G*(测量值-估计值) 最优估计值=估计值+G∗(测量值−估计值)
其中,G为比例系数,取值范围[0,1]。当G=1时,相当于我们完全用测量值表示真实值;当G=0时,相当于完全用估计值表示真实值。但更多的时候,最接近真实值的是估计值和测量值混合体(即0
通过前文可知,卡尔曼滤波需要用到测量值和估计值。测量值不必多说,利用传感器测量即可。那么,如何得到估计值呢?其实这个问题前文也有提到,就是利用数学模型。
但是,卡尔曼滤波使用的数学模型是有一定的要求的,这个要求专业点说就是要建立系统的状态方程。
那么,什么是状态方程,如何建立状态方程呢?自动化学科有一门课叫做《现代控制理论》,是一门32课时的大课,基本上就是在讲这两个问题,所以本文不可能讲得很到位,只能概述一下。
在解释状态方程前,首先要解释一个名词叫做状态量。狭义在卡尔曼滤波的范畴,状态量就是你想知道的量。比如前文房间温度的例子,状态量就是温度,只有一个量,但是状态量有时是多个,构成一个向量,比如车的位置,这就需要用坐标X,坐标Y两个量来表征。总之,状态量就是能够描述当前系统状态的一组物理量,可以是一个,也可以是多个。
在状态量的选择上,唯一的要求是各个量彼此间是独立的。独立的含义是协方差为0,更为具体的含义请参考数理统计的资料。(其实,卡尔曼滤波本身并没有独立的要求,但是工程实践中选择彼此独立的变量构成状态量会大大简化设计,并且有利于描述卡尔曼滤波原理的推到过程,所以我引入了这个要求)
这里以运动状态为例,根据物理学知识,能够描述一个物体运动状态的是速度和位移,因此我们可以选取如下向量作为表征物体运动的状态量。
运 动 状 态 = ( V , P ) T 运动状态= (V,P)^T 运动状态=(V,P)T
理解了状态量,我们就可以定义状态方程了。所谓状态方程就是描述状态量以时间为变量的递推方程。还是以描述匀速直线运动状态为例,此状态方程可写为:
[ V k P k ] = [ 1 0 d t 1 ] [ V k − 1 P k − 1 ] \left[ \begin{matrix} V_{k} \\ P_{k} \end{matrix} \right] = \left[ \begin{matrix} 1&0 \\ dt& 1 \end{matrix} \right] \left[ \begin{matrix} V_{k-1} \\ P_{k-1} \end{matrix} \right] [VkPk]=[1dt01][Vk−1Pk−1]
公式中的 d t dt dt为 k − 1 k-1 k−1时刻到 k k k时刻的时间间隔,为常数。
通过状态方程我们可以看出,匀速直线运动的状态从 K − 1 K-1 K−1时刻变换到 K K K时刻,只需要左乘一个矩阵 A A A:
A = [ 1 0 d t 1 ] A =\left[ \begin{matrix} 1&0 \\ dt& 1 \end{matrix} \right] A=[1dt01]
矩阵 A A A在状态方程中有一个专有的名称叫做状态转移矩阵。如果状态转移矩阵向上文中 A A A一样是由常数构成的,则称系统是线性系统。
进一步抽象一下,假设某系统的状态量为 X X X,状态转移矩阵为 A A A,则状态方程为:
X k = A X k − 1 X_{k} = AX_{k-1} Xk=AXk−1
对于基本的卡尔曼滤波, A A A必须是常数矩阵,即系统必须是线性系统。
(PS:状态方程中除了状态量外,其实还有控制量,以上的公式可以理解为控制量为0的情况,我个人认为引入控制量对下文描述卡尔曼滤波原理帮助不大,反而会带来麻烦,我觉得先从简单的情况将原理弄清楚,再看比较完备详细的资料时就可以很快明白,所以就没有写)
现在我们对系统建立了数学模型,并得到了状态方程,那么假设我们的模型足够准确,并令k时刻系统的真实值为 X k r e a l X^{real}_k Xkreal,是否存在如下关系呢?
X k r e a l = A X k − 1 r e a l X^{real}_k = A X^{real}_{k-1} Xkreal=AXk−1real
答案是否定的,因为以上公式忽略了环境噪声。正确的表达应该是这样的:
X k r e a l = A X k − 1 r e a l + ω k X^{real}_k = A X^{real}_{k-1}+\omega_k Xkreal=AXk−1real+ωk
这里 ω k \omega_k ωk就代表K时刻环境噪声对真实值的影响,并称这个 ω k \omega_k ωk为传递误差。之所以取这个名字,是因为根据公式可以看出,环境噪声的影响是会随着时间向下传递的。
虽然 ω k \omega_k ωk在任意时刻都是随机的,无法预测,但是基本卡尔曼滤波还是假设环境噪声(传递误差)具备统计学特征,即服从均值为0的正态分布。
过程误差的定义前文已经描述过,这里再公式化一下。
我们令k时刻系统的估计值为 X k X_k Xk,真实值为 X k r e a l X^{real}_k Xkreal,过程误差为 e k ^ \hat{e_k} ek^。则:
e k ^ = X k r e a l − X k = X k r e a l − A X k − 1 \hat{e_k} = X^{real}_k - X_k= X^{real}_k-AX_{k-1} ek^=Xkreal−Xk=Xkreal−AXk−1
带入得:
e k ^ = A ( X k − 1 r e a l − X k − 1 ) + ω k = A e k − 1 ^ + ω k \hat{e_k} = A(X^{real}_{k-1} - X_{k-1})+\omega_k=A\hat{e_{k-1}}+\omega_k ek^=A(Xk−1real−Xk−1)+ωk=Aek−1^+ωk
由此可以看出过程误差包含两部分,一部分是由上一时刻的过程误差,通过状态方程递推得到,在已知0时刻的初值时,这部分是可以预测的;另一部分则为无法预测的环境噪声。
前文已经提到,卡尔曼滤波通过融合估计值和测量值得到最优估计值,并使用最优估计值代表真实值。这里用数学公式表达如下:
设 X k b e s t X^{best}_{k} Xkbest为最优估计值, Z k Z_k Zk为测量值, X k X_k Xk为估计值,则:
X k b e s t = X k + G k ∗ ( Z k − X k ) X^{best}_{k} = X_k + G_k*(Z_k-X_k) Xkbest=Xk+Gk∗(Zk−Xk)
以上公式有两点需要说明。
第一,比例系数 G G G并不是一个常数,而是每一时刻都变化的量,所以,将K时刻的比例系数表示为 G k G_k Gk。
第二,以上公式隐含了一个前提,就是 Z k Z_k Zk和 X k X_k Xk必须是相同类型的物理量。例如, Z k Z_k Zk是速度,则 X k X_k Xk也必须是速度,否则两者是没有办法相减的,这个应该很好理解。但是在工程实践中,往往存在一个矛盾,即建模时容易估计的量也许并不容易测量。
比如有一个设备要求的工作温度是-40~60度,建模时出于方便的考虑选择 X k X_k Xk为角速度,但是经过一番调查发现并没有在此温度下工作的测量角速度的传感器(或者太贵了买不起),这就使得 Z k Z_k Zk无法得到。
解决的办法当然有两种:一种是修改模型,有时这当然可行的,但有时不行;另一种方法就是变换,比如我们发现在此工作温度下有速度传感器,则我们就选择 Z k Z_k Zk为速度,然后将 X k X_k Xk通过数学公式变换为速度,我们用 Z k ^ \hat{Z_k} Zk^表示。这样两者就可以相减了。
设变换矩阵为 H H H,则可公式化为:
Z k ^ = H ∗ X k \hat{Z_k} = H*X_k Zk^=H∗Xk
最优估计值的计算公式可改写为:
X k b e s t = X k + G k ∗ ( Z k − Z k ^ ) X^{best}_{k} = X_k + G_k*(Z_k-\hat{Z_k}) Xkbest=Xk+Gk∗(Zk−Zk^)
这种变换是为了工程实践的需要,如果你真的能找到合适的传感器,则估计值和测量值就是相同类型的物理量,此时可以认为 H = 1 H=1 H=1(更准确的说 H H H是单位矩阵)。
另外需要强调的一点是,这个 H H H也必须是一个由常数构成的矩阵,否则就有引入了非线性因素,不符合基本卡尔曼滤波的要求。
结合前文关于状态方程的描述,我们知道,状态量K时刻的估计值是由K-1时刻的状态量通过递推得到的,那么显然我们要利用K-1时刻的最优估计值来计算K时刻的估计值。因此有:
X k = A X k − 1 b e s t X k b e s t = X k + G k ∗ ( Z k − H ∗ X k ) X_{k} = AX^{best}_{k-1} \\ X^{best}_{k} = X_k + G_k*(Z_k-H*X_k) Xk=AXk−1bestXkbest=Xk+Gk∗(Zk−H∗Xk)
前文虽然给出了最优估计值的数学公式,但还有一个关键的问题没有解决,就是如何选取比例系数 G k G_k Gk。
卡尔曼滤波对比例系数 G k G_k Gk的选取规则是:使得K时刻的真实值与最优估计值的误差的协方差的和的期望最小。
这个规则读起来很拗口,所以烦请多读几遍,注意断句。这里强调两点:
下面就介绍一下如何根据这个规则推到出比例系数 G k G_k Gk的计算公式,如果对此不感兴趣,可以直接看结论。
首先,前文已经说过过程误差的计算方法,令 X k r e a l X^{real}_k Xkreal为真实值, e k ^ \hat{e_k} ek^为过程误差,则:
e k ^ = X k r e a l − X k \hat{e_k} =X^{real}_k-X_k ek^=Xkreal−Xk
其次,测量值=真实值+测量误差,令 v k v_k vk为测量误差,则:
Z k = H ∗ X k r e a l + v k Z_k =H* X^{real}_k+v_k Zk=H∗Xkreal+vk
公式中 H H H的含义前文已经解释过,这里不再赘述。同时,基本卡尔曼滤波假设 v k v_k vk服从均值为0的正态分布。
令 e k e_k ek表示真实值与最优估计值的误差,则:
e k = X k r e a l − X k b e s t = X k r e a l − [ X k + G k ∗ ( Z k − H ∗ X k ) ] \begin{matrix} e_k &=& X^{real}_k - X^{best}_{k}\\\\ &=& X^{real}_k -[X_k+G_k*(Z_k-H*X_k)] \end{matrix} ek==Xkreal−XkbestXkreal−[Xk+Gk∗(Zk−H∗Xk)]
令 I I I为单位矩阵,将前两个公式带入,可得:
e k = [ I − G k ∗ H ] e k ^ + G k ∗ v k e_k=[I-G_k*H]\hat{e_k}+G_k*v_k ek=[I−Gk∗H]ek^+Gk∗vk
令 E [ ] E[] E[]为求期望算子,那么求真实值与最优估计值的误差的协方差的期望等价于求 E [ e k e k T ] E[e_ke^T_k] E[ekekT]。
令 P k = E [ e k e k T ] P_k=E[e_ke^T_k] Pk=E[ekekT],由于状态量间彼此独立,所以 P k P_k Pk是一个对角矩阵(此结论依据数理统计的知识),求 P k P_k Pk的和就相当于求 P k P_k Pk的迹。令 t r [ ] tr[] tr[]为求迹算子,则协方差的和可表示为: t r [ P k ] tr[P_k] tr[Pk]。
综上所述,卡尔曼滤波中G的选择条件可以进一步表述为:选择合适的 G k G_k Gk,使得 t r [ P k ] tr[P_k] tr[Pk]最小。
将协方差期望公式展开:
P k = [ I − G k H ] E [ e k ^ e k ^ T ] [ I − G k H ] T + G k E [ v k v k T ] G k T = \begin{matrix} P_k&=&[I-G_kH]E[\hat{e_k}\hat{e_k}^T][I-G_kH]^T+G_kE[v_kv^T_k]G_k^T\\ &=& \end{matrix} Pk==[I−GkH]E[ek^ek^T][I−GkH]T+GkE[vkvkT]GkT
接下来令 P k ^ = E [ e k ^ e k ^ T ] \hat{P_k}=E[\hat{e_k}\hat{e_k}^T] Pk^=E[ek^ek^T], R = E [ v k v k T ] R = E[v_kv^T_k] R=E[vkvkT],则:
P k = [ I − G k H ] P k ^ [ I − G k H ] T + G k R G k T P_k=[I-G_kH]\hat{P_k}[I-G_kH]^T+G_kRG_k^T Pk=[I−GkH]Pk^[I−GkH]T+GkRGkT
这里的 R R R是测量误差的协方差期望的矩阵 。由于测量误差均服从均值为0的正态分布,所以 R R R是常数。
至此,将求协方差和的公式展开(这个展开涉及矩阵求迹运算的性质,请参阅相关资料吧),可得:
t r ( P k ) = t r ( P k ^ ) − 2 t r ( G k H P k ^ ) + t r ( G k [ H P k ^ H T + R ] G k T ) tr(P_k)=tr(\hat{P_k})-2tr(G_kH\hat{P_k})+tr(G_k[H\hat{P_k}H^T+R]G_k^T) tr(Pk)=tr(Pk^)−2tr(GkHPk^)+tr(Gk[HPk^HT+R]GkT)
我们可以将上面的求和公式看作以 G k G_k Gk为自变量的函数,则求最小值的问题,便可以通过求导数为0的点获得。求导数得:
∂ t r ( P k ) ∂ G k = − 2 ( H P k ^ ) T + 2 G k [ H P k ^ H T + R ] \dfrac{ \partial tr(P_k)}{\partial G_k} = -2(H\hat{P_k})^T+2G_k[H\hat{P_k}H^T+R] ∂Gk∂tr(Pk)=−2(HPk^)T+2Gk[HPk^HT+R]
令导数为0,可求得:
G k = P k ^ H T [ H P k ^ H T + R ] − 1 G_k = \hat{P_k}H^T[H\hat{P_k}H^T+R]^{-1} Gk=Pk^HT[HPk^HT+R]−1
至此,我们得到了 G k G_k Gk的计算公式。
在比例系数 G k G_k Gk的计算公式中,有一个未知的参数 P k ^ \hat{P_k} Pk^没有给出计算公式,下面就推到一下 P k ^ \hat{P_k} Pk^的计算方法。
首先,根据定义:
P k ^ = E [ e k ^ e k ^ T ] = E [ ( X k r e a l − X k ) ( X k r e a l − X k ) T ] = E [ ( A X k − 1 r e a l + ω k − A X k − 1 b e s t ) ( A X k − 1 r e a l + ω k − A X k − 1 b e s t ) T ] \begin{matrix} \hat{P_k}&=&E[\hat{e_k}\hat{e_k}^T]\\\\ &=&E[(X^{real}_k-X_k)(X^{real}_k-X_k)^T]\\\\ &=&E[(AX^{real}_{k-1}+\omega_k-AX^{best}_{k-1})(AX^{real}_{k-1}+\omega_k-AX^{best}_{k-1})^T] \end{matrix} Pk^===E[ek^ek^T]E[(Xkreal−Xk)(Xkreal−Xk)T]E[(AXk−1real+ωk−AXk−1best)(AXk−1real+ωk−AXk−1best)T]
前文说过 ω k \omega_k ωk服从均值为零的正太分布,则 E [ ω k ] = 0 E[\omega_k]=0 E[ωk]=0。所以,上式可化简为:
P k ^ = A E [ ( X k − 1 r e a l − X k − 1 b e s t ) ( X k − 1 r e a l − X k − 1 b e s t ) T ] A T + E [ ω k ω k T ] = A P k − 1 A T + E [ ω k ω k T ] \begin{matrix} \hat{P_k}&=&AE[(X^{real}_{k-1}-X^{best}_{k-1})(X^{real}_{k-1}-X^{best}_{k-1})^T]A^T+E[\omega_k\omega_k^T]\\\\ &=& AP_{k-1}A^T+E[\omega_k\omega_k^T] \end{matrix} Pk^==AE[(Xk−1real−Xk−1best)(Xk−1real−Xk−1best)T]AT+E[ωkωkT]APk−1AT+E[ωkωkT]
同样因为 ω k \omega_k ωk服从均值为零的正太分布,所以 E [ ω k ω k T ] E[\omega_k\omega_k^T] E[ωkωkT]是常数,令 Q = E [ ω k ω k T ] Q=E[\omega_k\omega_k^T] Q=E[ωkωkT],则:
P k ^ = A P k − 1 A T + Q \hat{P_k} = AP_{k-1}A^T+Q Pk^=APk−1AT+Q
将此公式带入到求 P k P_k Pk的公式中,我们有可以得到:
P k = ( I − G k H ) P k ^ P_k = (I-G_kH)\hat{P_k} Pk=(I−GkH)Pk^
至此,我们得到了经典卡尔曼滤波的五公式,如下:
X k = A X k − 1 b e s t P k ^ = A P k − 1 A T + Q G k = P k ^ H T [ H P k ^ H T + R ] − 1 X k b e s t = X k + G k ( Z k − H X k ) P k = ( I − G k H ) P k ^ \begin{matrix} X_{k} &=& AX^{best}_{k-1} \\\\ \hat{P_k} &=& AP_{k-1}A^T+Q\\\\ G_k &=& \hat{P_k}H^T[H\hat{P_k}H^T+R]^{-1}\\\\ X^{best}_{k} &=& X_k + G_k(Z_k-HX_k)\\\\ P_k&=&(I-G_kH)\hat{P_k} \end{matrix} XkPk^GkXkbestPk=====AXk−1bestAPk−1AT+QPk^HT[HPk^HT+R]−1Xk+Gk(Zk−HXk)(I−GkH)Pk^
以上五个公式便是卡尔曼滤波的完整计算算法。其中 Q Q Q和 R R R都是常数,其他的值都可以迭代计算获得,唯一的遗漏是 X 0 b e s t X^{best}_0 X0best和 P 0 P_0 P0如何获取。其实,这两个值可以给任意值,一般为单位矩阵,因为即使你在0时刻给定的值是错误的,卡尔曼滤波还是能通过测量值 Z k Z_k Zk,在迭代过程中纠正这个错误,进而估计出最优的真实值。当然,如果你给出的 X 0 b e s t X^{best}_0 X0best和 P 0 P_0 P0与真实情况较为接近,则卡尔曼滤波的收敛速度也会快一些。