MSCKF4讲:后端理论推导(下)

MSCKF4讲:后端理论推导(下)

文章目录

  • MSCKF4讲:后端理论推导(下)
  • [6 可观测性分析与约束](#6 可观测性分析与约束)
    • [6.1 为什么要做能观性分析](#6.1 为什么要做能观性分析)
    • [6.2 关于零空间解释](#6.2 关于零空间解释)
    • [6.3 可观测性分析](#6.3 可观测性分析)
    • [6.4 可观测性约束](#6.4 可观测性约束)
      • [① 状态转移矩阵Φ](#① 状态转移矩阵Φ)
      • [② 对观测矩阵H--观测的雅可比矩阵](#② 对观测矩阵H--观测的雅可比矩阵)

写在前面,为了防止偏航角被错误的可观,作者对状态转移矩阵和观测矩阵进行了一定的修改,使其满足可观性要求。

6 可观测性分析与约束

论文使用这种约束方法:OC-EKF

论文 Observability-constrained vision-aided inertial navigation

线性系统理论能观测能控概念

1 能观测:状态量(如位姿、偏差)是否可以由输出(如观测的预测值)反应

2 能控:状态量是否受到输入影响

6.1 为什么要做能观性分析

真实VIO系统不能观的维度是4 (平移和yaw角),而实际MSCKF不能观的维度变成了3,绕重力轴的旋转(yaw角)被错误地能观了 ,从而产生了不一致性 Inconsistency,系统误认为yaw角具有更多的信息从而将yaw对应的协方差设得比较小,最终导致VIO估计精度的下降。能观性分析就是为了能让MSCKF系统不可观的维度与真实系统一致,从而提高VIO精度。

补充:为什么vio系统不能观的维度是4?

​ 对于平移来说,如果系统没有全局信息,就很难确定相机在世界坐标系中的绝对位置。在滚动(roll)和俯仰(pitch)发生变化时,重力会在测量中引入一些不确定性,但是对于偏航来说,由于重力一直指向下,说白了没有这个方向的投影分量,它并不提供关于相机绝对朝向的信息。因此,偏航角在这种情况下被认为是不可观测的
补充:为什么yaw被错误的能观测了?

​ 计算能观性矩阵会用到状态转移矩阵观测矩阵 ,这两个Jacobian的计算依赖状态值。如果使用状态真实值计算Jacobian,系统不能观维度为4,与真实系统一致;如果使用状态估计值,由于使用了不同时刻的估计量,能观性阵中会出现一个扰动项 ΔΓ,扰动项的存在使得yaw角对应那一维的零空间向量不再成立,从而导致yaw角被错误地能观了。

6.2 关于零空间解释

Ax=0x就是矩阵A的零空间。

矩阵A零度 也就是不能观测的维度=n-秩。零度即零空间维度。

1 如果零空间维度为0,意味着矩阵的原像空间中只有一个样本可以被映射到矩阵像空间中的零点。(全0)

2 如果零空间维度为1:意味着矩阵的原像空间中有一条直线上的点经过矩阵算子后会被映射到像空间中的零点。

3 如果零空间维度为2:意味着矩阵的原像空间中有一个平面上的点经过矩阵算子后会被映射到像空间中的零点。

4 如果零空间维度为k:意味着矩阵的原像空间中有一个k维子空间,该k维子空间中的点经过矩阵算子后会被映射到像空间中的零点。

6.3 可观测性分析

系统的可观测性属性 影响估计器的一致性 。在使用线性化估计器(如EKF)时,对评估系统和测量雅可比矩阵进行线性化错误 会改变估计器获取信息的方向

如果这些信息沿着不可观测的方向,将导致更大的误差、更小的不确定性和不一致性。就是说,如果由不可观变成可以观测,就会导致

线性系统理论中提到,一个系统能否完全可观,看其能观测性判别矩阵 Q O Q_O QO是否满秩

放到这里,就是如下形式,H表示系统输出矩阵(投影矩阵,不是雅可比!), ϕ \phi ϕ表示了系统矩阵离散化后的描述形式!注意这是一个时变系统。
O ≜ [ H 1 H 2 Φ 1 ⋮ H k Φ k − 1 ⋯ Φ 1 ] \left.\mathcal{O}\triangleq\left[\begin{array}{c}\mathbf{H}_1\\\mathbf{H}_2\mathbf{\Phi}_1\\\vdots\\\mathbf{H}k\mathbf{\Phi}{k-1}\cdots\mathbf{\Phi}_1\end{array}\right.\right] O≜ H1H2Φ1⋮HkΦk−1⋯Φ1

这个矩阵对应的零空间如下

零空间:零空间的秩表示了不可观测的维度。很明显这个零空间的维度是4(两个全0行),刚好对应vio系统的不可观维度4,即平移与yaw。

O N 1 = 0 , N 1 = [ 0 3 R b v , 1 G g 0 3 0 3 0 3 − ( G v b , 1 ) ∧ G g 0 3 0 3 I 3 − ( t w b , 1 ) ∧ G g I 3 − ( p w ) ∧ G g ] = [ N t , 1 ∣ N r , 1 ] \left.\mathcal{O}\mathbf{N}_1=\mathbf{0},\quad\mathbf{N}_1=\left[\begin{array}{cc}\mathbf{0}3&R{bv,1}G\mathbf{g}\\\mathbf{0}_3&\mathbf{0}_3\\\mathbf{0}3&-(^G\mathbf{v}{b,1})^{\wedge G}\mathbf{g}\\\mathbf{0}_3&\mathbf{0}3\\\mathbf{I}3&-(t{wb,1})^{\wedge G}\mathbf{g}\\\mathbf{I}3&-(p_w)^{\wedge G}\mathbf{g}\end{array}\right.\right]=\left[\begin{array}{cc}\mathbf{N}{t,1}&|&\mathbf{N}{r,1}\end{array}\right] ON1=0,N1= 03030303I3I3Rbv,1Gg03−(Gvb,1)∧Gg03−(twb,1)∧Gg−(pw)∧Gg =[Nt,1∣Nr,1]

但是,随着状态增多,能观测性矩阵维度大了,其中 H k Φ k , 1 = H k Φ k , k − 1 ... Φ 2 , 1 Φ 1 \mathrm{H}k\Phi{k,1}=\mathrm{H}k\Phi{k,k-1}\ldots\Phi_{2,1}\Phi_1 HkΦk,1=HkΦk,k−1...Φ2,1Φ1递推过程中,形式和理想的形式不一致了。就是能观测性矩阵形式变了,那么原来的零空间的形式肯定不再满足。0空间的最后一列不成立,导致可观测性多了一维(yaw)。

论文中为了纠正这个问题,即仍然用原来零空间的形式,那么就只能强制修改能观测性矩阵的形式

6.4 可观测性约束

针对上述问题,修改状态转移矩阵 Φ观测矩阵 H 。本质上不需要关注0空间在每一时刻是否一样,只要保证每一个时刻的0空间维度都是4即可!也就是要满足下面两个式子!
N k = Φ k − 1 N k − 1 , H k N k = 0 \mathbf{N}k=\Phi{k-1}\mathbf{N}_{k-1},\quad\mathbf{H}_k\mathbf{N}_k=\mathbf{0} Nk=Φk−1Nk−1,HkNk=0

① 状态转移矩阵Φ

N k = Φ k − 1 N k − 1 \mathbf{N}k=\Phi{k-1}\mathbf{N}_{k-1} Nk=Φk−1Nk−1

展开
N r , k + 1 = Φ k N r , k → [ C ( q ^ c , k + 1 ∣ k ) c g 0 3 − ⌊ c v ^ t , k + 1 ∣ k × ⌋ c g 0 3 − ⌊ c p ^ t , k + 1 ∣ k × ⌋ c g ] = [ Φ 11 Φ 12 0 3 0 3 0 3 0 3 0 3 I 3 0 3 0 3 0 3 Φ 31 Φ 32 I 3 0 34 0 3 0 3 0 3 0 3 I 3 0 3 0 51 Φ 52 δ t I 3 Φ 54 I 3 ] [ C ( q ^ c , k ∣ k − 1 ) c g 0 3 − ⌊ q ^ t , k ∣ k − 1 × ⌋ c g 0 3 0 3 ] . \mathbf{N}{r,k+1}=\mathbf{\Phi}k\mathbf{N}{r,k}\quad\to\quad\begin{bmatrix}\mathbf{C}\left(\hat{q}{c,k+1|k}\right)^{c}\mathbf{g}\\\mathbf{0}{3}\\-\lfloor c\hat{\mathbf{v}}{t,k+1|k}\times\rfloor^{c}\mathbf{g}\\\mathbf{0}{3}\\-\lfloor{}^{c}\hat{\mathbf{p}}{t,k+1|k}\times\rfloor^{c}\mathbf{g}\end{bmatrix}=\begin{bmatrix}\Phi_{11}&\Phi_{12}&\mathbf{0}{3}&\mathbf{0}{3}&\mathbf{0}{3}&\mathbf{0}{3}\\\mathbf{0}{3}&\mathbf{I}{3}&\mathbf{0}{3}&\mathbf{0}{3}&\mathbf{0}{3}\\\Phi{31}&\Phi_{32}&\mathbf{I}{3}&\mathbf{0}{34}&\mathbf{0}{3}\\\mathbf{0}{3}&\mathbf{0}{3}&\mathbf{0}{3}&\mathbf{I}{3}&\mathbf{0}{3}\\\mathbf{0}{51}&\Phi{52}&\delta t\mathbf{I}{3}&\Phi{54}&\mathbf{I}{3}\end{bmatrix}\begin{bmatrix}\mathbf{C}\left(\hat{q}{c,k|k-1}\right)^{c}\mathbf{g}\\\mathbf{0}{3}\\-\lfloor\hat{q}{t,k|k-1}\times\rfloor^{c}\mathbf{g}\\\mathbf{0}{3}\\\mathbf{0}{3}\end{bmatrix}. Nr,k+1=ΦkNr,k→ C(q^c,k+1∣k)cg03−⌊cv^t,k+1∣k×⌋cg03−⌊cp^t,k+1∣k×⌋cg = Φ1103Φ3103051Φ12I3Φ3203Φ520303I303δtI30303034I3Φ5403030303I303 C(q^c,k∣k−1)cg03−⌊q^t,k∣k−1×⌋cg0303 .

我们把这个矩阵乘出来,能得到3个等式(主要是修改Φ11,31,51):

第1行:可以直接拿出来

C ( ′ q ˉ ^ G , k + 1 ∣ k ) c g = Φ 11 C ( ′ q ˉ ^ G , k ∣ k − 1 ) c g → Φ 11 = C ( ι , k + 1 ∣ k q ~ ^ ι , k ∣ k − 1 ) . \mathbf{C}\left({}^{\prime}\hat{\bar{q}}{G,k+1|k}\right)^{c}\mathbf{g}=\Phi{11}\mathbf{C}\left({}^{\prime}\hat{\bar{q}}{G,k|k-1}\right)^{c}\mathbf{g}\quad\to\Phi{11}=\mathbf{C}\left({}^{\iota,k+1|k}\hat{\tilde{q}}_{\iota,k|k-1}\right). C(′qˉ^G,k+1∣k)cg=Φ11C(′qˉ^G,k∣k−1)cg→Φ11=C(ι,k+1∣kq~^ι,k∣k−1).

第3、5行:论文中提到线性相关,无法直接求,或者说由多个解(等式中包含了反对

称矩阵导致实际右侧如果按照第⼀个式子那么算就会导致得到矩阵是线性相关的)

Φ 31 C ( q ^ c , k ∣ k − 1 ) G g = ⌊ G v ^ l , k ∣ k − 1 × ⌋ G g − ⌊ G v ^ l , k + 1 ∣ k × ⌋ G g Φ 51 C ( I q ^ G , k ∣ k − 1 ) G g = δ t ⌊ G v ^ l , k ∣ k − 1 × ⌋ G g − ⌊ G p ^ l , k + 1 ∣ k × ⌋ G g \begin{aligned}\Phi_{31}\mathbf{C}\left(\hat{q}{c,k|k-1}\right)^G\mathbf{g}&=\lfloor{}^G\hat{\mathbf{v}}{l,k|k-1}\times\rfloor^G\mathbf{g}-\lfloor{}^G\hat{\mathbf{v}}{l,k+1|k}\times\rfloor^G\mathbf{g}\\\Phi{51}\mathbf{C}\left({}^I\hat{q}{G,k|k-1}\right)^G\mathbf{g}&=\delta t\lfloor{}^G\hat{\mathbf{v}}{l,k|k-1}\times\rfloor^G\mathbf{g}-\lfloor{}^G\hat{\mathbf{p}}_{l,k+1|k}\times\rfloor^G\mathbf{g}\end{aligned} Φ31C(q^c,k∣k−1)GgΦ51C(Iq^G,k∣k−1)Gg=⌊Gv^l,k∣k−1×⌋Gg−⌊Gv^l,k+1∣k×⌋Gg=δt⌊Gv^l,k∣k−1×⌋Gg−⌊Gp^l,k+1∣k×⌋Gg

然后论文里面引入了一个最小二乘类似的约束,其中 A=Φ31 或 Φ51

min ⁡ A ∗ ∥ A ∗ − A ∥ F 2 , s.t. A ∗ u = w \min_{\mathbf{A}^{*}}\left\|\mathbf{A}^{*}-\mathbf{A}\right\|_{\mathcal{F}}^{2},\quad\text{s.t. }\mathbf{A}^{*}\mathbf{u}=\mathbf{w} A∗min∥A∗−A∥F2,s.t. A∗u=w

A ∗ = A − ( A u − w ) ( u T u ) − 1 u T \mathbf{A}^*=\mathbf{A}-(\mathbf{A}\mathbf{u}-\mathbf{w})\left(\mathbf{u}^T\mathbf{u}\right)^{-1}\mathbf{u}^T A∗=A−(Au−w)(uTu)−1uT

cpp 复制代码
// 5. Observability-constrained VINS 可观性约束
    // Modify the transition matrix
    // 5.1 修改phi_11
    // imu_state.orientation_null为上一个imu数据递推后保存的
    // 这块可能会有疑问,因为当上一个imu假如被观测更新了,
    // 导致当前的imu状态是由更新后的上一个imu状态递推而来,但是这里的值是没有更新的,这个有影响吗
    // 答案是没有的,因为我们更改了phi矩阵,保证了零空间
    // 并且这里必须这么处理,因为如果使用更新后的上一个imu状态构建上一时刻的零空间
    // 就破坏了上上一个跟上一个imu状态之间的0空间
    // Ni-1 = phi_[i-2] * Ni-2
    // Ni = phi_[i-1] * Ni-1^
    // 如果像上面这样约束,那么中间的0空间就"崩了"
    Matrix3d R_kk_1 = quaternionToRotation(imu_state.orientation_null);
    Phi.block<3, 3>(0, 0) =
        quaternionToRotation(imu_state.orientation) * R_kk_1.transpose();

    // 5.2 修改phi_31
    Vector3d u = R_kk_1 * IMUState::gravity;
    RowVector3d s = (u.transpose() * u).inverse() * u.transpose();

    Matrix3d A1 = Phi.block<3, 3>(6, 0);
    Vector3d w1 =
        skewSymmetric(imu_state.velocity_null - imu_state.velocity) * IMUState::gravity;
    Phi.block<3, 3>(6, 0) = A1 - (A1 * u - w1) * s;

    // 5.3 修改phi_51
    Matrix3d A2 = Phi.block<3, 3>(12, 0);
    Vector3d w2 =
        skewSymmetric(
            dtime * imu_state.velocity_null + imu_state.position_null -
            imu_state.position) *
        IMUState::gravity;
    Phi.block<3, 3>(12, 0) = A2 - (A2 * u - w2) * s;

② 对观测矩阵H--观测的雅可比矩阵

H c a m [ H θ G 0 3 × 9 H p l ∣ H f ] [ 0 3 C ( ι G , k ∣ k − 1 q ^ g ) c g 0 3 0 3 0 3 − ⌊ c q ^ ℓ , k ∣ k − 1 × ⌋ c g 0 3 0 3 I 3 − ⌊ c q ^ ℓ , k ∣ k − 1 × ⌋ c g I 3 − ⌊ c f ^ k ∣ k − 1 × ⌋ c g ] = [ 0 0 ] . \mathbf{H}{cam}\begin{bmatrix}\mathbf{H}{\theta_G}&\mathbf{0}{3\times9}&\mathbf{H}{\mathbf{p}l}&|&\mathbf{H}{\mathbf{f}}\end{bmatrix}\begin{bmatrix}\mathbf{0}{3}&\mathbf{C}\left(\iota{G,k|k-1}^{\hat{q}}\mathbf{g}\right)^{c}\mathbf{g}\\\mathbf{0}{3}&\mathbf{0}{3}\\\mathbf{0}{3}&-\lfloor{}^{c}\mathbf{\hat{q}}{\ell,k|k-1}\times\rfloor^{c}\mathbf{g}\\\mathbf{0}{3}&\mathbf{0}{3}\\\mathbf{I}{3}&-\lfloor{}^{c}\mathbf{\hat{q}}{\ell,k|k-1}\times\rfloor^{c}\mathbf{g}\\\mathbf{I}{3}&-\lfloor{}^{c}\mathbf{\hat{f}}{k|k-1}\times\rfloor^{c}\mathbf{g}\end{bmatrix}=\begin{bmatrix}\mathbf{0}&\mathbf{0}\end{bmatrix}. Hcam[HθG03×9Hpl∣Hf] 03030303I3I3C(ιG,k∣k−1q^g)cg03−⌊cq^ℓ,k∣k−1×⌋cg03−⌊cq^ℓ,k∣k−1×⌋cg−⌊cf^k∣k−1×⌋cg =[00].

还是上面同样的计算方法,这部分细节后续在考虑吧,先把代码对应上即可。

下面代码u就是对于了这个大矩阵(右),A就是对位姿的雅可比矩阵(左)。约束限制就是 A u = 0 = w Au=0=w Au=0=w。所以下面公式里的w其实是0.
H c a m [ H θ G H p l ] [ C ( q ^ G , k ∣ k − 1 ) G g ( ⌊ G f ^ k ∣ k − 1 × ⌋ − ⌊ G p ^ I , k ∣ k − 1 × ⌋ ) G g ] = 0. \mathbf{H}{cam}\begin{bmatrix}\mathbf{H}{\boldsymbol{\theta}G}&\mathbf{H}{\mathbf{p}l}\end{bmatrix}\begin{bmatrix}\mathbf{C}\left(\hat{\boldsymbol{q}}{G,k|k-1}\right)^G\mathbf{g}\\\left(\left\lfloor G\hat{\mathbf{f}}{k|k-1}\times\right\rfloor-\left\lfloor{}^G\hat{\mathbf{p}}{I,k|k-1}\times\right\rfloor\right)^G\mathbf{g}\end{bmatrix}=\mathbf{0}. Hcam[HθGHpl] C(q^G,k∣k−1)Gg(⌊Gf^k∣k−1×⌋−⌊Gp^I,k∣k−1×⌋)Gg =0.

H c a m \mathbf{H}_{cam} Hcam对应代码dz_dpc,即残差对相机系点 C P ^CP CP

H θ G \mathbf{H}_{\theta_G} HθG对应代码dpc_dxc,即相机系点 C P ^CP CP对旋转的雅可比

H p l \mathbf{H}_{\mathbf{p}_l} Hpl对应代码dpc_dxc,即相机系点 C P ^CP CP对平移的雅可比

H f \mathbf{H}_{\mathbf{f}} Hf对应代码dpc_dpg,即相机系点 C P ^CP CP对路标点 W P ^WP WP的雅可比

A ∗ = A − ( A u − w ) ( u T u ) − 1 u T \mathbf{A}^*=\mathbf{A}-(\mathbf{A}\mathbf{u}-\mathbf{w})\left(\mathbf{u}^T\mathbf{u}\right)^{-1}\mathbf{u}^T A∗=A−(Au−w)(uTu)−1uT

解决来之后,根据下面公式依次对应新的雅可比。代码中是双目,所以行维都是4.

H c a m H θ G = A 1 : 2 , 1 : 3 ′ , H c a m H p l = A 1 : 2 , 4 : 6 ′ , H c a m H f = − A 1 : 2 , 4 : 6 ′ \mathbf{H}{cam}\mathbf{H}{\theta_G}=\mathbf{A}{1:2,1:3}^{\prime},\mathbf{H}{cam}\mathbf{H}{\mathbf{p}l}=\mathbf{A}{1:2,4:6}^{\prime},\mathbf{H}{cam}\mathbf{H}{\mathbf{f}}=-\mathbf{A}{1:2,4:6}^{\prime} HcamHθG=A1:2,1:3′,HcamHpl=A1:2,4:6′,HcamHf=−A1:2,4:6′

cpp 复制代码
    // Modifty the measurement Jacobian to ensure
    // observability constrain.
    // 6. OC
    Matrix<double, 4, 6> A = H_x;
    Matrix<double, 6, 1> u = Matrix<double, 6, 1>::Zero();
    u.block<3, 1>(0, 0) = 
        quaternionToRotation(cam_state.orientation_null) * IMUState::gravity;
    u.block<3, 1>(3, 0) =
        skewSymmetric(p_w - cam_state.position_null) * IMUState::gravity;
    H_x = A - A * u * (u.transpose() * u).inverse() * u.transpose();
    H_f = -H_x.block<4, 3>(0, 3);//4*3大小,从0行3列开始取,对应公式