cartographer ros 配置详解
文章目录
- 2D
- 一、配置项介绍
- 1. 主配置文件(`xxx.lua`)
- 2. 传感器配置(`map_builder.sensor_bridge`)
- 3. 前端匹配(`trajectory_builder_2d`)
- 4. 子图构建(`trajectory_builder_2d.submaps`)
- 5. 后端优化(`map_builder.constraint_builder`)
- 5. 其他关键参数
- 二、参数关联逻辑
- 三、典型场景推荐配置
- 四、实用技巧
- 2D vs 3D
- Cartographer 2D与3D配置核心差异总览
- 一、传感器与核心设置差异
- 1. 传感器类型与依赖
- 2. 核心参数开关
- 二、运动过滤与点云处理差异
- 1. 运动过滤
- 2. 点云处理
- 三、扫描匹配差异
- 1. 匹配维度与参数
- 2. IMU融合
- 四、后端优化与地图表示差异
- 1. 地图表示
- 2. 后端优化
- 3. 输出格式与应用
- 五、其他关键差异
carto_ws/devel_isolated/cartographer/share/cartographer/configuration_files下查找对应的lua文件。该路径下包含的lua文件有:
map_builder.lua map_builder_server.lua pose_graph.lua trajectory_builder.lua trajectory_builder_2d.lua trajectory_builder_3d.lua
Cartographer配置文件主要分为传感器配置、前端匹配、后端优化、子图构建、滤波与处理等模块,各模块参数相互关联,共同决定建图效果。
2D
一、配置项介绍
1. 主配置文件(xxx.lua)
主配置文件:如:my_robot_2d.lua
- 坐标系与传感器设置
map_frame:全局地图的坐标系名,通常固定为"map"。tracking_frame:SLAM算法跟踪的坐标系。所有传感器数据都将转换到此坐标系下进行处理。如果使用了IMU,建议设置为IMU的链路,如"imu_link";否则通常设置为机器人基座,如"base_link"。published_frame:用于发布位姿的子坐标系。通常设置为"base_link",这意味着Cartographer会发布从map_frame到base_link的变换。odom_frame&provide_odom_frame:当provide_odom_frame = true时,Cartographer会提供一个不受回环检测影响的、连续的odom坐标系。这对于需要平滑里程计的导航任务非常有用。如果你已有外部里程计,则应设为false。use_odometry:是否使用来自/odom话题的里程计数据。如果启用,请确保提供准确的里程计信息。use_imu_data(在TRAJECTORY_BUILDER_2D中):在2D模式下,使用IMU数据可以显著改善旋转估计。
- 传感器数据配置
正确设置这些参数,Cartographer才能订阅到你的传感器数据。
num_laser_scans:设置为 1,表示订阅单个sensor_msgs/LaserScan话题(如/scan)。num_multi_echo_laser_scans:如果你使用的是多回波激光雷达数据 (sensor_msgs/MultiEchoLaserScan),则设置此参数。对于标准的单回波雷达,应将其设为 0。num_point_clouds:对于2D SLAM,通常使用单线激光雷达,故此参数设为 0。
2. 传感器配置(map_builder.sensor_bridge)
定义传感器数据的处理方式,核心是激光雷达和里程计(可选)的参数。
num_laser_scans:激光雷达数量(单线雷达填1,多线雷达需拆分时按实际数量填写)。num_multi_echo_laser_scans:多回波激光雷达数量(普通单线雷达填0)。num_point_clouds:点云传感器数量(若用深度相机转点云,需对应填写)。use_odometry:是否使用里程计(true/false,建议有里程计时开启,辅助抑制漂移)。odometry_sampling_ratio:里程计数据采样率(默认1.0,高频里程计可降低至0.5避免冗余)。imu_gravity_time_constant:IMU重力参数(默认10.0s,用于IMU初始化,若无IMU可忽略)。
关联逻辑:传感器数量需与实际硬件匹配,否则数据会被丢弃;开启里程计/IMU后,前端匹配会融合其数据提升稳定性。
3. 前端匹配(trajectory_builder_2d)
负责激光雷达帧与局部地图的匹配(扫描匹配),是实时性的关键。
min_range/max_range:激光点有效距离范围(过滤过近/过远噪声点,需根据雷达参数设置,如单线雷达通常设0.1~30m)。missing_data_ray_length:无效激光点(如超过max_range)的填充长度(建议设为max_range,保证地图连续性)。num_accumulated_range_data:用于构建局部地图的激光帧数量(默认1,增大可提高匹配精度但降低实时性,室内建议1~3,室外高速场景建议1)。voxel_filter_size:激光点体素滤波大小(单位m,默认0.05m,室外可增大至0.1~0.2m减少计算量)。
扫描匹配参数(scan_matcher):
translation_weight/rotation_weight:平移/旋转权重(影响匹配对平移/旋转的敏感度,默认1e3/1e6,旋转误差大时可提高rotation_weight)。ceres_solver_options.max_num_iterations:Ceres迭代次数(默认20,精度优先场景可增至30~50,实时优先减至10)。
关联逻辑:voxel_filter_size与num_accumulated_range_data共同决定局部地图的细节度,滤波粒度越大、累积帧数越多,计算量越大。
4. 子图构建(trajectory_builder_2d.submaps)
子图是局部地图的集合,后端基于子图优化全局轨迹。
num_range_data:每个子图包含的激光帧数量(默认90,子图越大地图细节越丰富,但后端优化成本越高,室内建议60120,室外可减少至3060)。grid_options_2d.resolution:子图栅格分辨率(单位m,默认0.05m,0.02~0.1m常用,分辨率越高细节越清晰但内存占用越大)。grid_options_2d.patch_size:子图存储的patch大小(默认8,影响内存分配,无需修改)。loop_closure_translation_weight/loop_closure_rotation_weight:回环检测时子图匹配的平移/旋转权重(默认1e3/1e6,与前端扫描匹配类似,需保持一致性)。
关联逻辑:resolution直接决定地图精度,与激光雷达精度匹配(如1cm精度雷达用0.01m分辨率,普通雷达用0.05m即可);num_range_data决定子图大小,子图过大易导致回环检测效率下降。
5. 后端优化(map_builder.constraint_builder)
负责回环检测与全局优化,决定建图的一致性。
sampling_ratio:子图对采样率(默认0.3,降低可减少计算量,实时场景可设0.1~0.2)。max_constraint_distance:回环检测的最大距离(单位m,默认15m,室内小场景可减小至510m,室外大场景增大至2050m)。min_score:回环匹配的最小分数(默认0.55,分数越高回环越可靠但可能漏检,室内建议0.6~0.7,室外可降低至0.5避免漏检)。global_sampling_ratio:全局采样率(默认0.003,控制全局回环检测的频率,小场景可提高至0.01)。ceres_solver_options.max_num_iterations:后端优化迭代次数(默认50,大场景需增至100~200保证收敛)。
关联逻辑:max_constraint_distance需根据场景尺度设置,过小会漏检回环,过大易引入错误约束;min_score与场景特征丰富度相关(特征少的场景如走廊需降低阈值)。
5. 其他关键参数
trajectory_builder_2d.use_online_correlative_scan_matcher:是否使用在线关联扫描匹配(默认true,提高匹配鲁棒性,计算量较大,低端设备可设false)。map_builder.fast_correlative_scan_matcher_2d.linear_search_window:快速匹配的线性搜索窗口(单位m,默认0.1m,里程计精度低时可增大至0.5~1m)。map_builder.fast_correlative_scan_matcher_2d.angular_search_window:角度搜索窗口(单位rad,默认0.17rad≈10°,旋转噪声大时可增至0.34rad≈20°)。
二、参数关联逻辑
各模块参数并非独立,核心关联如下:
- 传感器与前端:里程计/IMU的开启会影响前端匹配的初始猜测,降低扫描匹配的搜索范围(如
linear_search_window可减小)。 - 前端与子图:前端匹配的精度决定子图构建的准确性,子图的
resolution需与前端voxel_filter_size匹配(滤波粒度应小于等于分辨率,否则丢失细节)。 - 子图与后端:子图数量越多、
num_range_data越大,后端回环检测的计算量越大,需通过sampling_ratio平衡效率。 - 实时性与精度:提高
ceres_solver_options.max_num_iterations、num_accumulated_range_data等参数可提升精度,但会降低实时性,需根据硬件性能取舍。
三、典型场景推荐配置
室内小场景(<1000㎡,低速):高精度优先
- 传感器配置
use_odometry=true:启用轮式里程计辅助定位。室内场景中轮速计误差累积较慢,可提供短期稳定的运动先验,减少激光匹配歧义(尤其低速移动时,激光帧间变化小,里程计能增强连续性)。num_laser_scans=1:单激光雷达输入,适合室内常用的单线/多线激光(如16线),无需处理多传感器同步问题。
- 前端(局部里程计与扫描匹配)
voxel_filter_size=0.05m:体素滤波分辨率0.05m,保留更多点云细节(如墙角、桌椅边缘),提高匹配精度(室内特征密集,细粒度滤波不影响效率)。num_accumulated_range_data=2:累积2帧激光点云再处理。低速移动时,单帧点云运动信息少,累积后可增强特征显著性(如运动物体的轨迹连续性),提升匹配稳定性。ceres_solver_options.max_num_iterations=30:前端优化迭代次数30次。室内场景对实时性要求不极致,更多迭代可减少局部匹配误差(如激光与子图的对齐残差)。
- 子图参数
resolution=0.05m:子图分辨率0.05m,高密度网格可精确刻画室内细节(如门、窗台),为回环检测提供高辨识度特征。num_range_data=90:每个子图包含90帧激光数据。低速移动时,子图覆盖范围小(如10-20米),更多帧累积可减少子图拼接误差,保证局部地图一致性。
- 后端(回环检测与全局优化)
max_constraint_distance=10m:回环检测最大搜索距离10m。室内场景空间封闭(如办公室隔间),远距离回环概率低,限制搜索范围可减少无效计算。min_score=0.6:回环匹配最低得分0.6(较高阈值)。室内特征重复度高(如相同办公室布局),高阈值可减少误匹配(避免将相似场景误判为回环)。ceres_solver_options.max_num_iterations=100:后端全局优化迭代100次。室内对全局精度要求高(如厘米级定位),更多迭代可充分收敛,消除累积漂移。- 使用默认或较大的
optimize_every_n_nodes,避免频繁优化中断建图过程。
- 扫描匹配
use_online_correlative_scan_matcher=true:启用在线相关性扫描匹配。室内环境特征丰富,该算法通过暴力搜索局部位姿空间(结合里程计先验),可找到更精确的匹配结果(尤其低速下,计算耗时可接受)。linear_search_window=0.3m,angular_search_window=0.34rad(≈19.5°):搜索窗口小(平移±0.3m,旋转±19.5°)。低速移动时,里程计预测误差小,无需大窗口搜索,减少计算量的同时提高匹配精度。
室外大场景(>5000㎡,中速):实时性优先,依赖回环修正
- 传感器配置
use_odometry=true(+GPS优化):室外中速移动时,轮速计误差累积快,需结合GPS提供全局位姿约束(Cartographer可通过use_nav_sat集成),减少长距离漂移;若无GPS,依赖回环修正。
- 前端
voxel_filter_size=0.1m:体素滤波分辨率0.1m,降低点云密度。室外场景(如园区、街道)特征稀疏(多为地面、树木、建筑轮廓),粗粒度滤波可减少计算量,且不丢失关键特征。num_accumulated_range_data=1:不累积帧,单帧处理。中速移动时,帧间运动差异大,累积会导致点云畸变,单帧处理可保证实时性(避免延迟)。ceres_solver_options.max_num_iterations=15:前端迭代15次,减少计算耗时(中速移动对实时性要求高,优先保证帧率)。
- 子图参数
resolution=0.1m:子图分辨率0.1m,平衡精度与存储(室外大场景需避免子图数据量过大)。num_range_data=60:每个子图包含60帧数据。中速移动时,子图覆盖范围更大(如30-50米),减少子图总数,降低后端回环检测的匹配复杂度。
- 后端
max_constraint_distance=30m:回环搜索距离30m。室外场景开阔,机器人可能绕圈后回到远处区域(如园区环路),扩大搜索范围可提高回环检出率。min_score=0.5:降低回环匹配阈值。室外特征稀疏(如相似的树木排列),适当放宽阈值可增加回环数量(依赖后端优化剔除误匹配)。sampling_ratio=0.1:回环候选帧采样比例0.1,随机抽取10%的历史帧进行匹配,减少计算量(大场景下历史帧多,全量匹配耗时过高)。ceres_solver_options.max_num_iterations=150:后端迭代150次。室外累积漂移更显著,更多迭代可通过回环约束修正长距离轨迹(即使前端精度低,后端也能拉回全局一致性)。
- 扫描匹配
linear_search_window=0.5m,angular_search_window=0.52rad(≈29.8°):扩大搜索窗口。中速移动时,里程计误差更大(如路面不平导致轮速计打滑),大窗口可覆盖真实位姿范围,避免匹配失败。
低性能设备(嵌入式ARM):保证实时性,牺牲精度
- 核心优化方向
- 放宽
motion_filter:运动滤波器用于判断是否生成新的激光帧(如移动距离/角度小于阈值则跳过)。放宽阈值(如增大max_time_seconds或max_distance_meters)可减少处理的帧数量,是降低计算量最直接的方式。 - 降低回环频率:
sampling_ratio=0.05(仅5%历史帧参与回环匹配)、max_constraint_distance=20m(缩小搜索范围),大幅减少回环检测的计算负荷(回环是Cartographer最耗时的模块之一)。 - 减少后台线程:
num_background_threads=1,ARM平台算力有限,多线程切换开销大,单线程可避免资源竞争,提高效率。
- 前端
voxel_filter_size=0.2m:更粗的体素滤波,进一步减少点云数量(ARM平台处理能力弱,需降低输入数据量)。num_accumulated_range_data=1:单帧处理,避免累积导致的延迟。use_online_correlative_scan_matcher=false:禁用在线相关性匹配(该算法为暴力搜索,计算密集),改用轻量的迭代最近点(ICP)匹配,牺牲部分精度换速度。
- 子图与后端
num_range_data=30:每个子图仅30帧数据,减少子图存储和匹配成本(子图数量少,后端处理更快)。ceres_solver_options.max_num_iterations=50:后端迭代次数减少,降低优化耗时(ARM平台跑Ceres效率低,优先保证不卡顿)。
纯定位模式:在已有先验地图上进行实时定位,需要低延迟和高鲁棒性。
- 启用定位修剪器:在
my_robot_2d.lua中添加以下配置,防止内存无限增长。TRAJECTORY_BUILDER.pure_localization_trimmer = {max_submaps_to_keep = 3, -- 只保留最近的3个子图 } - 优化性能:
- 显著增加
motion_filter的阈值,例如max_distance_meters=0.2,max_angle_radians=math.rad(1),大幅减少节点生成。 - 降低
POSE_GRAPH.optimize_every_n_nodes(例如到 20),使位姿能更快地被校正。
- 显著增加
- 提升重定位能力:如前述,务必扩大
angular_search_window,这是解决机器人"丢失"问题的有效手段。
四、实用技巧
-
参数调优步骤:
- 先确保传感器数据正确(激光帧无畸变、里程计与激光同步)。
- 固定后端参数,调优前端匹配(观察实时轨迹是否平滑,有无跳变)。
- 再调优后端回环(检查地图是否闭合,有无明显错位)。
-
地图漂移处理:
- 若平移漂移大:增加
translation_weight,开启里程计,减小voxel_filter_size保留更多细节。 - 若旋转漂移大:增加
rotation_weight,增大angular_search_window,检查雷达安装是否水平。
- 若平移漂移大:增加
-
回环失效处理:
- 场景特征少(如长走廊):降低
min_score,增大max_constraint_distance。 - 回环误匹配:提高
min_score,减小max_constraint_distance,增加num_range_data使子图更具辨识度。
- 场景特征少(如长走廊):降低
-
内存优化:
- 大场景可减小
resolution(如0.1m),降低num_range_data(如30),减少子图存储量。 - 关闭
use_online_correlative_scan_matcher,降低前端内存占用。
- 大场景可减小
-
日志调试:
- 开启
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=xxx.bag rviz:=true,在RViz中观察子图、轨迹、回环约束,直观判断参数问题。
- 开启
2D vs 3D
以下是整理后的Cartographer 2D与3D配置差异文档,完整保留核心信息并结构化呈现:
Cartographer 2D与3D配置核心差异总览
| 配置维度 | Cartographer 2D | Cartographer 3D |
|---|---|---|
| 传感器要求 | 激光雷达(单线/多线转2D),IMU可选 | 必须使用多线激光雷达,IMU为必需传感器 |
| 核心参数开关 | use_trajectory_builder_2d = true | use_trajectory_builder_3d = true |
| 运动滤波 | 主要考虑水平移动(max_distance_m, max_angle_rad) | 需额外考虑时间阈值(max_time) |
| 点云处理 | 使用missing_data_ray_length替代max_range | 使用max_range和min_range,配置体素滤波器(voxel_filter_size) |
| 扫描匹配 | 使用单个occupied_space_weight | 使用两个权重参数(occupied_space_weight_0, occupied_space_weight_1),对应高低分辨率点云 |
| 后端优化 | 优化在二维平面内进行 | 优化在三维空间中进行,参数更复杂(如fix_z_in_3d) |
| 建图输出 | 2D栅格地图(可直接用于导航) | 3D混合概率地图(通常需投影为2D地图用于导航) |
| 产品特点 | 计算资源消耗少,实时优化,不追求高精度 | 计算资源消耗少,实时优化,不追求高精度 |
一、传感器与核心设置差异
1. 传感器类型与依赖
-
2D配置:
- 核心处理激光数据并投影到二维平面,支持单线激光雷达或多线雷达(通过截取特定射线环/投影到平面)。
- IMU可选(
TRAJECTORY_BUILDER_2D.use_imu_data),若启用可辅助改善运动估计。
-
3D配置:
- 必须使用多线激光雷达(如16线、32线)或深度相机,通过
num_point_clouds配置点云传感器数量(通常设1),num_laser_scans和num_multi_echo_laser_scans一般设0。 - 强制依赖IMU(
TRAJECTORY_BUILDER_3D.use_imu_data),用于提供初始重力方向估计,减少计算复杂度;需配置imu_gravity_time_constant(默认10s,需根据IMU参数校准)及imu_sampling_ratio(控制IMU数据采样率)。
- 必须使用多线激光雷达(如16线、32线)或深度相机,通过
2. 核心参数开关
- 2D与3D通过互斥参数启用:分别对应
use_trajectory_builder_2d = true和use_trajectory_builder_3d = true,不可同时启用。
二、运动过滤与点云处理差异
1. 运动过滤
- 2D:仅关注水平方向运动,通过
motion_filter设置距离(max_distance_m)和角度(max_angle_rad)阈值,决定是否插入新扫描帧到子图。 - 3D:除距离和角度阈值外,需额外设置时间阈值(
max_time),避免高频无效帧处理。
2. 点云处理
-
2D:
- 用
missing_data_ray_length替代max_range,处理激光未返回的区域(如空旷处)。
- 用
-
3D:
- 带通滤波:通过
TRAJECTORY_BUILDER_3D.min_range和max_range过滤无效测量值。 - 体素滤波:核心参数
voxel_filter_size控制下采样粒度(默认0.05m,比2D更敏感,直接影响计算量)。 - 高分自适应滤波:
high_resolution_adaptive_voxel_filter(如max_length=0.2m),保留近处细节、过滤远处冗余点。 - 地面过滤:新增
range_data_ingester.filter_ground参数,可过滤地面点以减少匹配干扰(2D无需此步骤)。
- 带通滤波:通过
三、扫描匹配差异
1. 匹配维度与参数
-
2D匹配:
- 在
TRAJECTORY_BUILDER_2D.ceres_scan_matcher中调整occupied_space_weight(占据空间权重)、translation_weight(平移权重)和rotation_weight(旋转权重)。
- 在
-
3D匹配:
- 需估计6自由度(x、y、z平移+滚转、俯仰、偏航角),点云分高低分辨率两部分,分别用
occupied_space_weight_0和occupied_space_weight_1调整权重。 - 旋转权重区分轴:
rotation_weight中滚转(roll)、俯仰(pitch)默认1e3,偏航(yaw)默认1e6(因偏航对地图一致性影响更大)。 - 三维关联匹配:
correlative_scan_matcher_3d参数(如linear_search_window默认0.5m,angular_search_window默认0.17rad≈10°),搜索范围大于2D(三维空间噪声更高)。 - 可选启用
use_online_correlative_scan_matching提高鲁棒性,但增加计算量。
- 需估计6自由度(x、y、z平移+滚转、俯仰、偏航角),点云分高低分辨率两部分,分别用
2. IMU融合
- 3D前端强制融合IMU数据,通过
imu_integration参数(如integrate_imu_function)优化位姿初始猜测,减少匹配搜索范围;2D中IMU为可选,融合作用较弱。
四、后端优化与地图表示差异
1. 地图表示
- 2D:使用
ProbabilityGrid(二维栅格地图),直接输出可导航的PGM格式文件。 - 3D:使用
TSDF(截断符号距离函数)或Submap3D(体素子图),核心参数:high_resolution/low_resolution:高/低分辨率体素参数(如resolution=0.1m/0.2m,分别控制局部细节和回环效率)。truncation_distance:默认0.5m,控制体素中距离值的有效范围(过大会模糊,过小易丢失细节)。
2. 后端优化
- 2D:仅在平面内优化,无重力约束。
- 3D:处理6自由度约束,优化更复杂:
- 约束构建:
map_builder_3d.constraint_builder中low_resolution_adaptive_voxel_filter(如max_length=1.0m)降低回环匹配计算量。 - 重力约束:
pose_graph_3d.optimization_problem中gravity_constraint_weight(默认1e6),确保z轴方向一致性(2D无此参数)。
- 约束构建:
3. 输出格式与应用
- 2D:直接生成2D栅格地图(PGM),可直接用于导航。
- 3D:生成
.pbstream格式3D混合概率地图,需通过cartographer_occupancy_grid_node投影为2D栅格用于导航;完整3D点云地图需通过assets_writer离线生成PLY/PCD文件。
五、其他关键差异
- 内存占用:3D体素地图内存消耗远高于2D,需通过
submaps.num_range_data(默认60,可减至30~40)和voxel_filter_size控制。 - 计算复杂度:3D因处理6自由度和更大数据量,计算需求高于2D,需平衡精度与实时性(如调整滤波粒度和搜索范围)。
