ORB-SLAM3是第一个能够让单目、立体和RGB-D相机和针孔和鱼眼镜头模型解耦进行视觉、视觉惯性和多地图SLAM的系统。第一个主要的创新是一个基于特征的紧密集成视觉惯性SLAM系统,它完全依赖于最大后验概率(MAP)估计,甚至在IMU初始化阶段也是如此。第二个主要的创新是一个多地图系统,它依赖于一种新的位置识别方法和改进的召回。多亏了它,ORB-SLAM3能够在长时间的不良视觉信息下生存:当它丢失时,它会启动一个新的地图,当重新访问地图区域时,它将与以前的地图无缝地合并。与只使用最后几秒信息的视觉里程计系统相比,ORB-SLAM3也是第一个能够在所有算法阶段重用所有先前信息的系统。这允许在BA优化中使用历史的共视关键帧,即使这些关键帧来自很久以前的地图或者不同子图。该系统在小型和大型,室内和室外环境中都能稳定地运行,并且比以前的方法精确2到5倍。
开源地址
论文地址
查看ORB-SLAM3的项目要求,要求安装Pangolin
1. 安装Pangolin所需要的依赖
查了一下其他大佬的方法
终端逐条运行以下命令:
sudo apt install libgl1-mesa-dev
sudo apt install libglew-dev CMake
sudo apt install cmake
sudo apt install libpython2.7-dev
sudo apt install pkg-config
sudo apt install libegl1-mesa-dev libwayland-dev libxkbcommon-dev wayland-protocols
sudo apt-get install cmake libeigen3-dev libsuitesparse-dev qtdeclarative5-dev qt5-qmake libqglviewer-dev
sudo apt-get install libboost-dev
2. 编译安装Pangolin
终端逐条运行以下命令:
cd Pangolin
mkdir build
cd build
cmake ..
cmake --build .
但是编译出现以下问题
大概意思是有的包配置文件没找到,或者干脆没安装,于是按照Pangolin的sh配置文件再安装一次。
终端cd到Pangolin文件夹下,执行以下命令:
./scripts/install_prerequisites.sh recommended
然后重复之前的命令:
cd Pangolin
mkdir build
cd build
cmake ..
cmake --build .
sudo make install
最终编译成功,会默认安装在/usr/local/include/pangolin
OBR官方提示OpenCV(要求>3.0)
关于怎么安装可以参考我这篇博客。
基于很多博客说建议源码安装,决定跟着大队走
其实前面已经有安装了,但是以防万一
sudo apt-get install libeigen3-dev
sudo updatedb #创建或更新 slocate/locate 命令所必需的数据库文件
locate eigen3 #查看位置,我的是安装在了/usr/include
ubuntu18.04 下默认boost版本 1.65.0,就算不进行到命令行安装ros也会自动安装,随意吧。
sudo apt-get install libboost-system-dev
更新:手动源码安装无法嵌入ros中,安装ros时还会再次命令行安装boost1.65版本,所以不需要手动安装,而且多版本boost存在有时会导致冲突。以下boost1.70步骤不需要进行,只做记录。
(1)下载boost库,我使用的是1.7.0 版本
(2)进入到该目录,解压到自己想放的位置
(3)之后通过终端进入boost目录执行命令
cd boost
sudo ./bootstrap.sh
bootstrap.sh会产生bjam和b2两个工具,继续执行
sudo ./b2 install
这个时候你的/usr/local/include下会产生boost的头文件,/usr/local/lib下面会产生boost库
(4)切换到profile.d目录下,使用超级用户创建文件boost.sh
cd /etc/profile.d
sudo touch boost.sh
sudo vim boost.sh
在里面添加如下内容
#!/bin/sh
BOOST_ROOT=(boost的解压路径)
BOOST_INCLUDE=/usr/local/include/boost
BOOST_LIB=/usr/local/lib
export BOOST_INCLUDE BOOST_LIB BOOST_ROOT
修改boost.sh的权限 ,执行 boost.sh
sudo chmod +x boost.sh
source /etc/profile.d/boost.sh
卸载源码安装boost:
sudo rm -rf /usr/local/include/boost
sudo rm -rf /usr/local/lib/libboost*
sudo rm -rf /usr/local/lib/cmake/*1.70.0*
卸载命令行安装boost:
要注意会同时把ros一起卸载掉
sudo apt-get autoremove libboost1.65-dev
查询版本
dpkg -l | grep boost1.XX
按照OBR官方提示:
我们使用DBoW2库的修改版本来执行地点识别和g2o库来执行非线性优化。两个修改后的库(BSD)都包含在第三方文件夹中。
意思应该是OBR包里包含了,不需要另外安装。
不过需要安装依赖:
sudo apt-get install libcanberra-gtk-module
sudo apt-get install libssl-dev
进入SLAM文件夹,运行以下命令:
cd ORB-SLAM3/
chmod +x build.sh
sudo ./build.sh
建议把build.sh中的指令逐条进行,这样就可以具体知道是哪个部分出问题了。
build.sh中的内容如下:
echo "Configuring and building Thirdparty/DBoW2 ..."
cd Thirdparty/DBoW2
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ../../g2o
echo "Configuring and building Thirdparty/g2o ..."
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ../../../
echo "Uncompress vocabulary ..."
cd Vocabulary
tar -xf ORBvoc.txt.tar.gz
cd ..
echo "Configuring and building ORB_SLAM3 ..."
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
出现报错:
找了很多资料,借鉴这个博客
确定是boost的问题,具体解决可以看上面的方法。
解决后删掉ORB-SLAM3下的bulid文件夹,重新编译,建议把build.sh中的指令逐条进行,这样就可以具体知道是哪个部分出问题了。
不同的Unbutn安装的Ros版本不同。Ubuntu18.04对应的ros版本为ROS Melodic
因为ROS挺多教程的,我参考这篇 博客。我遇到的所有问题他都给出解决方案实在良心,所以我就不专门写出具体的过程 ,直接套娃。
先创建文件夹,具体位置可以自己选择
mkdir -p catkin_ws/src
cd catkin_ws/src
然后下载usb_cam文件,可以终端下载也可以手动github或gitee下载
git clone https://github.com/ros-drivers/usb_cam.git
但是要注意先确定你的usb摄像头的编号和修改launch文件,不然要么会调用到默认摄像头要么报错。
查看接入的USB摄像头的设备号
ls /dev/video*
修改catkin_ws/src/usb_cam/launch/usb_cam-test.launch里面的参数,默认是/dev/video0
param name=“video_device” value=“/dev/video0”
修改后,终端回退到catkin_ws,编译usb_cam文件,
cd ../../../
catkin_make
编译失败1:
ERROR: cannot launch node of type [usb_cam/usb_cam_node]: usb_cam
解决1:
需要在终端./catkin_ws中打开以下目录 并键入以下命令
source devel/setup.bash
安装依赖
sudo apt install ros-melodic-uvc-camera
sudo apt install ros-melodic-image-view
sudo apt install ros-melodic-usb-cam
进入catkin_ws/src/usb_cam/launch文件夹打开终端,运行命令:
roslaunch usb_cam-test.launch
记得去对自己的USB相机进行标定,有关资料不在此列出!!!!
方法一、直接安装.sh命令:
cd ORB-SLAM3/
chmod +x build.sh
sudo ./build.sh
方法二、 进入build.sh间接安装:
echo "Configuring and building Thirdparty/DBoW2 ..."
cd Thirdparty/DBoW2
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ../../g2o
echo "Configuring and building Thirdparty/g2o ..."
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ../../../
echo "Uncompress vocabulary ..."
cd Vocabulary
tar -xf ORBvoc.txt.tar.gz
cd ..
echo "Configuring and building ORB_SLAM3 ..."
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
编译ros环境:
cd ..
./build_ros.sh
报错1:
No module named ‘rospkg’
解决方法:
虚拟环境 (虚拟环境名)
conda activate 虚拟环境名 #进入虚拟环境
conda install pip # 这里是让conda用虚拟环境里的 pip 确保 rospkg 装在该环境
pip install rospkg
非虚拟环境下 (base)
pip install rospkg
尝试了各种修改路径的方法,仍然是提示报错,但是gedit ~/.bashrc路径明明是添加进去了…
gedit ~/.bashrc
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/xxx/Guide_blind/ORB_SLAM3/Examples/ROS
source ~/.bashrc
后来发现是Examples和Examples_old文件问题
首先感谢这篇博客的博主,特别是这几天github有进不去了,以及感谢github问题区的解决者
其实解决这个问题需要先进行另一个步骤:
因为我现在编译的是ORB_SLAM1.0版本,这个版本有一个不同,就是区分Examples和Examples_old文件,我们需要的一些文件是在Examples_old文件中,需要先建立软链接:
1、在Examples中新建文件夹ROS,进入ROS文件夹终端
2、sudo ln -s /home/xxx/Guide_blind/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3 /home/xxx/Guide_blind/ORB_SLAM3/Examples/ROS
3、./build.sh
不间断运行 ./build_ros.sh
,会持续出现以下问题:
问题1:
提示找不到sophus库,修改Examples/ROS/ORB_SLAM3下的CMAKELISTS中添加修改为 {PROJECT_SOURCE_DIR}/…/…/…/Thirdparty/Sophus
解决 cv::Mat Tcw = mpSLAM->TrackMonocular(cv_ptr->image,cv_ptr->header.stamp.toSec()); 报错
#include
#include
引入上述两个头文件,然后删除ROS/ORB_SLAM3/src/AR/ros_mono_ar.cc第151行,由下面内容替换
cv::Mat Tcw;
Sophus::SE3f Tcw_SE3f = mpSLAM->TrackMonocular(cv_ptr->image,cv_ptr->header.stamp.toSec());
Eigen::Matrix4f Tcw_Matrix = Tcw_SE3f.matrix();
cv::eigen2cv(Tcw_Matrix, Tcw);
问题3:
解决 cv::Mat Xw = pMP->GetWorldPos();报错
引入上述两个头文件,然后删除ROS/ORB_SLAM3/src/AR/ViewerAR.cc第530行,由以下内容替换
cv::Mat Xw;
cv::eigen2cv(pMP->GetWorldPos(), Xw);
问题4:
cv中的eigen2cv问题,建议在每个修改文件的顶部包含以下文件头文件:
#include <Eigen/Dense>
#include <opencv2/core/eigen.hpp>
再编译,没有其他问题的话正常编译通过。
报错3:
解决方法:
没有解决的头绪,借鉴了挺多博客,总结了一下可能存在的问题:
与前面的1.0的步骤差不多,细节看前面:
echo "Configuring and building Thirdparty/DBoW2 ..."
cd Thirdparty/DBoW2
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ../../g2o
echo "Configuring and building Thirdparty/g2o ..."
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ../../../
echo "Uncompress vocabulary ..."
cd Vocabulary
tar -xf ORBvoc.txt.tar.gz
cd ..
echo "Configuring and building ORB_SLAM3 ..."
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
cd ..
./build_ros.sh
到这里和上面的安装编译是大同小异,如果只是这样直接尝试启动单目的话依然是失败的
#第一个窗口启动ROS服务
roscore
#第二个窗口启动usb摄像头节点
roslaunch usb_cam-test.launch
#第三个窗口启动SLAM3
rosrun ORB_SLAM3 Mono /home/xxx/Guide_blind/ORB_SLAM3/Vocabulary/ORBvoc.txt /home/xxx/Guide_blind/ORB_SLAM3/Examples/ROS/ORB_SLAM3/Asus.yaml
报错1:
Map Viewer空白, Current Frame没有图像画面。
解决方法:
以下方法有一些可能有用,有一些没有用,请根据自己请况进行修改:
1、cv_bridge编译修改opencv版本(不一定有用),因为在编译./builde_ros时出现警告,提示我opencv版本不对应问题,主要是两种方法,已修改现有的和下载新版本,建议没得办法时尝试,有关资料不在这里列出。
2、先到/opt/ros/melodic/share目录下,删除原来的ORB_SLAM3软连接(如果有的话)
sudo rm -r ORB_SLAM3
在/opt/ros/melodic/share目录下建立软链接
sudo ln -s /home/xxx/Guide_blind/ORB_SLAM3/Examples/ROS/ORB_SLAM3 /opt/ros/melodic/share/ORB_SLAM3
重新编译./builde_ros
此外在/opt/ros/melodic/share目录下建立ORB_SLAM3软链接,我在1.0版本没有尝试过,有兴趣可以自己调试一下。
这时就成功运行单目USB摄像头了
roscore
roslaunch usb_cam-test.launch
rosrun ORB_SLAM3 Mono /home/xxx/Guide_blind/ORB_SLAM3/Vocabulary/ORBvoc.txt /home/xxx/Guide_blind/ORB_SLAM3/Examples/ROS/ORB_SLAM3/Asus.yaml
首先复原初试的步骤,至少那里的步骤大致是没有什么错误的,接下来就是当时的错误“段错误”:
之前也思考过错误来源,经过大量试错,判断应该是opencv的版本冲突问题:
ROS的opencv3.2与本机opencv4.4冲突问题
本来想尝试修改CMakeLists.txt和cv_bridge使用本机opencv4,参考的是这位博主。
可是过程繁琐,且修改或依然无法使用(主要是和个人配置使用的某些环境出现冲突),导致失败。
那么就只能使用ROS的opencv3.2,参考的是这位博主。
找到ORB_SLAM3的CMakeLists.txt文件打开,找个这个位置修改4.4这个值,改为(OpenCV 3 REQUIRED),如图所示:
//find_package(OpenCV 4.4)
find_package(OpenCV 3 REQUIRED)
if(NOT OpenCV_FOUND)
message(FATAL_ERROR "OpenCV > 4.4 not found.")
endif()。
然后把ORB-SLAM3重新编译:
sudo ./build.sh
sudo ./build_ros.sh
报错1:
Map Viewer空白, Current Frame没有图像画面,并在左下角提示WAITING FOR IMAGES 。
解决方法:
1、按理来说,如果没有画面显示waiting for images时,就需要检查一下摄像头订阅。打开.cc文件发现"/camera/image_raw"没有修改成"/usb_cam/image_raw",所以需要修改。
参考这位博主
2、修改之后记得更新ORB_SLAM3软连接,在/opt/ros/melodic/share目录下,删除原来的ORB_SLAM3软连接(如果有的话)
sudo rm -r ORB_SLAM3
在/opt/ros/melodic/share目录下建立软链接
sudo ln -s /home/xxx/Guide_blind/ORB_SLAM3-1.0/Examples_old/ROS/ORB_SLAM3 /opt/ros/melodic/share/ORB_SLAM3
3、修改后需要重新编译ros:
sudo ./build_ros.sh
第1个终端:
roscore
第2个终端:
roslaunch usb_cam-test.launch
第3个终端:
rosrun ORB_SLAM3 Mono /home/xxx/Guide_blind/ORB_SLAM3-1.0/Vocabulary/ORBvoc.txt /home/xxx/Guide_blind/ORB_SLAM3-1.0/Examples_old/ROS/ORB_SLAM3/Asus.yaml
第4个终端:
rqt_graph
这个摄像头是合成图像的双目摄像头,意思就是使用的双目摄像头在计算机上是一个设备,即将两个摄像头的图像合成为了一副图像,此时需要先将一幅图分割为左右两幅,再分别作为一个ros_node发布。
ls /dev/video*
它的编号也只有一个能打开
# -*- coding: utf-8 -*-
import cv2
import time
AUTO = False # 自动拍照,或手动按s键拍照
INTERVAL = 2 # 自动拍照间隔
cv2.namedWindow("left")
cv2.namedWindow("right")
cap = cv2.VideoCapture(2)
# 设置分辨率左右摄像机同一频率,同一设备ID;左右摄像机总分辨率3840x1080;分割为两个1920x1080
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
counter = 0
utc = time.time()
folder = "./SaveImage/" # 拍照文件目录
def shot(pos, frame):
global counter
path = folder + pos + "_" + str(counter) + ".jpg"
cv2.imwrite(path, frame)
print("snapshot saved into: " + path)
while True:
ret, frame = cap.read()
print("ret:", ret)
# 裁剪坐标为[y0:y1, x0:x1] HEIGHT * WIDTH,
#双目相机是两个在一起的,通过剪切坐标位置可以单独分开相机
left_frame = frame[0:480, 0:640]
right_frame = frame[0:480, 640:1280]
cv2.imshow("left", left_frame)
cv2.imshow("right", right_frame)
now = time.time()
if AUTO and now - utc >= INTERVAL:
shot("left", left_frame)
shot("right", right_frame)
counter += 1
utc = now
key = cv2.waitKey(1)
if key == ord("q"):
break
elif key == ord("s"):
shot("left", left_frame)
shot("right", right_frame)
counter += 1
cap.release()
cv2.destroyWindow("left")
cv2.destroyWindow("right")
复制一份单目的launch文件更名为usb_cam-stereo
修改usb_cam-stereo的video_device和pixel_format,其中pixel_format的类型有mjpeg、yuyv等,根据自己的双目而定。
<launch>
<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
<param name="video_device" value="/dev/video2" />
<param name="image_width" value="1280" />
<param name="image_height" value="480" />
<param name="pixel_format" value="mjpeg" />
<param name="camera_frame_id" value="usb_cam" />
<param name="io_method" value="mmap"/>
</node>
<node name="image_view" pkg="image_view" type="image_view" respawn="false" output="screen">
<remap from="image" to="/usb_cam/image_raw"/>
<param name="autosize" value="true" />
</node>
</launch>
在usb_cam文件夹打开终端运行
roslaunch usb_cam-stereo.launch
第1个终端:
roscore
第2个终端:
roslaunch usb_cam-stereo.launch
第3个终端:
rosrun ORB_SLAM3 Mono /home/xxx/Guide_blind/ORB_SLAM3-1.0/Vocabulary/ORBvoc.txt /home/xxx/Guide_blind/ORB_SLAM3-1.0/Examples_old/Stereo/EuRoC.yaml
对比单目而言,双目比较稳定,可以进行适当的运动以及失联后的有效恢复,更快更稳。
在测试中发现Stereo文件夹下各个.yaml文件运行效果都有所差异,尝试制作自己的.yaml文件
制作自己的标定图集,注意摄像头编号、路径、角点和像素
# -*- coding: utf-8 -*-
import cv2
import time
AUTO = True # 自动拍照,或手动按s键拍照
INTERVAL = 6 # 自动拍照间隔
cv2.namedWindow("left")
cv2.namedWindow("right")
cap = cv2.VideoCapture(0)
# 设置分辨率左右摄像机同一频率,同一设备ID;左右摄像机总分辨率3840x1080;分割为两个1920x1080
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
counter = 0
utc = time.time()
folder = "/home/nh666/llw/ORB_FAR/标定图片/" # 拍照文件目录
def shot(pos, frame):
global counter
path = folder + pos + "_" + str(counter) + ".jpg"
cv2.imwrite(path, frame)
print("snapshot saved into: " + path)
while True:
ret, frame = cap.read()
print("ret:", ret)
# 裁剪坐标为[y0:y1, x0:x1] HEIGHT * WIDTH,
#双目相机是两个在一起的,通过剪切坐标位置可以单独分开相机
left_frame = frame[0:480, 0:640]
right_frame = frame[0:480, 640:1280]
cv2.imshow("left", left_frame)
cv2.imshow("right", right_frame)
now = time.time()
if AUTO and now - utc >= INTERVAL:
shot("left", left_frame)
shot("right", right_frame)
counter += 1
utc = now
key = cv2.waitKey(1)
if key == ord("q"):
break
elif key == ord("s"):
shot("left", left_frame)
shot("right", right_frame)
counter += 1
cap.release()
cv2.destroyWindow("left")
cv2.destroyWindow("right")
根据1、2来观察,通过4去删除偏差过大的图片,5用来观察极线,6是导出数据
建议复制一份新的来修改,怎么修改可以参考这篇博客
接下来需要进行地图测试了
未完待续。。。