参考网址:https://github.com/raulmur/ORB_SLAM2
按照上述网址中的官方流程,ORB SLAM 2 demo 的复现还算比较顺利,但是也遇到了一些小坑,本文把所有复现流程记录下来,方便以后查阅,或许也可以帮助其他读者解决 demo 复现中遇到的问题。
这里的普通模式是指直接运行编译之后的可执行文件,ROS 模式是以 ros node 的形式执行,后者在多机通讯环境中很方便,例如多机器人协同建图,机器人与 PC 机交互。
系统平台
- Ubuntu 18.04
官网里提到:在 Ubuntu 12.04, 14.04, 16.04 平台上测试过,没有提到 18.04,根据我们的测试,用 18.04 也没问题
安装依赖
OpenCV
这里选择安装 OpenCV 3.2 版本,具体安装流程可以参考我们的另外一篇文章
DBoW2 和 g2o
这两个库都在 Thirdparty 文件夹中,后边会随着 ORB SLAM 2 一起编译,这里先不管它们
ROS
这里选择了与 Ubuntu 18.04 比较匹配的 ROS melodic 版本。
按照官网步骤安装即可。
在国内网络环境下安装时,最后的两步经常会报错:
sudo rosdep init
rosdep update
在之前的文章中我们搜集了几种解决方案,仅供参考。
Eigen3
推荐用 3.2 版本。
从官网 下载源文件压缩包并解压
wget https://gitlab.com/libeigen/eigen/-/archive/3.2.10/eigen-3.2.10.tar.gz
tar -xvzf eigen-3.2.10.tar.gz
然后通过 cmake 方式安装到指定文件夹中
在源文件夹中建立 build 文件夹
在 build 文件夹中
cmake ..
-
sudo make install
默认安装到
/usr/local/include/eigen3
路径下。
我们可以修改这一路径,其基本结构为<CMAKE_INSTALL_PREFIX>/<INCLUDE_INSTALL_DIR>
默认:CMAKE_INSTALL_PREFIX
为/usr/local
,INCLUDE_INSTALL_DIR
为include/eigen3
cmake 时可以修改参数,例如
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
就可以将安装路径设置为/usr/include/eigen3
。
Pangolin
在 ORB SLAM 2 中那些很炫酷的实时建图画面是通过 Pangolin 实现的。
Pangolin 是一个轻量级的开发库,控制 OpenGL 的显示、交互等。
Pangolin 的核心依赖是 OpenGL 和 GLEW。
严格按照官网流程安装即可(https://github.com/stevenlovegrove/Pangolin)。
为了方便查阅,这里摘录了与 Ubuntu 系统对应的安装步骤:
# OpenGL
sudo apt install libgl1-mesa-dev
# Glew
sudo apt install libglew-dev
# CMake
sudo apt install cmake
# python
sudo apt install libpython2.7-dev
sudo python -mpip install numpy pyopengl Pillow pybind11
# Wayland
sudo apt install pkg-config
sudo apt install libegl1-mesa-dev libwayland-dev libxkbcommon-dev wayland-protocols
# FFMPEG (For video decoding and image rescaling)
sudo apt install ffmpeg libavcodec-dev libavutil-dev libavformat-dev libswscale-dev libavdevice-dev
# DC1394 (For firewire input)
sudo apt install libdc1394-22-dev libraw1394-dev
# libjpeg, libpng, libtiff, libopenexr (For reading still-image sequences)
sudo apt install libjpeg-dev libpng-dev libtiff5-dev libopenexr-dev
# build Pangolin
git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build
cd build
cmake ..
cmake --build . # 注意最后那个点
按照上述步骤安装之后可以运行例子测试一下:
cd ~/Pangolin/build/examples/HelloPangolin
./HelloPangolin
如果显示一个彩色立方体,并且可以通过鼠标左、右键和滚轮按住拖拽,就表示 Pangolin 安装成功了。
如果报错,尤其是与 EGL 相关的错误,很可能是显卡驱动的问题,可以尝试更新显卡驱动。
编译 ORB-SLAM2 文件
从 github 下载源文件
git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2
slam2 的作者将后续的编译过程整理成了 .sh 可执行文件,直接运行即可。
cd ORB_SLAM2
chmod +x build.sh
./build.sh
可以打开 build.sh
文件看一下,里面的内容实际上就是依次编译了 DBoW2、g2o,解压缩 vocabulary,最后编译 ORB_SLAM2. 如果在编译过程中显示 <usleep>
相关的错误,则需要在 ~/ORB_SLAM2/include/System.h
头文件中添加 #include <unistd.h>
.
如果要用 ROS 模式跑 demo,还要额外编译 ROS 文件。
首先将 ROS 所在目录加入 ROS_PACKAGE_PATH 环境变量中,具体操作是将下述命令添加到 .bashrc 文件末尾(别忘了替换下述命令中的 <PATH>):
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:<PATH>/ORB_SLAM2/Examples/ROS
source 更新变量之后开始编译:
chmod +x build_ros.sh
./build_ros.sh
在编译过程中可能会出现一个错误:undefined reference to symbol '_ZN5boost6system15system_categoryEv'
.
这是因为在编译时没有添加 boost_system 共享库文件。
修改 Examples/ROS/ORB_SLAM2/CMakeLists.txt
文件中的如下内容:
set(LIBS
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/../../../Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/../../../Thirdparty/g2o/lib/libg2o.so
${PROJECT_SOURCE_DIR}/../../../lib/libORB_SLAM2.so
-lboost_system
)
即只需要在最后加上 -lboost_system
.
到此为止,整个系统的编译部分就完成了,下边在普通模式和 ROS 模式下分别运行 demo.
普通模式
单目
这里采用了第一个数据集 fr1/xyz,压缩包为 0.47 GB,时长 30.09 秒,移动距离 7.112 米.
在后续测试中,所有数据集都放在与 Examples 同一目录下的 datasets 文件夹中。
运行单目 SLAM 的命令格式如下:
./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUMX.yaml PATH_TO_SEQUENCE_FOLDER
具体命令:
./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUM1.yaml datasets/rgbd_dataset_freiburg1_xyz
这里采用了 Download odometry data set (grayscale, 22 GB) 这个数据集,包含灰度图,子文件夹序号从 00 到 21. 我们只测试了 00 号文件夹。
命令格式如下:
./Examples/Monocular/mono_kitti Vocabulary/ORBvoc.txt Examples/Monocular/KITTIX.yaml PATH_TO_DATASET_FOLDER/dataset/sequences/SEQUENCE_NUMBER
具体命令:
./Examples/Monocular/mono_kitti Vocabulary/ORBvoc.txt Examples/Monocular/KITTI00-02.yaml datasets/KITTI/sequences/00
- EuRoC 数据集(https://projects.asl.ethz.ch/datasets/doku.php?id=kmavvisualinertialdatasets)
我们采用的是 Machine Hall 01,共 1.6GB.
命令格式:
./Examples/Monocular/mono_euroc Vocabulary/ORBvoc.txt Examples/Monocular/EuRoC.yaml PATH_TO_SEQUENCE/cam0/data Examples/Monocular/EuRoC_TimeStamps/SEQUENCE.txt
具体命令:
./Examples/Monocular/mono_euroc Vocabulary/ORBvoc.txt Examples/Monocular/EuRoC.yaml datasets/MH_01_easy/mav0/cam0/data Examples/Monocular/EuRoC_TimeStamps/MH01.txt
双目
- KITTI 数据集
依然采用前述 KITTI 数据集,sequence 00.
命令格式:
./Examples/Stereo/stereo_kitti Vocabulary/ORBvoc.txt Examples/Stereo/KITTIX.yaml PATH_TO_DATASET_FOLDER/dataset/sequences/SEQUENCE_NUMBER
具体命令:
./Examples/Stereo/stereo_kitti Vocabulary/ORBvoc.txt Examples/Stereo/KITTI00-02.yaml datasets/KITTI/sequences/00
- EuRoC 数据集
采用与单目时相同的数据集。
命令格式:
./Examples/Stereo/stereo_euroc Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml PATH_TO_SEQUENCE/cam0/data PATH_TO_SEQUENCE/cam1/data Examples/Stereo/EuRoC_TimeStamps/SEQUENCE.txt
具体命令:
./Examples/Stereo/stereo_euroc Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml datasets/MH_01_easy/mav0/cam0/data datasets/MH_01_easy/mav0/cam1/data Examples/Monocular/EuRoC_TimeStamps/MH01.txt
RGB-D 示例
依然采用之前的 TUM 数据集,这次加入深度信息。
这里需要对 rgb 图和 depth 图做一下匹配,官方提供了脚本程序 associate.py
格式如下:
python associate.py PATH_TO_SEQUENCE/rgb.txt PATH_TO_SEQUENCE/depth.txt > associations.txt
匹配之后得到 associations.txt 文件,然后运行 SLAM 程序,格式为:
./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUMX.yaml PATH_TO_SEQUENCE_FOLDER ASSOCIATIONS_FILE
具体命令为:
./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml datasets/rgbd_dataset_freiburg1_xyz datasets/rgbd_dataset_freiburg1_xyz/associations.txt
ROS 模式
在 ROS 模式下,需要从 rosbag 里面发布数据,因此要从上述数据网站上下载相应的 rosbag 数据包。
在运行时,一个关键的设置是将 slam node 接收的 ros topic 和 rosbag 发布的 ros topic 匹配起来,也就是收、发双方的 ros topic 名字必须相同.
topic 名字的转化既可以在运行 slam node 时设置,格式为
rosrun <package_name> <node_name> original_topic:=new_topic
也可以在 play rosbag 的时候设置,格式为
rosbag play <bag_name> original_topic:=new_topic
单目
这里采用 TUM 数据集对应的 rosbag
包含的 rostopic 如下:
/camera/depth/camera_info 798 msgs : sensor_msgs/CameraInfo
/camera/depth/image 798 msgs : sensor_msgs/Image
/camera/rgb/camera_info 798 msgs : sensor_msgs/CameraInfo
/camera/rgb/image_color 798 msgs : sensor_msgs/Image
/cortex_marker_array 3034 msgs : visualization_msgs/MarkerArray
/imu 15158 msgs : sensor_msgs/Imu
/tf 4242 msgs : tf/tfMessage
其中要用到的 topic 是 /camera/rgb/image_color
,而 rosnode ORB_SLAM2/Mono 接收的 topic 名字为 /camera/image_raw
。我们可以在 play rosbag 时将 rosbag 中的/camera/rgb/image_color
转换为 /camera/image_raw
。
完整命令如下:
roscore
rosrun ORB_SLAM2 Mono Vocabulary/ORBvoc.txt Examples/Monocular/TUM1.yaml
rosbag play datasets/rgbd_dataset_freiburg1_xyz.bag /camera/rgb/image_color:=/camera/image_raw
单目 AR
实现增强现实效果,可以向摄像头中的世界插入一个虚拟立方体,通过摄像头观察,这个虚拟立方体与实际物体相仿。
运行命令与上边几乎完全相同,只是将 rosrun ORB_SLAM2 Mono
替换为 rosrun ORB_SLAM2 MonoAR
.
双目
这里我们用 EuRoC 数据集对应的 rosbag,包含如下的 topic:
/cam0/image_raw 3682 msgs : sensor_msgs/Image
/cam1/image_raw 3682 msgs : sensor_msgs/Image
/imu0 36820 msgs : sensor_msgs/Imu
/leica/position 3099 msgs : geometry_msgs/PointStamped
其中关键的 topic 是左右两个摄像头的数据 /cam0/image_raw
和 /cam1/image_raw
。
而双目 rosnode Stereo 接收的 topic 分别为 /camera/left/image_raw
和 /camera/right/image_raw
,因此在运行时也需要转换一下 topic 名称。
完整命令如下:
roscore
rosrun ORB_SLAM2 Stereo Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml true
rosbag play --pause MH_01_easy.bag /cam0/image_raw:=/camera/left/image_raw /cam1/image_raw:=/camera/right/image_raw
RGB-D
这里我们采用 TUM 的 rosbag,也就是在单目示例中用到的那个.
此时用到两个 topic 数据:
/camera/depth/image 798 msgs : sensor_msgs/Image
/camera/rgb/image_color 798 msgs : sensor_msgs/Image
rosnode RGBD 接收的 topic 分别是 /camera/depth_registered/image_raw
和 /camera/rgb/image_raw
,因此也需要转换 topic.
完整命令如下:
roscore
rosrun ORB_SLAM2 RGBD Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml
rosbag play --pause rgbd_dataset_freiburg1_xyz.bag /camera/rgb/image_color:=/camera/rgb/image_raw /camera/depth/image:=/camera/depth_registered/image_raw
这里的结果有点出乎意料,相机镜头一直固定点附近晃动,没有形成之前我们常见的 SLAM 地图。
经过查找,发现是 Examples/RGB-D/TUM1.yaml
这个文件的参数设置有问题,其中
# Deptmap values factor
DepthMapFactor: 5000.0
这个参数似乎是深度值的校正系数。在具体使用时,表达式为 Z = depth_image[v,u] / factor;
在 TUM 官网中明确指出普通运行模式和 ROS 运行模式中,这个数值是不同的:
factor = 5000 # for the 16-bit PNG files
OR: factor = 1 # for the 32-bit float images in the ROS bag files
因此之前普通模式运行时用 Examples/RGB-D/TUM1.yaml
没有问题,但是在 ROS 模式下就需要修改一下参数
# Deptmap values factor
DepthMapFactor: 1.0
修改之后,再次运行上边的命令,就可以得到预期的效果。
总结
本文详细记录了 ORB SLAM 2 中 demo 的复现过程,以及其中可能存在的一些问题和解决方案。
在接下来的工作中,我们将参考高翔博士的工作 复现 ORB SLAM 2 + 点云建图,