天天看点

lio-mapping 及 VINS-Mono代码及理论推导(2)—— pre_integrationlio-mapping 及 VINS-Mono代码及理论推导(2)—— pre_integration

lio-mapping 及 VINS-Mono代码及理论推导(2)—— pre_integration

最近在看港科大刚开源的LIO及VINS-Mono论文和代码,他们一部分代码都是相同的,闲暇时间整理一下。持续更新中(如果有时间)。。。

LIO

代码链接: https://github.com/hyye/lio-mapping

相关介绍:https://sites.google.com/view/lio-mapping

论文地址:https://arxiv.org/abs/1904.06993

VINS

代码链接: https://github.com/castiel520/VINS-Mono

论文地址:https://arxiv.org/abs/1708.03852v1

预积分部分核心函数为

MidPointIntegration 预积分函数

VINS_Mono

void midPointIntegration(double _dt, 
                            const Eigen::Vector3d &_acc_0, const Eigen::Vector3d &_gyr_0,
                            const Eigen::Vector3d &_acc_1, const Eigen::Vector3d &_gyr_1,
                            const Eigen::Vector3d &delta_p, const Eigen::Quaterniond &delta_q, const Eigen::Vector3d &delta_v,
                            const Eigen::Vector3d &linearized_ba, const Eigen::Vector3d &linearized_bg,
                            Eigen::Vector3d &result_delta_p, Eigen::Quaterniond &result_delta_q, Eigen::Vector3d &result_delta_v,
                            Eigen::Vector3d &result_linearized_ba, Eigen::Vector3d &result_linearized_bg, bool update_jacobian)
    {
        //ROS_INFO("midpoint integration");
        Vector3d un_acc_0 = delta_q * (_acc_0 - linearized_ba);
        Vector3d un_gyr = 0.5 * (_gyr_0 + _gyr_1) - linearized_bg;
        result_delta_q = delta_q * Quaterniond(1, un_gyr(0) * _dt / 2, un_gyr(1) * _dt / 2, un_gyr(2) * _dt / 2);
        Vector3d un_acc_1 = result_delta_q * (_acc_1 - linearized_ba);
        Vector3d un_acc = 0.5 * (un_acc_0 + un_acc_1);
        result_delta_p = delta_p + delta_v * _dt + 0.5 * un_acc * _dt * _dt;
        result_delta_v = delta_v + un_acc * _dt;
        result_linearized_ba = linearized_ba;
        result_linearized_bg = linearized_bg;         

        if(update_jacobian)
        {
            Vector3d w_x = 0.5 * (_gyr_0 + _gyr_1) - linearized_bg;
            Vector3d a_0_x = _acc_0 - linearized_ba;
            Vector3d a_1_x = _acc_1 - linearized_ba;
            Matrix3d R_w_x, R_a_0_x, R_a_1_x;

            R_w_x<<0, -w_x(2), w_x(1),
                w_x(2), 0, -w_x(0),
                -w_x(1), w_x(0), 0;
            R_a_0_x<<0, -a_0_x(2), a_0_x(1),
                a_0_x(2), 0, -a_0_x(0),
                -a_0_x(1), a_0_x(0), 0;
            R_a_1_x<<0, -a_1_x(2), a_1_x(1),
                a_1_x(2), 0, -a_1_x(0),
                -a_1_x(1), a_1_x(0), 0;

            MatrixXd F = MatrixXd::Zero(15, 15);
            F.block<3, 3>(0, 0) = Matrix3d::Identity();
            F.block<3, 3>(0, 3) = -0.25 * delta_q.toRotationMatrix() * R_a_0_x * _dt * _dt + 
                                  -0.25 * result_delta_q.toRotationMatrix() * R_a_1_x * (Matrix3d::Identity() - R_w_x * _dt) * _dt * _dt;
            F.block<3, 3>(0, 6) = MatrixXd::Identity(3,3) * _dt;
            F.block<3, 3>(0, 9) = -0.25 * (delta_q.toRotationMatrix() + result_delta_q.toRotationMatrix()) * _dt * _dt;
            F.block<3, 3>(0, 12) = -0.25 * result_delta_q.toRotationMatrix() * R_a_1_x * _dt * _dt * -_dt;
            F.block<3, 3>(3, 3) = Matrix3d::Identity() - R_w_x * _dt;
            F.block<3, 3>(3, 12) = -1.0 * MatrixXd::Identity(3,3) * _dt;
            F.block<3, 3>(6, 3) = -0.5 * delta_q.toRotationMatrix() * R_a_0_x * _dt + 
                                  -0.5 * result_delta_q.toRotationMatrix() * R_a_1_x * (Matrix3d::Identity() - R_w_x * _dt) * _dt;
            F.block<3, 3>(6, 6) = Matrix3d::Identity();
            F.block<3, 3>(6, 9) = -0.5 * (delta_q.toRotationMatrix() + result_delta_q.toRotationMatrix()) * _dt;
            F.block<3, 3>(6, 12) = -0.5 * result_delta_q.toRotationMatrix() * R_a_1_x * _dt * -_dt;
            F.block<3, 3>(9, 9) = Matrix3d::Identity();
            F.block<3, 3>(12, 12) = Matrix3d::Identity();
            //cout<<"A"<<endl<<A<<endl;

            MatrixXd V = MatrixXd::Zero(15,18);
            V.block<3, 3>(0, 0) =  0.25 * delta_q.toRotationMatrix() * _dt * _dt;
            V.block<3, 3>(0, 3) =  0.25 * -result_delta_q.toRotationMatrix() * R_a_1_x  * _dt * _dt * 0.5 * _dt;
            V.block<3, 3>(0, 6) =  0.25 * result_delta_q.toRotationMatrix() * _dt * _dt;
            V.block<3, 3>(0, 9) =  V.block<3, 3>(0, 3);
            V.block<3, 3>(3, 3) =  0.5 * MatrixXd::Identity(3,3) * _dt;
            V.block<3, 3>(3, 9) =  0.5 * MatrixXd::Identity(3,3) * _dt;
            V.block<3, 3>(6, 0) =  0.5 * delta_q.toRotationMatrix() * _dt;
            V.block<3, 3>(6, 3) =  0.5 * -result_delta_q.toRotationMatrix() * R_a_1_x  * _dt * 0.5 * _dt;
            V.block<3, 3>(6, 6) =  0.5 * result_delta_q.toRotationMatrix() * _dt;
            V.block<3, 3>(6, 9) =  V.block<3, 3>(6, 3);
            V.block<3, 3>(9, 12) = MatrixXd::Identity(3,3) * _dt;
            V.block<3, 3>(12, 15) = MatrixXd::Identity(3,3) * _dt;

            //step_jacobian = F;
            //step_V = V;
            jacobian = F * jacobian;
            covariance = F * covariance * F.transpose() + V * noise * V.transpose();
        }

    }

           

LIO-Mapping

对比代码发现 LIO-Mapping 与 VINS部分细节不同,注释中有提及。

void MidPointIntegration(double dt,
                           const Vector3d &acc0, const Vector3d &gyr0,
                           const Vector3d &acc1, const Vector3d &gyr1,
                           const Vector3d &delta_p, const Quaterniond &delta_q,
                           const Vector3d &delta_v, const Vector3d &linearized_ba,
                           const Vector3d &linearized_bg, Vector3d &result_delta_p,
                           Quaterniond &result_delta_q, Vector3d &result_delta_v,
                           Vector3d &result_linearized_ba, Vector3d &result_linearized_bg,
                           bool update_jacobian) {
    //ROS_DEBUG("midpoint integration");

    // NOTE: the un_acc here is different from the un_acc in the Estimator
    Vector3d un_acc_0 = delta_q * (acc0 - linearized_ba);
    Vector3d un_gyr = 0.5 * (gyr0 + gyr1) - linearized_bg;
    result_delta_q = delta_q * Quaterniond(1, un_gyr(0) * dt / 2, un_gyr(1) * dt / 2, un_gyr(2) * dt / 2);
    Vector3d un_acc_1 = result_delta_q * (acc1 - linearized_ba);
    Vector3d un_acc = 0.5 * (un_acc_0 + un_acc_1);
    result_delta_p = delta_p + delta_v * dt + 0.5 * un_acc * dt * dt;
    result_delta_v = delta_v + un_acc * dt;
    result_linearized_ba = linearized_ba;
    result_linearized_bg = linearized_bg;

    if (update_jacobian) {
      Vector3d w_x = 0.5 * (gyr0 + gyr1) - linearized_bg;
      Vector3d a_0_x = acc0 - linearized_ba;
      Vector3d a_1_x = acc1 - linearized_ba;
      Matrix3d R_w_x, R_a_0_x, R_a_1_x;

      R_w_x << 0, -w_x(2), w_x(1),
          w_x(2), 0, -w_x(0),
          -w_x(1), w_x(0), 0;
      R_a_0_x << 0, -a_0_x(2), a_0_x(1),
          a_0_x(2), 0, -a_0_x(0),
          -a_0_x(1), a_0_x(0), 0;
      R_a_1_x << 0, -a_1_x(2), a_1_x(1),
          a_1_x(2), 0, -a_1_x(0),
          -a_1_x(1), a_1_x(0), 0;

      // NOTE: F = Fd = \Phi = I + dF*dt
      MatrixXd F = MatrixXd::Zero(15, 15);
      F.block<3, 3>(0, 0) = Matrix3d::Identity();
      F.block<3, 3>(0, 3) = -0.25 * delta_q.toRotationMatrix() * R_a_0_x * dt * dt +
          -0.25 * result_delta_q.toRotationMatrix() * R_a_1_x * (Matrix3d::Identity() - R_w_x * dt) * dt * dt;
      F.block<3, 3>(0, 6) = MatrixXd::Identity(3, 3) * dt;
      F.block<3, 3>(0, 9) = -0.25 * (delta_q.toRotationMatrix() + result_delta_q.toRotationMatrix()) * dt * dt;
//      F.block<3, 3>(0, 12) = -0.25 * result_delta_q.toRotationMatrix() * R_a_1_x * dt * dt * -dt;
      F.block<3, 3>(0, 12) = -0.1667 * result_delta_q.toRotationMatrix() * R_a_1_x * dt * dt * -dt;//0.1667与VINS不同
      F.block<3, 3>(3, 3) = Matrix3d::Identity() - R_w_x * dt;
      F.block<3, 3>(3, 12) = -1.0 * MatrixXd::Identity(3, 3) * dt;
      F.block<3, 3>(6, 3) = -0.5 * delta_q.toRotationMatrix() * R_a_0_x * dt +
          -0.5 * result_delta_q.toRotationMatrix() * R_a_1_x * (Matrix3d::Identity() - R_w_x * dt) * dt;
      F.block<3, 3>(6, 6) = Matrix3d::Identity();
      F.block<3, 3>(6, 9) = -0.5 * (delta_q.toRotationMatrix() + result_delta_q.toRotationMatrix()) * dt;
      F.block<3, 3>(6, 12) = -0.5 * result_delta_q.toRotationMatrix() * R_a_1_x * dt * -dt;
      F.block<3, 3>(9, 9) = Matrix3d::Identity();
      F.block<3, 3>(12, 12) = Matrix3d::Identity();
      //cout<<"A"<<endl<<A<<endl;

      // NOTE: V = Fd * G_c
      // FIXME: verify if it is right, the 0.25 part
      MatrixXd V = MatrixXd::Zero(15, 18);
//      V.block<3, 3>(0, 0) = 0.25 * delta_q.toRotationMatrix() * dt * dt;
      V.block<3, 3>(0, 0) = 0.5 * delta_q.toRotationMatrix() * dt * dt;//0.5与VINS不同
      V.block<3, 3>(0, 3) = 0.25 * -result_delta_q.toRotationMatrix() * R_a_1_x * dt * dt * 0.5 * dt;
//      V.block<3, 3>(0, 6) = 0.25 * result_delta_q.toRotationMatrix() * dt * dt;
      V.block<3, 3>(0, 6) = 0.5 * result_delta_q.toRotationMatrix() * dt * dt;//0.5与VINS不同
      V.block<3, 3>(0, 9) = V.block<3, 3>(0, 3);
      V.block<3, 3>(3, 3) = 0.5 * MatrixXd::Identity(3, 3) * dt;
      V.block<3, 3>(3, 9) = 0.5 * MatrixXd::Identity(3, 3) * dt;
      V.block<3, 3>(6, 0) = 0.5 * delta_q.toRotationMatrix() * dt;
      V.block<3, 3>(6, 3) = 0.5 * -result_delta_q.toRotationMatrix() * R_a_1_x * dt * 0.5 * dt;
      V.block<3, 3>(6, 6) = 0.5 * result_delta_q.toRotationMatrix() * dt;
      V.block<3, 3>(6, 9) = V.block<3, 3>(6, 3);
      V.block<3, 3>(9, 12) = MatrixXd::Identity(3, 3) * dt;
      V.block<3, 3>(12, 15) = MatrixXd::Identity(3, 3) * dt;

      //step_jacobian = F;
      //step_V = V;
      jacobian_ = F * jacobian_;
      covariance_ = F * covariance_ * F.transpose() + V * noise_ * V.transpose();
    }

  }
           

公式推导

下面是两帧雷达数据之间所以IMU数据的位置、速度、旋转量的积分公式

(1) p j = p i + ∑ k = i j − 1 [ v k Δ t + 0.25 ( R k i ( a k − b a k ) + R k + 1 i ( a k − b a k ) ) Δ t 2 ] p_{j}=p_i+\sum_{k=i}^{j-1}[v_k\Delta{t}+0.25(R_{k}^i(a_k-b_{a_k})+R_{k+1}^i(a_k-b_{a_k}))\Delta{t}^2] \tag{1} pj​=pi​+k=i∑j−1​[vk​Δt+0.25(Rki​(ak​−bak​​)+Rk+1i​(ak​−bak​​))Δt2](1)

(2) v j = v i + ∑ k = i j − 1 0.5 [ R k i ( a k − b a k ) Δ t + R k + 1 i ( a k − b a k ) Δ t ] v_{j}=v_{i}+\sum_{k=i}^{j-1}0.5[R_k^i(a_k-b_{a_k})\Delta{t}+R_{k+1}^i(a_k-b_{a_k})\Delta{t}] \tag{2} vj​=vi​+k=i∑j−1​0.5[Rki​(ak​−bak​​)Δt+Rk+1i​(ak​−bak​​)Δt](2)

(3) q j = q i ⊗ ∏ k = i j − 1 δ q k = q i ⊗ ∏ k = i j − 1 [ 1 2 Δ t ( ω k + ω k + 1 2 − b g k ) 1 ] q_j=q_i\otimes\prod_{k=i}^{j-1}\delta{q_k}=q_i\otimes\prod_{k=i}^{j-1}\begin{bmatrix}\frac{1}{2}\Delta{t}(\frac{\omega_k+\omega_{k+1}}{2}-b_{g_k}) \\ 1 \\ \end{bmatrix} \tag{3} qj​=qi​⊗k=i∏j−1​δqk​=qi​⊗k=i∏j−1​[21​Δt(2ωk​+ωk+1​​−bgk​​)1​](3)

不考虑噪声的情况下,每来一帧imu数据,其状态转移如下

(4) q k + 1 = q k ⊗ [ 1 2 Δ t ( ω k + ω k + 1 2 − b g k ) 1 ] {q_{k+1}}={q_k}\otimes\begin{bmatrix}\frac{1}{2}\Delta{t}(\frac{\omega_k+\omega_{k+1}}{2}-b_{g_k}) \\ 1 \end{bmatrix} \tag{4} qk+1​=qk​⊗[21​Δt(2ωk​+ωk+1​​−bgk​​)1​](4)

(5) p k + 1 = p k + v k Δ t + 0.25 ( R k ( a k − b a k ) + R k + 1 ( a k + 1 − b a k + 1 ) ) Δ t 2 {p}_{k+1}={p}_{k}+{v}_k\Delta{t}+0.25(R_k(a_k-b_{a_k})+R_{k+1}(a_{k+1}-b_{a_{k+1}}))\Delta{t}^2 \tag{5} pk+1​=pk​+vk​Δt+0.25(Rk​(ak​−bak​​)+Rk+1​(ak+1​−bak+1​​))Δt2(5)

(6) v k + 1 = v k + 0.5 ( R k ( a k − b a k ) + R k + 1 ( a k + 1 − b a k + 1 ) ) Δ t v_{k+1}=v_{k}+0.5(R_k(a_k-b_{a_k})+R_{k+1}(a_{k+1}-b_{a_{k+1}}))\Delta{t} \tag{6} vk+1​=vk​+0.5(Rk​(ak​−bak​​)+Rk+1​(ak+1​−bak+1​​))Δt(6)

(7) b a k + 1 = b a k b_{a_{k+1}}=b_{a_{k}} \tag{7} bak+1​​=bak​​(7)

(8) b g k + 1 = b g k b_{g_{k+1}}=b_{g_{k}} \tag{8} bgk+1​​=bgk​​(8)

误差状态 δ X = ( δ p , δ θ , δ v , δ b a , δ b g ) \delta{X}=(\delta{p},\delta{\theta},\delta{v},\delta{b_a},\delta{b_g}) δX=(δp,δθ,δv,δba​,δbg​)

加入噪声影响,加速度和陀螺仪的测量噪声为 n a ∼ N ( 0 , σ a 2 ) n_a\sim\mathcal{N}(0,\sigma_a^2) na​∼N(0,σa2​) , n w ∼ N ( 0 , σ w 2 ) n_w\sim\mathcal{N}(0,\sigma_w^2) nw​∼N(0,σw2​)。 加速度和陀螺仪偏置为随机游走噪声, n b a ∼ N ( 0 , σ b a 2 ) n_{b_a}\sim\mathcal{N}(0,\sigma_{b_a}^2) nba​​∼N(0,σba​2​) , n b w ∼ N ( 0 , σ b w 2 ) n_{b_w}\sim\mathcal{N}(0,\sigma_{b_w}^2) nbw​​∼N(0,σbw​2​) ,针对MidPointIntegration,其还需要增加 k + 1 k+1 k+1时刻的测量噪声,也即其噪声矩阵为。

Q = [ n a 0 0 0 0 0 0 n w 0 0 0 0 0 0 n a 0 0 0 0 0 0 n w 0 0 0 0 0 0 n b a 0 0 0 0 0 0 n b w ] Q=\begin{bmatrix} n_{a} &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0\\ 0 &amp; n_{w} &amp; 0 &amp; 0 &amp; 0 &amp; 0\\ 0 &amp; 0 &amp; n_{a} &amp; 0 &amp; 0 &amp; 0\\ 0 &amp; 0 &amp; 0 &amp; n_{w} &amp; 0 &amp; 0\\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; n_{b_a} &amp; 0\\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; n_{b_w}\end{bmatrix} Q=⎣⎢⎢⎢⎢⎢⎢⎡​na​00000​0nw​0000​00na​000​000nw​00​0000nba​​0​00000nbw​​​⎦⎥⎥⎥⎥⎥⎥⎤​

.

根据式(4),首先求 δ θ ˙ \dot{\delta{\theta}} δθ˙,定义 δ q = [ 1 2 δ θ 1 ] \delta{q}=\begin{bmatrix}\frac{1}{2}\delta{\theta} \\ 1\end{bmatrix} δq=[21​δθ1​]:

(9) δ θ ˙ = − [ ω k + ω k + 1 2 − b g k ] × δ θ − δ b g + 0.5 ( n w k + n w k + 1 )   \dot{\delta{\theta}}=-[\frac{\omega_k+\omega_{k+1}}{2}-b_{g_k}]_\times \delta{\theta}-\delta{b_{g}}+0.5(n_{w_k}+n_{w_{k+1}}) \tag{9} δθ˙=−[2ωk​+ωk+1​​−bgk​​]×​δθ−δbg​+0.5(nwk​​+nwk+1​​) (9)

δ θ \delta{\theta} δθ更新为:

(10) δ θ n e w ← ( I − [ ( ω k + ω k + 1 2 − b g k ) ] × Δ t ) δ θ − Δ t δ b g + 0.5 Δ t ( n w k + n w k + 1 ) \delta{\theta^{new}}\leftarrow (I-[(\frac{\omega_k+\omega_{k+1}}{2}-b_{g_k})]_{\times}\Delta{t})\delta{\theta}-\Delta{t}\delta{b_{g}}+0.5\Delta{t}(n_{w_k}+n_{w_{k+1}}) \tag{10} δθnew←(I−[(2ωk​+ωk+1​​−bgk​​)]×​Δt)δθ−Δtδbg​+0.5Δt(nwk​​+nwk+1​​)(10)

假设加加速度恒定,再求 δ v ˙ \dot{\delta{v}} δv˙ :

(11) δ v ˙ = − 0.5 ( R k [ a k − b a k ] × δ θ + R k + 1 [ a k + 1 − b a k + 1 ] × δ θ n e w ) + 0.5 ( R k + R k + 1 ) δ b a + 0.5 ( R k n a k + R k + 1 n a k + 1 ) = − 0.5 ( R k [ a k − b a k ] × δ θ + R k + 1 [ a k + 1 − b a k + 1 ] × ( ( I − [ ( ω k + ω k + 1 2 − b g k ) ] × Δ t ) δ θ − Δ t δ b g + 0.5 Δ t ( n w k + n w k + 1 ) ) + 0.5 ( R k + R k + 1 ) δ b a + 0.5 ( R k n a k + R k + 1 n a k + 1 ) = − 0.5 ( R k [ a k − b a k ] × + R k + 1 [ a k + 1 − b a k + 1 ] × ( ( I − [ ( ω k + ω k + 1 2 − b g k ) ] × Δ t ) ) δ θ − 0.5 ( R k + R k + 1 ) δ b a + 0.5 ( R k n a k + R k + 1 n a k + 1 ) + 0.5 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t δ b g − 0.25 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t ( n w k + n w k + 1 ) \begin{aligned} \dot{\delta{v}} =&amp;-0.5(R_{k}[a_k-b_{a_k}]_\times\delta{\theta}+R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\delta{\theta^{new}})\\ &amp;+0.5(R_k+R_{k+1})\delta{b_a}+0.5(R_k{n_{a_k}}+R_{k+1}n_{a_{k+1}}) \\ =&amp; -0.5(R_{k}[a_k-b_{a_k}]_\times\delta{\theta}+R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times((I-[(\frac{\omega_k+\omega_{k+1}}{2}-b_{g_k})]_{\times}\Delta{t})\delta{\theta}-\Delta{t}\delta{b_{g}}+0.5\Delta{t}(n_{w_k}+n_{w_{k+1}}))\\ &amp;+0.5(R_k+R_{k+1})\delta{b_a} +0.5(R_k{n_{a_k}}+R_{k+1}n_{a_{k+1}})\\ =&amp; -0.5(R_{k}[a_k-b_{a_k}]_\times+R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times((I-[(\frac{\omega_k+\omega_{k+1}}{2}-b_{g_k})]_{\times}\Delta{t}))\delta{\theta}\\ &amp; -0.5(R_k+R_{k+1})\delta{b_a}+0.5(R_k{n_{a_k}}+R_{k+1}n_{a_{k+1}}) \\ &amp; +0.5R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\Delta{t}\delta{b_{g}} -0.25R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\Delta{t}(n_{w_k}+n_{w_{k+1}}) \end{aligned} \tag{11} δv˙===​−0.5(Rk​[ak​−bak​​]×​δθ+Rk+1​[ak+1​−bak+1​​]×​δθnew)+0.5(Rk​+Rk+1​)δba​+0.5(Rk​nak​​+Rk+1​nak+1​​)−0.5(Rk​[ak​−bak​​]×​δθ+Rk+1​[ak+1​−bak+1​​]×​((I−[(2ωk​+ωk+1​​−bgk​​)]×​Δt)δθ−Δtδbg​+0.5Δt(nwk​​+nwk+1​​))+0.5(Rk​+Rk+1​)δba​+0.5(Rk​nak​​+Rk+1​nak+1​​)−0.5(Rk​[ak​−bak​​]×​+Rk+1​[ak+1​−bak+1​​]×​((I−[(2ωk​+ωk+1​​−bgk​​)]×​Δt))δθ−0.5(Rk​+Rk+1​)δba​+0.5(Rk​nak​​+Rk+1​nak+1​​)+0.5Rk+1​[ak+1​−bak+1​​]×​Δtδbg​−0.25Rk+1​[ak+1​−bak+1​​]×​Δt(nwk​​+nwk+1​​)​(11)

得到 δ v n e w \delta{v^{new}} δvnew:

(12) δ v n e w ← δ v + δ v ˙ Δ t \delta{v^{new}}\leftarrow\delta{v}+\dot{\delta{v}}\Delta{t} \tag{12} δvnew←δv+δv˙Δt(12)

再求 δ p ˙ \dot{\delta{p}} δp˙​

(13) δ p ˙ = 0.5 ( δ v + δ v n e w ) = δ v + 0.5 δ v ˙ \begin{aligned} \dot{\delta{p}} =&amp;0.5(\delta{v}+\delta{v^{new}}) \\ =&amp;\delta{v}+0.5\dot{\delta{v}} \end{aligned} \tag{13} δp˙​==​0.5(δv+δvnew)δv+0.5δv˙​(13)

求 δ p \delta{p} δp

(14) δ p n e w ← δ p + δ p ˙ Δ t \delta{p^{new}}\leftarrow\delta{p}+\dot{\delta{p}}\Delta{t} \tag{14} δpnew←δp+δp˙​Δt(14)

最后更新偏置 δ b a \delta{b_a} δba​, δ b g \delta{b_g} δbg​

(15) δ b a n e w ← δ b a + n b a Δ t \delta{b_a^{new}}\leftarrow \delta{b_a} + n_{b_a}\Delta{t} \tag{15} δbanew​←δba​+nba​​Δt(15)

(16) δ b g n e w ← δ b g + n b w Δ t \delta{b_g^{new}}\leftarrow \delta{b_g} + n_{b_w}\Delta{t} \tag{16} δbgnew​←δbg​+nbw​​Δt(16)

状态转移矩阵为:

F = [ I f 01 I Δ t − 0.25 ( R k + R k + 1 ) Δ t 2 0.25 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t 3 0 I − [ 0.5 ( ω k + ω k + 1 ) − b g k ] × Δ t 0 0 − I Δ t 0 f 21 I − 0.5 ( R k + R k + 1 ) Δ t 0.5 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t 2 0 0 0 I 0 0 0 0 0 I ] F=\begin{bmatrix} I &amp; f_{01} &amp; I\Delta{t} &amp; -0.25(R_{k}+R_{k+1})\Delta{t}^2 &amp; 0.25R_{k+1}[a_{k+1}-b_{a_{k+1}}]_{\times}\Delta{t}^3\\ 0 &amp; I-[0.5(\omega_k+\omega_{k+1})-b_{g_k}]_{\times}\Delta{t} &amp; 0 &amp; 0 &amp; -I\Delta{t}\\ 0 &amp; f_{21} &amp; I &amp; -0.5(R_{k}+R_{k+1})\Delta{t} &amp; 0.5R_{k+1}[a_{k+1}-b_{a_{k+1}}]_{\times}\Delta{t}^2\\ 0 &amp; 0 &amp; 0 &amp; I &amp; 0\\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; I \end{bmatrix} F=⎣⎢⎢⎢⎢⎡​I0000​f01​I−[0.5(ωk​+ωk+1​)−bgk​​]×​Δtf21​00​IΔt0I00​−0.25(Rk​+Rk+1​)Δt20−0.5(Rk​+Rk+1​)ΔtI0​0.25Rk+1​[ak+1​−bak+1​​]×​Δt3−IΔt0.5Rk+1​[ak+1​−bak+1​​]×​Δt20I​⎦⎥⎥⎥⎥⎤​

其中

f 01 = − 0.25 ( R k [ a k − b a k ] × Δ t 2 − R k + 1 [ a k + 1 − b a k + 1 ] × ( I − [ 0.5 ( ω k + ω k + 1 ) − b g k ] × Δ t ) ) Δ t 2 f 21 = − 0.5 R k ∗ [ a k − b a k ] × Δ t − 0.5 R k + 1 [ a k + 1 − b a k + 1 ] × ( I − [ 0.5 ( ω k + ω k + 1 ) − b g k ] × Δ t ) Δ t f_{01}=-0.25(R_k[a_k-b_{a_k}]_{\times}\Delta{t}^2-R_{k+1}[a_{k+1}-b_{a_{k+1}}]_{\times}(I-[0.5(\omega_k+\omega_{k+1})-b_{g_k}]_{\times}\Delta{t}))\Delta{t}^2 \\ f_{21}=-0.5R_k*[a_k-b_{a_k}]_{\times}\Delta{t}-0.5R_{k+1}[a_{k+1}-b_{a_{k+1}}]_{\times}(I-[0.5(\omega_k+\omega_{k+1})-b_{g_k}]_{\times}\Delta{t})\Delta{t} f01​=−0.25(Rk​[ak​−bak​​]×​Δt2−Rk+1​[ak+1​−bak+1​​]×​(I−[0.5(ωk​+ωk+1​)−bgk​​]×​Δt))Δt2f21​=−0.5Rk​∗[ak​−bak​​]×​Δt−0.5Rk+1​[ak+1​−bak+1​​]×​(I−[0.5(ωk​+ωk+1​)−bgk​​]×​Δt)Δt

雅克比矩阵更新:

(17) J n e w ← F J J^{new}\leftarrow FJ \tag{17} Jnew←FJ(17)

上述雅克比矩阵更新是在两帧imu数据之间的更新,在激光SLAM问题中,一般需要求得两帧雷达点云之间状态变换的雅克比矩阵,这只需要累乘 F F F矩阵即可。

噪声的观测矩阵则为:

V = [ 0.25 R k Δ t 2 − 0.125 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t 3 0.25 R k + 1 Δ t 2 − 0.125 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t 3 0 0 0 0.5 I Δ t 0 0.5 I Δ t 0 0 0.5 R k Δ t − 0.25 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t 2 0.5 R k + 1 Δ t − 0.25 R k + 1 [ a k + 1 − b a k + 1 ] × Δ t 2 0 0 0 0 0 0 I Δ t 0 0 0 0 0 0 I Δ t ] V=\begin{bmatrix} 0.25R_k\Delta{t}^2 &amp; -0.125R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\Delta{t}^3 &amp; 0.25R_{k+1}\Delta{t}^2 &amp; -0.125R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\Delta{t}^3 &amp; 0 &amp; 0\\ 0 &amp; 0.5I\Delta{t} &amp; 0 &amp; 0.5I\Delta{t} &amp; 0 &amp; 0\\ 0.5R_k\Delta{t} &amp; -0.25R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\Delta{t}^2 &amp; 0.5R_{k+1}\Delta{t} &amp; -0.25R_{k+1}[a_{k+1}-b_{a_{k+1}}]_\times\Delta{t}^2 &amp; 0 &amp; 0\\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; I\Delta{t} &amp; 0\\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; I\Delta{t}\end{bmatrix} V=⎣⎢⎢⎢⎢⎡​0.25Rk​Δt200.5Rk​Δt00​−0.125Rk+1​[ak+1​−bak+1​​]×​Δt30.5IΔt−0.25Rk+1​[ak+1​−bak+1​​]×​Δt200​0.25Rk+1​Δt200.5Rk+1​Δt00​−0.125Rk+1​[ak+1​−bak+1​​]×​Δt30.5IΔt−0.25Rk+1​[ak+1​−bak+1​​]×​Δt200​000IΔt0​0000IΔt​⎦⎥⎥⎥⎥⎤​

则协方差更新:

P n e w ← F P F T + V Q V T P^{new}\leftarrow FPF^T+VQV^T Pnew←FPFT+VQVT

状态更新:

δ X n e w ← F δ X + V Q \delta{X}^{new}\leftarrow F\delta{X}+VQ δXnew←FδX+VQ

继续阅读