ORBSLAM2在ROS下运行

Posted 小C酱油兵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORBSLAM2在ROS下运行相关的知识,希望对你有一定的参考价值。


 ORBSLAM2运行ROS节点障碍

  ORBSLAM2提供了与ROS耦合的应用程序,放在单独的ROS文件夹中。同样的,它提供了与ROS无关联的同类型的应用程序。不过,为了方便,笔者主要测试了它在ROS下的应用程序,因为笔者的摄像头是用ROS提供的openni2来驱动的,所以可以利用相机主题直接为ORBSLAM2提供输入图像。不过,笔者在跑通这个程序的过程中遇到了一些障碍,所以在此做个总结。

  问题1:ROS路径设置的问题

  问题2:cv_bridge的opencv版本冲突的问题;


ROS路径设置的问题

  由于ORBSLAM2中设置了rosbuild_init(),而我们编译文档之前需要先关联工作区间。ORBSLAM2这里提供的这个文档中,并没有我们熟悉的ROS里的package.xml和devel这些文件,所以起初笔者在编译的时候,一直不知道该怎么办?

  直接编译会显示ORBSLAM2路径冲突之类的问题,具体错误是:

  [rosbuild] rospack found package "ORB_SLAM2" at "", but the current directory is "/home/xiaoC/ORB_SLAM2/Examples/ROS/ORB_SLAM2"

  当然,后面这个路径就是笔者放ORBSLAM2的路径。这个显示的错误表示ROS环境并没有设置正确。

  因此,笔者首先在~/.bashrc上设置了路径:

sudo vim ~/.bashrc
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/xiaoC/ORB_SLAM2/Examples/ROS
source ~/.bashrc

  注意,后面这个path是笔者的路径,不同用户路径不同。

  理论上,这个应该要work的,不过遗憾的是,并没有。如何确认有没有work呢?方法是:

echo $ROS_PACKAGE_PATH

  如果终端显示了笔者刚刚加入的路径,说明ROS路径配置成功了,遗憾的是,并没有。

  具体可以参考:https://github.com/raulmur/ORB_SLAM2/issues/url

  后来,笔者继续查找原因,发现添加的路径的位置好像错了,于是在ROS的安装路径下更改路径:

cd /opt/ros/indigo/
sudo vim setup.bash 
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/xiaoC/ORB_SLAM2/Examples/ROS
source setup.bash

  同样,我们可以用两种方式来确认路径添加成功了没有,第一种就是我们上面提到的echo,第二种是:

roscd ORB_SLAM2

  如果能进入这个文件夹,说明我们路径设置成功了。

  具体可以参考:https://www.cnblogs.com/xy123001/p/6918334.html

  于是,通过这个设置,笔者便把ROS编译这关通过了。


 cv_bridge的opencv版本冲突的问题

  接下来就是这个大问题,困扰了笔者一个下午的时间,都没搞定。后来吃了个晚饭回来,就解决了。所以说,精神食粮贫乏的时候,需要真正的食量来激发灵感。

  这个问题主要出现的位置是,在笔者运行RGBD节点的时候:

rosrun ORB_SLAM2 RGBD ../../../Vocabulary/ORBvoc.txt ./Asus.yaml

  显示的错误主要是opencv版本冲突。其实这个问题在前面编译的时候就提醒过我们,提示内容:

. . .
[ 33%] [100%] [100%] Building CXX object CMakeFiles/Stereo.dir/src/ros_stereo.cc.o
Building CXX object CMakeFiles/Mono.dir/src/ros_mono.cc.o
Building CXX object CMakeFiles/RGBD.dir/src/ros_rgbd.cc.o
Linking CXX executable ../Mono
/usr/bin/ld: warning: libopencv_core.so.3.0, needed by ../../../../lib/libORB_SLAM2.so, may conflict with libopencv_core.so.2.4
[100%] Built target Mono
Linking CXX executable ../RGBD
Linking CXX executable ../Stereo
/usr/bin/ld: warning: libopencv_core.so.3.0, needed by ../../../../lib/libORB_SLAM2.so, may conflict with libopencv_core.so.2.4
[100%] Built target RGBD
/usr/bin/ld: warning: libopencv_imgproc.so.3.0, needed by ../../../../lib/libORB_SLAM2.so, may conflict with libopencv_imgproc.so.2.4
[100%] Built target Stereo

  不过笔者并没有多在意,直接就跳过了,寻思着编译能通过,应该没问题的。毕竟对于程序员来说,warning见怪不怪,error才是大头。

  后来分析了一下原因:笔者用来编译ORBSLAM2的opencv版本是3.2.0,而ros indigo自带的opencv版本是2.4.x的。在运行ROS节点的时候,调用了liborbslam2.so,这里链接了opencv 3.2.0的版本,而cv_bridge是连接到2.4.x的版本,所以形成了冲突。具体运行错误:

OpenCV Error: Bad argument (Invalid pointer to file storage) in cvGetFileNodeByName, file /build/buildd/opencv-2.4.8+dfsg1/modules/core/src/persistence.cpp, line 740
terminate called after throwing an instance of \'cv::Exception\'
what(): /build/buildd/opencv-2.4.8+dfsg1/modules/core/src/persistence.cpp:740: error: (-5) Invalid pointer to file storage in function cvGetFileNodeByName

Aborted (core dumped)

  为了更好地看到问题是什么,笔者在RGBD所在节点下看了一下链接情况:

ldd RGBD | grep opencv
libopencv_imgproc.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.2.4 (0x00007f67d053f000)
    libopencv_highgui.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4 (0x00007f67d02f4000)
    libopencv_core.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4 (0x00007f67cfebc000)
    libopencv_core.so.3.2 => /usr/local/lib/libopencv_core.so.3.2 (0x00007f67ced2b000)
    libopencv_imgproc.so.3.2 => /usr/local/lib/libopencv_imgproc.so.3.2 (0x00007f67cd4f7000)
    libopencv_contrib.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_contrib.so.2.4 (0x00007f67cac9b000)
    libopencv_calib3d.so.3.2 => /usr/local/lib/libopencv_calib3d.so.3.2 (0x00007f67c4db9000)
    libopencv_features2d.so.3.2 => /usr/local/lib/libopencv_features2d.so.3.2 (0x00007f67c4ae7000)
    libopencv_highgui.so.3.2 => /usr/local/lib/libopencv_highgui.so.3.2 (0x00007f67c48da000)
    libopencv_features2d.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_features2d.so.2.4 (0x00007f67c24fd000)
    libopencv_calib3d.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_calib3d.so.2.4 (0x00007f67c2266000)
    libopencv_ml.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_ml.so.2.4 (0x00007f67c1fee000)
    libopencv_video.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_video.so.2.4 (0x00007f67c1d9a000)
    libopencv_objdetect.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_objdetect.so.2.4 (0x00007f67c1b1f000)
    libopencv_flann.so.3.2 => /usr/local/lib/libopencv_flann.so.3.2 (0x00007f67ba0c1000)
    libopencv_imgcodecs.so.3.2 => /usr/local/lib/libopencv_imgcodecs.so.3.2 (0x00007f67b9e80000)
    libopencv_flann.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_flann.so.2.4 (0x00007f67b980b000)

  可以看到,这是一连串令人头皮发麻的链接库,又有3.2.0版本的,又有2.4.x版本的opencv。笔者琢磨了很久。

  当然,这个问题在github上的issue上还是开放的:https://github.com/raulmur/ORB_SLAM2/issues/118

  也有部分解决方案在这里:https://github.com/raulmur/ORB_SLAM2/issues/103

  但是这也确实解决不了我的问题,一方面是要autoremove opencv2.4,我看到要卸载很多软件,甚至包括图形界面,我就不打算尝试了。还有重建系统的,更加不考虑了,捡芝麻丢西瓜不合算。所以就继续寻找解决方案。

  有三个比较有参考价值的回答:

  1. https://blog.csdn.net/hansry/article/details/76764491

  2. https://github.com/introlab/rtabmap/issues/86

  3. https://www.cnblogs.com/cv-pr/p/5366764.html

  建议我们卸载原始的cv_bridge,然后重装新版本:

sudo apt-get remove ros-indigo-cv-bridge
git clone https://github.com/ros-perception/vision_opencv.git
catkin_make --pkg cv_bridge

  注意,上面是在ROS的工作区间中运行的。

  于是,ORBSLAM2的ROS节点便可以运行了。


 实际运行情况

1. RGBD

  首先,笔者用的是华硕xtion一代RGBD相机。直接用ROS提供的内部参数(当然,更重要的是标定深度相机的难度比较大),修改了ORBSLAM2中ROS节点里的Asus.yaml中的内参数。

  

  然后就是跑起来了,效果如下(由于没办法插入视频,笔者就只能放图片了):

  

  ORBSLAM2的效果是相当好的,不过笔者也测试了一下白墙、快速运动以及遮挡和光照突然从亮到暗以及从暗到亮三种情况。

  白墙:白墙这种情况,其实很难解决,毕竟ORBSLAM2用的是角点信息,没有纹理自然就没有特征点。不过值得注意的是,有时候从纹理多的地方稍微快一点运动到纹理较少的地方也是会丢的,只能往回走,靠重定位才能找回来。

  快速运动:这个快速运动的定义视情况而定,读者也可以根据自己的实际情况去做测试。笔者这里的快速运动主要是基本超过帧率的运动,这个一晃就丢了。不过只要有重叠区域,速度慢下来以后还是可以重定位成功的。

  遮挡:笔者还尝试了一下用手来遮挡相机,短时间内的遮挡,ORBSLAM2还是可以定位成功的,当然笔者只做了几秒左右的遮挡。

  光照变化:笔者在晚上做的测试,先在开灯的情况下定位,而后关掉灯光,ORBSLAM2一下就丢了,不过开灯以后能重新定位到。笔者也没有具体测试隔了多久开灯会定位失败。不过按照代码的形式,如果超过一定帧数没有定位到,ORBSLAM2就会判定定位丢失,进行重定位或者重置初始化。

2. AR

  除了RGBD节点,笔者还测试了Mono_AR这个节点,参数还是用了Asus.yaml里的,这个时候就直接用Xtion的RGB相机作为采集设备了,深度值没有用。

  跑起来的效果如下:

 

  刚开始启动的时候,笔者特别犯糊涂,为啥没有定位,一直显示SLAM未初始化。后来才发现,是ORBSLAM2要求单目初始化的条件特别苛刻。所以笔者在一个纹理特别多的地方停留了一会儿,然后稍微有一点平移,才使得初始化成功了。接着就是放置模型了。

  这个AR的定位效果还是特别鲁棒的,但是同样,上面RGBD存在的问题,AR也有。所以笔者就不赘述了。期待读者们能在此基础上有所突破。Enjoy。

  OK,今天就不总结了,因为这篇博客就是笔者昨天跑程序的笔记总结。希望对读者有所帮助。

PS:

  如果您觉得我的博客对您有所帮助,欢迎关注我的博客。此外,欢迎转载我的文章,但请注明出处链接。

  对本文有任何问题可以在留言区进行评论,也可以在泡泡机器人论坛:http://paopaorobot.org/bbs/index.php?c=cate&fid=1中的SLAM技术交流模块发帖提问。

  我的github链接是:https://github.com/yepeichu123/orbslam2_learn

 

 

  

  

以上是关于ORBSLAM2在ROS下运行的主要内容,如果未能解决你的问题,请参考以下文章

ROS环境下Android客户端与ORBSLAM2

[ros]编译ORBSLAM2时候,ros路径问题

KINECT2通过ROS在线跑ORBSLAM2

ORB SLAM2运行步骤/怎样跑通orbslam2

ORB SLAM2运行步骤/怎样跑通orbslam2

Ubuntu16.04下编译安装及运行单目ORBSLAM2