imu 里程计融合_MSCKF那些事(十一)算法改进4:融合直接观测

2023-05-16

在实际应用过程中往往不只有视觉和IMU的融合,还有其他很多传感器(GPS、激光、里程计等),这些传感器数据和VIO进行融合能够极大提高VIO的精度和稳定性。融合的方式分为松耦合和紧耦合,常见的做法是将VIO看成一个独立的传感器与其他传感器进行松耦合,但有时为了提高VIO本身的精度也可以将部分传感器信息加入到VIO融合框架中。

状态向量中某些量可能会被其他传感器直接观测到,例如GPS可以给出

中的位置观测或速度观测,平面移动机器人有三个维度可以固定
,在MSCKF中可以对直接观测构建观测模型进行EKF更新。直接观测有两类:
  • 一类是传感器直接测量到的观测:比如GPS位置、GPS速度、轮式里程计
  • 一类是基于先验信息给出的观测:比如平面机器人可以假设
    ,此外还有零速检测(Zero-velocity UPdaTe,ZUPT),当检测到IMU处于静止状态时,可以认为速度为0,陀螺仪观测的均值作为陀螺仪的bias。

直接观测融合十分简单,构建观测模型

,然后套用EKF更新公式即可。
矩阵在观测状态的对应位置填1,其他填0,以融合速度观测为例,设{G}系下的IMU观测速度为
,误差
,EKF更新流程如下:

代码实现上可以做成一个通用的直接观测更新接口,输入参数:

  • observe_vec:直接观测向量,所有观测合并成一个向量
  • state_vec:直接观测向量中每一项对应的当前状态估计量
  • index_vec:直接观测向量中每一项对应协方差矩阵中的位置索引
  • noise_vec:直接观测向量中每一项的观测噪声

只要直接观测到状态向量中的任意项,都可以调用该API进行更新。

void updateVector(const VectorXd& observe_vec, const VectorXd& state_vec, const VectorXi& index_vec, const VectorXd& noise_vec)

{

    auto& P = m_state_server.state_cov;

    int D = index_vec.rows();

    MatrixXd H = MatrixXd::Zero(D, P.cols());

    MatrixXd HP = MatrixXd::Zero(D, P.cols());

    MatrixXd Q = MatrixXd::Zero(D, D);

    for(int i = 0; i < D; i++)

    {

        H(i, index_vec(i)) = 1;

        HP.row(i) = P.row(index_vec(i));

        Q(i, i) = noise_vec(i);

    }

    // Compute the Kalman gain.

    MatrixXd S = HP * H.transpose() + Q;

    MatrixXd K_transpose = S.ldlt().solve(HP);

    MatrixXd K = K_transpose.transpose();

    // Compute the error of the state.

    VectorXd err = observe_vec - state_vec;

    VectorXd delta_x = K * err;

    if(updateState(delta_x, false)) updateStateCov(K, H, Q);

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

imu 里程计融合_MSCKF那些事(十一)算法改进4:融合直接观测 的相关文章

随机推荐