第四章:参数总览——move_base参数架构与关键参数清单
说实话,很多新手拿到move_base,第一反应就是「参数好多啊」。我当年也是这样,看着launch文件里几十个参数,完全不知道从哪下手。后来踩了不少坑,才慢慢理清这套参数体系的脉络。
这一章,我就带你把这个参数架构彻底搞明白。说白了,move_base的参数就三大块:全局规划、局部规划、代价地图。你把这三大块摸透了,调参就有了方向感。
4.1 move_base参数架构全景
先看整体结构。我习惯把move_base想象成一个三层架构:
核心逻辑层:move_base节点本身,负责调度全局和局部规划器
规划器层:global_planner + local_planner,一个负责大方向,一个负责细节
地图层:global_costmap + local_costmap,给规划器提供环境信息
嗯,这里要注意,每个层都有自己的参数文件。我见过有人把所有参数塞进一个yaml里,结果改一个参数要找半天。我个人建议按功能拆成四个文件:
config/
├── move_base_params.yaml # 核心调度参数
├── global_planner_params.yaml # 全局规划参数
├── local_planner_params.yaml # 局部规划参数
├── costmap_common_params.yaml # 代价地图公共参数
├── global_costmap_params.yaml # 全局代价地图参数
└── local_costmap_params.yaml # 局部代价地图参数
这样拆开,你改局部规划的时候,根本不用碰全局的东西。我在项目里一直这么用,团队协作时也清晰很多。
4.2 核心调度参数(move_base_params.yaml)
这部分参数控制move_base节点本身的行为。我挑几个最关键的说说:
| 参数名 | 默认值 | 说明 |
|---|---|---|
| base_global_planner | navfn/NavfnROS | 全局规划器类型,可选global_planner/GlobalPlanner |
| base_local_planner | base_local_planner/TrajectoryPlannerROS | 局部规划器类型,常用dwa_local_planner/DWAPlannerROS |
| controller_frequency | 20.0 | 局部规划器的控制频率(Hz) |
| planner_frequency | 0.0 | 全局规划频率,0表示只在需要时规划 |
| max_planning_retries | -1 | 规划失败最大重试次数,-1表示无限重试 |
我的经验:controller_frequency别设太高。我曾经设到30Hz,结果机器人原地抖动,CPU占用飙到90%。后来降到10Hz,反而更稳。你想想看,传感器数据更新频率就那么多,控制频率再高也是白算。
4.3 全局规划参数(global_planner_params.yaml)
全局规划说白了就是「看地图,找路径」。我常用的参数:
GlobalPlanner:
allow_unknown: false # 是否允许通过未知区域
default_tolerance: 0.5 # 目标点容差(米)
visualize_potential: false # 是否可视化势场
use_dijkstra: true # true用Dijkstra,false用A*
use_quadratic: true # 使用二次近似
use_grid_path: false # 是否生成网格路径
old_navfn_behavior: false # 是否兼容旧版navfn
这里有个坑:allow_unknown设成true,机器人可能会往没探索过的地方走。我曾经在仓库里测试,机器人直接冲着未知区域去了,结果撞到货架。嗯,建议设成false,除非你的地图已经完整建好了。
至于Dijkstra和A*的选择:Dijkstra保证最优,但慢;A*快,但不一定最优。我个人的习惯是,室内小场景用A*,室外大场景用Dijkstra。为什么?室内路径短,A*那点误差无所谓;室外路径长,Dijkstra的全局最优能省不少冤枉路。
4.4 局部规划参数(local_planner_params.yaml)
局部规划是避障的核心。我用DWA(Dynamic Window Approach)举例:
DWAPlannerROS:
# 机器人速度限制
max_vel_x: 0.5
min_vel_x: -0.1
max_vel_y: 0.0
min_vel_y: 0.0
max_vel_trans: 0.5
min_vel_trans: 0.1
max_vel_theta: 1.0
min_vel_theta: 0.3
# 加速度限制
acc_lim_x: 2.5
acc_lim_y: 0.0
acc_lim_theta: 3.2
# 轨迹评分权重
path_distance_bias: 32.0 # 路径跟随权重
goal_distance_bias: 24.0 # 目标趋向权重
occdist_scale: 0.02 # 障碍物惩罚权重
# 前向模拟参数
sim_time: 1.5 # 模拟时间(秒)
sim_granularity: 0.025 # 模拟步长(米)
vx_samples: 6 # x方向速度采样数
vtheta_samples: 20 # 角速度采样数
避坑指南:我曾经把occdist_scale设成0.5,结果机器人离障碍物老远就开始绕路,在走廊里走S形。后来降到0.02,路径就直了。这个参数要跟path_distance_bias配合调,说白了就是「贴边走」和「远离墙」之间的平衡。
4.5 代价地图参数(costmap_common_params.yaml)
代价地图是规划器的「眼睛」。我把它分成三部分:
4.5.1 障碍物层参数
obstacle_layer:
enabled: true
obstacle_range: 2.5 # 障碍物最大检测距离(米)
raytrace_range: 3.0 # 射线追踪最大距离(米)
inflation_radius: 0.55 # 膨胀半径(米)
track_unknown_space: false # 是否追踪未知空间
observation_sources: laser_scan_sensor
laser_scan_sensor:
data_type: LaserScan
topic: /scan
marking: true
clearing: true
min_obstacle_height: 0.0
max_obstacle_height: 2.0
这里inflation_radius是关键。设大了,机器人过窄门会卡住;设小了,容易蹭到墙。我一般设成机器人宽度的1/3左右。比如机器人宽0.6米,我就设0.2米。
4.5.2 膨胀层参数
inflation_layer:
enabled: true
cost_scaling_factor: 10.0 # 代价衰减因子
inflation_radius: 0.55 # 必须跟obstacle_layer一致
cost_scaling_factor控制代价从障碍物边缘向外衰减的速度。值越大,衰减越快,机器人越敢靠近障碍物。我遇到过有人设成100,结果代价几乎不衰减,机器人离墙老远就停住了。
4.5.3 静态地图层参数
static_layer:
enabled: true
map_topic: /map
first_map_only: false # 是否只使用第一帧地图
subscribe_to_updates: true # 是否订阅地图更新
4.6 全局与局部代价地图的差异
全局代价地图和局部代价地图虽然参数结构类似,但用途不同:
| 属性 | 全局代价地图 | 局部代价地图 |
|---|---|---|
| 尺寸 | 整个地图 | 机器人周围小范围 |
| 更新频率 | 低(几秒一次) | 高(10Hz以上) |
| 分辨率 | 可低一些 | 尽量高 |
| 滚动窗口 | 否 | 是(跟随机器人) |
我举个例子你就明白了:全局代价地图像一张城市地图,告诉你从A到B的大致路线;局部代价地图像车载雷达,实时告诉你前面有没有车、要不要变道。两个缺一不可。
4.7 参数调优的通用原则
最后,分享几个我总结的调参原则:
- 一次只改一个参数。改完测试,记录效果。我见过有人同时改5个参数,出了问题根本不知道是哪个引起的。
- 从安全开始。先把速度设慢、膨胀半径设大,确保机器人不会撞。然后再逐步优化效率。
- 用bag包回放测试。别让机器人在真实环境里反复跑,用rosbag录一段数据,离线调参效率高得多。
- 关注计算资源。参数设得太精细,CPU扛不住。我遇到过sim_time设成3秒,结果控制周期从50ms变成200ms,机器人反应迟钝。
核心要点:move_base参数调优不是玄学,是有章可循的。先理解架构,再逐个参数调试,最后用数据验证。你按这个流程走,地图精度和避障效果都能稳步提升。
这张图把move_base的参数架构梳理清楚了。从上到下,核心节点调度规划器,规划器依赖代价地图,代价地图又由多个图层叠加而成。每个层级都有对应的参数文件,调参时按图索骥就行。
好了,这一章我们把参数架构和关键清单过了一遍。下一章开始,我会带你逐个参数实战调试,看看每个参数到底怎么影响地图精度和避障效果。