LSD-SLAM是一个semi-dense的直接法SLAM算法。
其主页见https://vision.in.tum.de/research/vslam/lsdslam?redirect=1
其代码见https://github.com/tum-vision/lsd_slam
官方在github上给出默认环境有两个
- ROS fuerte + Ubuntu 12.04
- ROS indigo + Ubuntu 14.04
因此推荐使用上面的环境,出错较少。下面是我在ROS kinetic + Ubuntu 16.04环境下实现LSD-SLAM的过程
1.安装ROS kinetic
这个地方一般不会有问题,请参考ROS wiki或者一些博客,如博客,根据博客安装、初始化并测试ROS。如果出错,请换个源或者VPN试试。
2.编译LSD-SLAM
1.创建rosbuild工作空间
# python默认版本应为2.7,或者下载python3-rosinstall
sudo apt-get install python-rosinstall
# 具体路径请自己更改
mkdir ~/rosbuild_ws
cd ~/rosbuild_ws
rosws init . /opt/ros/kinetic
mkdir package_dir
rosws set ~/rosbuild_ws/package_dir -t .
echo "source ~/rosbuild_ws/setup.bash" >> ~/.bashrc
bash
2.安装依赖
# 注意LSD-SLAM依赖qt4而不是qt5,请自行安装正确版本libqglviewer-dev-qt4
sudo apt-get install ros-kinetic-libg2o ros-kinetic-cv-bridge liblapack-dev libblas-dev freeglut3-dev libsuitesparse-dev libx11-dev
3.获取LSD-SLAM
cd package_dir
git clone https://github.com/tum-vision/lsd_slam.git lsd_slam
4.编译
rosmake lsd_slam
编译过程中不会一帆风顺,可能出现许多错。我出现的错如下:
error 1
# 报错信息
ERROR [gendeps] 1 Finding dependencies for /home/gjh/code/rosbuild_ws/package_dir/lsd_slam/lsd_slam_viewer/cfg/LSDSLAMViewerParams.cfg
......
Exception: quotes not allowed in description string `log10 of threshold on point's variance, in the respective keyframe's scale.
# 解决方法[1]
删除lsd_slam_viewer/cfg/LSDSLAMViewerParams.cfg和lsd_slam_core/cfg/LSDDebugParams.cfg两个文件中出现的单引号
error 2
# 报错信息
main_stitchVideos.cpp:(.text+0xd65c):对‘cv::imshow(cv::String const&, cv::_InputArray const&)’未定义的引用
main_stitchVideos.cpp:(.text+0xd668):对‘cv::String::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xd672):对‘cv::waitKey(int)’未定义的引用
main_stitchVideos.cpp:(.text+0xd715):对‘cv::fastFree(void*)’未定义的引用
main_stitchVideos.cpp:(.text+0xd7b5):对‘cv::fastFree(void*)’未定义的引用
main_stitchVideos.cpp:(.text+0xd84d):对‘cv::fastFree(void*)’未定义的引用
main_stitchVideos.cpp:(.text+0xd8e5):对‘cv::fastFree(void*)’未定义的引用
main_stitchVideos.cpp:(.text+0xd985):对‘cv::fastFree(void*)’未定义的引用
CMakeFiles/videoStitch.dir/src/main_stitchVideos.cpp.o:main_stitchVideos.cpp:(.text+0xda25): 跟着更多未定义的参考到 cv::fastFree(void*)
CMakeFiles/videoStitch.dir/src/main_stitchVideos.cpp.o:在函数‘inlayVid(int, char**)’中:
main_stitchVideos.cpp:(.text+0xdeb4):对‘cv::String::allocate(unsigned long)’未定义的引用
main_stitchVideos.cpp:(.text+0xdedf):对‘cv::Mat::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xdeec):对‘cv::Mat::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xdefd):对‘cv::Mat::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xdf0e):对‘cv::Mat::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xdf1f):对‘cv::Mat::deallocate()’未定义的引用
CMakeFiles/videoStitch.dir/src/main_stitchVideos.cpp.o:main_stitchVideos.cpp:(.text+0xdf30): 跟着更多未定义的参考到 cv::Mat::deallocate()
CMakeFiles/videoStitch.dir/src/main_stitchVideos.cpp.o:在函数‘inlayVid(int, char**)’中:
main_stitchVideos.cpp:(.text+0xdfb7):对‘cv::String::allocate(unsigned long)’未定义的引用
main_stitchVideos.cpp:(.text+0xe212):对‘cv::String::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xe23e):对‘cv::String::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xe26e):对‘cv::String::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xe282):对‘cv::String::deallocate()’未定义的引用
main_stitchVideos.cpp:(.text+0xe2a6):对‘cv::String::deallocate()’未定义的引用
# 解决方法
对lsd_slam_viewer中的CMAKELISTS最后增加与OpenCV的链接:
find_package(OpenCV REQUIRED)
rosbuild_add_executable(videoStitch src/main_stitchVideos.cpp)
target_link_libraries(videoStitch ${OpenCV_LIBS})
error 3
# 报错信息
void getPosition(qreal& x, qreal& y, qreal& z) const;
^
# 解决方法[1]
lsd_slam_viewer/src/PointCloudViewer.h中,第135行:将float x, y, z修改为qreal x, y, z
lsd_slam_viewer/src/PointCloudViewer.cpp中,第326行:将float x, y, z修改为qreal x, y, z
error 4
# 报错信息
enum Status
^
# 解决方法[1]
将文件lsd_slam_viewer/src/KeyFrameDisplay.cpp的头文件:
# include "opencv2/opencv.hpp"
注释掉
error 5
# 报错信息
/usr/bin/ld: CMakeFiles/viewer.dir/src/main_viewer.cpp.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/x86_64-linux-gnu/libboost_system.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
# 解决方法
对lsd_slam_viewer中的CMAKELISTS最后增加boost_system库的链接
target_link_libraries(viewer ${QGLViewer_LIBRARIES} ${QT_LIBRARIES} ${QGLVIEWER_LIBRARY} GL glut GLU boost_system)
error 6
# 报错信息
/usr/bin/ld: CMakeFiles/live_slam.dir/src/main_live_odometry.cpp.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/x86_64-linux-gnu/libboost_system.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
......
/usr/bin/ld: CMakeFiles/dataset_slam.dir/src/main_on_images.cpp.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/x86_64-linux-gnu/libboost_system.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
# 解决方法与上一个类似
对lsd_slam_core中的CMAKELISTS最后增加boost_system库的链接
# build live ros node
rosbuild_add_executable(live_slam src/main_live_odometry.cpp)
target_link_libraries(live_slam lsdslam boost_system)
# build image node
rosbuild_add_executable(dataset_slam src/main_on_images.cpp)
target_link_libraries(dataset_slam lsdslam boost_system)
error 7
# 报错信息
../lib/liblsdslam.so:对‘cv::waitKey(int)’未定义的引用
../lib/liblsdslam.so:对‘cv::namedWindow(cv::String const&, int)’未定义的引用
../lib/liblsdslam.so:对‘cv::destroyAllWindows()’未定义的引用
../lib/liblsdslam.so:对‘cv::resizeWindow(cv::String const&, int, int)’未定义的引用
../lib/liblsdslam.so:对‘cv::imshow(cv::String const&, cv::_InputArray const&)’未定义的引用
# 解决方法与error2类似
find_package(OpenCV REQUIRED)
# build live ros node
rosbuild_add_executable(live_slam src/main_live_odometry.cpp)
target_link_libraries(live_slam lsdslam boost_system ${OpenCV_LIBS})
# build image node
rosbuild_add_executable(dataset_slam src/main_on_images.cpp)
target_link_libraries(dataset_slam lsdslam boost_system ${OpenCV_LIBS})
error 8
# 报错信息
DebugWindow DEPTH [Not Responding]
# 解决方法[2]
可以把lsd_slam_core/src/util/settings.cpp中改成
bool displayDepthMap = false;
但是只能正常显示点云地图,无法显示DebugWindow了
另一种方法是重新编译OpenCV,不带QT
cmake -D WITH_QT=off ..
如果还有其他问题,也大可以在这两个链接中找到解决方法:
2 github/issues issues中的问题比较全,基本可以解决遇到的问题
需要注意的是lsd-slam分两个部分编译,先编译lsd_slam_viewer,再编译lsd_slam_core。我们必须对错误的地方定位准确,当出现下面的信息(两部分都pass),则编译通过:
[rosmake-2] Finished <<< lsd_slam_viewer [PASS] [ 4.35 seconds ] [ 4 warnings ]
[rosmake-2] Starting >>> lsd_slam_core [ make ]
[rosmake-2] Finished <<< lsd_slam_core [PASS] [ 17.97 seconds ]
[ rosmake ] Results:
[ rosmake ] Built 47 packages with 0 failures.
[ rosmake ] Summary output to directory
最后,我将自己修改后的代码托管到github上了,使用方法没变:
https://github.com/gjgjh/lsd-slam
3.运行示例程序
下载并解压缩数据示例数据
#分别打开三个终端运行下面四条命令
roscore # start the ROS master
rosrun lsd_slam_viewer viewer # start a node, usage: rosrun package node
rosrun lsd_slam_core live_slam image:=/image_raw camera_info:=/camera_info
#选择正确的数据路径
rosbag play ~/LSD_room.bag # playback a bag, usage: rosbag play/record bag
4.理论和代码的学习
相关的有三篇论文
2013 Semi-dense Visual Odometry for a Monocular Camera
2014 Semi-dense visual odometry for AR on a smartphone
2014 LSD-SLAM: Large-Scale Direct Monocular SLAM
另外推荐hitcm的博客,其中有比较详细的介绍
个人理解错误的地方还请不吝赐教,转载请标明出处