3. Cartographer配置参数解析与调整

任务目标

本案例以Cartographer官方2D示例配置为基础,解读backpack_2d.lua及其引用的map_builder.lua、trajectory_builder_2d.lua中与建图质量最相关的参数,并实际修改栅格分辨率与子图更新频率,通过重新建图对比效果差异。

配置结构与关键参数

Cartographer的配置采用Lua脚本,分为三层:

  • map_builder.lua:全局地图构建器配置(是否使用2D/3D、是否启用回环检测)
  • trajectory_builder_2d.lua:前端扫描匹配与运动滤波参数
  • 具体机器人配置(如backpack_2d.lua):调用上述模板并覆盖参数,同时设置地图帧、发布频率等

以下为官方backpack_2d.lua的完整内容,标注了本案例将修改的两个关键参数:

-- backpack_2d.lua(完整文件)
include "map_builder.lua"
include "trajectory_builder_2d.lua"

options = {
  map_builder = MAP_BUILDER,
  trajectory_builder = TRAJECTORY_BUILDER_2D,
  map_frame = "map",
  tracking_frame = "base_link",
  published_frame = "base_link",
  odom_frame = "odom",
  provide_odom_frame = true,
  publish_frame_projected_to_2d = false,
  use_odometry = false,
  use_nav_sat = false,
  use_landmarks = false,
  num_laser_scans = 1,
  num_multi_echo_laser_scans = 0,
  num_subdivisions_per_laser_scan = 1,
  num_point_clouds = 0,
  lookup_transform_timeout_sec = 0.2,
  submap_publish_period_sec = 0.3,        -- ★ 子图发布周期(秒),影响RViz中子图刷新频率
  pose_publish_period_sec = 5e-3,
  trajectory_publish_period_sec = 30e-3,
  rangefinder_sampling_ratio = 1.,
  odometry_sampling_ratio = 1.,
  fixed_frame_pose_sampling_ratio = 1.,
  imu_sampling_ratio = 1.,
  use_constant_odometry_variance = false,
  constant_odometry_variance = 1e-4,
}

TRAJECTORY_BUILDER_2D.use_imu_data = false
TRAJECTORY_BUILDER_2D.min_range = 0.3
TRAJECTORY_BUILDER_2D.max_range = 30.
TRAJECTORY_BUILDER_2D.missing_data_ray_length = 5.
TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true
TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1)
TRAJECTORY_BUILDER_2D.motion_filter.max_distance_m = 0.15

MAP_BUILDER.use_trajectory_builder_2d = true
MAP_BUILDER.num_background_threads = 4
MAP_BUILDER.pose_graph.optimize_every_n_nodes = 90

-- ★ 关键修改1:栅格分辨率(米/像素),默认0.05,改为0.10观察地图变粗糙
MAP_BUILDER.map_builder_2d.submaps.resolution = 0.10

-- ★ 关键修改2:子图插入频率(每N帧激光数据插入一次子图),默认1,改为5降低更新频率
MAP_BUILDER.map_builder_2d.submaps.num_range_data = 5

return options

参数含义与调整方法

参数路径默认值作用调整方向与预期效果
MAP_BUILDER.map_builder_2d.submaps.resolution0.05每个栅格像素代表的物理尺寸(米)。决定地图精细度与内存占用增大到0.10:地图变粗糙、细节丢失,但建图计算量下降、内存占用减少
MAP_BUILDER.map_builder_2d.submaps.num_range_data1累积多少帧激光数据后插入一次子图(即子图更新频率)增大到5:子图更新变慢,局部地图刷新频率降低,但前端计算压力减小
submap_publish_period_sec0.3RViz中已完成的子图发布间隔(秒)仅影响可视化刷新率,不影响建图算法本身

运行与对比验证

使用官方2D示例数据集(cartographer_paper_deutsches_museum.bag)进行验证:

# 1. 启动离线建图(默认配置)
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=/path/to/cartographer_paper_deutsches_museum.bag

# 2. 修改配置后重新建图
#    编辑 backpack_2d.lua 中的 resolution 和 num_range_data 后,重新执行上述命令

对比方法:分别用默认参数与修改后参数运行建图,保存生成的PGM地图文件,观察:

  • 分辨率0.05→0.10:地图中墙体边缘出现明显锯齿/方块感,窄通道可能断裂,走廊宽度失真
  • num_range_data 1→5:在RViz中观察子图(绿色方块)出现频率降低,回环检测修正时地图跳变幅度增大

通过条件:

  1. 修改参数后Cartographer能正常启动且不报配置错误
  2. 生成的地图文件尺寸随分辨率变化(0.10分辨率地图像素尺寸约为0.05时的1/2)
  3. 肉眼可分辨两种参数下地图细节的明显差异

常见问题

  • 修改后无法启动:检查Lua语法,注意math.rad()需要完整写法;确认修改的是MAP_BUILDER.map_builder_2d.submaps下的字段而非其他层级
  • 地图出现重影:num_range_data调大后子图插入间隔变长,若机器人转弯过快可能导致局部地图匹配漂移,此时应配合增大motion_filter.max_distance_m
  • 分辨率调大后内存反而不足:确认是否同时调整了MAP_BUILDER.map_builder_2d.submaps.resolution与num_range_data,两者共同决定内存占用,分辨率增大时建议同步增大num_range_data以控制子图数量