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。
