【ROS】恢复行为
前言
本文将介绍 ROS 导航系统中核心节点之一的内部模块——恢复行为(recovery_behavior
)。
当导航过程中机器人陷入停滞或无法继续前进时,恢复行为模块会尝试更新障碍物信息,并执行一系列预设操作以帮助机器人脱困,从而重新规划一条可行的全局路径。
我的环境:
本教程使用的环境是:实体 ROS 小车,Ubuntu 18.04,ROS1 Melodic
参考资料:
- ROS导航系统 | 恢复行为 | Recovery Behaviors
- ROS导航系统 | 恢复行为的参数设置 | Recovery Behaviors
- ROS Wiki - rotate_recovery
- ROS Wike - clear_costmap_recovery
恢复行为(recovery_behavior)概述
当机器人被动态障碍物困住,无法继续导航任务时,ROS 导航系统会启用一种应急机制——恢复行为(recovery_behavior
)。该机制的目标是在导航“卡死”时,尝试清除障碍信息、刷新代价地图,并重新进行路径规划,从而帮助机器人“脱困”,恢复正常导航。
推荐参考讲解视频:
👉 ROS导航系统 | 恢复行为 | Recovery Behaviors(2–7分钟)
恢复行为机制的框架图如下:
恢复行为策略说明:
-
保守重置(conservative_reset):
清除机器人当前位置附近较小范围内的障碍物信息,用于轻微的路径阻塞处理。 -
激进重置(aggressive_reset):
清除更大范围内的障碍物信息,用于尝试处理更严重的路径堵塞。 -
第一次旋转清除(rotate_recovery 1):
原地旋转一圈,让激光雷达完整扫描一圈,用于更新全方位障碍信息,解决可能因激光雷达盲区导致的信息不完整问题。 -
第二次旋转清除(rotate_recovery 2):
与第一次类似,但覆盖范围更大,进一步尝试清理未被检测的障碍。
✅ 实际使用中,保守和激进清除的效果有限,真正发挥作用的往往是旋转清除,尤其对带有雷达盲区的机器人来说尤为关键。
恢复行为的参数
该部分内容推荐参考:
更多恢复行为的参数说明可参考官方文档:
我们可以直接使用 ROS 提供的三种恢复行为,为它们设置对应参数,并对三者进行组合,从而构建一套自定义的恢复策略。
示例:recovery_behavior.yaml
配置文件
恢复行为(recovery behavior)的参数理论上可以放在任意位置,只要加载到 ROS 参数服务器时命名空间设置正确即可。
常见做法是将参数写入 recovery_behaviors.yaml
、global_costmap.yaml
、move_base_params.yaml
等文件,并通过 rosparam
加载。
关键在于确保参数所属的命名空间与调用模块一致,例如使用 ns=recovery_behavior
进行加载时,配置文件中的命名空间也应对应。
建议:虽然参数文件的位置没有强制要求,但为了结构清晰、便于管理,通常建议将恢复行为参数统一放在 move_base
的参数文件中,如 move_base_params.yaml
。
下面是一个示例的 recovery_behavior.yaml
配置文件:
recovery_behaviors:
- name: 'reset_recovery' # 定义一个名为 'reset_recovery' 的恢复行为
type: 'clear_costmap_recovery/ClearCostmapRecovery' # 指定该恢复行为的类型为清除代价地图
- name: 'rotate_recovery' # 定义一个名为 'rotate_recovery' 的恢复行为
type: 'rotate_recovery/RotateRecovery' # 指定该恢复行为的类型为原地旋转
- name: 'move_slow_and_clear' # 定义一个名为 'move_slow_and_clear' 的恢复行为
type: 'move_slow_and_clear/MoveSlowAndClear' # 指定该恢复行为的类型为缓慢移动并清除障碍物
# 'reset_recovery' (clear_costmap_recovery) 的参数
reset_recovery:
reset_distance: 3.0 # 注意:对于 clear_costmap_recovery,这个参数通常不适用或没有实际效果。
# 它更常用于 move_slow_and_clear 类型的恢复行为,表示清除障碍物的距离。
# 对于 clear_costmap_recovery,更关键的是 'layer_names' 参数。
layer_names: ['obstacle_layer'] # 指定需要清除的代价地图图层名称列表。
# 这里设置为清除名为 'obstacle_layer' 的图层。
# 'rotate_recovery' (rotate_recovery) 的参数
rotate_recovery:
sim_granularity: 0.017 # 旋转时检查障碍物的角度间隔(弧度)。
# 0.017 弧度约为 1 度。数值越小,检查越精细。
frequency: 20.0 # 向机器人发送旋转速度指令的频率(赫兹)。
# 'move_slow_and_clear' (move_slow_and_clear) 的参数
move_slow_and_clear:
clearing_distance: 0.5 # 机器人前方尝试清除障碍物的距离(米)。
limited_trans_speed: 0.25 # 机器人在此恢复行为中允许的最大平移速度(米/秒)。
limited_rot_speed: 0.45 # 机器人在此恢复行为中允许的最大旋转速度(弧度/秒)。
planner_namespace: 'PlannerROS' # 规划器的命名空间。这个参数用于在执行清除动作时与规划器进行交互。
# 例如,在清除障碍物后可能需要通知规划器重新规划路径。
参数说明与配置原则
- 恢复行为的名称(name) 可以自定义,但 type 类型 必须是以下三种之一:
clear_costmap_recovery/ClearCostmapRecovery
(重置清除)rotate_recovery/RotateRecovery
(原地旋转清除)move_slow_and_clear/MoveSlowAndClear
(缓慢移动清除,风险较高,通常不建议使用)
恢复行为模块的参数设置
reset_recovery(重置行为:清除代价地图)
reset_distance
:清除半径范围,单位为米。会清除该范围 以外 的所有障碍物信息。layer_names
:指定需要清除的地图层,通常为obstacle_layer
,表示障碍物层(动态障碍地图)。
注意:
清除操作完成后,激光雷达会在下一帧自动重新检测并更新障碍物信息,因此可能无法直观观察到“清除”的过程,但地图实际上已经刷新。
参数冲突说明与解决方法
clear_costmap_recovery
插件默认清除的是名为 obstacles
的层,而 costmap_2d
中常用的障碍层名称为 obstacle_layer
,两者不一致将导致清除失败。因此,我们需要进行以下修改:
修改步骤:
① 修改 costmap_common_params.yaml
中的插件名称,统一为 obstacle
:
plugins:
- {name: static_layer, type: "costmap_2d::StaticLayer"}
- {name: obstacles, type: "costmap_2d::VoxelLayer"}
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
② 修改恢复行为配置文件中 reset_recovery
的参数:
reset_recovery:
reset_distance: 3.0
layer_names: ['obstacle_layer']
推荐参考视频讲解:
恢复行为参数设置(8~11分钟)
rotate_recovery(旋转清除)
该恢复行为用于原地旋转来尝试摆脱困境。
详细参数说明请见:
rotate_recovery - ROS Wiki
常用参数:
sim_granularity
:模拟障碍检测的角度分辨率,单位为弧度。值越小,检测越精细,旋转越安全但计算开销更大。frequency
:向机器人发送旋转速度指令的频率(单位:Hz)。rotational_vel
:机器人旋转的角速度(单位:rad/s)。