【SLAM】VINS-MONO解析——综述

82
0
5天前

目前网上有很多分析文章,但是都只是一些比较基础的原理分析,而且很多量,虽然有推倒,但是往往没有讲清楚这些量是什么,为什么要有这些量,这些量是从哪来的,也没有刷通整个代码,或者太简练了,对新手不友好。这一次我计划从原理/代码一步步刷通整个VINS,并且说清楚代码中遇到的每一个数据结构对应的作用是什么。vins系列可以说是vio或者是SLAM传感器融合的必读经典巨作,希望你能从我的分享中有所收获。

 

github官方上开源了VINS-mono,VINS-Fusion和VINS-mobile,还有另一个VINS-course是贺一家基于VINS-MONO的手写后端版(不用ceres/ROS)的代码,这个代码对VINS的理解,尤其是后端的理解非常有帮助。

 

后续有时间的话,我会写一下vins-fusion的全流程解析。实际上,mono和fusion的区别不是很大,如果mono彻底明白了,fusion(的主流程也)很好理解的。

 

官方链接:vins-monovins-fusionvins-mobile

 

我的github请点击此处,对vins-mono进行了一些小的修改,修改的地方请见此处的介绍。另外,我根据vins-mono开发了一个双目vio系统,感谢沈老师课题组的开源。

 

各个部分的讲解内容如下:

【SLAM】VINS-MONO解析——综述

【SLAM】VINS-MONO解析——feature_tracker

【SLAM】VINS-MONO解析——IMU预积分

【SLAM】VINS-MONO解析——vins_estimator

【SLAM】VINS-MONO解析——初始化(理论部分)

【SLAM】VINS-MONO解析——初始化(代码部分)

【SLAM】VINS-MONO解析——后端优化(理论部分)

【SLAM】VINS-MONO解析——后端优化(代码部分)

【SLAM】VINS-MONO解析——sliding window

【SLAM】VINS-MONO解析——回环检测

【SLAM】VINS-Fusion解析——流程

【SLAM】VINS-MONO解析——对vins-mono的修改使流程逻辑更清晰

【SLAM】VINS-MONO解析——基于vins-mono的slam系统开发

【SLAM】面试常见问题

1.总体布局

原论文:

【SLAM】VINS-MONO解析——综述插图

在正常运行过程中,初始化只进行一次。前端负责不断地提取特征点发给后端;后端负责IMU数据采集,预积分和优化/滑窗等操作。前端和后端在运行过程中不断地循环。

或者,

 

【SLAM】VINS-MONO解析——综述插图(1)

 

这个系统包括以下几个过程:特征提取与发布;IMU提取与预积分;初始化;滑窗与优化;回环检测。

 

代码主要包括3个node:feature_tracker,vins_estimator,pose_graph,其中feature_tracker仅负责特征点提取和发布,pose_graph关键帧的选择/位姿图建立/回环检测,而vins_estimator的内容最多了,包含了初始化,滑窗,优化等后端内容和IMU预积分等前端内容,并且在这个结点里分出了2个线程。

 

一般来讲,一个标准的SLAM系统是前后端分离的,如下图所示,

 

【SLAM】VINS-MONO解析——综述插图(2)

 

而VINS系统,他的前端仅包括光流计算;初始化等工作都放在vins_estimator里面了。

 

我的理解它之所以这么做,是因为IMU的数据获取如果放在前端,预积分完了之后还需要advertise到ROS系统里,让后端接收,与其这样,还不如让后端直接接收IMU数据就在后端处理了,减少通信过程。

 

VINS结点通信过程如下图所示,

 

【SLAM】VINS-MONO解析——综述插图(3)

 

或者更具体一些,

 

【SLAM】VINS-MONO解析——综述插图(4)

 

2.VINS系统的启动

启动VINS系统时,首先source一下bash文件,roscore,然后就是启动lauch文件了,它们包括:

roslaunch vins_estimator euroc.launch 
roslaunch vins_estimator vins_rviz.launch
rosbag play YOUR_PATH_TO_DATASET/MH_01_easy.bag

 

首先看一下euroc.launch文件的内容,它在source/vins_estimator/launch目录下。

2.1 euroc.launch文件

2.1.1 launch文件内的局部变量配置

<arg name="config_path" default = "$(find feature_tracker)/../config/euroc/euroc_config.yaml" />
  <arg name="vins_path" default = "$(find feature_tracker)/../config/../" />

 

这里定义了两个path,而这两个path在代码中大量出现,第一个是config_path,即配置文件的路径。后面内容的意思是要想找到config_path的路径,首先先找到find feature_tracker所在路径,然后返回上一层目录,再找到config/euroc文件夹下的euroc_config.yaml配置文件,里面定义了ROS topic,相机参数,特征提取的极限值,IMU参数。

 

然后就是vins_path,基本上所有的程序都是基于这个路径,它是feature_tracker的上一层。

 

2.2.2 node结点的定义

就以feature_tracker为例,后面都是一样的,内容很好理解。

<node name="feature_tracker" pkg="feature_tracker" type="feature_tracker" output="log">
    <param name="config_file" type="string" value="$(arg config_path)" />
    <param name="vins_folder" type="string" value="$(arg vins_path)" />
</node>

 

注意,vins_pose多了4个变量的定义:

<param name="visualization_shift_x" type="int" value="0" />
<param name="visualization_shift_y" type="int" value="0" />
<param name="skip_cnt" type="int" value="0" />
<param name="skip_dis" type="double" value="0" />

 

visualization_shift_x和visualization_shift_y表示在进行位姿图优化后,对得到的位姿在x坐标和y坐标的偏移量(一般都设为0);
skip_cnt在pose_graph_node的process()中,表示每隔skip_cnt个图像帧才进行一次处理;
skip_dis也在pose_graph_node的process()中,目的是将距上一帧的时间间隔超过SKIP_DIS的图像创建为位姿图中的关键帧。

 

2.2 vins_rviz.launch文件

打开rviz进行可视化。

<launch>
    <node name="rvizvisualisation" pkg="rviz" type="rviz" output="log" args="-d $(find vins_estimator)/../config/vins_rviz_config.rviz" />
</launch>

 

2.3 利用evo进行性能测试

看到了一个非常好的文章,https://blog.csdn.net/Hanghang_/article/details/104535370,虽然目前阅读量不高,但是写的真好,我就不再重复写了,这里附上链接。

参考文献:

《VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator》 秦神
《从零开始手写VIO》贺神,高神,崔神;
《VINS论文推导及代码解析》崔神;
《主流VIO技术综述及VINS解析》崔神;
《因子图的理论基础》董靖博士;
《SLAM十四讲》高神;
https://blog.csdn.net/qq_41839222/article/details/85793998 Manii;
《古月 · ROS入门21讲》古月神

发表评论

后才能评论