1. 开篇为什么你的LeGO-LOAM在Ubuntu 20.04上总是编译失败如果你正在Ubuntu 20.04上折腾LeGO-LOAM大概率已经踩过几个坑了。我刚开始的时候也一样满心欢喜地克隆了代码结果catkin_make一敲下去满屏的红色错误什么OpenCV找不到、Eigen报错、Boost库缺失……瞬间头大。这太正常了因为LeGO-LOAM这个优秀的激光SLAM算法最初是针对ROS KineticUbuntu 16.04和ROS MelodicUbuntu 18.04环境开发的而Ubuntu 20.04自带的是全新的软件包生态比如OpenCV 4和PCL 1.10这就导致了很多接口不兼容的问题。别担心这篇文章就是为你准备的。我不是要给你一堆冷冰冰的错误代码列表而是想把我自己从环境配置、编译、到最终成功运行整个过程中遇到的所有“坑”和解决方案像朋友聊天一样分享给你。你会发现这些问题都有清晰的解决路径跟着步骤走你完全可以在Ubuntu 20.04上顺利跑通LeGO-LOAM。整个过程不仅是为了成功编译更是让你理解背后“为什么”下次遇到类似问题你也能自己搞定。2. 环境准备搭建一个稳固的ROS Noetic工作空间在开始编译LeGO-LOAM之前一个干净、配置正确的ROS环境是基础。Ubuntu 20.04对应的ROS版本是Noetic这是最后一个支持Ubuntu的ROS 1发行版。很多新手会忽略这一步直接用旧教程里的命令结果导致依赖关系混乱。2.1 ROS Noetic的完整安装与验证首先确保你的系统已经安装了完整的ROS Noetic。如果你不确定可以重新执行一遍核心安装步骤。打开终端依次输入以下命令# 设置软件源确保使用国内的镜像以加速下载 sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list # 设置密钥 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 # 更新软件包索引 sudo apt update # 安装完整版的ROS Noetic包括ROS、rqt、rviz等常用工具 sudo apt install ros-noetic-desktop-full安装完成后最关键的一步是初始化rosdep。这个工具用于安装ROS包的系統依赖LeGO-LOAM编译时很多库找不到的问题根源可能就是它没初始化好。sudo rosdep init rosdep update最后别忘了把ROS环境变量添加到你的bashrc文件中这样每次打开新终端都会自动载入ROS环境。echo source /opt/ros/noetic/setup.bash ~/.bashrc source ~/.bashrc验证安装是否成功可以运行一个经典的小海龟测试。分别打开两个终端一个运行roscore另一个运行rosrun turtlesim turtlesim_node。如果能看到小海龟窗口说明ROS核心环境没问题。2.2 创建并初始化专属的Catkin工作空间我不建议在系统默认的ROS路径下编译你的项目。创建一个独立的工作空间是个好习惯便于管理也避免污染系统环境。# 在你的用户目录下或其他你喜欢的位置创建工作空间文件夹 mkdir -p ~/lego_loam_ws/src cd ~/lego_loam_ws/src # 初始化工作空间这会生成顶层的CMakeLists.txt catkin_init_workspace # 返回工作空间根目录进行首次编译空编译 cd ~/lego_loam_ws catkin_make首次编译成功后同样需要将这个工作空间的环境变量也加入bashrc。注意工作空间的环境设置要放在系统ROS环境设置之后这样你的自定义包才能覆盖系统的。echo source ~/lego_loam_ws/devel/setup.bash ~/.bashrc source ~/.bashrc至此一个专为LeGO-LOAM准备的ROS开发沙箱就搭建好了。接下来我们就可以把主角请进来了。3. 获取源码与安装核心依赖LeGO-LOAM的编译依赖几个关键的第三方库其中最重要的是GTSAM因子图优化库。很多编译错误其实是因为依赖库版本不对或没安装完整。3.1 安装GTSAM因子图优化的基石GTSAM是LeGO-LOAM后端优化的核心。Ubuntu的软件源里虽然有libgtsam-dev但版本可能较旧。我推荐从源码编译安装一个较新的稳定版本如4.1.0兼容性更好。# 安装编译所需的工具 sudo apt install cmake libboost-all-dev -y # 下载GTSAM 4.1.0版本源码你也可以在GitHub release页面查看最新稳定版 cd ~ git clone https://github.com/borglab/gtsam.git cd gtsam git checkout 4.1.0 # 切换到4.1.0标签 # 编译并安装 mkdir build cd build cmake -DGTSAM_BUILD_WITH_MARCH_NATIVEOFF .. # 关闭特定CPU优化以提高兼容性 make -j$(nproc) # -j参数根据你的CPU核心数并行编译加快速度 sudo make install安装完成后GTSAM的头文件和库文件会被安装到/usr/local/include和/usr/local/lib下。系统通常能自动找到它们。3.2 克隆LeGO-LOAM源码到工作空间现在将LeGO-LOAM的源码克隆到我们刚才创建的工作空间的src目录下。cd ~/lego_loam_ws/src git clone https://github.com/RobustFieldAutonomyLab/LeGO-LOAM.git克隆完成后你的src目录结构应该是这样的~/lego_loam_ws/src/ └── LeGO-LOAM/ ├── CMakeLists.txt ├── package.xml ├── launch/ ├── src/ └── ...准备工作看似完成了但直接编译肯定会出问题。因为Ubuntu 20.04的“新特性”正在前面等着我们。接下来我们就进入问题排查与修复的核心环节。4. 编译错误全攻略逐个击破Ubuntu 20.04的“坑”这是最核心的部分我会按照编译时错误出现的典型顺序带你一步步解决。你可以边操作边编译测试。4.1 第一个拦路虎OpenCV 4的头文件路径错误这是你执行catkin_make后几乎必定会遇到的第一个错误。错误信息类似于fatal error: opencv/cv.h: No such file or directory这是因为在OpenCV 3及以前核心头文件放在opencv/cv.h而OpenCV 4采用了模块化这个路径已经废弃了。LeGO-LOAM源码里还在用老式的包含方式。解决方法很简单但需要细心找到文件在LeGO-LOAM文件夹下找到include/utility.h文件。修改头文件用文本编辑器打开它找到这一行#include opencv/cv.h将其修改为OpenCV 4对应的头文件#include opencv2/imgproc.hpp // 有时可能还需要添加核心头文件如果后续还有opencv相关报错可以加上 // #include opencv2/core.hpp保存文件。这个改动是因为utility.h中可能只使用了OpenCV的图像处理功能imgproc.hpp基本够用。这个修改是解决OpenCV兼容性问题最关键的一步。4.2 第二个难题PCL库与C标准不匹配解决了OpenCV再次编译你可能会遇到关于PCL点云库的错误。这通常表现为两类问题A需要C14标准错误信息可能不直接说C版本但一些语法特性不支持。LeGO-LOAM的代码用到了C14的特性而默认的编译标准可能较低。解决修改LeGO-LOAM项目根目录下的CMakeLists.txt文件。 找到设置编译标志的行或者直接在project()声明之后添加set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON)我更推荐这种方式比直接修改CMAKE_CXX_FLAGS更规范。问题BEigen命名空间冲突这是一个非常典型的错误错误信息如下/usr/include/pcl-1.10/pcl/filters/voxel_grid.h:340:21: error: ‘Index’ is not a member of ‘Eigen’这是因为PCL 1.10Ubuntu 20.04默认安装中的某些模板与Eigen库的版本存在兼容性问题。Eigen::Index这个类型在特定上下文中没有被正确定义。解决这是一个系统头文件的问题我们不能直接修改/usr/include下的文件。但我们可以通过一个“打补丁”的方式在编译时绕过它。原理是创建一个同名的头文件放在我们项目的include路径中编译器会优先使用我们的版本。在LeGO-LOAM/include目录下创建一个新文件命名为voxel_grid.h注意这和PCL的系统头文件同名。在这个新文件中添加以下内容#include pcl/filters/voxel_grid.h // 解决Eigen::Index编译错误 namespace pcl { using ::Eigen::Index; }然后需要修改LeGO-LOAM中所有包含了原版pcl/filters/voxel_grid.h的源文件主要是imageProjection.cpp,featureAssociation.cpp,mapOptmization.cpp,transformFusion.cpp将它们改为包含我们自己的这个头文件。例如将#include pcl/filters/voxel_grid.h改为#include “voxel_grid.h” // 注意使用引号表示从本地路径查找这个操作稍微繁琐但一劳永逸。它告诉编译器当遇到pcl::Eigen::Index时使用全局的Eigen::Index。4.3 第三个障碍Boost库链接错误继续编译你可能会遇到关于Boost库的链接错误/usr/bin/ld: 找不到 -lBoost::serialization ...错误信息显示找不到Boost的某些组件。这是因为CMake在查找Boost时没有明确指定需要哪些组件。解决再次打开LeGO-LOAM的CMakeLists.txt文件。找到find_package(Boost REQUIRED)这一行如果存在或者在其附近添加。将其修改为明确列出所需的组件find_package(Boost REQUIRED COMPONENTS serialization timer thread chrono)修改后CMake在配置阶段就会去检查这些特定的Boost组件是否存在并设置正确的链接库名称从而避免链接器ld报错。4.4 编译成功后的“最后一公里”错误假设你解决了以上所有问题catkin_make终于顺利通过生成了可执行文件。但当你激动地运行roslaunch时可能还会遇到运行时错误。问题动态链接库缺失错误示例.../devel/lib/lego_loam/mapOptmization: error while loading shared libraries: libmetis.so: cannot open shared object file...这表示程序运行时找不到libmetis.so这个动态库。GTSAM的某些功能依赖METIS图划分库但它在编译时是静态链接或找到了运行时环境却缺失。解决安装对应的开发包即可。sudo apt-get install libparmetis-dev这个包会同时提供libmetis.so。安装后一般不需要重新编译LeGO-LOAM直接再次运行即可。5. 运行与可视化让点云地图动起来当所有错误都解决后就可以享受胜利果实了。LeGO-LOAM通常使用KITTI数据集进行测试。5.1 准备与运行数据集下载数据集从KITTI官网下载点云数据集例如2011_09_26_drive_0005并解压。修改启动文件打开LeGO-LOAM/launch/run.launch文件。找到加载bag文件的部分修改args参数将其指向你数据集bag文件的实际路径。例如arg namebag_file default/home/你的用户名/Downloads/kitti_data/2011_09_26_drive_0005_synced.bag/启动LeGO-LOAMcd ~/lego_loam_ws source devel/setup.bash roslaunch lego_loam run.launch如果一切正常你应该会看到RViz窗口弹出并且开始处理点云数据。5.2 解决RViz可视化中的小毛病有时候算法跑起来了但RViz里的显示有点奇怪比如轨迹不显示或者点云变成奇怪的大方块。话题不对应检查RViz中订阅的话题名称是否与LeGO-LOAM发布的话题匹配。例如原始代码发布的轨迹话题可能是/key_pose_origin但RViz订阅的可能是key_pose_origin少了前面的斜杠。这个斜杠在ROS里代表全局命名空间。你需要保持两者一致。通常修改RViz的订阅话题名更容易。点云显示为大方块这在RViz中很常见。在RViz的Displays面板中找到对应的PointCloud2显示项将其Style属性从默认的Points改为Flat Squares或Boxes大小Size调小到0.01或0.05点云就会以清晰的小方块形式显示了。没有轨迹或地图首先在终端里用rostopic list命令查看LeGO-LOAM是否发布了/laser_cloud_surround、/aft_mapped_to_init等关键话题。如果话题存在但RViz不显示检查RViz中对应显示项的Topic设置是否正确以及Fixed Frame是否设置为/camera_init或/map根据launch文件中的定义。6. 进阶调试与性能优化建议成功运行只是第一步。在实际项目中你可能还需要调整参数以获得更好的建图效果或者进行性能分析。6.1 关键参数调优点LeGO-LOAM的参数配置文件通常在LeGO-LOAM/include/utility.h中以宏定义或常量的形式存在。几个可以关注的参数点云降采样分辨率laserCloudWidth,laserCloudHeight等影响处理速度和内存占用。在资源受限的设备上可以适当降低。特征提取阈值如曲率阈值影响角点和平面点的提取数量关系到匹配的精度和鲁棒性。回环检测参数如搜索半径、历史关键帧数量影响回环闭合的效果和计算量。修改这些参数后需要重新编译项目catkin_make。6.2 使用ROS工具进行调试RQT工具套件rqt_graph可以查看节点和话题的实时连接图检查数据流是否畅通。rqt_plot可以绘制某个话题中数据的曲线比如位姿的变化速度用于分析系统稳定性。TF树检查在终端输入rosrun tf view_frames可以生成当前TF变换关系的PDF图检查/camera_init、/velodyne、/map等坐标系之间的变换链是否正确建立。LeGO-LOAM的位姿输出通常是相对于/camera_init这个初始帧的。6.3 编译与依赖管理的经验之谈经过这么一轮折腾你应该对ROS包的编译依赖有了更深的理解。我的经验是在Ubuntu高版本上编译为低版本ROS设计的包时脑子里要绷紧几根弦OpenCV版本、C标准、PCL/Eigen兼容性、Boost组件。遇到链接错误先看CMake的find_package是否写全了遇到运行时库缺失用ldd命令检查可执行文件依赖哪些so库然后针对性安装-dev包。最后保持工作空间的整洁。如果某个包实在搞不定可以尝试在Docker容器中构建一个与项目原版匹配的ROS环境如Melodic这对于复现论文结果有时是更高效的选择。但在宿主机上成功征服这些兼容性问题带来的成就感和对系统理解的加深是无可替代的。希望这份详细的指南能帮你少走弯路顺利在Ubuntu 20.04上驾驭LeGO-LOAM开启你的激光SLAM探索之旅。