Hi~ o(_ ̄▽ ̄_)ブ,好久不见,甚是想念。大家好,我是小沐,嘿嘿。

前言

小沐寒假消失了,被一个叫做驾照的恶魔抓走了,还好小沐聪明的一批,过五关斩六将,亿顿操作下来之后,驾照这个恶魔被小沐成功感化,这才放我回来,实在是太难了! (师弟:笑不活了,你接着编。o(*≧▽≦)ツ┏━┓ 我:你见过砂锅大的拳头吗?!)

小皮一下,接下来我们书归正传,今天呢,和大家讨论一下ORB_SLAM3的安装,之所以会写这个文章,主要是因为它安装起来太太太玄学了。我自己安装的时候查阅了不少东西,整理了些许笔记,想着可能大家应该会有需要,于是发出来和大家共同探讨。

强烈建议,在进行安装之前通读全文特别是错误展示之处,会事半功倍!!!!

正文

说实话,网上的ORB_SLAM3的安装的教程超级多,但是我测试的是基本上没几个跑成功的,索性直接就是跟着github来,ORB_SLAM3网址如下:https://github.com/UZ-SLAMLab/ORB_SLAM3

首先呢,我的环境是ubuntu 18.04,ROS是melodic已经装好了。

在安装之前给各位打好预防针,ORB_SLAM3还是有些复杂的,既然决定安装了那就遇到问题不要慌,冷静分析。

接下来我们直接去github看readme:

根据github,我们首先是检查我们的C++版本,显示要支持C++11特性,那我们如何知道自己可不可以呢,

我们可以使用一个简单粗暴的方法:新建一个cpp文件,使用C++11编译它,成功说明可以。

新建一个main.cpp (诶,写个什么好呢,诶,Hello World!)

#include <iostream>
using namespace std ;
int main ()
{
    cout<<"Hello World"<<endl;
    return 0;
}

然后我们打开我们的终端,编译它,命令:

g++ -std=c++11 -o main main.cpp

然后继续命令:

echo $?

看清楚嗷,这个时候应该输出一个 0。如图:

(我还给大家输出了一下,证明我没错,哈哈)这个时候呢,说明我们的系统具备C++11特性,然后我们就可以继续下一步了,这里放一下我的gcc版本:

接下来我们就要开始进行ORB_SLAM3的安装了,我呢,有一个“好习惯”,就是比较喜欢整理,所以我的ROS环境都在workspace文件夹下,在这个文件夹下创建各个ROS的工作空间,这次的ORB_SALM也是一样,因为ORB_SALM依赖比较多,所以我又在ORB_SALM下多加了一级专门存放依赖文件。

接下来,我们开始进行Pangolin的安装

在你的工作空间打开终端,依次输入以下命令:

git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build
cd build
cmake ..
cmake --build .
sudo make install(这个也是需要的,网上很多教程没有这个命令)

我简单介绍一下这个步骤哈(不要嫌弃我啰嗦,我感觉教程越细越好,别问,问就是风格!)

git clone这里呢就是将github的包下载到本地

mkdir build是使用mkdir创建了一个build文件夹

cd build是进入到build文件夹下

cmake ..链接配置文件

cmake —build .命令用来将调用与构建平台相关的构建命令,例如cmake —build .在linux平台相当于执行

sudo make install是用来安装的,它也从Makefile中读取指令,安装到指定的位置

关于cmake的一些简单要点可以看这里:https://www.jianshu.com/p/23683ddaaa1c

个人感觉还是不错的。

可能会报错,如果错误是缺少依赖:

sudo apt install libgl1-mesa-dev
sudo apt install libglew-dev
sudo apt install libpython2.7-dev
sudo apt install pkg-config
sudo apt install libegl1-mesa-dev libwayland-dev libxkbcommon-dev wayland-protocols

如果没有报错的话,就是安装成功了,这里我们可以通过一个小例子测试:

cd build/examples/HelloPangolin
./HelloPangolin

这里呢,是进入到了build/examples/HelloPangolin文件夹下,运行了一个HelloPangolin的示例。效果如下(是一个立方体):

我个人这一步并没有报错,如果有人报错不能解决的话,可以评论,我会关注动态的。

安装Eigen

这里呢,需要特别注意下,ORB_SLAM的github上说的是最少3.1.0,但是经过我的安装测试,3.1.0并不能满足我们的需求,后期用ROS启动时候3.1.0编译是会报错,采取3.3.5,为了减少后期的卸载安装的麻烦,我们直接使用3.3.5。Eigen的gitlab:https://gitlab.com/libeigen/eigen/-/releases/3.3.5

这里下载下来是个压缩包,我们将压缩包放到我们的工作空间下,进行解压缩然后进入eigen-3.3.5文件夹下打开终端:

  mkdir build
  cd build
  cmake ..
  sudo make install

这里安装后,其头文件安装在/usr/local/include/eigen3/。我们可以打开一个新的终端运行下面这个命令可以查看eigen3位置。

locate eigen3

到这安装结束。

值得一提的是这一步,这一步是后面编译过程中出现find_package(Eigen3 REQUIRED)无法找到Eigen3的错误,此时我们可以建立软连接解决:

sudo ln -s /usr/local/include/eigen3 /usr/include/eigen3

后记:这里eigen3的安装位置有点迷惑了,有的时候是安装在/usr/local/include/eigen3(旧系统安装的时候),有些时候是安装在/usr/include/eigen3(重装系统验证的时候),不过可能是因为我特意重装系统验证环境的原因,这里影响不大两个位置都可以使用,装在了/usr/include/eigen3还省去了软连接的操作。

安装opencv

这里opencv至少需要 3.0。官方使用 OpenCV 3.2.0 和 4.4.0 测试。我们求稳起见,使用官方测试过的,我使用的是opencv-3.2.0。github包地址:https://github.com/opencv/opencv/releases/tag/3.2.0

下载完成后,老样子放到工作空间下解压缩然后进入opencv文件夹下,右键打开终端:

mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

安装opencv不出意外的话你会遇到这个问题:ICV: Downloading ippicv_linux_20151201.tgz…之后提示很多错误,这里是因为这个ippicv_linux_20151201.tgz包下载不下来导致的,这里我们需要手动下载,将其放到然后复制替换到opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e文件下.

ippicv_linux_20151201.tgz包下载地址(需要vpn):https://raw.githubusercontent.com/Itseez/opencv_3rdparty/81a676001ca8075ada498583e4166079e5744668/ippicv/ippicv_linux_20151201.tgz

因为大小并不大我放百度网盘一份:

链接: https://pan.baidu.com/s/1In12KXpDK-EwVOAXv7iWVA 提取码: 7kga

接着回到终端编译:

sudo make

安装

sudo make install

配置opencv环境:

sudo gedit /etc/ld.so.conf.d/opencv.conf

文末添加:

/usr/local/lib

保存后使路径生效:

sudo ldconfig

接下来是bash:

sudo gedit /etc/bash.bashrc

文件末添加:

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  
export PKG_CONFIG_PATH

保存使配置生效

source /etc/bash.bashrc

更新

sudo updatedb

配置完成。这里opencv就结束了。

后记:如果你在安装opencv之前安装了qt5的话可能会出现如下错误:

解决办法如下:

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

添加一个参数限制-DENABLE_PRECOMPILED_HEADERS=OFF,改为

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. -DENABLE_PRECOMPILED_HEADERS=OFF

其他命令不用变,重复上面的步骤即可。

DBoW2 和 g2o(包含在第三方文件夹中)

源码中有,无需下载,我们会在后面进行编译。

Python

sudo apt install libpython2.7-dev

我呢,提前装好ROS了,python2.7在装ROS的时候就装好了,故不用执行这一步。

到此依赖编译完成。

编译ORB_SLAM3

在工作空间下,打开终端,获取源代码:

git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git ORB_SLAM3

然后等一下,按照官网的步骤接下是:这里我们先不要操作,先看一下命令是啥意思。

cd ORB_SLAM3
chmod +x build.sh
./build.sh

chmod +x build.sh是给 build.sh赋予可允许权限。

./build.sh是直接运行。

这里我们要注意了,build.sh这是一个bash脚本,也就是说这是一个自动化脚本,既然注意都注意了,那我们就看看这里面有什么吧!

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 ../../Sophus

echo "Configuring and building Thirdparty/Sophus ..."

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 -j4

兄弟们注意到什么了吗,这个脚本编译了5个文档,这就是很多人第一次编译ORB_SLAM3连错误都不看不明白的大部分原因,连续编译5个,都不知道那个错是哪个的。所以鉴于我们第一次编译ORB_SLAM3,这里我们按部就班一步一步来。

我们首先编译Thirdparty/DBoW2,在ORB_SLAM3文件夹下打开终端

cd Thirdparty/DBoW2
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j

编译成功后,编译g2o

cd ../../g2o
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j

编译成功后,编译Sophus

cd ../../Sophus
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j

编译成功后,进入Vocabulary解压文件

cd ../../../
cd Vocabulary
tar -xf ORBvoc.txt.tar.gz
cd ..

接下来就是注如灵魂了:构建 ORB_SLAM3

mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4

编译遇到问题集合:

问题一:
fatal error: boost/serialization/serialization.hpp: No such file or directory
解决方案:sudo apt install libboost-filesystem-dev

问题二:
fetal error:openssl/md5.h: No such file or directory
解决方案:sudo apt-get install libssl-dev

问题三:
/usr/bin/ld: cannot find -lboost_serialization
collect2: error: ld returned 1 exit status
CMakeFiles/ORB_SLAM3.dir/build.make:832: recipe for target '../lib/libORB_SLAM3.so' failed
解决方案:sudo apt install libboost-all-dev

ORB_SLAM3编译报错问题-找不到OpenCV4.4,报错如下:

CMake Warning at CMakeLists.txt:33 (find_package):
  Could not find a configuration file for package "OpenCV" that is compatible
  with requested version "4.4".

  The following configuration files were considered but not accepted:

    /usr/share/OpenCV/OpenCVConfig.cmake, version: 3.2.0



CMake Error at CMakeLists.txt:35 (message):
  OpenCV > 4.4 not found.


-- Configuring incomplete, errors occurred!
See also "/home/tys/ORB_SLAM3/build/CMakeFiles/CMakeOutput.log".
make: *** 没有指明目标并且找不到 makefile。 停止。

找到ORB_SLAM3文件夹下的CMakeList.txt 中上图位置,修改find_package(OpenCV 4.4),如下代码所示。

LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

find_package(OpenCV 4.4)
    if(NOT OpenCV_FOUND)
       message(FATAL_ERROR "OpenCV > 4.4 not found.")
    endif()

改成如下:

LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

find_package(OpenCV 3.2.0)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 4.4 not found.")
   endif()

我是把原来的注释之后添加的,如下:

编译完成后我们可以进行一些使用测试了。

我们先下载数据集,我下载的是EuRoC MAV 数据集,这个数据集不用挂梯子,地址:https://projects.asl.ethz.ch/datasets/doku.php?id=kmavvisualinertialdatasets

当我们下载完数据集返回github准备启动文件的时候,我们会发现一些问题,Readme中写明的启动文件没了,估计是作者删除了,但是不重要,在其他的github仓库可以找到,地址:https://github.com/yuantao15/ORB_SLAM3

如图:这个启动文件内是一个启动文件命令集合,我们可以选取其中的某一行命令运行即可。

我呢,选取euroc_examples.sh中的示例是:

其中我们修改的地方是:

"$pathDatasetEuroc"/V103

pathDatasetEuroc表示数据集路径。我呢,下载的数据集是V1_03_difficult,将其解压缩,并解压缩后的文件名修改为V103,准备把数据集放在 datasets/EuRoC( datasets/EuRoC这个文件夹是我自己创建的)下,故应该设置为 ./datasets/EuRoC/V103

undefined

修改如下:

./Examples/Monocular-Inertial/mono_inertial_euroc ./Vocabulary/ORBvoc.txt ./Examples/Monocular-Inertial/EuRoC.yaml ./datasets/EuRoC/V103 ./Examples/Monocular-Inertial/EuRoC_TimeStamps/V103.txt dataset-V103_monoi

然后我们回到图中这里,右键打开终端输入修改后的代码就可以跑数据集了。

undefined

效果图:

我这里改了两个节点的,大家自己看着用。

Stereo Examples

./Examples/Stereo/stereo_euroc ./Vocabulary/ORBvoc.txt ./Examples/Stereo/EuRoC.yaml ./datasets/EuRoC/V103 ./Examples/Stereo/EuRoC_TimeStamps/V103.txt dataset-V103_stereo

Monocular-Inertial Examples
./Examples/Monocular-Inertial/mono_inertial_euroc ./Vocabulary/ORBvoc.txt ./Examples/Monocular-Inertial/EuRoC.yaml ./datasets/EuRoC/V103 ./Examples/Monocular-Inertial/EuRoC_TimeStamps/V103.txt dataset-V103_monoi

ROS部分编译

对ROS的编译:

根据github的ROS部分来,先在~/.bashrc环境中添加环境变量,值得一体的是,由于orb_slam作者的更新,ROS示例被放到了Examples_old位置,所以编译文件时应该注意,我们不再是进入Examples,而是进入到Examples_old。Examples需要修改为Examples_old,我们在~/.bashrc中添加环境变量也就变成了:

export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:PATH/ORB_SLAM3/Examples_old/ROS

还记得如何打开~/.bashrc吗?

sudo gedit ~/.bashrc

如图,/home/m/v_slam_orb3 这是我的工作空间,大家记得修改成自己的:

看到这个第一行的英文没,这句话的意思是这一行必须放在bashrc的最后一行!否则环境变量写不进去。

我们可以通过下面这句话验证一下,查看ROS的环境变量:

echo $ROS_PACKAGE_PATH

不再最后一行:

在最后一行:

github是直接脚本,我喜欢看着.sh文件进行编译,自动化脚本对于第一次编译的时候并不友好,毕竟某些环境问题还没解决一步一步来更可靠。所以我来到了.sh文件,一步一步来。

echo "Building ROS nodes"

cd Examples/ROS/ORB_SLAM3
mkdir build
cd build
cmake .. -DROS_BUILD_TYPE=Release
make -j

可以看到内容结构还是很简单的。我推荐看着这个自己开终端操作。

这里,由于orb_slam作者的更新ros示例被放到了Examples_old位置,所以编译文件时应该注意,我们不再是进入Examples,而是进入到Examples_old。

cd Examples_old/ROS/ORB_SLAM3
mkdir build
cd build
cmake .. -DROS_BUILD_TYPE=Release
make -j

静等编译完成。

关于报错

错误1:

[rosbuild] Building package ORB_SLAM3
[rosbuild] Error from directory check: /opt/ros/melodic/share/ros/core/rosbuild/bin/check_same_directories.py  /home/m/v_slam_orb3/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3
1
Traceback (most recent call last):
  File "/opt/ros/melodic/share/ros/core/rosbuild/bin/check_same_directories.py", line 46, in <module>
    raise Exception
Exception
CMake Error at /opt/ros/melodic/share/ros/core/rosbuild/private.cmake:99 (message):
  [rosbuild] rospack found package "ORB_SLAM3" at "", but the current
  directory is "/home/m/v_slam_orb3/ORB_SLAM3/Examples_old/ROS/ORB_SLAM3".
  You should double-check your ROS_PACKAGE_PATH to ensure that packages are
  found in the correct precedence order.
Call Stack (most recent call first):
  /opt/ros/melodic/share/ros/core/rosbuild/public.cmake:177 (_rosbuild_check_package_location)
  CMakeLists.txt:4 (rosbuild_init)

这个错误呢,就是环境变量引起的了,你没听话,没有将

export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:PATH/ORB_SLAM3/Examples_old/ROS

放在最后一行。

make -j报错:

报错一:(附带图片)
CMakeFiles/MonoAR.dir/build.make:198: recipe for target ‘CMakeFiles/MonoAR.dir/src/AR/ViewerAR.cc.o’ failed

解决思路来自于github的解答: https://github.com/UZ-SLAMLab/ORB_SLAM3/issues/442
但是值得注意的是如果要使用cv::eigen2cv()还需要添加头文件 参考:https://www.jianshu.com/p/23b40b0f66aa

其中 #include 可有可无,c++默认的。头函数如下:

#include <Eigen/Dense>
#include <iostream>
#include <opencv2/core/eigen.hpp>
#include <opencv2/opencv.hpp>

具体操作如下:

首先我们根据图片中内容分析,很容易就找找到了这几个文件所在。

改代码之前记得先添加头文件。

找到ORB_SLAM3/Examples_old/ROS/ORB_SLAM3/src/AR下的ros_mono_ar.cc文件:

解决 cv::Mat Tcw = mpSLAM->TrackMonocular(cv_ptr->image,cv_ptr->header.stamp.toSec()); 报错:

 cv::Mat Tcw = mpSLAM->TrackMonocular(cv_ptr->image,cv_ptr->header.stamp.toSec());

替换为:

 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);

找到ORB_SLAM3/Examples_old/ROS/ORB_SLAM3/src/AR下的ViewerAR.cc文件:

解决 vPoints.push_back(pMP->GetWorldPos()); 报错:

vPoints.push_back(pMP->GetWorldPos());

改为:

cv::Mat WorldPos;
cv::eigen2cv(pMP->GetWorldPos(), WorldPos);
vPoints.push_back(WorldPos);

解决 cv::Mat Xw = pMP->GetWorldPos();报错:

cv::Mat Xw = pMP->GetWorldPos();

改为:

cv::Mat Xw;
cv::eigen2cv(pMP->GetWorldPos(), Xw);

重新编译。

后记:我重装系统验证时在此就编译成功了。

还可能遇到错误:

fatal error: sophus/se3.h: No such file or directory

这个其实在上文的github上面也有所解答。

具体操作如下:找到ORB_SLAM3/Examples_old/ROS/ORB_SLAM3下的CMakeLists.txt 修改它,include_directories中添加 ${PROJECT_SOURCE_DIR}/../../../Thirdparty/Sophus

还可以通过重新安装的方式:参考:https://blog.csdn.net/weixin_44684139/article/details/104803225

最后呢,我们为了方便后期编译,记得把自动化脚本也改过来。改为如下:

echo "Building ROS nodes"

cd Examples_old/ROS/ORB_SLAM3
mkdir build
cd build
cmake .. -DROS_BUILD_TYPE=Release
make -j

至此我们的安装结束了。

根据github启动ROS节点:

ROS启动:

分别打开三个终端:

启动roscore:

roscore

使用Stereo节点启动:

rosrun ORB_SLAM3 Stereo Vocabulary/ORBvoc.txt Examples_old/Stereo/EuRoC.yaml true

启动rosbag:

rosbag play --pause V1_03_difficult.bag /cam0/image_raw:=/camera/left/image_raw /cam1/image_raw:=/camera/right/image_raw /imu0:=/imu

分析:

rosrun一行命令要在工作空间内启动。

rosbag要在bag包所在空间内启动。

效果:

到此,结束了。

结语

这一篇文章有点长了,感谢大家的阅读,写的过于罗嗦了,见谅见谅。期待下次见面,共勉。