文章同步更新于github pages,欢迎收藏关注。
扩展卡尔曼滤波的缺陷
存在正反馈
普通的扩展卡尔曼滤波(EKF),通过对动态方程的线性化,来估计状态与状态的协方差。比如有一个系统定义为
x˙t=f(xt,ut)+nt
其中xt是系统状态,ut是输入,nt是系统噪声。假设某个时刻对状态的估计为x^t,并定义状态误差为et=xt−x^t,则根据EKF,对f在x^t处线性化(一阶泰勒展开),并注意到f(x^tn,ut)=x^˙tn+1,有
e˙t=x˙t−x^˙t=f(xt,ut)−x^˙t+nt≈f(x^t,ut)+Fx^t,ut(xt−x^t)−x^˙t+nt=Fx^t,ut(xt−x^t)+nt=Fx^t,utet+nt
上式是状态误差的线性传递方程,因此可以使用标准的卡尔曼滤波来估计协方差。
但是这里存在一个问题,上面误差传递方程中,系统矩阵F依赖当前状态的估计量。在有噪声引入时,状态估计量是无法预测的,这就导致很难对上述系统方程做收敛性分析,实际上,任何EKF都没有收敛性保证。当状态估计值与真值差距较大时,直接导致依赖状态估计值的F也有较大偏差,使用这样的F继续传递误差后,又进一步放大误差,整个误差传递系统形成正反馈,最终导致滤波器发散。
实际上,在滤波器进行状态更新时也有类似问题。设系统的观测方程为
yt=h(xt)+st
其中st是观测噪声。设实际观测与估计观测的误差为zt=yt−y^t,有
zt=yt−y^t=h(xt)−y^t+st≈h(x^t)+Hx^t(xt−x^t)−y^t+st=Hx^tet+st
上式即观测误差与状态误差之间的线性近似关系。同样的,Hx^t与状态估计值有关,当真实状态与估计值差距较大时,利用上式进行更新可能起不到正面效果。
从上面的分析可知,普通EKF对初值的准确性要求挺高的,如果状态初值设定得与实际情况差距较大,很难让滤波器收敛。
非一致性
EKF还会导致另外一个问题,即所谓的不一致性。每当新的观测到来时,EKF会更新当前状态的估计,但是用于计算新状态的量,都是通过旧状态的线性化得来的。使用EKF的更新方法会出现不一致性,导致本来不该观测到信息的方向上观测到信息,在SLAM问题中这种现象比较明显,表现为较大的drift,以及过于乐观的协方差估计。因此,有很多针对该问题的方法,比如OC(Observability Constrain),FEJ(First Estimateed Jacobian)以及Robocentric等,这些方法都是对现有EKF框架的修补,而且使用起来都不容易。最后引用一张[1]中的图更直观的描述这个问题。
不变扩展卡尔曼滤波
不变扩展卡尔曼滤波(简写为InEKF),可以较好的解决上面EKF存在的两个问题,而且有严格的数学推导作为保证。这里不介绍InEKF的收敛性和一致性的推导(实在有点复杂*_*!),主要关注其思想和用法。
InEKF的想法还是比较简单的——通过改变状态误差的定义方法,实现误差传递矩阵F与状态估计值的独立。在EKF中,我们的状态误差直接定义为两个状态的差,即et=xt−x^t,这太过于粗暴了,我们面对的是非线性系统,误差怎么都不应该是线性的形式。
现在我们以一个简单的问题为例,说明InEKF的用法。假设我们有一架无人机,上面装了IMU以及双目相机等传感器,我们打算对无人机的位姿进行估计。假设IMU的bias为零(之后会讨论有bias的情况),则IMU的系统方程为
R˙tv˙tp˙t=Rt[w~t−ntw]×=Rt(a~t−nta)+g=vt
其中w~t,a~t是IMU的测量值,ntw,nta分别是gyro和acc的噪声,g是重力设为已知,待估计的量就是R,v,p,根据上一章李群的内容,我们发现这三个量刚好能构成一个SE2(3)群,于是我们将InEKF的状态量写为
χt=⎝⎛Rt00vt10pt01⎠⎞
这里已经和EKF有很大不同了,一般EKF的状态量是个矢量,而InEKF的状态量是一个矩阵,而且构成群。既然是群,其误差也应该定义在群上,自然是不能再用减法了,设状态估计值为χ^t,和真值的误差有两种形式
ηtηt=χt−1χ^t=χ^tχt−1
第一种称为左不变误差(left-invariant),因为对χt,χt^都左乘一个相同的群元素后,误差不变。同理,第二种为右不变误差(right-invariant)。具体使用哪种误差,要看该误差能否实现状态传递矩阵与状态估计值的独立。在很多SLAM问题中,右不变误差可以满足要求,因此下文都使用右不变误差。
误差传递
仿照EKF,现在推导这个误差的系统方程。
ηt=χ^tχt−1=⎝⎛R^tRtT00v^t−R^tRtTvt10p^t−R^tRtTpt01⎠⎞
令
R^tRtTv^t−R^tRtTvtp^t−R^tRtTpt=ηRt=ξvt=ξpt
设ηRt对应的李代数为ξRt,即ηRt=Exp(ξRt),由于ηRt是小量,用指数函数的一阶泰勒近似为ηRt≈I+[ξRt]×,则
ηt˙≈⎝⎛[ξ˙Rt]×00ξ˙vt00ξ˙pt00⎠⎞=dtdΛ⎝⎛ξRtξvtξpt⎠⎞
即η˙t就是群SE2(3)在幺元处的切空间,其中
[ξ˙Rt]×≈η˙Rt=R^˙tRtT+R^tR˙tT=R^t[w~t]×RtT+R^t[w]×RtT=R^t[w~t−wt]×RtT=R^t[ntw]×RtT=R^t[ntw]×R^tTR^tRtT=[R^tntw]×ηRt≈[R^tntw]×(I+[ξRt]×)≈[R^tntw]×
上面最后一步忽略了高阶小量[R^tntw]×[ξRt]×。
同理有
ξ˙vt=v^˙t−η˙Rtvt−ηRtv˙t=R^ta~t+g−[R^tntw]×vt−R^tRtT(Rtat+g)=R^t(a~t−at)+g−[R^tntw]×vt−R^tRtTg≈R^tnta+g−[R^tntw]×vt−(I+[ξRt]×)g=[g]×ξRt+([vt]×R^t)ntw+R^tnta
以及
ξ˙pt=p^˙t−η˙Rtpt−ηRtp˙t=v^t−[R^tntw]×pt−R^tRtTvt=(v^t−R^tRtTvt)−[R^tntw]×pt=ξvt+([pt]×R^t)ntw
综上有
dtdΛ⎝⎛ξRtξvtξpt⎠⎞=⎝⎛[R^tntw]×00[g]×ξRt+([vt]×R^t)ntw+R^tnta00ξvt+([pt]×R^t)ntw00⎠⎞=Λ[⎝⎛0[g]×000I000⎠⎞⎝⎛ξRtξvtξpt⎠⎞+⎝⎛R^tntw([vt]×R^t)ntw+R^tnta([pt]×R^t)ntw⎠⎞] 分离状态项和噪声项=Λ[⎝⎛0[g]×000I000⎠⎞⎝⎛ξRtξvtξpt⎠⎞+⎝⎛R^t[v^t]×R^t[p^t]×R^t0R^t000R^t⎠⎞⎝⎛ntwnta0⎠⎞]
令ξt=(ξRtT,ξvtT,ξptT)T,以及nt=(ntw,nta,0),可得误差的线性系统方程
ξ˙t=Ftξt+Adχ^tnt
其中
FtAdχ^t=⎝⎛0[g]×000I000⎠⎞=⎝⎛R^t[v^t]×R^t[p^t]×R^t0R^t000R^t⎠⎞
与普通EKF的误差系统方程相比,最大不同就是系统矩阵Ft是一个常量!和输入以及状态估计值均无关!而噪声项前面的矩阵,刚好是当前状态矩阵的伴随。基于这样的系统方程,可以证明其收敛性还有一致性都有较好的保证。
后面的事情就和普通EKF一样了,根据系统方程估计下一时刻的状态(使用RK4积分等方法),然后对误差系统方程积分,得到状态转移矩阵,并传递协方差矩阵,即
Pt=ΦtPt−1ΦtT+Adχ^tQtAdχ^tT
其中Φt是通过Ft积分后得到的状态转移矩阵,Qt=E(ntntT)是系统噪声的协方差矩阵。由于系统矩阵是常量,积分可以变得非常简单,甚至直接写出解析式。这也算是InEKF的另一个优点吧。
状态更新
假设地图中有很多landmark,用m1,m2,...,mk表示,无人机上的传感器可以观测到这些landmark相对于自身的位置,分别用yt1,yt2,...,ytk表示,设每个观测的噪声为st1,st2,...,stk,则观测方程就是
yt1yt2ytk=RtT(m1−pt)+st1=RtT(m2−pt)+st2⋮=RtT(mk−pt)+stk
拿其中一个观测来举例,我们可以发现观测方程可以写为如下形式
⎝⎛yi01⎠⎞=⎝⎛RtT00−RtTvt10−RtTpt01⎠⎞⎝⎛mi01⎠⎞+⎝⎛sti00⎠⎞
注意等号右边第一项的矩阵是状态矩阵的逆,令Yti=(yti,0,1),Mi=(mi,0,1),Sti=(sti,0,0)(由于不方便书写,所以都写为行向量的形式,实际上它们都是列向量),有
Yti=χt−1Mi+Sti
现在我们定义观测误差。如果定义为
Zti=Yti−χ^t−1Mi
那么就与普通的EKF无异。考虑到我们的状态量是一个群元素,可以定义观测误差为(这样定义的目的在后面的推导中会变清晰)
Zti=χ^tYti−Mi
这样就可以得到
Zti=χ^t(χt−1Mi+Sti)−Mi=χ^tχt−1Mi−Mi+χ^tSti=ηtMi−Mi+χ^tSti
将所有的观测误差按照列向量的方式堆叠起来,有
zt=⎝⎜⎛ηtM1−M1+χ^tSt1⋮ηtMk−Mk+χ^tStk⎠⎟⎞
和EKF一样,现在需要求出观测误差与状态误差之间的线性关系。利用状态误差的一阶近似ηt≈I+Λ(ξt),有
zt≈⎝⎜⎛(I+Λ(ξt))M1−M1+χ^tSt1⋮(I+Λ(ξt))Mk−Mk+χ^tStk⎠⎟⎞=⎝⎜⎛Λ(ξt)M1+χ^tSt1⋮Λ(ξt)Mk+χ^tStk⎠⎟⎞
上式计算后,每三行就有两行是全零,为了使计算和书写更紧凑,可以将zt中全是零的行去掉,得到z~t,即
z~t=⎝⎜⎛[ξRt]×m1+ξpt+R^tst1⋮[ξRt]×mk+ξpt+R^tstk⎠⎟⎞=⎝⎜⎛−[m1]×⋮−[mk]×0011⎠⎟⎞⎝⎛ξRtξvtξpt⎠⎞+⎝⎜⎛R^tst1⋮R^tstk⎠⎟⎞=Htξt+st
下面考虑怎么根据观测误差更新InEKF的状态。回想一下普通EKF的更新方式
x^t+=x^t+Kt[yt−h(x^t)]=x^t+Ktzt
等价于状态误差的更新(上式两边减去xt)
et+=et+Ktzt
其中Kt是卡尔曼增益。
同理,根据InEKF的误差定义,更新后的误差
ηt+=χ^t+χt−1=χ^t+χ^t−1χ^tχt−1=χ^t+χ^t−1ηt
其中χ^t+χ^t−1就是更新前后状态的差异,可以设
χ^t+χ^t−1=Exp(Ktzt)
就得InEKF的状态误差的更新方程
ηt+=Exp(Ktzt)ηt
以及状态的更新方程
χ^t+=Exp(Ktzt)χ^t
即InEKF采用的是“指数更新”。最后来看看增益Kt怎么算,由误差的更新方程以及观测误差的定义可得
ηt+=Exp(Ktzt)ηt
利用指数函数的一阶近似Exp(ξ)≈I+Λ(ξ),有
I+Λ(ξt+)=[I+Λ(Ktzt)][I+Λ(ξt)]
忽略高阶小量Λ()⋅Λ(),有
ξt+=ξt+Ktzt
上式与普通EKF中的误差更新方程et+=et+Ktzt有相同的形式,所以增益Kt的计算和普通的EKF完全相同。上式也可以用更紧凑的z~t代替,对应的更紧凑的增益记为K~t,则
K~t=PtHtT(HtPtHtT+Vt)
其中,Pt是状态误差ξt的协方差矩阵,Ht是之前推出的z~t与ξt之间的观测矩阵,Vt=E(ststT)是观测误差的协方差矩阵(注意,st中的每一项噪声都被R^t旋转过)。状态的更新自然就是
χ^t+=Exp(K~tz~t)χ^t
References
- Non-linear state error based extended Kalman flters with applications to navigation
- Contact-Aided Invariant Extended Kalman Filtering for Legged Robot State Estimation
- Invariant Kalman Filtering for Visual Inertial SLAM