第一次接触Cartographer时,我被它强大的建图能力吸引,但编译过程确实踩了不少坑。这里分享我从零开始搭建环境的完整过程,特别适合刚接触ROS和SLAM的开发者。
Ubuntu 18.04+ROS Melodic是最稳定的组合,我实测在20.04上也能运行,但需要处理更多依赖问题。建议新手先用这个配置:
bash复制sudo apt-get update
sudo apt-get install -y python-wstool python-rosdep ninja-build
创建独立工作空间很重要,避免污染系统环境。我习惯用catkin_ws_cartographer命名,清晰区分其他项目:
bash复制mkdir -p ~/catkin_ws_cartographer/src
cd ~/catkin_ws_cartographer
wstool init src
这里有个关键技巧:修改.rosinstall文件中的ceres-solver源。由于网络访问限制,直接使用GitHub镜像更稳定:
bash复制wstool merge -t src https://raw.githubusercontent.com/googlecartographer/cartographer_ros/master/cartographer_ros.rosinstall
sed -i 's#https://ceres-solver.googlesource.com#https://github.com/ceres-solver#g' src/.rosinstall
wstool update -t src
安装protobuf3时可能会遇到权限问题,建议先手动执行脚本:
bash复制chmod +x src/cartographer/scripts/install_proto3.sh
src/cartographer/scripts/install_proto3.sh
最后编译时加入--use-ninja参数能显著加快速度,我的i7处理器大概需要15分钟:
bash复制catkin_make_isolated --install --use-ninja
source install_isolated/setup.bash
编译成功后,先用2D数据集验证安装是否正确。这个博物馆数据集约500MB,包含激光和IMU数据:
bash复制wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_2d/cartographer_paper_deutsches_museum.bag
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
在RViz中应该看到实时构建的地图。如果出现TF报错,检查demo_2d.rviz配置中的坐标系设置。常见问题是:
3D数据集验证更复杂,8GB数据下载后运行:
bash复制roslaunch cartographer_ros demo_backpack_3d.launch bag_filename:=${HOME}/Downloads/b3-2016-04-05-13-54-42.bag
这时要注意GPU性能,笔记本可能需要降低分辨率。在backpack_3d.lua中修改:
lua复制TRAJECTORY_BUILDER_3D.voxel_filter_size = 0.15 -- 原值0.05
TRAJECTORY_BUILDER_3D.submaps.num_range_data = 50 -- 原值100
实际项目中,我常用Velodyne VLP-16。与仿真数据不同,真实设备需要处理几个关键问题:
首先修改launch文件,注意坐标系命名。这是我的cartographer_demo_velodyne.launch核心配置:
xml复制<node name="cartographer_node" pkg="cartographer_ros"
args="-configuration_directory $(find cartographer_ros)/configuration_files
-configuration_basename velodyne16.lua"
output="screen">
<remap from="points2" to="/velodyne_points" />
</node>
对应的velodyne16.lua需要调整这些参数:
lua复制options = {
map_frame = "map",
tracking_frame = "velodyne",
published_frame = "velodyne",
provide_odom_frame = true,
use_odometry = false, -- 没有里程计时设为false
num_point_clouds = 1, -- 使用点云模式
}
TRAJECTORY_BUILDER_2D.min_range = 0.5 -- VLP-16最小有效距离
TRAJECTORY_BUILDER_2D.max_range = 15.0 -- 室外可增大到50
TRAJECTORY_BUILDER_2D.use_imu_data = false -- 无IMU时禁用
启动顺序很关键:
bash复制roslaunch velodyne_pointcloud VLP16_points.launch
bash复制rostopic echo /velodyne_points | head -n 1
bash复制roslaunch cartographer_ros cartographer_demo_velodyne.launch
实际建图中遇到过地图漂移问题,通过调整这些参数解决:
lua复制POSE_GRAPH.optimize_every_n_nodes = 50 -- 原值35,增大可降低计算负载
POSE_GRAPH.constraint_builder.min_score = 0.75 -- 原值0.65,提高匹配要求
TRAJECTORY_BUILDER_2D.submaps.num_range_data = 45 -- 原值35,增加子图数据量
保存地图时,我推荐先用服务终止轨迹:
bash复制rosservice call /finish_trajectory 0
rosservice call /write_state "{filename: '${HOME}/mymap.pbstream'}"
转换地图格式时,分辨率0.05适合室内,室外建议0.1-0.2:
bash复制rosrun cartographer_ros cartographer_pbstream_to_ros_map \
-map_filestem=${HOME}/mymap \
-pbstream_filename=${HOME}/mymap.pbstream \
-resolution=0.1
生成的PGM和YAML文件可直接用于导航。如果地图有空白区域,尝试调整min_score和missing_data_ray_length参数。