Bootstrap

VINS-Mono笔记01_VINS-Mono的编译运行

本笔记记录在Ubuntu18.04下基于Ruroc数据集编译运行VINS-Mono项目的过程.

编译VINS-Mono

安装ROS

关于ROS安装的教程很多,随便找一篇照着做就行.为提升速度,可以将软件源换成国内源.

安装OpenCV,Eigen3和Ceres

OpenCV和Eigen3可以用apt命令安装:

sudo apt -y install libopencv-dev		# 安装OpenCV
sudo apt -y install libeigen3-dev		# 安装Eigen3

Ceres不在apt仓库内,因此需要通过源码安装.主要步骤就是cmake,再make && make install,在网上随便搜一篇教程照着做就行.

创建ROS工作空间

所有ROS程序都必须放置在某个ROS工作空间(workspace)下,我们在家目录下创建一个名为catkin_ws的ROS工作空间(ROS工作的空间名字可以随便取,一般约定俗成以_ws结尾).

mkdir -p ~/catkin_ws/src		# 递归创建工作空间及其下的src目录
cd ~/catkin_ws/src				# 移动到工作空间下的src目录
catkin_init_workspace			# 初始化工作空间

可以看到,在~/catkin_ws/src路径下创建了一个CMakeLists.txt文件.

一个典型的ROS工作空间目录结构如下:

catkin_ws/         			# 工作空间
├── src/                   	  # src目录放置源码
│   ├── CMakeLists.txt          # 顶层CMakeLists.txt
│   ├── package_1/				# ROS包1
│   ├── package_2/				# ROS包2
│   └── package_n/				# ROS包n
├── build/                    # build目录放置编译结果
├── devel/                    # devel目录放置开发相关文件
│   └── setup.bash              # 运行该脚本才能让该工作空间下的包被ROS发现
└── install/                  # install目录放置安装相关文件

src目录下存放的是我们写的源码,builddevelinstall目录都是ROS在编译过程中为我们生成的,不需要我们创建或修改.

导入ROS包

ROS程序是以ROS包(package)的形式组织的,一系列相关的程序(节点,node)被组织成一个ROS包,放置在工作空间的src路径下.

VINS-Mono程序实际上包含了6个包: feature_tracker, vins_estimator, ar_demo, benchmark_publisher, camera_model, pose_graph.我们将整个VINS-Mono项目的代码放在catkin_ws/src下,得到的目录结构如下:

catkin_ws/         				# 工作空间
└── src						  	  # src目录放置源码
    └── VINS-Mono
        ├── feature_tracker			# ROS包feature_tracker,用于前段光流
        ├── pose_graph				# ROS包pose_graph,用于位姿图优化
        ├── vins_estimator			# ROS包vins_estimator,用于预积分
        ├── ar_demo					# ROS包ar_demo,用于展示AR的demo
        ├── benchmark_publisher		# ROS包benchmark_publisher,用于发布groun truth
        ├── camera_model			# ROS包camera_model,用于提供相机模型
        └── config					# 配置文件目录,非ROS包

值得注意的是,与上文中ROS工作空间目录示意图略有不同的是,我们的ROS包并非放置在ROS工作空间src目录的直接下层,而是间隔了一层VINS-Mono目录,这也是允许的.

ROS包的标志是其直接路径下package.xml文件,该文件记载了该ROS包的信息,例如feature_tracker包的package.xml内容如下:

<?xml version="1.0"?>
<package>
	<name>feature_tracker</name>
	<version>0.0.0</version>
	<description>The feature_tracker package</description>

	<maintainer email="[email protected]">dvorak</maintainer>
	
    <license>TODO</license>

    <buildtool_depend>catkin</buildtool_depend>
	<build_depend>roscpp</build_depend>
	<build_depend>camera_model</build_depend>
	<build_depend>message_generation</build_depend>
	<run_depend>roscpp</run_depend>
	<run_depend>camera_model</run_depend>
	<run_depend>message_runtime</run_depend>
</package>

编译

在工作空间~/catkin_ws下使用catkin_make命令即可编译ROS包.

catkin_make			# 编译当前工作空间下的所有ROS包

编译完成后,可以看到工作空间下多出了builddevel目录,目录结构如下:

catkin_ws/         			# 工作空间
├── src
│   └── VINS-Mono
│       ├── feature_tracker			
│       ├── pose_graph			
│       ├── vins_estimator		
│       ├── ar_demo					
│       ├── benchmark_publisher		
│       ├── camera_model			
│       └── config					
├── build/                    
└── devel/
    └── setup.bash

其中devel目录下有setup.bash脚本,运行该脚本才能让工作空间下的包被ROS发现.因此每次运行VINS-Mono程序之前,都要先运行该setup.bash脚本:

source ~/catkin_ws/devel/setup.bash

每次启动命令行都执行一遍上面命令比较麻烦,因此一般将上调命令加入到~/bashrc脚本的最后一行.~/bashrc在每次启动命令行时自动执行,因此我们添加source ~/catkin_ws/devel/setup.bash命令也被执行,从而使VINS-Mono的包被ROS发现.

运行VINS-Mono

运行ROS节点

ROS中,程序被称为ROS节点(node),不准确地说,一个包含main函数的完整程序就是一个ROS节点.VINS-Mono程序包含很多ROS节点.

在运行ROS节点之前,应先启动一个命令行窗口,执行roscore命令启动一个ROS核心,才能执行其他的ROS命令.

roscore		# 启动一个ROS核心

运行ROS节点的命令格式如下:

rosrun ROS包名 ROS节点名 [参数1:=值1 参数2:=值2]

例如想要运行feature_tracker包中的feature_tracker节点,需要执行以下命令:

roscore&rosrun feature_tracker feature_tracker _config_file:=~/learning_ros_ws/src/VINS-Mono/config/euroc/euroc_config.yaml _vins_path:=~/learning_ros_ws/src/VINS-Mono

运行launch文件

一个完整的应用通常包含很多个ROS节点,一次使用rosrun命令启动这些节点并配置参数较为麻烦,因此将一系列节点和运行参数写进launch文件中,通过roslaunch命令一次启动多个节点.

launch文件一般放在ROS包下的launch目录,例如使用VINS-Mono运行Euroc数据集对应的luanch文件是euroc.launch,位于vins_estimator包下,其完整路径为~/catkin_ws/src/VINS-Mono/vins_estimator/launch/euroc.launch.

launch文件是以xml形式组织的,例如euroc.launch文件内容如下:

<launch>	
    <!-- 全局参数config_path和vins_path -->    
    <arg name="config_path" default="$(find feature_tracker)/../config/euroc/euroc_config.yaml"/>    
    <arg name="vins_path" default="$(find feature_tracker)/../config/../"/>    
    
    <!-- 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_estimator包下的vins_estimator节点 -->    
    <node name="vins_estimator" pkg="vins_estimator" type="vins_estimator" output="screen">        
        <param name="config_file" type="string" value="$(arg config_path)"/>        
        <param name="vins_folder" type="string" value="$(arg vins_path)"/>    
    </node>    
    
    <!-- pose_graph包下的pose_graph节点 -->    
    <node name="pose_graph" pkg="pose_graph" type="pose_graph" output="screen">        
        <param name="config_file" type="string" value="$(arg config_path)"/>        
        <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"/>    
    </node>
</launch>

运行roslaunch文件的命令格式如下:

rosrun ROS包名 launch文件名

ROS会自动在第一次运行launch文件的窗口调用roscore(可以理解为每个launch文件都有一个缺省的roscore节点),因此只需要一个命令行窗口就可以运行所有相关的ROS节点.

例如,想要运行euroc.launch,命令如下

roslaunch vins_estimator euroc.launch 		# 运行vins_estimator包下的euroc.launch文件

执行上述命令后,命令行窗口内输出一系列调试信息,说明运行成功.

请添加图片描述

想实时查看VINS-Mono运行过程中的状态,还需要运行vins_estimator下的vins_rviz.launch,命令如下:

roslaunch vins_estimator vins_rviz.launch			# 运行vins_estimator包下的vins_rviz.launch文件

执行上述命令后,出现一个可视化窗口,说明运行成功.

请添加图片描述

准备数据

本次实验使用Euroc MAV数据集,需要下载bag格式的数据集,放置在任意路径下,例如本次下载其中的MH_01_easy.bag数据集,放置在~/Dataset/MH_01_easy.bag路径下.

请添加图片描述

ROS bag是ROS支持的一种数据集格式,文件后缀名为.bag,一个ROS bag中可以包含多组不同格式不同来源的数据,使用rosbag命令对其进行操作.

rosbag play命令用来播放ROS bag,也就是将ROS bag中的数据信息发送给ROS系统,从而发送给需要对应数据的ROS节点,rosbag play的命令格式如下:

rosbag play bag路径

例如要播放本次实验下载的MH_01_easy.bag,命令如下:

rosbag play ~/Dataset/MH_01_easy.bag		# 播放对应路径下的MH_01_easy.bag数据集

在播放ROS bag数据集前应先运行上节提到的两个launch文件.

执行上述命令后,VINS-Mono开始运行,可视化界面显示实时信息,说明运行成功.

请添加图片描述

查看节点间的关系

ROS话题(ROS topic)是ROS中信息传递的最基本方式,节点之间通过发布和订阅一系列话题实现通信,上节的rosbag play命令本质上是启动了一个/play节点,发布对应的ROS话题.

使用rqt_graph命令可以看到当前ROS系统中所有节点和话题,结果如下:

rqt_graph

下图中椭圆表示节点,方块表示话题.可以看到,/play节点发布了/cam0/imu0两个话题,分别对应相机和IMU数据,VINS-Mono的各节点订阅对应的话题,且VINS-Mono的节点间也是以话题的形式进行通信的.

请添加图片描述

;