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 stowROS 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-cpp和ceres-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子模块。我曾在团队协作时因为这个参数漏掉,导致三人花了半天排查编译错误。
编译环节要特别注意两点:
- 必须使用项目自带的
catkin_make.sh脚本 - 不能直接使用
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) -- 运动采样阈值 }建图过程中实时调试技巧:
- 新终端执行
rviz -d $(rospack find cartographer_ros)/configuration_files/demo_2d.rviz - 关注
/submap_list话题的更新频率 - 通过
rostopic echo /scan | grep range_min验证数据范围
常见问题排查:
- 如果地图出现鬼影,检查
min_range是否设置过小 - 建图漂移严重时,尝试调小
motion_filter.max_distance_meters - 出现断断续续的轨迹,可能是
submaps.num_range_data设置过大
4. 地图保存与后处理
Cartographer支持两种地图保存方式:
传统栅格地图(用于导航)
rosrun map_server map_saver -f my_map原始数据格式(用于继续优化)
./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. 定位模式实战
纯定位模式需要准备:
- 已有的.pbstream地图文件
- 修改过的定位专用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定位精度验证方法:
- 播放bag时记录ground truth(如有)
- 运行
rosrun tf view_frames生成tf树图 - 对比
/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性能监控建议:
- 使用
top命令观察CPU占用 - 通过
rostopic hz /scan检查数据速率 - 记录
cartographer_node的ROS日志:
roslaunch cartographer_ros demo_backpack_2d.launch | tee carto_log.txt对于大型场景,我总结出这些优化经验:
- 子图数量控制在50个以内
- 每5-10个子图执行一次全局优化
- 优先保证前端匹配质量,后端优化可以适当降低频率
- 使用
num_accumulated_range_data累积点云时要同步调整voxel_filter_size