
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 LTSFocal 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需要C11以上)构建工具 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包需要安装rosdep和catkin构建系统的相关工具。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_makecatkin_make命令会初始化工作空间生成build和devel目录。同样我们需要将这个工作空间的环境也配置到终端。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-dev4.2 编译安装PangolinPangolin用于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 处理OpenCVROS自带与手动安装的共存策略如前所述ROS Noetic自带OpenCV 4.2.0。我们可以通过以下命令查看pkg-config --modversion opencv4ORB-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_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local/opencv-3.4.16 \ -D OPENCV_EXTRA_MODULES_PATH~/opencv_contrib/modules \ -D WITH_TBBON \ -D WITH_OPENMPON \ -D ENABLE_PRECOMPILED_HEADERSOFF \ -D BUILD_opencv_worldOFF .. # 关闭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.git5.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这个脚本会将Examples/ROS/ORB_SLAM3目录链接到Catkin工作空间的src下。在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节点可执行文件例如Mono、Mono_Inertial、Stereo、RGBD等。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.tgz6.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/libCMake 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_SOFTWARE1。这强制使用软件渲染虽然慢但通常能显示。长期解决需要配置好显卡驱动。运行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_MAKEFILEON参数让make输出每一条编译和链接命令方便定位是哪个文件出了错。检查依赖库版本使用ldd命令检查生成的可执行文件依赖了哪些库确认链接的OpenCV、Pangolin等库的路径是否正确。ldd ~/catkin_ws/devel/lib/ORB_SLAM3/RGBD | grep opencv7. 环境固化与项目迁移建议当你在一台机器上成功搭建环境后如何将其“固化”下来方便在其他机器上复现或者防止自己的系统崩溃后重装呢7.1 使用脚本自动化将上述所有安装和编译步骤除了需要交互的部分写成一个Shell脚本。关键步骤如编译OpenCV、ORB_SLAM3时可以加入错误检查如果失败就退出。对于需要特定版本依赖的项目这种脚本是团队协作的利器。7.2 依赖清单管理除了脚本维护一个requirements.txt或Dockerfile是更专业的做法。对于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探索之旅。如果在实际操作中遇到了本文未涵盖的新问题欢迎在社区分享技术的进步正是在这样的交流中不断累积的。