激光SLAM Cartographer从零安装到跑通官网数据集的完整指南

激光SLAM Cartographer从零安装到跑通官网数据集的完整指南 做激光SLAM的同学早晚都会撞上Cartographer这堵墙。不管你是做扫地机、仓储AGV还是搞自动驾驶的感知融合只要点云数据一上来gmapping那种轻量级的构图方式就有点撑不住了而Cartographer靠着submap回环检测那一套能在二维和三维场景里给你搓出一张质量高得多的栅格地图。但它也是出了名的难装依赖链长、版本敏感、编译时间感人网络上各种教程版本又乱得一塌糊涂很多人甚至卡在第一步的依赖安装上几天都出不来。这篇文章我不打算复读官方文档而是把我自己从零开始装Cartographer、跑通官网数据集的全过程拆开揉碎讲给你听。里面涉及环境选型、依赖编译顺序、数据集下载的绕坑方案、launch文件启动后的结果验证以及我在这个过程中碰到的一堆报错和解决办法。无论你是Ubuntu新手还是已经被ROS折腾过几轮的老手按着这条链路走不说一次成功至少能把排查方向摸清楚。1. 安装前先搞明白Cartographer的依赖链到底长什么样很多人上来就clone官方仓库然后开始编译编译到一半报错就懵了。核心原因是没有理解Cartographer项目的依赖层级。我先把这条链理顺你后面每一步操作心里都有底。Cartographer本体是一个C写的算法库它本身不依赖ROS甚至可以在Windows上编译运行。真正和ROS打交道的是上层封装包cartographer_ros它负责把ROS的消息比如/scan、/odom、/imu转成Cartographer算法库能吃的格式然后再把构建好的地图发布出来。所以你安装的时候必须分开看底层是cartographer上层是cartographer_ros两者不能混为一谈。往下再看cartographer算法库依赖了几个关键第三方库Eigen3矩阵运算库基本所有SLAM算法都要用Ubuntu软件源里自带。Ceres SolverGoogle出的非线性最小二乘优化库Cartographer的后端图优化全靠它。这个库的版本选择和编译方式有讲究后面细说。protobufGoogle的序列化库Cartographer用它做数据的序列化和配置文件的解析。官方要求用protobuf 3.0以上版本但ROS自己的很多包又和系统自带的protobuf版本耦合很深这一个点就够劝退一批人。abseil-cppGoogle的C公共库protobuf 3.x某些版本会依赖它Cartographer的某些版本也需要它。版本锁得非常死不是随便拉一个最新版就能用。glog/gflags日志和命令行参数库编译Ceres和Cartographer时都会用到。如果你的环境里已经装了ROS比如Ubuntu 20.04配ROS Noetic系统里其实已经自带了Eigen3、glog、gflags这些库的某一版本但版本往往对不上Cartographer的要求。所以社区里流行的做法是把这些依赖全部用源码编译到系统里靠新版覆盖旧版或者单独指定路径。听起来有点粗暴但确实是目前被验证过的最稳的一条路。我画了条依赖链你在动手前先记住这个顺序abseil-cpp → protobuf → Ceres Solver → cartographer → cartographer_ros后面的操作基本就是按这个顺序走的。为什么要先装abseil再装protobuf因为某些protobuf版本编译时需要abseil的头文件为什么Ceres要放在Cartographer之前因为Cartographer的CMakeLists里会直接find_package(Ceres)。这个顺序一旦颠倒你可能会遇到找不到Ceres或者protobuf版本冲突的诡异问题。2. 环境选型Ubuntu版本、ROS版本和安装方式的取舍先说结论想少踩坑Ubuntu 20.04 ROS Noetic是目前最舒服的组合。Ubuntu 18.04 ROS Melodic也能装但你要多处理几个python相关的坑Ubuntu 22.04 ROS Humble就麻烦一些了Cartographer官方对ROS 2的支持是后加的网上大量教程还是基于ROS 1写的照着做容易在中间步骤卡住。我不建议在虚拟机里跑这套流程。Cartographer编译的时候CPU占用极高8个核能给你全部跑满虚拟机分配CPU和内存后性能打折编译时间会拉得很难看。如果你手头只有Windows机器先装VMware开一个Ubuntu 20.04的虚拟机也行但请把内存分到8GB以上磁盘至少留30GB空余。我实测过在同样配置下虚拟机编译Cartographer全家桶大概需要40到50分钟物理机直接装大概20到30分钟。接下来是ROS的安装。Noetic的完整安装命令网上已经烂大街了这里不啰嗦记住一个关键点一定要装ros-noetic-desktop-full不要装ros-noetic-desktop。因为desktop版不带rosbag和rviz里面部分插件跑数据集的时候你会发现工具缺这缺那很恼火。ROS装好之后很多人会犹豫Cartographer到底用apt直接装还是源码编译Ubuntu 20.04的官方源里其实没有直接可用的ros-noetic-cartographer这个包但ROS的第三方源里有。我试过apt直接装版本是旧版而且它和后续你想跑官方demo时要求的版本不完全一致会有一些莫名其妙的behavior差异。更关键的是如果你后面想改Cartographer源码、加一些自己写的回调函数apt装的版本很难办。所以我的建议非常明确源码编译。总共要编译四个东西abseil-cpp、protobuf如果系统版本太老的话、Ceres Solver、cartographer、cartographer_ros。别嫌麻烦这个过程本身就是一次很好的排错训练你以后接触其他算法库会感谢这段经历。还有一个绕不开的方案是鱼香ROS一键安装。这是国内社区给ROS新手准备的脚本工具能帮你快速装好ROS环境和一些常用工具。我的看法是用它可以快速把ROS本体装好省去配源和更新时的折腾。但Cartographer本身的依赖编译还是得自己来一键脚本能帮你处理的只是环境层面的问题。所以别把它当成万能解药。3. 依赖库编译实操abseil、protobuf、Ceres一步步来在开始之前先确保系统里有基础的编译工具链sudo apt update sudo apt install -y git cmake g pkg-config libeigen3-dev libgflags-dev libgoogle-glog-dev liblua5.3-dev libboost-all-dev libcairo2-dev python3-vcstool这里我特别说明一下为什么装了libgoogle-glog-dev。Ceres编译时依赖glog而系统里自带的glog版本通常会工作得很好不需要我们再编译。网上有些教程会让你把系统的glog卸掉再装新版这个操作极其危险可能导致ROS其他包的依赖失效。实测下来Ubuntu 20.04自带的glog够用别折腾。3.1 abseil-cpp版本锁死别想当然Cartographer官方推荐的abseil版本是20200225.2这个版本号你可能在其他地方见过。为什么锁这个版本因为后续版本的abseil改了API接口protobuf和Cartographer编译时按旧接口调用会直接报错。我第一次装的时候没注意拉了当时最新的abseil结果ceres编译到一半疯狂报错查了半天才发现是abseil版本问题。cd ~ git clone https://github.com/abseil/abseil-cpp.git cd abseil-cpp git checkout 20200225.2 mkdir build cd build cmake .. -DCMAKE_POSITION_INDEPENDENT_CODEON make -j$(nproc) sudo make install-DCMAKE_POSITION_INDEPENDENT_CODEON这个参数必须加否则后续编译动态库时链接会出现recompile with -fPIC的错误。这是个典型的隐蔽坑不加到后面再回头改就折腾了。3.2 protobuf优先用apt版本别一开始就源码编这一步我要给出一个和很多教程不同的建议。很多教程会让你源码编译protobuf 3.6.x但Ubuntu 20.04自带的protobuf版本是3.6.1而ROS Noetic里的很多包比如roscpp、tf2对这个版本是有依赖的。如果你用源码装了新版protobuf覆盖了系统版本最直接的后果是某个ROS节点启动时protobuf的libprotobuf.so版本对不上报一些非常隐晦的错误。我的做法是先不动系统protobuf直接往后走。Cartographer本体要求在编译时能找到protobuf如果系统头文件路径和库路径都对的话直接用apt装的版本就能过。只有当编译Cartographer报出protobuf version mismatch之类的错误时才考虑用源码装一个指定版本到/usr/local目录。实际的编译依赖关系我也测过Ubuntu 20.04自带的3.6.1基本能支撑Cartographer的编译和运行。3.3 Ceres Solver明确版本注意编译参数Ceres的版本选择也是一个大坑。我推荐的版本是1.13.0这是Cartographer官方在文档里明确验证过的版本。别用Ceres 2.x它的接口变化会导致Cartographer源码编译报错。cd ~ git clone https://github.com/ceres-solver/ceres-solver.git cd ceres-solver git checkout 1.13.0 mkdir build cd build cmake .. make -j$(nproc) sudo make install如果cmake过程中提示缺少某些依赖检查一下是不是没有装libgoogle-glog-dev和libgflags-dev。Ceres编译时间大约10分钟算是这几个库里比较久的。3.4 编译安装Cartographer本体和cartographer_ros依赖备齐后接下来就是正主了。官方推荐用wstool一次性拉取源码但这个工具在某些网络环境下不太稳定我习惯用git clone的方式手动拉两个仓库。cd ~ git clone https://github.com/cartographer-project/cartographer.git cd cartographer mkdir build cd build cmake .. make -j$(nproc) sudo make install这里提一句make -j$(nproc)在某些内存较小的机器上可能因为并行编译内存爆炸如果编译过程中出现g: internal compiler error: Killed这类报错降低并行度比如改用make -j2或者先关掉其他大型应用释放内存。cartographer本体安装完成后编译cartographer_ros。cartographer_ros和cartographer使用不同的构建系统这个包是放在ROS工作空间里通过catkin构建的mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com/cartographer-project/cartographer_ros.git cd ~/catkin_ws catkin_make如果catkin_make报错提示找不到cartographer说明cartographer的cmake配置文件没有被系统正确识别。可以检查一下/usr/local/lib/cmake/Cartographer目录是否存在如果不存在说明前面的sudo make install没执行成功需要回到cartographer的build目录重新install。还有一点需要注意如果你在编译cartographer_ros时提示找不到某个ROS包比如tf2_eigen或者message_generation大概率是前面用apt装的ROS未包含全部组件。这时候直接补齐sudo apt install -y ros-noetic-tf2-eigen ros-noetic-message-generation ros-noetic-geometry-msgs ros-noetic-nav-msgs4. 官网数据集的下载绕开网络问题找到可靠镜像代码都编译好了下一步就是下数据。Cartographer的官方数据集托管在Google Drive上这个在国内网络环境下基本是拉不动的页面一直转圈或者下载中途失败是常态。这里请记住一个原则不要花大量时间去纠结直接下载链接善用国内社区的搬运资源。两个最推荐的数据集2D背包数据集cartographer_paper_deutsches_museum.bag这是Cartographer论文里的经典数据录的是德国一个博物馆的场景有激光、IMU、里程计数据长度大概几百MB。3D背包数据集cartographer_3d_deutsches_museum.bag节点更多数据量更大主要是用来测试3D建图效果的。下载途径我实测可用的有两个第一个是国内CSDN或知乎上很多博主分享的百度网盘链接搜索cartographer官网数据集或者cartographer backpack数据集就能找到。这些分享链接通常包含上面两个bag文件还有对应的urdf和lua配置文件非常全。因为文件比较大2D的100MB左右3D的接近600MB百度网盘非会员下载速度慢建议先挂着下载同时继续看后面的步骤。第二个途径是去Gitee上搜索别人搬运的仓库有些仓库直接把数据集和demo配置放一起了比如cartographer_data之类。这类仓库的好处是不用登录git clone或者直接下载zip都可以。我建议git clone因为zip下载大文件时经常中断。注意下载下来的bag文件不需要放在工作空间里随便放个目录就行比如~/Downloads。但为了后续命令方便我统一放在~/bags目录下mkdir -p ~/bags mv ~/Downloads/cartographer_paper_deutsches_museum.bag ~/bags/这个目录路径后面要反复用到放一个固定位置省心很多。5. 跑通官网demolaunch文件、rviz验证、bag播放技巧下载好数据集之后按照官方文档的说明理论上一条命令就能跑起来roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:/home/你的用户名/bags/cartographer_paper_deutsches_museum.bag但实际执行时经常遇到三类问题我一个个说。5.1 找不到launch文件或没有执行权限如果你在catkin_make之前没有source工作空间roslaunch会报package cartographer_ros not found。每个新终端都要source一下source ~/catkin_ws/devel/setup.bash如果你不想每次开终端都手动source就写进.bashrcecho source ~/catkin_ws/devel/setup.bash ~/.bashrc source ~/.bashrc还有一种情况是launch文件本身没执行权限但这在roslaunch里其实不要求可执行权限一般不会遇到除非你手动改过。5.2 launch正常启动但rviz里没地图这个问题的出现频率最高。launch启动后终端会刷出一堆日志rviz也会自动打开但地图始终是灰的或者轨迹线始终不更新。原因可能是bag文件里的tf树不完整或者cartographer没有收到正确的IMU数据。首先确认bag在正常播放。你可以在另一个终端用rostopic list查看当前话题列表如果bag中的数据已经发布应该能看到/scan、/imu、/odom之类的话题。如果这些话题不存在说明bag播放异常或者launch里没有定义话题重映射。第二个排查点是TF。Cartographer的建图非常依赖TF树尤其是map→odom→base_link这条链路。你可以用rosrun tf view_frames生成TF树的可视化PDF确认坐标系之间的关系是否正确。如果你的bag数据是从别的设备录的坐标系名字可能和launch文件里定义的不一致这时候需要修改launch文件或者urdf里对应的frame名。最常用的验证命令是看rviz中是否出现不断延伸的绿色轨迹线。有轨迹线说明Cartographer的位姿估计在更新只是地图还没显示出来。地图不显示的常见原因是rviz的fixed frame没有设置成map打开rviz左上角的Global Options把Fixed Frame改成map即可。5.3 bag播放速度问题默认情况下一路play过去处理速度跟不上播放速度会让Cartographer丢失数据建图效果变差。建议用--pause参数先暂停bag播放等Cartographer初始化完成后再手动继续rosbag play --pause ~/bags/cartographer_paper_deutsches_museum.bag然后在终端按空格开始播放。如果处理速度仍然跟不上可以降低播放速率比如-r 0.5表示以一半速度播放。我实测过在八代i7处理器上2D数据集全程用0.8倍速播放基本能跟上。5.4 数据集跑完后的可视化验证bag播放完毕后按CtrlC终止roslaunchcartographer会把最终的地图以Pbstream格式保存吗默认demo不会自动保存但你可以手动调用保存接口rosservice call /finish_trajectory 0 rosservice call /write_state {filename: /home/你的用户名/map.pbstream}保存下来的map.pbstream是Cartographer的原生格式如果你想把它转成更通用的.pgm/.yaml文件栅格地图需要用到cartographer_ros自带的pbstream_to_assets工具rosrun cartographer_ros cartographer_pbstream_to_assets_map -pbstream_filename ~/map.pbstream -map_filestem ~/map运行之后会生成map.pgm和map.yaml这两个文件可以直接被ROS的map_server加载后面做导航定位直接用得上。6. 踩坑复盘我的编译翻车记录和解决思路这一节我把自己实际踩过、以及帮别人排查时遇到过的坑整理出来基本覆盖了从环境准备到跑通demo这一路上的主要问题。6.1 编译断在abseil或protobuf的头文件找不到症状编译Cerer或Cartographer时报错absl/time/time.h: No such file or directory。原因要么没编译安装abseil要么abseil版本太新头文件路径改动。解决确认ls /usr/local/include/absl存在。不存在就回到abseil目录重新编译安装确保用了20200225.2版本。6.2 catkin_make时提示找不到cartographer症状提示Could not find a package configuration file provided by cartographer。原因cartographer的cmake配置文件没安装成功或者系统里多个版本混乱。解决进入~/cartographer/build目录重新执行sudo make install安装后确认/usr/local/lib/cmake/Cartographer/CartographerConfig.cmake存在。如果还是找不到手动在~/.bashrc里加上环境变量export CMAKE_PREFIX_PATH/usr/local:$CMAKE_PREFIX_PATH6.3 ceres编译报一堆源码错误症状Ceres编译出现大量不认识的模板报错或者一直提示缺少glog/logging.h。原因最常见的是Ceres版本太新或者glog没装好。解决把ceres切回1.13.0并安装libgoogle-glog-dev。如果用的是Ubuntu 22.04glog版本可能和ceres 1.13.0不兼容这时候可以考虑手动编译glog的0.4.0版本但这属于高阶操作新手不推荐。6.4 运行demo时提示找不到lua文件症状Error opening Lua file configuration: /home/xxx/cartographer_ros/configuration_files/backpack_2d.lua原因cartographer_ros包的路径没有正确加载或者你把包放在了其他位置。解决确认是否source了正确的workspace以及cartographer_ros包是否在~/catkin_ws/src下。用rospack find cartographer_ros可以查看包的路径是否正常。6.5 数据集播放后没有任何输出症状rosbag play没有报错launch也没有回声rviz地图空白。解决先用rostopic list确认话题是否在发布。如果话题存在但rviz里看不到数据检查launch文件里topic的remap是否和bag里的topic匹配。官方数据集的扫描话题是/scan但如果bag里实际是/laser_scan就需要改launch。我常用的小技巧是先用rosbag info 文件名.bag查看bag里实际包含的所有topic再对照launch文件里的remap关系。6.6 编译时提示boost相关错误症状No such file or directory: boost/xxx.hpp常见于Ubuntu 20.04环境。解决安装libboost-all-dev并且确认CMake能找到Boost库。对Cartographer而言Boost主要是给ceres用的如果ceres都编译过了基本不会出这个问题。如果ceres编译时没问题而cartographer编译时报boost找不到大概率是cartographer的CMakeLists里boost检测路径有问题检查pkg-config --modversion boost是否正常。7. 跑通之后还能往哪里走到这里你已经成功在本地编译安装了Cartographer并且跑通了官网的2D数据集看到了博物馆场景的地图慢慢勾勒出来的过程。这个成就感是实打实的毕竟这套流程拦住了多少人。但我想说的是跑通官网demo其实只是第一步。最关键的收获是把依赖链和编译流程彻底理解了你知道abseil装在哪一层、Ceres的版本为什么不能乱动、protobuf为什么尽量不动系统版本、roslaunch里topic remap怎么排查。这些东西在以后打交道其他SLAM方案比如LIO-SAM、FAST-LIO时都能复用因为它们的依赖链和编译问题和Cartographer本质上是一路的。对于我自己来说每次重新搭这个环境还是会踩到一两个小坑毕竟系统状态、ROS版本、第三方库全局改动都会影响结果。所以我一直建议身边的朋友装Cartographer前先备份系统或者用Docker分离环境避免搞乱日常开发环境。等你在干净环境跑通一次之后再用自己的激光雷达和里程计数据替换掉官方bag你会发现从能跑demo到能跑自己的数据之间还有一段路但那已经是下一步的故事了。