Ubuntu18.04中ORB-SLAM2在c++和ROS下环境配置与复现

ORB-SLAM2复现

1 环境准备

Ubuntu18.04

1.1 Pangolin

安装依赖

sudo apt -get install libglew-dev
sudo apt -get install libboost-dev libboost-thread-dev libboost-filesystem-dev
sudo apt -get install libpython2.7-dev

​ 选择0.5版本的Pangolin进行源码编译安装。

# 最后的参数使得git的包名为Pangolin 
git clone https://github.com/stevenlovegrove/Pangolin/tree/v0.5 Pangolin 
cd Pangolin						
mkdir build && cd build
cmake ..
make -j4
sudo make install   # 安装

1.2 OpenCV

OpenCV,这里选择了3.4.16

  • 安装依赖
sudo apt install build-essential cmake git pkg-config libgtk-3-dev \
    libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
    libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
    gfortran openexr libatlas-base-dev python3-dev python3-numpy \
    libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
    libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev    # 根据需要安装
  • 源码编译
cd opencv-3.4.16
mkdir build && cd build
cmake ..
make -j4       # 可能会有点慢
sudo make install

1.3 Eigen3

sudo apt install libeigen3-dev  # 直接命令行安装即可

1.4 DBoW2 and g2o

作者进行了修改,直接在ORB源码编译时进行安装

2 C++编译

2.1 下载源码

git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2
cd ORB_SLAM2
chmod +x build.sh
gedit build.sh

2.2 build.sh

# 1.编译DBoW2
cd Thirdparty/DBoW2
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j

# 2.编译g2o
cd ../../g2o
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j

# 3 解压ORB字典
cd Vocabulary
tar -xf ORBvoc.txt.tar.gz
cd ..

# 4.编译ORB源码
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j

2.3 报错

./build.sh  # 虚拟机性能不行的话,第一次可以一步一步按上面命令单独执行

# 把下面两句放在CMakeLists.txt来减少不必要的警告
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")

① 报错1

​ 报错:ORB/ORB_SLAM2-master/src/System.cc:134:17: error: ‘usleep’ was not declared in this scope ​ usleep(1000); ​ ^~~~~~

​ 即使用了未定义的引用,也就是缺少相应的头文件,很明显指System.cc中缺失,然后就会发现很多文件都缺失了这个头文件,都补上即可。

#include <unistd.h>   // 在上面文件加上头文件即可消除报错


System.cc
Tracking.cc
LocalMapping.cc
LoopClosing.cc
Viewer.cc
    
mono_euroc.cc
mono_kitti.cc
mono_tum.cc
stereo_kitti.cc
stereo_euroc.cc
rgbd_tum.cc    

②报错2

​ 出现这种问题,就是pangolin的版本不对,换成0.5就ok,否则在make时候会找不到/usr/bin/ld: cannot find -leigen3

CMake Warning (dev) at CMakeLists.txt:103 (add_executable):
  Policy CMP0028 is not set: Double colon in target name means ALIAS or
  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
  Use the cmake_policy command to set the policy and suppress this warning.

  Target "stereo_kitti" links to target "Eigen3::Eigen" but the target was
  not found.  Perhaps a find_package() call is missing for an IMPORTED
  target, or an ALIAS target is missing?
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at CMakeLists.txt:107 (add_executable):
  Policy CMP0028 is not set: Double colon in target name means ALIAS or
  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
  Use the cmake_policy command to set the policy and suppress this warning.

  Target "stereo_euroc" links to target "Eigen3::Eigen" but the target was
  not found.  Perhaps a find_package() call is missing for an IMPORTED
  target, or an ALIAS target is missing?
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at CMakeLists.txt:107 (add_executable):
  Policy CMP0028 is not set: Double colon in target name means ALIAS or
  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
  Use the cmake_policy command to set the policy and suppress this warning.

  Target "stereo_euroc" links to target "Eigen3::Eigen" but the target was
  not found.  Perhaps a find_package() call is missing for an IMPORTED
  target, or an ALIAS target is missing?
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at CMakeLists.txt:107 (add_executable):
  Policy CMP0028 is not set: Double colon in target name means ALIAS or
  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
  Use the cmake_policy command to set the policy and suppress this warning.

  Target "stereo_euroc" links to target "Eigen3::Eigen" but the target was
  not found.  Perhaps a find_package() call is missing for an IMPORTED
  target, or an ALIAS target is missing?
This warning is for project developers.  Use -Wno-dev to suppress it.

2.4 配置文件

KITTI00-02.yaml为例

Camera.fx: 718.856		# 内参K
Camera.fy: 718.856
Camera.cx: 607.1928
Camera.cy: 185.2157

Camera.k1: 0.0			# 畸变参数
Camera.k2: 0.0
Camera.p1: 0.0
Camera.p2: 0.0

Camera.width: 1241		# 图像宽高
Camera.height: 376

Camera.fps: 10.0		# 相机帧率

Camera.bf: 386.1448		# 双目基线b

# Color order of the images (0: BGR, 1: RGB. It is ignored if images are grayscale)
Camera.RGB: 1

# Close/Far threshold. Baseline times.  远近点阈值
ThDepth: 35

#--------------------------------------------------------------------------------------------
# ORB Parameters 特征提取参数
#--------------------------------------------------------------------------------------------
ORBextractor.nFeatures: 2000
ORBextractor.scaleFactor: 1.2
ORBextractor.nLevels: 8		
ORBextractor.iniThFAST: 20
ORBextractor.minThFAST: 7

#--------------------------------------------------------------------------------------------
# Viewer Parameters 可视化参数
#--------------------------------------------------------------------------------------------
Viewer.KeyFrameSize: 0.6
Viewer.KeyFrameLineWidth: 2
Viewer.GraphLineWidth: 1
Viewer.PointSize:2
Viewer.CameraSize: 0.7
Viewer.CameraLineWidth: 3
Viewer.ViewpointX: 0
Viewer.ViewpointY: -100
Viewer.ViewpointZ: -0.1
Viewer.ViewpointF: 2000

3 C++下运行

在这里插入图片描述

3.1 Monocular

3.1.1 KITTI Dataset

  • mono_kitti.cc
// arg0:可执行文件   arg1:字典路径   arg2:配置文件yaml   arg3:数据路径
if(argc != 4)
{
    cerr << endl << "Usage: ./mono_kitti path_to_vocabulary path_to_settings path_to_sequence" << endl;
    return 1;
}

...
    
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");  // 保存的关键帧轨迹 TMU数据格式
  • 执行
cd ORB_SLAM2  
./Examples/Monocular/mono_kitti Vocabulary/ORBvoc.txt Examples/Monocular/KITTIX.yaml xxx # 这里写数据路径    敲的时候最好利用tab补全,避免打错 

# /mnt/hgfs/dataset/KITTI/rgb/04/ 这里跑了KITTI04数据集,数据结果

在这里插入图片描述

3.1.2 TUM Dataset

数据地址

  • mono_tum.cc
{
    // arg0:可执行文件 arg1:字典路径 arg2:配置文件  arg3:图像路径
    cerr << endl << "Usage: ./mono_tum path_to_vocabulary path_to_settings path_to_sequence" << endl;
    return 1;
}

...

SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt"); 
  • 执行
cd ORB_SLAM2 
./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUM3.yaml /mnt/hgfs/TUM/rgbd_dataset_freiburg3_long_office_household

# 注意这里的配置文件要和数据文件对应!

在这里插入图片描述

3.1.3 EuRoC Dataset

数据地址,这里提供了ROS bagASL Dataset Format

  • mono_euroc.cc
if(argc != 5)
{
    // arg0:可执行文件  arg1:字典路径  arg2:相机配置文件ymal  arg3:图像路径  arg4:时间戳路径
    cerr << endl << "Usage: ./mono_tum path_to_vocabulary path_to_settings path_to_image_folder path_to_times_file" << endl;
    return 1;
}

...
    
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");
  • 执行
cd ORB_SLAM2  
./Examples/Monocular/mono_euroc Vocabulary/ORBvoc.txt Examples/Monocular/EuRoC.yaml PATH_TO_SEQUENCE_FOLDER/mav0/cam0/data # 图像路径
Examples/Monocular/EuRoC_TimeStamps/SEQUENCE.txt 	# 时间戳路径

3.2 Stereo

3.2.1 KITTI Dataset

  • stereo_kitti.cc
// arg0:可执行文件   arg1:字典路径   arg2:配置文件yaml   arg3:数据路径
if(argc != 4)
{
     cerr << endl << "Usage: ./stereo_kitti path_to_vocabulary path_to_settings path_to_sequence" << endl;
    return 1;
}

...
    
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");  // 保存的关键帧轨迹 TMU数据格式
  • 执行
cd ORB_SLAM2  
./Examples/Stereo/stereo_kitti Vocabulary/ORBvoc.txt Examples/Stereo/KITTIX.yaml PATH_TO_DATASET_FOLDER/dataset/sequences/SEQUENCE_NUMBER

KITTI00双目,如果这里用的还是单目的配置文件,就会启动失败!两个配置文件是有差异的,比如ThDepth: 35

在这里插入图片描述

3.2.2 EuRoC Dataset

  • stereo_euroc.cc
if(argc != 5)
{
    // arg0:可执行文件  arg1:字典路径  arg2:相机配置文件ymal  arg3:左目图像路径  
    // arg4:右目图像路径		   arg5:时间戳路径
    cerr << endl << "Usage: ./stereo_euroc path_to_vocabulary path_to_settings path_to_left_folder path_to_right_folder path_to_times_file" << endl;
    return 1;
}

...
    
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");
  • 执行
cd ORB_SLAM2  
./Examples/Stereo/stereo_euroc Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml /mnt/hgfs/euroc/mav0/cam0/data /mnt/hgfs/euroc/mav0/cam1/data Examples/Stereo/EuRoC_TimeStamps/MH05.txt

MH05数据集

在这里插入图片描述

3.3 RGB-D(TUM)

3.3.1 关联数据

​ 需要通过该网站中的 associate.py 来对彩色RGB图片和深度depth图进行关联。

Examples/RGB-D/associations/ 目录中已经提供了一些已经关联好的数据数列。可以通过以下命令生成自己的数据序列:

python associate.py PATH_TO_SEQUENCE/rgb.txt PATH_TO_SEQUENCE/depth.txt > associations.txt

​ 以Kinect为例,其原理是以非同步的方式提供颜色和深度图像。这意味着彩色图像的时间戳与深度图像的时间戳不会相交。因此,需要找到一种将彩色图像与深度图像相关联的方法。

​ 为了这个目的,使用 associate.py 进行关联,其原理是读取rgb.txt和depth.txt的时间戳信息,然后把最接近的匹配到一起。

3.3.2 测试

  • rgbd_tum.cc
int main(int argc, char **argv)
{
    if(argc != 5)
    {
        cerr << endl << "Usage: ./rgbd_tum path_to_vocabulary path_to_settings path_to_sequence path_to_association" << endl;
        return 1;
    }
}
  • 执行
./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM3.yaml PAHT-to/TUM/rgbd_dataset_freiburg3_long_office_household ./Examples/RGB-D/accelerometer_long_office_household.txt

# 如果报错了,一般是关联数据的txt文件有问题

在这里插入图片描述

4 运行报错

4.1 报错1:Failed to load image

在这里插入图片描述

报错:不能加载数据。原因要么是数据路径有问题,或者就是配置有问题,就是双目的ymal和使用的rgb数据等

4.2 无法保存轨迹

用ORB-SLAM2运行KITTI数据集时,最后窗口卡住,无法保存轨迹文件。

// 注释system.cc文件中这两行  319-320行
if (mpViewer)
        pangolin::BindToContext("ORB-SLAM2: Map Viewer");

5 ROS编译

5.1 编译

./build_ros.sh

5.2 报错

① 报错1

rospack found package "ORB_SLAM2" at "", but the currentdirectory is "/home/p/ORB_SLAM2-master/Examples/ROS/ORB_SLAM2 报错的意思是

rospack find ORB_SLAM2 失败,找不到这个功能包,解决办法就是把功能包的路径加入到${ROS_PACKAGE_PATH},然后再次编译即可成功(如果还是报同样的错,那就是路径不对,比如我这里一直报错因为home前面/忘打了)。

gedit ~/.bashrc # 然后在最后加上下面这句
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/p/ORB_SLAM2/Examples/ROS

source ~/.bashrc	# 刷新



# 验证修改
echo ${ROS_PACKAGE_PATH}   # 查看路径

p@p:~/ORB_SLAM2-master/Examples/ROS/ORB_SLAM2$ rospack list # 直接查找
ORB_SLAM2 /home/p/ORB_SLAM2-master/Examples/ROS/ORB_SLAM2
....

② 报错2

Failed to invoke rospack to get compile flags for package 'ORB_SLAM2'. Look above for errors from rospack itself. Aborting. Please fix the broken dependency!

$ sudo rosdep fix-permissions
$ rosdep update

③ 报错3

undefined reference to symbol '_ZN5boost6system15system_categoryEv'

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  		# 把这个加上   ROS下的那个CMakeLists.txt
)

④ 报错4

ViewerAR.cc:233:9: error: ‘usleep’ was not declared in this scope usleep(mT*1000);

#include <unistd.h>   // 在上面文件加上头文件即可消除报错

6 ROS运行测试

6.1 测试单目节点

​ 记得改一下配置文件,没有图像就是话题名错误,改下程序中的订阅话题(或在命令行中更改)。运行单目增强流程和这里差不多。

rosrun ORB_SLAM2 Mono PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE _rgb:=/camera/rgb/image_raw 

在这里插入图片描述

6.2 测试RGB-D

利用Astra pro相机进行测试

roslaunch astra_camera astrapro.launch # 要开始相机节点
rostopic list  # 查看相关话题名,方便订阅图像数据

rosrun ORB_SLAM2 RGBD Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml  _rgb:=/camera/rgb/image_raw _depth:=/camera/depth_registered/image_raw

在这里插入图片描述

6.3 测试双目数据集

rosrun ORB_SLAM2 Stereo PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE ONLINE_RECTIFICATION
rosrun ORB_SLAM2 Stereo Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml true
rosbag play --pause V1_01_easy.bag /cam0/image_raw:=/camera/left/image_raw /cam1/image_raw:=/camera/right/image_raw			# 没有双目相机,就利用ros数据

7 运行自己的数据集

​ 以KITTI为例,需要准备配置文件(相机内参和畸变系数)和时间戳文件。

假设有一段视频数据,我们利用python程序把它拆分为图像数据,并生成时间戳文件。接着按上面的方法运行即可,但是发现很多时候会跟丢,例如拐弯处。

# -*- coding: utf-8 -*-

import cv2
import os
from datetime import datetime

def split_video_to_frames(video_path, output_folder):
    cap = cv2.VideoCapture(video_path)
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    fps = int(cap.get(cv2.CAP_PROP_FPS))

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    timestamps = []

    for i in range(frame_count):
        ret, frame = cap.read()
        if not ret:
            break

        timestamp = "{:.6e}".format(i / fps)
        timestamps.append(timestamp)

        frame_filename = os.path.join(output_folder, '{:06d}.jpg'.format(i))

        cv2.imwrite(frame_filename, frame)

    cap.release()
    return timestamps

# 设置视频路径和输出文件夹
video_path = 'video.mp4'
output_folder = 'data'

# 拆分视频,并记录时间戳
timestamps = split_video_to_frames(video_path, output_folder)

# 保存时间戳到文件
timestamps_file = os.path.join(output_folder, 'times.txt')
with open(timestamps_file, 'w') as f:
    f.write('\n'.join(timestamps))
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值