1.简介
ROVIO全称是Robust Visual Inertial Odometry,鲁棒视觉-惯性里程计,由ETHZ的Michael Bloesch在2017年提出。相比于单纯视觉信息,IMU弥补了视觉在一些因为光照变化强烈、弱纹理等原因无法对特征点进行跟踪的问题。而视觉又弥补了IMU随着时间延长而导致的漂移越来越大的问题。ROVIO核心是基于稀疏图像块的EKF实现的VIO。ROVIO属于紧耦合的VIO。因为作者将视觉信息加入到了状态变量中,与IMU所测量得到的信息进行了滤波融合。
本篇博客不过多涉及ROVIO理论,想了解更多可以参考论文。官方Github网页是这里。由于其Github文档中对于安装和使用写得不是很详细,所以这里就从代码编译和运行的角度介绍一下。
2.新建工作空间
因为ROVIO是基于ROS开发的,所以建议专门为它新建一个Catkin工作空间,方便管理。可以输入如下命令完成工作空间的创建和初始化。
mkdir -p rovio_workspace/src
cd rovio_workspace/src
catkin_make
这样工作空间就创建和初始化完成了,当然,为了方便使用,还可以将这个工作空间source一下加到.bashrc
文件里,这样就可以在任何地方调用了,gedit ~/.bashrc
打开文件,输入如下内容。
保存以后再source
一下即可。
3.源码下载
在我们刚刚创建的rovio_workspace/src
目录下,打开终端,然后输入如下命令将ROVIO克隆到本地。
git clone https://github.com/ethz-asl/rovio
这样,代码就下好了,先放在一边。
4.安装依赖
ROVIO的依赖其实比较少,主要就三个:ROS、Kindr、Lightweight_filtering。ROS就不用说了,如果还没装ROS,参考这篇博客。其中后两个是他们自己写的库,现在介绍如何安装。
(1) Kindr
Kindr是他们自己写的库,官网Github网页是这里。可以在rovio_workspace
目录下,打开终端,然后输入如下命令将Kindr克隆到本地。
git clone https://github.com/ethz-asl/kindr.git
cd kindr
mkdir build
cd build
cmake ..
make install
这样就完成了Kindr的安装,当然如果卸载也非常简单make uninstall
即可。
(2) Lightweight_filtering
这同样是他们写的工具,在rovio_workspace/src/rovio
目录下打开终端,输入如下内容即可下载代码。
git submodule update --init --recursive
(3) 其它依赖
ROVIO可以选择是否搭配OpenGL Scene。如果编译的时候搭配了OpenGL Scene,那么在运行的时候就会出现一个如下所示的可视化界面。 否则,就没有上面的这个可视化界面。如果需要搭配OpenGL Scene的话,还需要安装OpenGL、GLUT、GLEW。如果你之前有在电脑上源码编译过OpenCV,基本上就不需要装什么东西了。当然,如果没有,可以输入如下命令安装。
apt-get install freeglue3-dev
apt-get install libglew-dev
这样依赖环境就配置好了。
5.编译源码
回到我们建立的工作空间根目录rovio_workspace
下,打开终端,然后输入如下命令进行编译。
# 两者选其一
# 不搭配OpenGL Scene可视化界面
catkin_make rovio --cmake-args -DCMAKE_BUILD_TYPE=Release
# 搭配OpenGL Scene可视化界面
catkin_make rovio --cmake-args -DCMAKE_BUILD_TYPE=Release -DMAKE_SCENE=ON
# 然后再编译一下
catkin_make
6.运行测试
我们可以打开rovio_workspace/src/rovio/launch
目录,可以看到有三个launch文件,分别是rovio_node.launch
、rovio_rosag_node.launch
、valgrind_rovio.launch
。第一个是针对实时或者播放rosbag的形式开发的节点,第二个是针对已有的rosbag文件开发的节点,第三个是利用Valgrind进行内存泄漏检测的节点。
(1) rovio_node节点
打开rovio_node.launch
文件,我们可以看到相关配置信息是在cfg
文件夹下面的。
如果需要跑不同数据,只需要照葫芦画瓢地写个文件,并在launch文件里指向它就可以了。这里我们就以EuRoC数据集为例进行演示。首先,我们播放RosBag,比如rosbag play MH_03_medium.bag
。然后再任意打开一个终端,输入roslaunch rovio rovio_node.launch
,即可启动ROVIO节点,如下。
这样,ROVIO就顺利运行起来了。
(2) rovio_rosbag_node节点
这个节点其实和上面的节点运行起来效果是一样的,只不过是直接在launch文件中传入rosbag文件的路径,不需要手动播放了。我们可以打开rovio_rosbag_node.launch
文件,如下。
可以看到参数都比较好理解,对应修改即可。这其中最关键的就是rosbag_filename
这个参数了,要指定对才可以,当然还有Topic的参数也不能错。修改好以后,我们直接在终端中输入如下内容即可启动节点。
roslaunch rovio rovio_rosbag_node.launch
当然,这里有个隐性的错误,你可能会有如下报错。
说是无法打开文件什么的。这是因为在运行这个节点的时候,ROVIO还会在你rosbag文件所在的目录下输出一系列的log文件。但是一般情况下你rosbag目录下是不会有rovio
这个文件夹的,所以就会报错。因此这个问题的解决也很简单,那就是在你rosbag目录下新建一个rovio
文件夹就可以了。运行效果如下。
7.RViz可视化
虽然说我们在用rovio_node
节点的时候会出现可视化界面,但毕竟和我们期望的还有些差距。我们想看到估计的运动轨迹。这时就需要RViz帮忙了。我们首先启动ROVIO节点,然后播放Bag文件。然后在终端中输入rviz
启动RViz,如果不出意外的话你会遇到下面的错误。
说Global Status有错误。这个错误其实非常简单,原因就是我们没有固定住世界坐标系。从报错的情况来看,他说map这个Fixed Frame并不存在。我们在上面的Global Options中可以看到,默认的Fixed Frame就是map。所以我们可以点击进行切换,把Fixed Frame换到world即可。
然后我们就可以点击RViz左下角的Add按钮,在弹出的对话框中选择“By Topic”。在下面找到/rovio/odometry
点击OK即可进行订阅,然后就可以动态展示估计的位姿了。
8.视觉与IMU融合
所谓视觉与IMU的紧耦合和松耦合是这样定义的。松耦合的方法采用独立的惯性定位模块和定位导航模块,两个模块更新频率不一致,模块之间存在一定的信息交换。在松耦合方式中以惯性数据为核心,视觉测量数据修正惯性测量数据的累积误差。松耦合方法中视觉定位方法作为一个黑盒模块,由于不考虑IMU信息的辅助,因此在视觉定位困难的地方不够鲁棒,另外该方法无法纠正视觉测量引入的漂移。紧耦合方式使用IMU完成视觉VO中的运动估计,IMU在图像帧间的积分的误差比较小,IMU的数据可用于预测帧间运动,加速完成点匹配,完成VO位姿估计。相对于松耦合,紧耦合的另外一个优点是IMU的尺度度量信息可以用于辅助视觉中的尺度的估计。 此外,根据处理方式的不同还可以进一步分为基于滤波器的松/紧耦合和基于优化的松/紧耦合方案。ROVIO将图像块特征直接融合到了特征向量中,属于典型的紧耦合框架。同时后端使用IEKF作为滤波方式,因此是基于滤波器的紧耦合框架。因此一些紧耦合框架的优缺点它也都有。另外,由于他利用稀疏的影像块,因此,计算量相对小一些,但对于不同的设备需要调整参数,会对精度造成影响。缺点是没有闭环模块、Mapping线程,因此对于误差累积的处理还有进一步提升空间。
最后,放一张ORB-SLAM3论文里的各类VO/SLAM方法的对比表格,总结得很全面,有很大的参考价值。
9.参考资料
- [1] https://github.com/ethz-asl/rovio
- [2] https://github.com/ethz-asl/kindr
- [3] https://www.cnblogs.com/youzx/p/6291368.html
- [4] https://blog.csdn.net/a7691176/article/details/101353168
- [5] https://blog.csdn.net/danmeng8068/article/details/80846027
- [6] https://blog.csdn.net/weixin_40358083/article/details/83088591
- [7] https://blog.csdn.net/xiaoxiaowenqiang/article/details/81192045
本文作者原创,未经许可不得转载,谢谢配合