Ubuntu 20.04环境部署ORB-SLAM3:从ROS Noetic到OpenCV版本兼容全攻略

Ubuntu 20.04环境部署ORB-SLAM3:从ROS Noetic到OpenCV版本兼容全攻略

1. 项目缘起与核心价值

最近在折腾一个基于ROS的移动机器人项目,需要一套稳定且性能不错的视觉SLAM方案来做定位和建图。ORB-SLAM3作为当前开源视觉SLAM领域的标杆,其多地图系统、IMU融合以及对多传感器的支持,无疑是首选。然而,当我在一台新装的Ubuntu 20.04系统上准备搭建环境时,发现网上教程虽然多,但要么步骤跳跃太大,要么依赖版本对不上,要么就是ROS版本混杂,一路踩坑无数。从安装ROS Noetic,到编译OpenCV、Pangolin,再到最终搞定ORB-SLAM3,整个过程就像在玩一个依赖地狱版的“俄罗斯方块”。

所以,我决定把这次从零开始,在Ubuntu 20.04上安装ROS Noetic并成功编译运行ORB-SLAM3的完整过程、所有坑点以及解决方案详细记录下来。这篇文章的目标是让你拿到后,能像有一份详细的“施工图纸”一样,一步步操作,避开我遇到的所有陷阱,最终在你的机器上成功跑通ORB-SLAM3。无论你是SLAM初学者,还是需要快速部署环境的研究者,这篇详解都应该能帮到你。我们不仅会安装,还会解释每一步为什么要这么做,以及遇到报错时该如何思考和排查。

2. 环境蓝图与前置准备

在动手之前,我们必须对整体的软件生态有一个清晰的蓝图。Ubuntu 20.04 LTS(Focal Fossa)是一个长期支持版本,系统稳定,社区支持完善。与之对应的ROS官方版本是ROS Noetic Ninjemys,这也是ROS 1的最后一个LTS版本。ORB-SLAM3虽然官方仓库说明支持ROS,但它本质上是一个独立的C++库,ROS包只是其一个封装接口,因此我们需要同时准备ROS工作环境和ORB-SLAM3的编译环境。

核心组件清单与版本选择:

  • 操作系统: Ubuntu 20.04.6 LTS (推荐使用此子版本,避免最新镜像的未知问题)
  • ROS发行版: ROS Noetic Desktop-Full (推荐安装完整版,避免后续缺少Gazebo、rviz等工具)
  • C++编译器: gcc/g++ 9 (Ubuntu 20.04默认,ORB-SLAM3需要C++11以上)
  • 构建工具: CMake >= 3.16 (用于编译ORB-SLAM3及其依赖)
  • Python: Python 3.8 (Ubuntu 20.04默认,ROS Noetic依赖)
  • 关键依赖库
    • Pangolin: 用于可视化和用户交互的轻量级库,必须安装。
    • OpenCV: 计算机视觉基础库,版本>=3.0。这里有个关键点:ROS Noetic自带了OpenCV 4.2.0,但ORB-SLAM3官方推荐使用OpenCV 3。经过实测,使用ROS自带的OpenCV 4.2.0编译ORB-SLAM3可能会在链接阶段出现符号冲突。因此,更稳妥的方案是额外安装一个OpenCV 3.4.x,并与ROS的OpenCV 4共存。
    • Eigen3: 线性代数库,必须安装。
    • DBoW2 和 g2o: ORB-SLAM3源码中已包含,通常无需单独安装。

系统初始化检查:在开始任何安装之前,请先打开终端,执行以下命令更新系统并安装一些基础编译工具。这一步能解决很多因系统软件源未更新或基础开发包缺失导致的诡异问题。

sudo apt update sudo apt upgrade -y sudo apt install -y build-essential cmake git pkg-config

注意-y参数表示自动确认安装,如果你希望手动确认每个安装包,可以去掉它。确保你的网络连接通畅,因为后续需要从GitHub克隆多个仓库。

3. ROS Noetic 安装与工作空间配置

ROS是机器人开发的“操作系统”,它为我们的ORB-SLAM3提供了消息通信、工具链和仿真环境。安装ROS Noetic是第一步,也是最标准化的一步。

3.1 配置软件源与密钥

Ubuntu的apt包管理器需要知道从哪里获取ROS的软件包。我们通过以下命令添加ROS官方的软件源。

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'

接下来,添加ROS软件源的GPG密钥,用于验证软件包的完整性。

sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -

3.2 安装ROS Noetic Desktop-Full

更新软件源列表并安装ROS。这里我强烈推荐安装desktop-full版本,它包含了ROS、RQT、rviz、机器人通用库、2D/3D仿真器、导航等功能包。虽然体积大一些,但避免了后续因缺少某个功能包而四处寻找的麻烦。

sudo apt update sudo apt install -y ros-noetic-desktop-full

安装过程可能需要10-30分钟,取决于你的网速。安装完成后,ROS的核心命令(如roscore,rosrun)已经就位,但它们还不在你的终端默认环境变量中。

3.3 配置ROS环境变量

为了让系统知道ROS命令的位置,我们需要将ROS的环境设置脚本添加到终端的启动文件中。这样每次打开新的终端,ROS环境都会自动生效。

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc source ~/.bashrc

第一行命令将source命令写入你的.bashrc文件末尾。第二行命令立即生效当前终端的环境。

3.4 安装ROS构建工具和依赖管理工具

为了后续创建我们自己的工作空间并编译ORB-SLAM3的ROS包,需要安装rosdepcatkin构建系统的相关工具。

sudo apt install -y python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential

初始化rosdep,这是一个用于安装ROS包系统依赖的工具。

sudo rosdep init rosdep update

实操心得sudo rosdep init这一步可能会失败,提示“Website may be down.”。这通常是由于网络问题导致无法访问raw.githubusercontent.com。解决方案有两种:一是使用稳定的网络环境(可能需要配置网络);二是可以暂时跳过此步,因为ORB-SLAM3的核心依赖我们后续会手动安装,rosdep主要用于更复杂的ROS生态包。如果跳过,后续在编译ROS工作空间时,如果遇到缺少系统依赖的报错,再手动apt install对应包即可。

3.5 创建Catkin工作空间

Catkin是ROS的官方构建系统。我们将在这个独立的工作空间里编译和存放自己的ROS包(包括ORB-SLAM3的ROS接口)。

mkdir -p ~/catkin_ws/src cd ~/catkin_ws/ catkin_make

catkin_make命令会初始化工作空间,生成builddevel目录。同样,我们需要将这个工作空间的环境也配置到终端。

echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc

至此,一个完整的ROS Noetic开发环境已经准备就绪。你可以通过运行roscore来测试ROS核心是否正常启动。

4. ORB-SLAM3 核心依赖库的编译与安装

这是整个过程中最容易出错的部分。ORB-SLAM3依赖的几个关键库需要从源码编译,以确保版本兼容性。我们将按照依赖关系,从底层到高层逐一解决。

4.1 安装系统级基础依赖

首先安装一些通用的开发库,这些是编译C++项目常见的依赖。

sudo apt install -y libglew-dev libboost-all-dev libssl-dev libeigen3-dev libsuitesparse-dev libmetis-dev

4.2 编译安装Pangolin

Pangolin用于ORB-SLAM3的可视化,例如显示相机轨迹、特征点等。我们从其GitHub仓库克隆并编译。

cd ~ git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin mkdir build && cd build cmake .. make -j$(nproc) sudo make install
  • -j$(nproc): 使用你电脑所有可用的CPU核心进行并行编译,可以显著加快速度。
  • sudo make install: 将编译好的库文件和头文件安装到系统目录(通常是/usr/local/),这样其他项目就能找到它。

4.3 处理OpenCV:ROS自带与手动安装的共存策略

如前所述,ROS Noetic自带OpenCV 4.2.0。我们可以通过以下命令查看:

pkg-config --modversion opencv4

ORB-SLAM3官方代码主要基于OpenCV 3.x编写。直接使用OpenCV 4编译可能会导致函数接口不兼容。因此,我们选择额外安装OpenCV 3.4.16,这是一个非常稳定的版本。

步骤1:安装OpenCV 3.4.16的编译依赖

sudo apt install -y 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

步骤2:下载并编译OpenCV 3.4.16

我们指定安装路径为/usr/local/opencv-3.4.16,与系统默认路径隔离。

cd ~ wget -O opencv.zip https://github.com/opencv/opencv/archive/refs/tags/3.4.16.zip wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/refs/tags/3.4.16.zip unzip opencv.zip unzip opencv_contrib.zip mv opencv-3.4.16 opencv mv opencv_contrib-3.4.16 opencv_contrib cd opencv mkdir build && cd build

现在进行CMake配置,关键是指定OPENCV_EXTRA_MODULES_PATH(贡献模块路径)和CMAKE_INSTALL_PREFIX(安装路径)。

cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-3.4.16 \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \ -D WITH_TBB=ON \ -D WITH_OPENMP=ON \ -D ENABLE_PRECOMPILED_HEADERS=OFF \ -D BUILD_opencv_world=OFF .. # 关闭world模块,避免与ROS OpenCV冲突

为什么关闭BUILD_opencv_worldOpenCV的world模块会将所有库打包成一个libopencv_world.so。ROS自带的OpenCV 4可能也使用了类似的大库或不同的符号命名。同时存在两个world库或符号冲突,会导致链接器(ld)不知道使用哪个版本的函数,从而引发“未定义引用”或“符号冲突”错误。关闭此选项,让OpenCV 3生成独立的库文件(如libopencv_core.so.3.4),冲突概率大大降低。

配置完成后,开始编译和安装。

make -j$(nproc) sudo make install

步骤3:配置环境变量(可选但推荐)

为了让系统在编译ORB-SLAM3时能找到我们安装的OpenCV 3,可以设置一个环境变量。但更推荐的做法是在编译ORB-SLAM3时,通过CMake的-D参数显式指定OpenCV 3的路径,这样控制更精确。我们会在后面用到。

echo 'export OpenCV_DIR=/usr/local/opencv-3.4.16/lib/cmake/opencv-3.4' >> ~/.bashrc source ~/.bashrc

至此,我们拥有了两套OpenCV:系统(ROS)的OpenCV 4和我们手动安装的OpenCV 3。在后续编译ORB-SLAM3时,我们将明确告诉CMake使用OpenCV 3。

5. ORB-SLAM3 源码获取与编译

依赖库全部就位后,终于可以开始编译ORB-SLAM3本体了。

5.1 克隆ORB-SLAM3仓库

建议克隆到~/catkin_ws/src目录下,这样它就可以作为一个ROS包被我们的Catkin工作空间管理。

cd ~/catkin_ws/src git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git

5.2 编译ORB-SLAM3库(非ROS部分)

ORB-SLAM3的主体是一个独立的C++库。我们先编译它。

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

这个build.sh脚本会自动创建build目录并使用CMake编译。但是,这里极有可能第一次编译失败!失败的原因通常就是上一步提到的OpenCV版本问题。脚本默认会查找系统的OpenCV,很可能找到ROS的OpenCV 4。

5.3 解决编译错误:手动指定OpenCV 3路径

我们需要修改CMakeLists.txt或直接修改编译命令,强制使用我们安装的OpenCV 3。最直接的方法是,先清理之前的编译,然后手动执行CMake。

# 进入ORB_SLAM3目录,清理之前的build rm -rf build mkdir build && cd build

现在,关键的一步来了:执行CMake,并通过-D OpenCV_DIR参数明确指出OpenCV 3的CMake配置路径。

cmake .. -D OpenCV_DIR=/usr/local/opencv-3.4.16/lib/cmake/opencv-3.4

如果配置成功,终端输出中应该能看到类似Found OpenCV: /usr/local/opencv-3.4.16 (found version "3.4.16")的信息。确认无误后,开始编译。

make -j$(nproc)

这次编译应该能顺利通过。编译完成后,在build目录下会生成libORB_SLAM3.so这个核心库文件,以及Examples文件夹下的各种可执行文件(如单目、双目、RGB-D的示例)。

5.4 编译ROS接口包

ORB-SLAM3的ROS包位于ORB_SLAM3/Examples/ROS/ORB_SLAM3目录。我们需要将其编译到Catkin工作空间中。

首先,确保这个ROS包的CMakeLists.txt能找到ORB_SLAM3的主库。通常,它通过find_package(ORB_SLAM3 REQUIRED)来寻找。我们需要确保ORB_SLAM3_DIR环境变量指向了包含ORB_SLAM3Config.cmake文件的目录。这个文件在我们上一步编译主库时,通常会被安装或生成在build目录下。

一个更可靠的方法是,在Catkin工作空间中编译时,修改ROS包的CMakeLists.txt。但ORB_SLAM3提供的ROS包已经做了较好的适配。我们直接使用其提供的脚本。

cd ~/catkin_ws/src/ORB_SLAM3 chmod +x build_ros.sh ./build_ros.sh

这个脚本会:

  1. Examples/ROS/ORB_SLAM3目录链接到Catkin工作空间的src下。
  2. 在Catkin工作空间根目录执行catkin_make,编译ROS包。

同样,如果遇到OpenCV相关的链接错误,你可能需要检查并修改Examples/ROS/ORB_SLAM3/CMakeLists.txt,在其中find_package(OpenCV REQUIRED)语句前或后,手动设置OpenCV_DIR变量。

# 在 CMakeLists.txt 中 find_package(OpenCV REQUIRED) 附近添加 set(OpenCV_DIR /usr/local/opencv-3.4.16/lib/cmake/opencv-3.4) find_package(OpenCV REQUIRED)

修改后,重新运行./build_ros.sh。编译成功后,在~/catkin_ws/devel/lib目录下会出现ORB_SLAM3相关的ROS节点可执行文件,例如MonoMono_InertialStereoRGBD等。

6. 运行测试与常见问题深度排错

环境搭建成功与否,最终需要用数据跑起来验证。ORB-SLAM3官方提供了一些公共数据集用于测试。这里以TUM数据集中的rgbd_dataset_freiburg1_desk为例,测试RGB-D模式。

6.1 下载测试数据集

首先,下载数据集并解压。你需要准备大约2GB的磁盘空间。

cd ~ wget https://vision.in.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_desk.tgz tar -xzvf rgbd_dataset_freiburg1_desk.tgz

6.2 准备词汇文件

ORB-SLAM3需要一个大词汇文件ORBvoc.txt用于回环检测。这个文件通常已经在源码的Vocabulary目录下。如果不存在,可以从发布版本中下载。确保其路径正确。

6.3 启动ROS核心并运行RGB-D节点

打开第一个终端,启动ROS核心服务。

roscore

打开第二个终端,运行ORB-SLAM3的RGB-D节点。你需要根据你的实际路径修改命令中的参数:

  • vocabulary: 指向ORBvoc.txt的路径。
  • settings: 指向相机参数文件TUM1.yaml的路径(在ORB_SLAM3/Examples/RGB-D目录下)。
  • path_to_sequence: 指向你解压的数据集目录路径。
source ~/catkin_ws/devel/setup.bash rosrun ORB_SLAM3 RGBD ~/catkin_ws/src/ORB_SLAM3/Vocabulary/ORBvoc.txt ~/catkin_ws/src/ORB_SLAM3/Examples/RGB-D/TUM1.yaml ~/rgbd_dataset_freiburg1_desk

如果一切顺利,你应该会看到Pangolin窗口打开,并开始显示特征点跟踪和地图构建的过程。

6.4 典型报错与解决方案全解析

在实际操作中,你几乎一定会遇到一些报错。下面是我遇到并解决的主要问题汇总:

报错现象可能原因解决方案
error while loading shared libraries: libORB_SLAM3.so: cannot open shared object file系统找不到ORB_SLAM3的主库。将库路径加入动态链接库缓存:sudo ldconfig。或者更直接地,在运行ROS节点前,设置环境变量:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/你的用户名/catkin_ws/src/ORB_SLAM3/lib
CMake Error at CMakeLists.txt:11 (find_package): By not providing "FindOpenCV.cmake"...CMake找不到OpenCV,或者找到了错误版本。在编译ORB-SLAM3主库或ROS包时,使用-D OpenCV_DIR明确指定OpenCV 3.4.16的CMake路径。
undefined reference tocv::xxx‘` 链接错误链接了错误的OpenCV库(链接了OpenCV 4但代码需要OpenCV 3的符号)。确保编译ORB_SLAM3时OpenCV_DIR指向的是3.4.16。检查ROS包的CMakeLists.txt,也强制其使用OpenCV 3。
Pangolin X11: Unable to retrieve framebuffer optionsPangolin显示问题,可能与NVIDIA驱动或显示设置有关。尝试在运行命令前设置环境变量:export LIBGL_ALWAYS_SOFTWARE=1。这强制使用软件渲染,虽然慢但通常能显示。长期解决需要配置好显卡驱动。
运行ROS节点后,Pangolin窗口黑屏或秒退数据集路径错误、相机参数文件不匹配、词汇文件损坏。仔细检查所有文件路径是否正确。确认相机参数文件TUM1.yaml与数据集(freiburg1)对应。重新下载词汇文件。
catkin_make编译ROS包时报错,提示找不到ORB_SLAM3Catkin在系统范围内找不到ORB_SLAM3包。build_ros.sh脚本应该已经处理了链接。如果没有,可以手动在~/catkin_ws/src/下为ORB_SLAM3主目录创建一个软链接,或者确保ORB_SLAM3_DIR环境变量指向其build目录。

6.5 进阶调试技巧

如果遇到更隐晦的错误,可以尝试以下方法:

  • 逐级编译:在编译ORB-SLAM3主库时,先不用-j$(nproc),而是用make单线程编译,这样错误信息会更清晰,不会混在一起。
  • 查看详细CMake信息:在CMake阶段,添加-DCMAKE_VERBOSE_MAKEFILE=ON参数,让make输出每一条编译和链接命令,方便定位是哪个文件出了错。
  • 检查依赖库版本:使用ldd命令检查生成的可执行文件依赖了哪些库,确认链接的OpenCV、Pangolin等库的路径是否正确。
    ldd ~/catkin_ws/devel/lib/ORB_SLAM3/RGBD | grep opencv

7. 环境固化与项目迁移建议

当你在一台机器上成功搭建环境后,如何将其“固化”下来,方便在其他机器上复现,或者防止自己的系统崩溃后重装呢?

7.1 使用脚本自动化

将上述所有安装和编译步骤(除了需要交互的部分)写成一个Shell脚本。关键步骤如编译OpenCV、ORB_SLAM3时,可以加入错误检查,如果失败就退出。对于需要特定版本依赖的项目,这种脚本是团队协作的利器。

7.2 依赖清单管理

除了脚本,维护一个requirements.txtDockerfile是更专业的做法。对于ROS项目,可以使用rosdep来管理系统依赖。你可以在你的ORB_SLAM3 ROS包的根目录创建一个package.xml文件(如果还没有),并定义依赖,然后使用rosdep install --from-paths src --ignore-src -r -y来一键安装。

7.3 考虑使用Docker

这是最彻底的解决方案。创建一个Docker镜像,其中包含了Ubuntu 20.04、ROS Noetic、OpenCV 3.4.16、Pangolin以及编译好的ORB-SLAM3。这样,在任何支持Docker的机器上,你只需要一条docker run命令就能获得完全一致的环境,彻底摆脱“在我机器上是好的”这类问题。构建Dockerfile的步骤其实就是将本文的手动安装命令自动化。

7.4 文档记录

最后,也是最重要的:像本文一样,详细记录下所有步骤、版本号和遇到的坑。即使是自己写的脚本,时间久了也可能忘记当时为什么某个参数要那么设置。清晰的文档是可持续维护的基石。

整个安装过程虽然步骤繁多,但每一步都有其必要性。理解每一步的作用,能让你在遇到问题时更快地定位和解决。希望这份超详细的指南能帮助你顺利在Ubuntu 20.04上构建起ORB-SLAM3的开发环境,并以此为起点,开始你的视觉SLAM探索之旅。如果在实际操作中遇到了本文未涵盖的新问题,欢迎在社区分享,技术的进步正是在这样的交流中不断累积的。