vins 解读_VINS 中的 IMU 预积分推导和代码解读

VIO中的IMU预积分避免了因关键帧旋转矩阵变化导致的重复积分,通过将参考坐标系改为前一帧体坐标系,计算两帧间的相对运动。本文详细解读了预积分的连续和离散形式,并提供了相关代码解析。
摘要由CSDN通过智能技术生成

点击上方“计算机视觉life”,选择“星标”

快速获得最新干货

VIO 中,如果在世界坐标系中对 IMU 进行积分,积分项中包含体坐标系相对于世界坐标系的瞬时旋转矩阵。然而,在优化位姿时,关键帧时刻体坐标系相对于世界坐标系的旋转矩阵会发生变化,那么需要对 IMU 重新进行积分。预积分就是为了避免这种重复积分。IMU 预积分将参考坐标系改为前一帧的体坐标系,从而积出了两帧之间的相对运动。

预积分

将第 k 帧和第 k+1 帧之间的所有 IMU 进行积分,可得第 k+1 帧的位置、速度和旋转(PVQ),作为视觉估计的初始值,示意图如下:

3ed033bb70e8e5e93b3783f7c6eb69ca.png

29f86d5174c07e482df69db52ab98c40.png

(点击图片放大看公式)

连续形式

be8113ccc6c5428c158fd65942a098c6.png

4280e5e3dc863aca3aa1e1384321f0dc.png

离散形式

b90ccaa82c148f3a84c0281a37201212.png

//采用的是中值积分的传播方式
Vector3d un_gyr = 0.5 * (gyr_0 + angular_velocity) - Bgs[j];
Rs[j] *= Utility::deltaQ(un_gyr * dt).toRotationMatrix();
Vector3d un_acc_1 = Rs[j] * (linear_acceleration - Bas[j]) - g;
Vector3d un_acc = 0.5 * (un_acc_0 + un_acc_1);
Ps[j] += dt * Vs[j] + 0.5 * dt * dt * un_acc;
Vs[j] += dt * un_acc;

(左右滑动试试)

b8958f16188f64c47d80e7242a314f60.png

f6ac4f8908f79fce99566b9f1d632e58.png

F:

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();

(左右滑动试试)

V:

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;

(左右滑动试试)

离散形式的 PVQ 增量误差的 Jacobian 和协方差

78a5aa40b7e64b6f1e14bb9de488a139.png

对应代码在integration_base.h文件的midPointIntegration():

jacobian = F * jacobian;
covariance = F * covariance * F.transpose() + V * noise * V.transpose();

ccd19ed5f6e493eb533810007ff2941e.png

从零开始学习三维视觉核心技术SLAM,扫描查看介绍,3天内无条件退款

3d81a1a53ae7e5dd5df540d9375686bb.png早就是优势,学习切忌单打独斗,这里有教程资料、练习作业、答疑解惑等,优质学习圈帮你少走弯路,快速入门!

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、算法竞赛、图像检测分割、人脸人体、医学影像、自动驾驶、综合等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

ec4551241a13af931a808d9c5cc5b11a.png

推荐阅读

从零开始一起学习SLAM | 为什么要学SLAM?

从零开始一起学习SLAM | 学习SLAM到底需要学什么?

从零开始一起学习SLAM | SLAM有什么用?

从零开始一起学习SLAM | C++新特性要不要学?

从零开始一起学习SLAM | 为什么要用齐次坐标?

从零开始一起学习SLAM | 三维空间刚体的旋转

从零开始一起学习SLAM | 为啥需要李群与李代数?

从零开始一起学习SLAM | 相机成像模型

从零开始一起学习SLAM | 不推公式,如何真正理解对极约束?

从零开始一起学习SLAM | 神奇的单应矩阵

从零开始一起学习SLAM | 你好,点云

从零开始一起学习SLAM | 给点云加个滤网

从零开始一起学习SLAM | 点云平滑法线估计

从零开始一起学习SLAM | 点云到网格的进化

从零开始一起学习SLAM | 理解图优化,一步步带你看懂g2o代码

从零开始一起学习SLAM | 掌握g2o顶点编程套路

从零开始一起学习SLAM | 掌握g2o边的代码套路

从零开始一起学习SLAM | ICP原理及应用

从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧

可视化理解四元数,愿你不再掉头发

视觉SLAM技术综述

研究SLAM,对编程的要求有多高?

深度学习遇到SLAM | 如何评价基于深度学习的DeepVO,VINet,VidLoc?

现在开源的RGB-D SLAM有哪些?

详解 | SLAM回环检测问题

汇总 | SLAM、重建、语义相关数据集大全

吐血整理 | SLAM方向国内有哪些优秀的公司?

最强战队 | 三维视觉、SLAM方向全球顶尖实验室汇总

SLAM方向公众号、知乎、博客上有哪些大V可以关注?

汇总 | 最全 SLAM 开源数据集

综述 | SLAM回环检测方法

干货总结 | SLAM 面试常见问题及参考解答 2019 最新SLAM、定位、建图求职分享,看完感觉自己就是小菜鸡! 2019暑期计算机视觉实习应聘总结

2018年SLAM、三维视觉方向求职经验分享

经验分享 | SLAM、3D vision笔试面试问题

最新AI干货,我在看  9b4958b617484ddcc6431cbe8c13a141.gif

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值