【SLAM】Cartographer配置实战:从环境搭建到地图生成全流程解析
2026/4/22 12:24:07 网站建设 项目流程

1. 环境准备:Ubuntu系统与依赖安装

Cartographer作为Google开源的SLAM算法,对系统环境有明确要求。我推荐使用Ubuntu 20.04 LTS版本,这个长期支持版能完美兼容所有依赖库。刚开始接触时,我尝试过Ubuntu 18.04和22.04,结果在protobuf版本兼容性上踩了不少坑。

核心依赖安装可以分为三个层次:基础工具链、ROS环境和Cartographer专用库。先确保系统已更新:

sudo apt update && sudo apt upgrade -y

接着安装必备工具(建议逐行执行以便排查问题):

sudo apt install -y git cmake python3-wstool python3-rosdep ninja-build stow

ROS Noetic的安装要注意一个细节:官方推荐使用rosdep初始化时,国内开发者可能会遇到网络问题。这时可以改用清华源:

sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'

安装Cartographer的专用依赖时,最容易出问题的是abseil-cppceres-solver。我整理了一个可靠的一键安装脚本:

wget https://gist.githubusercontent.com/yourname/xxxx/raw/install_deps.sh chmod +x install_deps.sh ./install_deps.sh

这个脚本会自动处理以下关键操作:

  • 编译安装abseil-cpp时启用C++17标准
  • 为ceres-solver添加SuiteSparse和CXSparse支持
  • 设置正确的LD_LIBRARY_PATH环境变量

注意:如果之前安装失败过,务必先执行sudo rm -rf /usr/local/lib/cmake/Ceres清理残留文件

验证安装成功的技巧:运行ldconfig -p | grep absl查看abseil库是否被系统识别。我第一次配置时因为漏掉这个检查,导致后续编译报错却找不到原因。

2. 源码获取与编译技巧

推荐使用带详细注释的源码版本,这对理解算法原理很有帮助。我对比过原始仓库和几个注释版本,发现李想老师的版本对关键参数解释最全面。获取源码时建议新建独立工作空间:

mkdir -p ~/carto_ws/src cd ~/carto_ws/src git clone --recurse-submodules https://github.com/xiangli0608/cartographer_detailed_comments_ws.git

这里有个隐藏坑点:--recurse-submodules参数必须加上,否则会缺失protobuf子模块。我曾在团队协作时因为这个参数漏掉,导致三人花了半天排查编译错误。

编译环节要特别注意两点:

  1. 必须使用项目自带的catkin_make.sh脚本
  2. 不能直接使用catkin_make

背后的原因是这个工程对编译顺序有特殊要求。脚本里其实做了关键操作:

#!/bin/bash catkin_make_isolated --install --use-ninja -DCMAKE_BUILD_TYPE=Release

实测发现--install参数会将编译结果安装到isolated目录,这是后续环境配置的基础

编译完成后,环境变量设置是个易错点。很多人直接在.bashrc里写死路径,更好的做法是:

echo "source $(pwd)/install_isolated/setup.bash" >> ~/.bashrc

这样即使移动了工作空间目录,也能保持路径正确。我迁移系统时就因为这个技巧省去了重新配置的麻烦。

3. 2D建图实战与参数调优

准备好bag文件后,先验证数据完整性:

rosbag info your_bag.bag | grep -E 'topics|types'

关键要看是否包含/scan(激光数据)和/tf(坐标变换)。有次我用自制数据集建图总是失败,后来发现是bag里漏了tf静态变换。

启动2D建图有两种方式:

  • 快速验证:使用默认配置

    roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/bagfiles/your_bag.bag
  • 定制化配置:修改launch文件

    <param name="/use_sim_time" value="true" /> <node name="cartographer_node" pkg="cartographer_ros" type="cartographer_node" args=" -configuration_directory $(find cartographer_ros)/configuration_files -configuration_basename backpack_2d.lua" output="screen"> </node>

lua参数调优是建图质量的关键。在backpack_2d.lua中这几个参数最值得关注:

TRAJECTORY_BUILDER_2D = { min_range = 0.3, -- 过滤近距离噪声 max_range = 8., -- 根据实际传感器调整 missing_data_ray_length = 5., -- 处理遮挡问题 use_imu_data = false, -- 没有IMU时务必关闭 motion_filter.max_angle_radians = math.rad(0.5) -- 运动采样阈值 }

建图过程中实时调试技巧:

  1. 新终端执行rviz -d $(rospack find cartographer_ros)/configuration_files/demo_2d.rviz
  2. 关注/submap_list话题的更新频率
  3. 通过rostopic echo /scan | grep range_min验证数据范围

常见问题排查:

  • 如果地图出现鬼影,检查min_range是否设置过小
  • 建图漂移严重时,尝试调小motion_filter.max_distance_meters
  • 出现断断续续的轨迹,可能是submaps.num_range_data设置过大

4. 地图保存与后处理

Cartographer支持两种地图保存方式:

  1. 传统栅格地图(用于导航)

    rosrun map_server map_saver -f my_map
  2. 原始数据格式(用于继续优化)

    ./finish_slam_2d.sh # 生成.pbstream文件

我更喜欢第二种方式,因为:

  • 保留完整的SLAM状态信息
  • 支持回环检测的后续优化
  • 可以导出不同分辨率的地图

地图优化技巧

  • 使用assets_writer_2d.launch时可以调整这些参数:

    <param name="resolution" value="0.05" /> <!-- 地图分辨率 --> <param name="fill_holes" value="true" /> <!-- 填充小空洞 -->
  • 对于大场景地图,建议分区域保存:

    roslaunch cartographer_ros assets_writer_2d.launch bag_filenames:=${HOME}/bagfiles/your_bag.bag pose_graph_filename:=${HOME}/map.pbstream

有次我在200米长廊建图时,直接保存的全幅地图在RViz中卡顿严重。后来改用分块保存再拼接的方案,既保证了精度又提升了显示性能。

5. 3D建图特殊配置

3D建图对硬件要求更高,建议先确认系统性能:

glxinfo | grep "OpenGL renderer"

关键配置差异体现在backpack_3d.lua中:

TRAJECTORY_BUILDER_3D = { min_range = 0.5, -- 比2D需要更大值 max_range = 10., num_accumulated_range_data = 1, -- 多帧累积需谨慎 voxel_filter_size = 0.15, -- 点云降采样粒度 high_resolution_adaptive_voxel_filter = { -- 高精度滤波 max_length = 2., min_num_points = 150, max_range = 15. } }

启动3D建图时建议限制CPU占用:

roslaunch cartographer_ros demo_backpack_3d.launch bag_filename:=${HOME}/bagfiles/your_bag.bag rate:=1.0

这里的rate:=1.0表示以原始速度播放bag数据。我在i7处理器上测试发现,超过2倍速会导致点云丢失。

3D地图后处理有个实用技巧:使用PCL工具过滤噪点:

pcl_voxel_grid -i input.pcd -o filtered.pcd -leaf 0.1,0.1,0.1

这个命令将点云体素网格化,显著减少数据量。记得最后按高度着色检查一致性:

pcl_viewer filtered.pcd

然后按键盘4启用高度着色模式,异常点会明显显现。

6. 定位模式实战

纯定位模式需要准备:

  1. 已有的.pbstream地图文件
  2. 修改过的定位专用lua配置

关键配置变更:

POSE_GRAPH.optimize_every_n_nodes = 0 -- 关闭在线优化 TRAJECTORY_BUILDER.pure_localization = true -- 启用纯定位 TRAJECTORY_BUILDER_2D.submaps.num_range_data = 20 -- 减少子图数量

启动命令需要显式指定地图路径:

roslaunch cartographer_ros demo_backpack_2d_localization.launch \ load_state_filename:=${HOME}/map.pbstream \ bag_filename:=${HOME}/bagfiles/localization.bag

定位精度验证方法:

  1. 播放bag时记录ground truth(如有)
  2. 运行rosrun tf view_frames生成tf树图
  3. 对比/tf中的map->odom变换与真实位姿

遇到定位漂移时,可以尝试:

  • 调大TRAJECTORY_BUILDER_2D.ceres_scan_matcher.translation_weight
  • 减小POSE_GRAPH.constraint_builder.min_score
  • 增加POSE_GRAPH.constraint_builder.sampling_ratio

7. 高级配置与性能优化

对于复杂场景,需要调整后端优化参数:

POSE_GRAPH = { optimize_every_n_nodes = 90, -- 优化频率 constraint_builder = { sampling_ratio = 0.3, -- 约束采样率 min_score = 0.55, -- 回环匹配阈值 global_localization_min_score = 0.6 -- 全局定位阈值 }, matcher_translation_weight = 5e2, -- 平移权重 matcher_rotation_weight = 1.6e3 -- 旋转权重 }

多传感器融合配置示例(IMU+轮速计):

options = { use_odometry = true, use_nav_sat = false, use_landmarks = false, num_laser_scans = 0, num_point_clouds = 1 } TRAJECTORY_BUILDER_3D.use_odometry = true TRAJECTORY_BUILDER_3D.use_online_correlative_scan_matching = true

性能监控建议:

  1. 使用top命令观察CPU占用
  2. 通过rostopic hz /scan检查数据速率
  3. 记录cartographer_node的ROS日志:
roslaunch cartographer_ros demo_backpack_2d.launch | tee carto_log.txt

对于大型场景,我总结出这些优化经验:

  • 子图数量控制在50个以内
  • 每5-10个子图执行一次全局优化
  • 优先保证前端匹配质量,后端优化可以适当降低频率
  • 使用num_accumulated_range_data累积点云时要同步调整voxel_filter_size

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询