什么是预积分
即对两个关键帧之间的imu数据进行整合,得到一个factor,并且该factor基本上不随两个关键帧的状态改变而变化
预积分计算
回顾惯导解算,已知系统位置、速度、姿态的微分方程如下:
˙pwbt=vwt˙vwt=awt˙qwbt=qwbt⊗[012ωbt]
基于上述微分方程,可以得到连续时间下的状态传播方程:
pwbj=pwbi+vwiΔt+∬t∈[i,j](qwbtabt−gw)δt2
vwj=vwi+∫t∈[i,j](qwbtabt−gw)δt
qwbj=∫t∈[i,j]qwbt⊗[012ωbt]δt
由于上面三个公式都与前一个时刻的状态有关,因此需要进行变换:
根据qwbt=qwbi⊗qbibt,即可将上面三个公式中的前一个时刻的位姿项提取出来:
pwbj=pwbi+vwiΔt−12gwΔt2+qwbi∬t∈[i,j](qbibtabt)δt2⏟α
vwj=vwi−gwΔt+qwbi∫t∈[i,j](qbibtabt)δt⏟β
qwbj=qwbi∫t∈[i,j]qbibt⊗[012ωbt]δt⏟γ
将上式的积分项分别提取出来,有:
αbibj=∬t∈[i,j](qbibtabt)δt2
βbibj=∫t∈[i,j](qbibtabt)δt
qbibj=∫t∈[i,j]qbibt⊗[012ωbt]δt
由于上面的推导都是基于连续时间下的,在实际使用中,通常使用离散形式计算,采用中值积分法:
ω=12[(ωbk−bgk)+(ωbk+1−bgk)]
a=12[qbibk(abk−bak)+qbibk+1(abk+1−bak)]
那么预积分量αbibj,βbibj,qbibj可以通过迭代计算得到,当新的一帧imu数据到达时,计算该imu预积分的第k+1次迭代,有:
αbibk+1=αbibk+βbibkδt+12aδt2
βbibk+1=βbibk+aδt
qbibk+1=qbibk⊗[112ωδt]
预积分量计算完成
基于预积分量的导航状态更新公式为:
[pwbjvwjqwbjbajbgj]=[pwbi+vwiΔt−12gwΔt2+qwbiαbibjvwi−gwΔt+qwbiβbibjqwbiqbibjbaibgi]
此中,陀螺仪和加速度计的零偏不变是认为在这个预积分中,由于时间很短,bias基本没有变化。然而,在整个系统中,其实是认为bias在缓慢变化的,因此,陀螺仪加速度计的模型为:
预积分更新
从上面的推导可以发现,预积分量中包含了bias,而在后续的优化过程中,bias作为待优化状态量会随优化而发生改变,因此,预积分量应该随之更新,为了避免完全重新计算预积分,一个技巧是把预积分结果在bias处进行泰勒展开,通过线性近似得到更新的预积分:
αbibj=¯αbibj+Jαbaibai+Jαbgiδbgi
βbibj=¯βbibj+Jβbaiδbai+Jβbgiδbgi
qbibj=¯qbibj⊗[112Jqbgiδbgi]
其中,(详细计算见后续)
Jαbai=∂αbibj∂δbaiJαbgi=∂αbibj∂δbgiJβbai=∂βbibj∂δbaiJβbgi=∂βbibj∂δbgiJqbgi=qiibj∂bgi
预积分(误差)协方差计算
由于预积分量是由imu数据迭代计算得到的,然而imu单次测量包含噪声,时间越长,预积分量越不准确,因此,需要计算对应的协方差来表示其不确定性,方差计算公式如下:
Pi,k+1=FkPi,kF⊤k+GkQG⊤k
注意:上式的Fk,Gk是离散时间下的状态转移矩阵
下面需要求关于预积分误差的微分方程:
已知连续时间下的微分方程形式为:
˙X=FtX+GtN
其中,
X=[δαbktδθbktδβbktδbatδbwt]
N=[nanwnbanbw]
预积分微分方程
δ˙θbkt微分方程推导
符号简化:δ˙θbkt→δ˙θ
此处的qt就是上面的qbibk+1
- 写出不考虑误差的微分方程
˙qt=12qt⊗[0ωt−bωt]
- 写出考虑误差的微分方程
˙˜qt=12˜qt⊗[0˜ωt−˜bωt]
- 写出带有误差的参数与理想真实值之间的关系
˜qt=qt⊗δq
˜ωt=ωt+nω
˜bωt=bωt+δbωt
其中,δθ是计算坐标系与真实导航坐标系的偏差 或者 在body系与计算误差body系之间的偏差
δq=[cos(|δθ|2)δθ|δθ|sin(|δθ|2)]≈[1δθ2]
- 将误差值与理想真实值的关系代入(2)
(qt˙⊗δq)=12qt⊗δq⊗[0ωt+nω−bωt−δbωt]
其中,
(qt˙⊗δq)=˙qt⊗δq+qt⊗δ˙q
- 把(1)中的关系代入(4)
(qt˙⊗δq)=12qt⊗δq⊗[0ωt+nω−bωt−δbωt]˙qt⊗δq+qt⊗δq=12qt⊗[0ωt−bωt]⊗δq+qt⊗˙δq=
- 化简
(5)两边同时左乘(qt)−1,然后移项得到:
δ˙q=12δq⊗[0ωt+nω−bωt−δbωt]−12[0ωt−bωt]⊗δq
因此,可得:
δ˙q=12[0ω1]Rδq−12[0ω2]Lδq=12[0(ω2−ω1)T(ω1−ω2)−[ω1+ω2]×]δq
其中,
ω1=ωt+nω−bωt−δbωt
ω2=ωt−bωt
又因为:
δ˙q=[0δ˙θ2]
可以得到关于δ˙θ的方程:
δ˙θ=−[ω1+ω2]×δθ2+(ω1−ω2)=−[2ωt+nω−2bωt−δbωt]×δθ2+nω−δbωt
忽略上式中的二阶小项,可得δ˙θbkt微分方程
δ˙θ=−[ωt−bωt]×δθ+nω−δbωt
δ˙βbkt微分方程推导
符号简化:δ˙βbkt→δ˙β,此处的β就是上面的βbibk+1
- 写出不考虑误差的微分方程
˙β=Rt(at−bat)
其中,Rt表示载体姿态
- 写出考虑误差的微分方程
˙˜β=˜Rt(˜at−˜bat)
- 写出带有误差的参数与理想真实值之间的关系
˜β=β+δβ
˜at=at+na
˜bat=bat+δbat
˜Rt=Rtexp([δθ]×)=Rt(I+[δθ]×)
关于姿态与理想真实值的关系: 因为 δθ表示的是在载体姿态上的误差,直接右乘即可
- 将误差值与理想真实值的关系代入(2)
˙β+δ˙β=Rt(I+[δθ]×)(at+na−bat−δbat)
- 把(1)中的关系代入(4)
Rt(at−bat)+δβ=Rt(I+[δθ]×)(at+na−bat−δbat)
- 化简(忽略二阶小项)
δ˙β=Rt[δθ]×(at−bat)+Rt(na−δbat)=−Rt[at−bat]×δθ+Rt(na−δbat)
δ˙αbkt微分方程推导
符号简化:δ˙αbkt→δ˙α
- 写出不考虑误差的微分方程
˙α=β
- 写出考虑误差的微分方程
˙˜α=˜β
- 写出带有误差的参数与理想真实值之间的关系
˜α=α+δα˜β=β+δβ
- 将误差值与理想真实值的关系代入(2)
˙(α+δα)=β+δβ˙α+˙δα=β+δβ
- 把(1)中的关系代入(4)
β+δ˙α=β+δβ
- 化简
δ˙α=δβ
预积分离散时间递推方程
实际上,计算预积分的方差,还需要离散时间下的递推方程,因此,需要对上面求出来的连续时间微分方程进行离散化,即:
已知连续时间下的微分方程形式为:
˙X=FtX+GtN
离散化后的递推方程形式为:
Xk+1=FkXk+GkNk
其中,
Xk+1=[δαk+1δθk+1δβk+1δbak+1δbωk+1]Xk=[δαkδθkδβkδbakδbωk]Nk=[naknwknak+1nwk+1nbanbw]
δθk+1递推
这里直接写出上面推导的微分方程:
δ˙θ=−[ωt−bωt]×δθ+nω−δbωt
改写成中值积分法:
δ˙θk=−[ωk+ωk+12−bωt]×δθk+nω−δbωt
因此,离散时间下,有:
δθk+1=δθk+(−[ωk+ωk+12−bωt]×δθk+nω−δbωt)δt=[I−[ωk+ωk+12−bωk]×δt]δθk+δtnωk+nωk+12−δtδbωk
令: ¯ω=ωk+ωk+12−bωk,则上式可重写为:
δθk+1=[I−[¯ω]×δt]δθk+δt2nωk+δt2nωk+1−δtδbωk
δβk+1递推
这里直接写出上面推导的微分方程,即连续时间下,有:
δ˙β=−Rt[at−bat]×δθ+Rt(na−δbat)
改成中值积分法形式,有:
δ˙βk=−12Rk[ak−bak]×δθk−12Rk+1[ak+1−bak]×δθk+1+12Rknak+12Rk+1nak+1−12(Rk+Rk+1)δbak
根据上述δβk+1递推的结果,δθk+1如下:
δθk+1=[I−[¯ω]×δt]δθk+δt2nωk+δt2nωk+1−δtδbωk
其中,¯ω=ωk+ωk+12−bωk
将δθk+1代入到δ˙βk,可得:
δ˙βk=−12Rk[ak−bak]×δθk−12Rk+1[ak+1−bak]×{[I−[¯ω]×δt]δθk+δt2nωk+δt2nωk+1−δtδbωk}+12Rknak+12Rk+1nak+1−12(Rk+Rk+1)δbak
进一步化简,合并同类项,可以得到微分方程中间结果:
δ˙βk=−12[Rk[ak−bak]×+Rk+1[ak+1−bak]×(I−[¯ω]×δt)]δθk−δt4Rk+1[ak+1−bak]×nωk−δt4Rk+1[ak+1−bak]×nωk+1+δt2Rk+1[ak+1−bak]×δbωk+12Rknak+12Rk+1nak+1−12(Rk+Rk+1)δbak
对δt进行积分,即由导数形式可以得到递推形式如下:
δβk+1=δβk+δ˙βkδt=δβk−δt2[Rk[ak−bak]×+Rk+1[ak+1−bak]×(I−[¯ω]×δt)]δθk−δt24Rk+1[ak+1−bak]×nωk−δt24Rk+1[ak+1−bak]×nωk+1+δt22Rk+1[ak+1−bak]×δbωk+δt2Rknak+δt2Rk+1nak+1−δt2(Rk+Rk+1)δbak
δαk+1递推
这里直接写出上面推导的微分方程,即连续时间下,有:
δ˙α=δβ
改成中值积分法形式,有:
δ˙αk=12δβk+12δβk+1
将δβk+1的递推结果代入到可得:
δ˙αk=12δβk+12δβk+1=δβk−δt4[Rk[ak−bak]×+Rk+1[ak+1−bak]×(I−[¯ω]×δt)]δθk−δt28Rk+1[ak+1−bak]×nωk−δt28Rk+1[ak+1−bak]×nωk+1+δt24Rk+1[ak+1−bak]×δbωk+δt4Rknak+δt4Rk+1nak+1−δt4(Rk+Rk+1)δbak
对δt进行积分,即由导数形式可以得到递推形式如下:
δαk+1=δαk+δ˙αkδt=δαk+δtδβk−δt24[Rk[ak−bak]×+Rk+1[ak+1−bak]×(I−[¯ω]×δt)]δθk−δt38Rk+1[ak+1−bak]×nωk−δt38Rk+1[ak+1−bak]×nωk+1+δt34Rk+1[ak+1−bak]×δbωk+δt24Rknak+δt24Rk+1nak+1−δt24(Rk+Rk+1)δbak
预积分方差计算
由上面的离散时间下的递推方程,可以写出预积分离散时间的状态方程:
Xk+1=FkXk+GkNk
其中Fk如下,
Fk=[If12Iδt−14(Rk+Rk+1)δt2f150I−[¯ω]×δt00−Iδt0f32I−12(Rk+Rk+1)δtf35000I00000I]
且:
f12=−δt24[Rk[ak−bak]×+Rk+1[ak+1−bak]×(I−[¯ω]×δt)]f15=δt34Rk+1[ak+1−bak]×δbωkf32=−δt2[Rk[ak−bak]×+Rk+1[ak+1−bak]×(I−[¯ω]×δt)]f35=δt22Rk+1[ak+1−bak]×
其中Gk如下,
Gk=[14Rkδt2g1214Rk+1δt2g1400012Iδt012Iδt0012Rkδtg3212Rk+1δtg34000000Iδt000000Iδt]
且:
g12=−δt38Rk+1[ak+1−bak]×g14=−δt38Rk+1[ak+1−bak]×g32=−δt24Rk+1[ak+1−bak]×g34=−δt24Rk+1[ak+1−bak]×
需要注意的是,上面的Rk,Rk+1都是相对于这个imu预积分起始时刻的,即Rk=Rbibk,Rk+1=Rbibk+1
计算得到矩阵Fk和Gk后,即可按照如下公式来计算方差:
Pi,k+1=FkPi,kF⊤k+GkQG⊤k
预积分残差关于待求状态量的雅可比
在优化时,需要求出残差对待求解的状态量的雅可比。
已知基于预积分量的状态更新如下:
[pwbjqwbjvwjbajbgj]=[pwbi+vwiΔt−12gwΔt2+qwbiαbibjqwbiqbibjvwi−gwΔt+qwbiβbibjbaibgi]
把上式左侧状态移到右侧,在理想的情况下左侧应该只剩下0,但是由于误差的存在,可以使用残差小量r代替,因此有:
[rprqrvrbarbg]=[pwbj−pwbi−vwiΔt+12gwΔt2−qwbiαbibj2[q∗bibj⊗(q∗wbi⊗qwbj)]xyzvwj−vwi+gwΔt−qwbiβbibjbaj−baibgj−bgi]
其中,关于姿态残差rq部分,需要将四元数拆开来看,根据四元数与等轴旋转矢量ϕ的关系:
q=cosϕ2+(uxi+uyj+uzk)sinϕ2=[cos(ϕ/2)usin(ϕ/2)]
等效旋转矢量可以用向量ϕ,并用单位向量u表示它的朝向,ϕ表示它的大小,因此有: ϕ=ϕu
其中,
rq=2[q∗bibj⊗(q∗wbi⊗qwbj)]xyz
取[]xyz就是取四元数的虚部usin(ϕ/2),特别的,当旋转角度ϕ是小量时,sin(ϕ/2)≈ϕ/2,对其乘个2,就得到了上面的姿态残差rq。
在上面的预积分误差中,和预积分相关的量,仍然与上一时刻的姿态有关,如rp,rv,无法直接加减(啥意思),因此,把预积分残差进行修正,得到:
[rprqrvrbarbg]=[q∗wbi(pwbj−pwbi−vwiΔt+12gwΔt2)−αbibj2[q∗bibj⊗(q∗wbi⊗qwbj)]xyzq∗wbi(vwj−vwi+gwΔt)−βbibjbaj−baibgj−bgi]
其中,待优化的变量是前后两帧的状态量:
[pwbiqwbivwibaibgi]
[pwbjqwbjvwjbajbgj]
而实际上,求导使用了扰动量,即实际上是对以下扰动量求雅可比:
[δpwbiδθwbiδvwiδbaiδbgi]
[δpwbjδθwbjδvwjδbajδbgj]
rp对状态量的雅可比
首先,直接写出残差:
rp=q∗wbi(pwbj−pwbi−vwiΔt+12gwΔt2)−αbibj
对状态i求雅可比
对状态j求雅可比
rq对状态量的雅可比
首先,直接写出残差:
rq=2[q∗bibj⊗(q∗wbi⊗qwbj)]xyz
对状态i求雅可比
对状态j求雅可比
rv对状态量的雅可比
对状态i求雅可比
对状态j求雅可比
rba对状态量的雅可比
对状态i求雅可比
对状态j求雅可比
rbg对状态量的雅可比
对状态i求雅可比
对状态j求雅可比
小结
残差
上面与vins-mono代码中 IntegrationBase::evaluate()对应
待优化变量
雅可比
计算 Jacobian 时,残差对应的求偏导对象为上面的优化变量,但是计算时采用扰动方式 计算,即扰动为:
上面公式在vins-mono代码中对应:class IMUFactor : public ceres::SizedCostFunction<15, 7, 9, 7, 9> 对于 Evaluate 输入 double const const parameters, parameters[0], parameters[1], parameters[2], parameters[3]分别对应 4 个输入参数, 它们的长度依次是 7,9,7,9,分别对应 4 个优化变量的 参数块