Advertisement

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

阅读量:

本文主要介绍了VINS(VIO或SLAM传感器融合的必读经典)的分析与代码分享。作者计划从原理到代码逐步刷通VINS,并解释其中的每一个数据结构及其作用。文章列出了多个VINS系列的GitHub开源项目,包括VINS-mono、VINS-Fusion和VINS-course,并提到基于VINS-mono开发的双目VIO系统。此外,作者详细解析了VINS-mono的各个部分,包括前端特征提取、后端优化(如预积分、滑窗和回环检测)以及初始化流程。文章还介绍了VINS系统的启动流程,包括使用roslaunch脚本启动节点和使用evo进行性能测试。最后,作者分享了多个VINS系统的解析博客链接,供读者进一步学习。

目前网上关于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-Mono

我的GitHub仓库https://github.com/iwander-all/vins-mono-self-improved/对vins-mono进行了少量的优化,具体修改内容可参考这篇介绍。此外,基于vins-mono开发了一个双目vio系统https://github.com/iwander-all/VINS-Dual-VINS-Mono-VIO/,感谢沈老师课题组的开源支持。

原创内容,转载请先与我联系并注明出处,谢谢!

各个部分的讲解如下链接:

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

SLAM

SLAM

SLAM

SLAM

同时定位与地图构建

同时定位与地图构建

SLAM

SLAM

解析

SLAM

SLAM

SLAM

SLAM

SLAM

SLAM

SLAM

SLAM

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

SLAM

SLAM

SLAM

SLAM

SLAM

相比之前上学时刚开始学习SLAM,现在不再有精力进行逐行解析,而是将注意力转向搭建开源框架时的流程图记录作为学习记录。

SLAM

SLAM

【SLAM】LIO-SAM流程图

【SLAM】ORB-SLAM2 流程图

1.总体布局

原论文:

初始化操作在正常运行周期内仅执行一次。前端系统持续不断地从数据源提取特征点并传递给后端系统;后端系统则负责对IMU数据进行预积分处理,并结合优化算法或滑窗技术进行数据优化。在运行周期中,前端和后端系统持续进行数据交互与处理。

或者,

在这里插入图片描述

该系统包含以下几个步骤:特征提取及发布、IMU采集与预积分、初始化、滑动窗口与优化、环检测。

代码主要由三个节点构成,其中feature_tracker主要负责特征点的提取与发布,pose_graph则承担关键帧的选取、位姿图的构建以及回环检测的任务。vins_estimator节点功能最为丰富,不仅涵盖了初始化、滑窗优化等后端功能,还整合了IMU预积分等前端处理,并在此节点中划分了两个独立的线程。

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

在这里插入图片描述

VINS系统中,前端仅负责光流计算,而初始化相关工作则整合到vins_estimator模块中。
我认为,VINS系统采用这种设计主要是因为如果将IMU数据处理放在前端,经过预积分后仍需通过advertise指令发送至ROS系统,以便后端接收处理。相比之下,直接将IMU数据传输至后端进行处理,可以减少不必要的通信开销。

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

在这里插入图片描述

或者更具体一些,

在这里插入图片描述

2.VINS系统的启动

启动VINS系统时,首先执行一下bash文件,启动roscore脚本,然后就是启动launch文件了,这些内容包括:

复制代码
    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/../" />

这里定义了两个路径,这两个路径在代码中频繁使用。其中,config_path表示配置文件的路径。要找到config_path的路径,首先,找到find feature_tracker所在的路径,然后返回其父目录,最后在config/euroc文件夹中查找euroc_config.yaml配置文件,该文件中定义了ROS主题、相机参数、特征提取的极限值以及IMU参数。

就是vins_path,主要所有的程序都是基于这个路径,它是feature_tracker的上级组件。

例如,以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>

令人惊喜地超越了性能的水平,我认为这得益于其简洁的设计和高效的代码结构。

读到了一篇非常优秀的文章,<>,尽管阅读量不高,但写作风格独到。我决定不再重复阐述,现附上文章链接。

参考文献:

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

全部评论 (0)

还没有任何评论哟~