VIO残差函数的构建以及IMU预积分和协方差传递

544 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


在这里插入图片描述

基于滑动窗口的 VIO Bundle Adjustment,为了节约计算量采用滑动窗口形式的 Bundle Adjustment,在 i 时刻, 滑动窗口内待优化的系统状态量定义如下:

χ=[Xn,Xn+1,...,Xn+N,λm,λm+1,...,λm+M]\chi = [X_n,X_{n+1},...,X_{n+N},\lambda{m},\lambda{m+1},...,\lambda{m+M}]
Xi=[pwbi,qwbi,viw,babi,bgbi],i[n,n+N]X_i=[p_{wb_i},q_{wb_i},v_i^w,b_a^{b_i},b_g^b{_i}],i \in [n,n+N]

其中:

  • xix_i包含ii 时刻 IMU 机体的在惯性坐标系中的位置,速度,姿态,以及 IMU 机体坐标系中的加速度和角速度的偏置量估计。
  • m,nm,n分别是机体状态量,路标在滑动窗口里的起始时刻。
  • NN 滑动窗口中关键帧数量。
  • MM 是被滑动窗口内所有关键帧观测到的路标数量。
  • λ\lambda 是逆深度。

IMU的真实值为w,aw,a,测量值为w~,a~\tilde{w},\tilde{a},则有:

w~b=wb+bg+ng\tilde{w}^b=w^b+b^g+n^g
a~b=qbw(aw+gw)+ba+na\tilde{a}^b=q_{bw}(a^w+g^w)+b^a+n^a

P(位置),V(速度),Q(位姿) 对时间的导数可写成:

p˙wbt=vtw,v˙tw=atw,q˙wbt=qwbt[012wbt]\dot{p}_{wb_t}=v^w_t,\dot{v}^w_t=a^w_t,\dot{q}_{wb_t}=q_{wb_t}⊗ \begin{bmatrix} 0 \\ {1\over 2}w^{b_t} \\ \end{bmatrix}

从第 ii 时刻的 PVQ 对 IMU 的测量值进行积分得到第 jj 时刻的 PVQ:

pwbj=pwbi+viwΔt+t[i,j](qwbtabtgw)δt2p_{wb_j}=p_{wb_i}+v_i^w\Delta t +\iint_{t \in [i,j]}(q_{wb_t}a^{b_t}-g^w)\delta t^2
qwbj=t[i,j]qwbt[012wbt]δtq_{wb_j}=\int_{t \in [i,j]}q_{wb_t}⊗ \begin{bmatrix} 0 \\ {1\over 2}w^{b_t} \\ \end{bmatrix}\delta t

每次 qwbtq_{wb_t} 优化更新后,都需要重新进行积分,运算量较大。因此提出IMU预积分:

qwbt=qwbiqbibtq_{wb_t}=q_{wb_i}⊗q_{b_ib_t}

那么,PVQ 积分公式中的积分项则变成相对于第 ii 时刻的姿态,而不是相对于世界坐标系的姿态:

pwbj=pwbi+viwΔt+t[i,j](qwbtabtgw)δt2=pwbi+viwΔt12gwΔt2+t[i,j](qwbtabt)δt2p_{wb_j}=p_{wb_i}+v_i^w\Delta t +\iint_{t \in [i,j]}(q_{wb_t}a^{b_t}-g^w)\delta t^2 =p_{wb_i}+v_i^w\Delta t- {1\over 2}g^w \Delta t^2+\iint_{t \in [i,j]}(q_{wb_t}a^{b_t})\delta t^2
    pwbj=pwbi+viwΔt12gwδt2+qwbit[i,j](qbibtabt)δt2\implies \color{red}{p_{wb_j}=p_{wb_i}+v_i^w\Delta t- {1\over 2}g^w \delta t^2+q_{wb_i}\iint_{t \in [i,j]}(q_{b_ib_t}a^{b_t})\delta t^2}
viw=viw+t[i,j](qwbtabtgw)δt    viw=viwgwΔt+qwbit[i,j](qbibtabt)δtv_i^w=v_i^w+\int_{t \in [i,j]}(q_{wb_t}a^{b_t}-g^w)\delta t \implies \color{red}{ v_i^w=v_i^w-g^w\Delta t+q_{wb_i}\int_{t \in [i,j]}(q_{b_ib_t}a^{b_t})\delta t}
qwbj=t[i,j]qwbt[012wbt]δt    qwbj=qwbit[i,j]qbibt[012wbt]δtq_{wb_j}=\int_{t \in [i,j]}q_{wb_t}⊗ \begin{bmatrix} 0 \\ {1\over 2}w^{b_t} \\ \end{bmatrix}\delta t \implies \color{red}{q_{wb_j}=q_{wb_i}\int_{t \in [i,j]}q_{b_ib_t}⊗ \begin{bmatrix} 0 \\ {1\over 2}w^{b_t} \\ \end{bmatrix}\delta t}

预积分量仅仅跟 IMU 测量值有关,它将一段时间内的 IMU 数据直接积分起来就得到了预积分量:

αbibj=t[i,j](qbibtabt)δt2\alpha_{b_ib_j}=\iint_{t \in [i,j]}(q_{b_ib_t}a^{b_t})\delta t^2
βbibj=t[i,j](qbibtabt)δt\beta_{b_ib_j}=\int_{t \in [i,j]}(q_{b_ib_t}a^{b_t})\delta t
qbibj=t[i,j]qbibt[012wbt]δtq_{b_ib_j}=\int_{t \in [i,j]}q_{b_ib_t}⊗ \begin{bmatrix} 0 \\ {1\over 2}w^{b_t} \\ \end{bmatrix}\delta t

αbibj,βbibj,qbibj\alpha_{b_ib_j},\beta_{b_ib_j},q_{b_ib_j}代入整理可得到最终的PVQ积分公式:

[pwbjvjwqwbjbjabjg]=[pwbi+viwΔt12gwΔt2+qwbiαbibjviwgwΔt+qwbiβbibjqwbiqbibjbiabig]\begin{bmatrix} p_{wb_j}\\v_j^w\\q_{wb_j}\\b_j^a\\b_j^g\\ \end{bmatrix}=\begin{bmatrix} p_{wb_i}+v_i^w\Delta t- {1\over 2}g^w \Delta t^2+q_{wb_i}\color{red}{\alpha_{b_ib_j}}\\v_i^w-g^w\Delta t+q_{wb_i}\color{red}{\beta_{b_ib_j}} \\q_{wb_i}\color{red}{q_{b_ib_j}}\\b_i^a\\b_i^g\\ \end{bmatrix}

预积分误差:一段时间内 IMU 构建的预积分量作为测量值,对两时刻之间的状态量进行约束

[rprqrvrbarbg]=[pwbjpwbiviwΔt+12gwΔt2qwbiαbibj2[qbjbi(qbiwqwbj)]xyzvjwviw+gwΔtqwbiβbibjbjabiabjgbig]=[qbiw(pwbjpwbiviwΔt+12gwΔt2)αbibj2[qbjbi(qbiwqwbj)]xyzqbiw(vjwviw+gwΔt)βbibjbjabiabjgbig]\begin{bmatrix} r_p\\r_q\\r_v\\r_{ba}\\r_{bg}\\ \end{bmatrix}=\begin{bmatrix} p_{wb_j} - p_{wb_i}-v_i^w\Delta t+ {1\over 2}g^w \Delta t^2-q_{wb_i}\color{red}{\alpha_{b_ib_j}}\\ 2[{\color{red}{q_{b_jb_i}}}⊗(q_{b_iw} ⊗ q_{wb_j})]_{xyz} \\v_j^w - v_i^w+g^w\Delta t-q_{wb_i}\color{red}{\beta_{b_ib_j}} \\b_j^a-b_i^a\\b_j^g-b_i^g\\ \end{bmatrix}=\begin{bmatrix} q_{b_iw}(p_{wb_j} - p_{wb_i}-v_i^w\Delta t+ {1\over 2}g^w \Delta t^2)-\color{red}{\alpha_{b_ib_j}}\\ 2[{\color{red}{q_{b_jb_i}}}⊗(q_{b_iw} ⊗ q_{wb_j})]_{xyz} \\q_{b_iw}(v_j^w - v_i^w+g^w\Delta t)-\color{red}{\beta_{b_ib_j}} \\b_j^a-b_i^a\\b_j^g-b_i^g\\ \end{bmatrix}

上面误差中位移,速度,偏置都是直接相减得到。第二项是关于四元数的旋转误差,其中 []xyz[\cdot]_{xyz} 表示只取四元数的虚部 (x,y,z)(x, y, z) 组成的三维向量。


预积分的离散形式 以上是预积分的连续形式,也可以使用离散形式,这里使用 midpointmid-point 方法,即两个相邻时刻 kkk+1k+1 的位姿是用两个时刻的测量值 a,ωa, ω 的平均值来计算:

w={1 \over 2}((w^{b_k}-b_k^g)+(w^{b_{k+1}}-b_k^g))\
a=12(qbibk(abkbka)+qbibk+1(abk+1bka))a={1\over 2}(q_{b_ib_k}(a^{b_k}-b_k^a)+q_{b_ib_{k+1}}(a^{b_{k+1}}-b_k^a))

预积分量的方差 协方差传递性质:在一个线性系统中,已知一个变量 y=Ax,xN(0,Σx)y = Ax, x ∈ \mathcal N (0, Σ_x), 则有Σy=AΣxAΣ_y = AΣ_xA^⊤

Σy=E((Ax)(Ax))=E(AxxA)=AΣxAΣ_y = E((Ax)(Ax)^⊤) = E(Axx^⊤A^⊤) = AΣ_xA^⊤

要推导预积分量的协方差,我们需要知道 imu 噪声和预积分量之间的线性递推关系。

假设已知了相邻时刻误差的线性传递方程:

ηik=Fk1ηik1+Gk1nk1η_{ik} = {\color{red}F_{k−1}η_{ik−1}} + {\color{blue}G_{k−1}n_{k−1}}

比如:状态量误差为 ηik=[δθik,δvik,δpik]η_{ik} = [δθ_{ik}, δv_{ik}, δp_{ik}],测量噪声为nk=[nkg,nka]n_k = [n^g_k, n^a_k]。 误差的传递由两部分组成:1.当前时刻的误差传递给下一时刻,2.当前时刻测量噪声传递给下一时刻。 协方差矩阵可以通过递推Σy=AΣxAΣ_y = AΣ_xA^⊤计算得到:

Σik=Fk1Σik1Fk1+Gk1ΣnGk1Σ_{ik} = {\color{red} F_{k−1}Σ_{ik−1}F^⊤_{k−1}} +{\color{blue} G_{k−1}Σ_nG^⊤_{k−1}}

其中,ΣnΣ_n 是测量噪声的协方差矩阵,方差从ii 时刻开始进行递推,Σii=0Σ_{ii} = 0


状态误差线性递推公式的推导(线性化) 协方差传递性质只对于线性化系统,通常对于状态量之间的递推关系是非线性的方程如xk=f(xk1,uk1)x_k = f(x_{k−1}, u_{k−1}),其中状态量为 xux,u为系统的输入量。

我们可以用两种方法来推导状态误差传递的线性递推关系:

  1. 一种是基于一阶泰勒展开的误差递推方程(应用于 EKF 的协方差预测)。 令状态量为 x=x^+δxx = \hat{x} + δx,其中,真值为 x^\hat{x},误差为 δxδx。另外,输入量uu 的噪声为 nn。 非线性系统 xk=f(xk1,uk1)x_k = f(x_{k−1}, u_{k−1}) 方程进行一阶泰勒展开有:
xk=f(xk1,uk1)x_k = f(x_{k−1}, u_{k−1})
x^k+δxk=f(x^k1+δxk1,u^k1+nk1)\hat{x}_k +δx_k= f(\hat{x}_{k−1}+δx_{k-1}, \hat{u}_{k−1}+n_{k-1})
x^k+δxk=f(x^k1,u^k1)+Fδxk1+Gnk1\hat{x}_k +δx_k= f(\hat{x}_{k−1}, \hat{u}_{k−1})+Fδx_{k-1}+Gn_{k-1}
δxk=Fδxk1+Gnk1{\color{red}δx_k= Fδx_{k-1}+Gn_{k-1}}

其中,F 是状态量 xkx_k 对状态量 xk1x_{k−1} 的雅克比矩阵,G 是状态量 xkx_k对输入量 uk1u_{k−1} 的雅克比矩阵。 2. 一种是基于误差随时间变化的递推方程。 如果我们能够推导状态误差随时间变化的导数关系,比如:δx˙=Aδx+Bnδ\dot{x} = Aδx + Bn 则误差状态的传递方程为:

δxk=δxk1+δx˙k1tδxk=(I+At)δxk1+Btnk1δx_k = δx_{k−1} + δ\dot{x}_{k−1}∆t → δx_k = (I + A∆t)δx_{k−1} + B∆tn_{k−1}

这两种推导方式的可以看出有: F=I+At,G=BtF = I + A∆t, G = B∆t


回顾预积分(离散形式)的误差递推公式,将测量噪声也考虑进模型:

w=12((wbk+nkgbkg)+(wbk+1+nk+1gbkg))w={1 \over 2}((w^{b_k}+ {\color{red}n_k^g}-b_k^g)+(w^{b_{k+1}}+ {\color{red}n_{k+1}^g}-b_k^g))
a=12(qbibk(abk+nkabka)+qbibk+1(abk+1+nk+1abka))a={1\over 2}(q_{b_ib_k}(a^{b_k}+ {\color{red}n_k^a}-b_k^a)+q_{b_ib_{k+1}}(a^{b_{k+1}}+ {\color{red}n_{k+1}^a}-b_k^a))

确定误差传递的状态量,噪声量,然后开始构建传递方程。用前面一阶泰勒展开的推导方式,我们能推导出如下的形式:

[δαbk+1bk+1δθbk+1bk+1δβbk+1bk+1δbk+1aδbk+1g]=F[δαbkbkδθbkbkδβbkbkδbkaδbkg]+G[nkankgnk+1ank+1gnbaanbkg]\begin{bmatrix} δα_{b_{k+1}b′_{k+1}} \\ δθ_{b_{k+1}b′_{k+1}} \\ δβ_{b_{k+1}b′_{k+1}} \\δb^a_{k+1}\\ δb^g_{k+1}\\ \end{bmatrix}=F\begin{bmatrix} δα_{b_{k}b′_{k}} \\ δθ_{b_{k}b′_{k}} \\ δβ_{b_{k}b′_{k}} \\δb^a_{k}\\ δb^g_{k}\\ \end{bmatrix}+G\begin{bmatrix} n^a_k\\n^g_k\\n^a_{k+1}\\n^g_{k+1}\\n_{b^a_a}\\n_{b^g_k}\\ \end{bmatrix}

F, G 为两个时刻间的协方差传递矩阵。


对VIO残差函数的构建的理解:

对于TT时刻的状态量,如位置、速度、变换、偏置。可通过IMU测量值(w,a)(w,a)积分得到T+1T+1时刻的状态。

由于状态量中的参考系都在全局坐标系下,对于每一时刻的状态优化完成之后,需要重新积分得到下一时刻的状态,因此提出预积分的概念,将积分转换成相对于上一时刻的量。

通过对上一时刻TT预积分得到当前时刻T+1T+1的状态作为测量值,通过当前时刻的真实值作为约束,得到残差函数

以上过程再考虑到噪声、误差的影响,通过线性系统的协方差传递性质,将状态量之间的递推关系线性化,即利用F,G,考虑到上一时刻的误差以及当前时刻的观测误差。最终所得到的残差函数即为,上一时刻的预积分加上传递误差,与当前时刻的约束。