- 机器人
- ROS
【免费下载链接】moveit2
:robot: MoveIt for ROS 2
导读
混合规划(Hybrid Planning)是 MoveIt 2 在 ROS 2 平台上的核心架构探索:它将"全局规划 + 局部执行"拆分为 Global Planner、Local Planner 与 Hybrid Planning Manager 三个可独立组合的 ROS 2 组件,通过 action 与 topic 协作完成从运动请求到实时轨迹执行的全链路闭环。本文以moveit_hybrid_planning包(CHANGELOG.rst)为脉络,结合 README.md、源码、配置文件与集成测试,系统梳理该架构的组成、四类插件接口、参数配置与启动方式,并沿版本时间线还原其从骨架搭建到成熟稳定的演进历程。读者读完后将掌握混合规划 demo 的启动与配置方法、每个插件在链路中的职责与源码实现,以及该包近年来的关键技术决策。
一、混合规划架构全景:三大组件与四类插件
从源码目录结构(moveit_ros/hybrid_planning)可以看出,moveit_hybrid_planning包由三个 Component 节点与四类可插拔接口组成:
| 目录 | 组件/插件 | 职责 |
|---|---|---|
hybrid_planning_manager/hybrid_planning_manager_component | HybridPlanningManager | 架构控制中枢,接收用户的HybridPlanneraction 请求,编排全局/局部规划器 |
global_planner/global_planner_component | GlobalPlannerComponent | 提供全局规划 action 服务,将MotionSequenceRequest交给插件求解 |
local_planner/local_planner_component | LocalPlannerComponent | 周期迭代执行局部规划,向控制器发布实时轨迹命令 |
hybrid_planning_manager/planner_logic_plugins | planner logic 插件 | 定义"反应式逻辑":何时发送全局/局部规划请求、如何响应反馈事件 |
global_planner/global_planner_plugins | global planner 插件 | 实现具体的全局求解算法(默认走 MoveIt 规划管线) |
local_planner/trajectory_operator_plugins | trajectory operator 插件 | 维护全局参考轨迹,从当前状态提取下一个目标路点 |
local_planner/local_constraint_solver_plugins | local constraint solver 插件 | 每个迭代周期计算局部解并输出控制器命令 |
1.1 控制中枢:HybridPlanningManager
在 hybrid_planning_manager.hpp 中,HybridPlanningManager通过pluginlib::ClassLoader<PlannerLogicInterface>加载 planner logic 插件,同时持有三个 action 接口:
rclcpp_action::Server<moveit_msgs::action::HybridPlanner>:对外暴露混合规划请求服务(测试中以run_hybrid_planning为 action 名);rclcpp_action::Client<moveit_msgs::action::GlobalPlanner>与rclcpp_action::Client<moveit_msgs::action::LocalPlanner>:分别向全局、局部规划器发送请求。
全局解(MotionPlanResponse)通过global_solution_sub_订阅获取,executeHybridPlannerGoal()在独立线程中处理长耗时回调,并用std::atomic<bool> stop_hybrid_planning_保证取消操作线程安全——这正是 CHANGELOG 中多次提到的"action abortion"与"improve action cancellation"演进所对应的实现。
1.2 全局规划器:GlobalPlannerComponent
global_planner_component.hpp 中的GlobalPlannerComponent加载GlobalPlannerInterface插件,提供GlobalPlanneraction 服务,并在规划完成后将MotionPlanResponse发布到global_trajectory话题,供 Local Planner 与 Manager 监听。
1.3 局部规划器:LocalPlannerComponent
local_planner_component.hpp 定义了局部规划器的四个内部状态:
enum class LocalPlannerState : int8_t { ABORT = -1, ERROR = 0, UNCONFIGURED = 1, AWAIT_GLOBAL_TRAJECTORY = 2, LOCAL_PLANNING_ACTIVE = 3 };LocalPlannerComponent 通过定时器按local_planning_frequency周期性调用executeIteration();内部同时加载 trajectory operator 与 local constraint solver 两个插件;同时维护PlanningSceneMonitor(监听/planning_scene、/collision_object、/joint_states话题)以及 TF buffer,用于碰撞检测与状态同步。局部解最终发布到local_solution_topic(默认为控制器命令话题)。
二、四类插件逐一拆解:接口职责与源码实现
2.1 Planner Logic 插件:决定"何时做什么"
planner logic 插件实现了PlannerLogicInterface::react(),将 Hybrid Planning 事件映射为具体的动作(HybridPlanningAction,如SEND_GLOBAL_SOLVER_REQUEST、SEND_LOCAL_SOLVER_REQUEST、RETURN_HP_SUCCESS)。仓库自带两个 demo 插件:
SinglePlanExecution(single_plan_execution.cpp):"跑一次全局规划,再用局部规划器执行全局解"的最简逻辑。其状态机为:收到请求 → 发送全局求解;全局解可用时等待 action 完成;全局 action 成功 → 启动局部规划器(用local_planner_started_防止重复启动);全局 action 中止 → 以PLANNING_FAILED终止;局部规划成功 → 返回混合规划成功。
ReplanInvalidatedTrajectory(replan_invalidated_trajectory.cpp):在 SinglePlanExecution 基础上增加反应式重规划——当局部规划器反馈COLLISION_AHEAD(前方碰撞)或LOCAL_PLANNER_STUCK(局部规划卡住)时,重新发送全局求解请求,以更新失效的全局轨迹。
两个插件的 pluginlib 导出分别见 single_plan_execution_plugin.xml 与 replan_invalidated_trajectory_plugin.xml,并通过package.xml的<moveit_hybrid_planning>export 段对外声明。
2.2 Global Planner 插件:默认走 MoveIt 规划管线
MoveItPlanningPipeline(moveit_planning_pipeline.cpp)是唯一的全局规划插件,它封装 MoveItCpp API:初始化时声明planning_pipelines.pipeline_names、plan_request_params.*、planning_scene_monitor_options.*等参数;plan()中把MotionSequenceRequest的第一个 item 转换为moveit_cpp::PlanningComponent的PlanRequestParameters,调用plan()后把RobotTrajectory写入MotionPlanResponse返回。从源码可见,该插件目前只接受单 item 的 motion sequence,多 item 请求仅取第一个作为全局目标并给出警告。
2.3 Trajectory Operator 插件:路点采样与轨迹更新
SimpleSampler(simple_sampler.cpp)维护全局参考轨迹与路点索引next_waypoint_index_:
addTrajectorySegment()收到新的全局轨迹时直接替换参考轨迹("global trajectory updates simply replace the reference trajectory"),并用computeTimeStamps()补全时间戳;getLocalTrajectory()取出下一个目标路点作为局部轨迹;当当前状态与目标路点的关节距离 ≤WAYPOINT_RADIAN_TOLERANCE(0.2 rad,L1 范数)时索引前进,形成"到达即推进"的局部目标更新;getTrajectoryProgress()以索引是否抵达末尾判断全局轨迹是否走完。
2.4 Local Constraint Solver 插件:碰撞检测与卡死检测
ForwardTrajectory(forward_trajectory.cpp)实现"把下一个路点转发给控制器":
- 通过
stop_before_collision参数(默认false)控制是否启用碰撞检查;启用时用LockedPlanningSceneRO只读锁定规划场景,调用isPathValid()校验局部轨迹,无效则保持当前位置、清零速度/加速度,并只发送一次COLLISION_AHEAD反馈; - 内置卡死检测:若连续
STUCK_ITERATIONS_THRESHOLD(5 次)迭代中目标路点距离变化 ≤STUCK_THRESHOLD_RAD(1e-4 rad),则反馈LOCAL_PLANNER_STUCK并中止; - 最终把
RobotTrajectory转为JointTrajectory消息发布给控制器。
该插件的卡死反馈正是 ReplanInvalidatedTrajectory 重规划逻辑的触发源,两个插件通过LocalFeedbackEnum(feedback_types.hpp)中的反馈字符串完成解耦。
三、参数配置:三个 YAML 与四张插件清单
moveit_hybrid_planning的 demo 参数集中在 test/config 目录,配合 hp_manager_parameters.yaml 与 local_planner_parameters.yaml 两个generate_parameter_library生成的参数定义使用。
3.1 混合规划管理器参数
hybrid_planning_manager.yaml 是架构中最小但最关键的一个文件——它决定整体行为逻辑:
planner_logic_plugin_name: "moveit_hybrid_planning/ReplanInvalidatedTrajectory"默认加载重规划插件;如需"一次规划、一次执行"的简单行为,可替换为moveit_hybrid_planning/SinglePlanExecution。该参数在hp_manager_parameters.yaml中声明,类型为 string,默认值即moveit::hybrid_planning/ReplanInvalidatedTrajectory。
3.2 局部规划器参数
local_planner.yaml 的完整参数如下(对应local_planner_parameters.yaml中的声明与默认值):
| 参数 | 类型 | demo 取值 | 说明 |
|---|---|---|---|
group_name | string | panda_arm | 使用的规划组 |
trajectory_operator_plugin_name | string | moveit_hybrid_planning/SimpleSampler | 轨迹算子插件 |
local_constraint_solver_plugin_name | string | moveit_hybrid_planning/ForwardTrajectory | 局部约束求解插件 |
local_planning_frequency | double | 100.0 | 局部规划器迭代频率(Hz),默认 1.0 |
global_solution_topic | string | global_trajectory | 全局解订阅话题 |
local_solution_topic | string | /panda_joint_group_position_controller/commands | 局部解发布话题(也可用panda_arm_controller/joint_trajectory) |
local_solution_topic_type | string | std_msgs/Float64MultiArray | 局部解消息类型(也可用trajectory_msgs/JointTrajectory) |
publish_joint_positions | bool | true | 是否发布位置命令 |
publish_joint_velocities | bool | false | 是否发布速度命令 |
monitored_planning_scene | string | /planning_scene | 参考规划场景话题(默认/planning_scene) |
collision_object_topic | string | /collision_object | 碰撞物体话题(默认/collision_object) |
joint_states_topic | string | /joint_states | 关节状态话题(默认/joint_states) |
stop_before_collision | bool | true | ForwardTrajectory 专属:碰撞前停车 |
其中local_solution_topic_type支持两种控制器接口(位置数组std_msgs/Float64MultiArray或关节轨迹trajectory_msgs/JointTrajectory),配合publish_joint_positions/publish_joint_velocities可适配不同的控制器实现——这也是 CHANGELOG 中"Enable different interfaces between local planner and controller"(#426)与"Add publish_joint_positions and publish_joint_velocities param"两项演进留下的配置面。
3.3 全局规划器参数
global_planner.yaml 以global_planner_name指定插件(moveit_hybrid_planning/MoveItPlanningPipeline),其余参数沿袭 moveit_cpp 惯例,分为三组命名空间:
planning_scene_monitor_options: name: "planning_scene_monitor" robot_description: "robot_description" joint_state_topic: "/joint_states" publish_planning_scene_topic: "/planning_scene" monitored_planning_scene_topic: "/planning_scene" wait_for_initial_state_timeout: 10.0 planning_pipelines: pipeline_names: ["ompl"] plan_request_params: planning_attempts: 1 planning_pipeline: ompl max_velocity_scaling_factor: 1.0 max_acceleration_scaling_factor: 1.0这些参数与MoveItPlanningPipeline::initialize()中的declare_parameter一一对应(如plan_request_params.planning_attempts默认 5、planning_time默认 1.0、wait_for_initial_state_timeout默认 10.0 等),可在运行时通过 action 请求中的MotionPlanRequest字段覆盖。
3.4 控制器配置
demo_controller.yaml 展示了 demo 的 ros2_control 硬件接口:joint_trajectory_controller/JointTrajectoryController(panda_arm_controller)、forward_command_controller/ForwardCommandController(panda_joint_group_position_controller)与joint_state_broadcaster,对应 Panda 的 7 个关节。注意 CHANGELOG 显示该配置经历了重要演进:position_controllers在 2.5.1(#1285)被移除、2.15.0(#3753)彻底迁移出position_controllers,改用 forward_command_controller;2.15.2(#3851)又为 controller spawner 补充了参数文件。
四、启动 Demo:从 launch 到容器内组件编排
README 给出的启动命令为:
ros2 launch moveit_hybrid_planning hybrid_planning_demo.launch.py该 demo 的实际编排逻辑集中在 hybrid_planning_common.py:使用MoveItConfigsBuilder("moveit_resources_panda")加载 Panda 的 URDF/SRDF 与 OMPL 规划管线,然后把三个组件放入同一个多线程 ComposableNodeContainer(hybrid_planning_container):
moveit::hybrid_planning::GlobalPlannerComponent(global_planner)moveit::hybrid_planning::LocalPlannerComponent(local_planner)moveit::hybrid_planning::HybridPlanningManager(hybrid_planning_manager)
三个节点分别接收各自的 YAML 参数(global_planner.yaml、local_planner.yaml、hybrid_planning_manager.yaml),全局与局部节点还叠加moveit_config.to_dict()提供机器人描述。这种"进程内多组件 + 参数文件分离"的组织方式对应 CHANGELOG 中"Move common launch elements to a Python file, for easy re-use"(2.3.1)与"Launch file cleanup"(2.5.2)的演进。
五、集成测试:验证 action 闭环与取消语义
test_basic_integration.cpp 展示了混合规划 API 的标准用法,可视为第三方集成的参考模板:
- 创建
rclcpp_action::Client<moveit_msgs::action::HybridPlanner>连接run_hybrid_planningaction; - 初始化
PlanningSceneMonitor,等待/joint_states与 action server 就绪; - 构造
MotionPlanRequest(目标关节值、planner_id="ompl"、allowed_planning_time=2.0),封装为MotionSequenceItem(blend_radius=0.0表示单目标)并装入MotionSequenceRequest; - 发送
HybridPlanner::Goal(含planning_group与motion_sequence),通过 result/feedback 回调断言ActionCompletion成功。
该测试与cancel_action.cpp、test_basic_integration.test.py共同构成集成测试面;CHANGELOG 中关于测试的反复打磨(#980 增加 action abortion 与测试、#1051 一度禁用测试、#3809 "De-flake servo and hybrid_planning launch fixtures")也印证了这类多进程集成测试的稳定性是持续维护重点。
六、版本演进主线:从架构骨架到工程化沉淀
将 CHANGELOG.rst 与源码结构对照,可以还原出moveit_hybrid_planning的清晰演进脉络:
6.1 架构奠基期(2.3.x – 2.5.x,2021–2022)
- 2.3.0:引入
Hybrid planning architecture(#311),搭建 manager / global planner / local planner 骨架与简单状态机;后续(#426)重构为 "component + plugin" 结构,新增forward_trajectory局部求解插件与next_waypoint_sampler(后更名simple_sampler)轨迹算子插件,并用 ros2_control 仿真关节; - 2.3.1–2.3.2:
Enable reaction to planner failure in the planner logic、Add generic global planner plugin, support MotionSequenceRequest(#585)——全局规划器抽象为插件接口,支持运动序列请求; - 2.4.0:
Put hybrid planning actions under a common namespace(#932)、修复全局规划 action 命名(#960); - 2.5.0:
[hybrid planning] configurable planning scene topics(#1052)、Use a map of expected feedback codes(#1065)、Adjust planning scene locking(#1087,改用LockedPlanningSceneRO并复制规划场景、使用 const 机器人状态)、Add action abortion and test(#980)、Delete the pass-through option(#986)——这一系列提交把碰撞检查、规划场景访问与取消语义打磨成型。
6.2 工程化与并行能力期(2.6.x – 2.10.x,2022–2024)
- 2.6.0:
Parallel planning pipelines(#1420)在 MoveItCpp 层面引入MultiPipelinePlanRequestParameters,支持多规划管线并行求解与solution_selection_callback选择机制,为混合规划提供更丰富的全局求解能力; - 2.7.2:
[hybrid planning] improve planning scene monitoring(#1090)——局部约束求解器内创建独立的 PlanningSceneMonitor、降低规划场景更新频率、改用updateSceneWithCurrentState(); - 2.7.4:以
rclcpp版本判断替代ROS_DISTRO环境变量检查(#2135); - 2.8.0:
Replaced numbers with SystemDefaultsQos()(#2271),以 QoS 枚举替代魔法数字; - 2.9.0:全面切换到节点化日志(#2599/#2482)、支持规划器链(#2457)、float→double 迁移(#2343);
- 2.10.0:
Remove HP error codes interface(#2774)、Unify log names(#2720)、Clean-up hybrid planning package(#2603),以及ros-planning组织整体迁移为moveit(#2847)。
6.3 现代化与兼容期(2.11.x – 2.15.x,2024–2026)
- 2.12.0:
.h→.hpp头文件统一(#3113); - 2.13.0:适配
generate_parameter_library 0.4.0(#3255); - 2.15.0:
Remove use of ament_target_dependencies(#3726,改用命名空间 CMake target,如moveit_ros_planning::moveit_ros_planning)、Replace rclcpp::Rate with rclcpp::WallRate(#3558)、迁移出已移除的position_controllers(#3753)、de-flake 测试夹具(#3809)、为 GCC 15 补<cstdint>/<fstream>include(#3754); - 2.15.1–2.15.2:修复 Ubuntu 26.04 的 CI(#3818)、弃用 FindBoost.cmake,以及为 controller spawner 提供参数文件(#3851)。
从这一时间线可以看到,混合规划包在保持"三组件 + 四插件"架构稳定的同时,持续吸收 MoveIt 整体的工程化成果:节点日志、QoS 规范、C++ 头文件规范、参数库化与 CMake 现代化。当前仓库中的插件清单(forward_trajectory_plugin.xml、moveit_planning_pipeline_plugin.xml、simple_sampler_plugin.xml、single_plan_execution_plugin.xml、replan_invalidated_trajectory_plugin.xml)与package.xml中的插件导出声明,正是这套演进沉淀下来的最终形态。
结语
moveit_hybrid_planning的价值在于提供了一个清晰的"全局求解 + 局部实时执行 + 反应式逻辑"分层范式:Manager 通过 planner logic 插件定义行为策略,Global/Local Planner 各自通过插件接口隔离算法实现,topic 与 action 的解耦则让碰撞检测、卡死恢复与重规划成为可插拔的能力。无论是直接运行 demo、按test_basic_integration.cpp的模式接入自己的机器人,还是编写自定义插件替换四类接口中的任一环节,本文所梳理的组件职责、参数语义与源码路径都足以作为切入的索引。
- 机器人
- ROS
【免费下载链接】moveit2
:robot: MoveIt for ROS 2
相关推荐
MoveIt 2 Hybrid Planning 混合规划架构深度解析:架构、插件体系与配置实战
MoveIt 2 Hybrid Planning 混合规划架构深度解析:架构、插件体系与配置实战 Hybrid Planning 是 MoveIt 2 中一种将
机器人ROSMoveIt 2 CHOMP 规划器接口(chomp_interface)演进全解析:插件架构、参数调优与 ROS 1→ROS 2 移植路线图
MoveIt 2 CHOMP 规划器接口(chomp_interface)演进全解析:插件架构、参数调优与 ROS 1→ROS 2 移植路线图 本文以 chom
机器人ROSMoveIt 2 插件元包(moveit_plugins)演进全解析:从控制器插件到 ROS 2 集成
MoveIt 2 插件元包(moveit_plugins)演进全解析:从控制器插件到 ROS 2 集成 导读 本文基于 moveit_plugins/movei
机器人ROS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考