RMCS 框架插件组件,负责:
- 维护飞镖全局状态机 (State Machine)
- 管理任务队列 (Task Queue),每帧驱动当前任务向前推进
- 通过 RMCS Interface 黑板与底层硬件组件通信
- 对任务失败提供统一的异常处理入口
src/manager/
├── core/
│ ├── components/ # 组件入口:DartManager / RemoteCommandBridge
│ └── runtime/ # 通用运行时:Action / ActionSequence / ActionSet / Task
└── resources/
├── actions/ # 具体机械动作
├── tasks/ # 由多个 action 组装出的业务 task
└── task_factory.*# 命令到 task 的统一装配入口
重构后的依赖方向为:core/components -> resources/task_factory -> resources/tasks|actions -> core/runtime。
这样 manager 的核心调度逻辑与自定义动作资源分离,新增动作/任务时不需要再把实现塞进组件入口文件。
┌─────────────────────────────────────────────────────────────────┐
│ │
│ IDLE ──[提交Task]──► RUNNING ──[SUCCESS]──► IDLE |
│ ▲ │ │
│ │ ├──[FAILURE]──► ERROR │
│ │ │ │
│ [recover] [cancel()] │
│ │ │ │
│ ERROR ◄────────────────-┘ │
└─────────────────────────────────────────────────────────────────┘
DartManager 继承自 rmcs_executor::Component 和 rclcpp::Node,在初始化时会注册一系列输入输出接口,用于与底层硬件和外部组件通信。
系统内部运行态由 ManagerLifecycleState 定义:
IDLE:空闲,无任务运行。RUNNING:有任务正在执行。ERROR:任务失败,等待恢复。
每帧通过 update() 函数轮询命令并驱动任务执行:
- 空闲 (
IDLE):从队列中取出下一个任务并开始执行。 - 运行中 (
RUNNING):调用tick_current_task()推进当前任务。根据任务返回的状态 (SUCCESS,FAILURE, 或RUNNING) 进行状态转换。 - 错误 (
ERROR):暂停调度,等待外部发送recover命令。
当前阶段 DartManager 只接收遥控器命令,命令由 RemoteCommandBridge 直接写入 /dart/manager/command。
遥控器映射如下:
- 双下:
cancel - 左拨杆
UP且右拨杆DOWN:carriage_init - 左拨杆
DOWN -> MIDDLE:recover - 左拨杆进入
UP:manual_control - 左拨杆保持
MIDDLE且右拨杆MIDDLE -> DOWN:launch_prepare/launch_prepare_with_vision/launch_cancel - 左拨杆保持
MIDDLE且右拨杆MIDDLE -> UP:fire_preload
内置保留命令包括:
cancel:取消当前任务并清空任务队列。recover:从ERROR状态恢复到IDLE。
其他任务命令(如 launch_prepare, fire_preload)会在 poll_command() 中解析并生成对应的 Task 加入队列。
当 vision_enable=true 时,遥控发射准备入口会发出 launch_prepare_with_vision;否则发出 launch_prepare。
开发者可以通过派生 Action 或组装现有的 Action 创建 Task。组件层会先组装 ManagerInputContext、ManagerOutputContext、ManagerSettings 和 ManagerRuntimeState,再由 task_factory 统一创建具体任务,避免 DartManager 直接依赖所有自定义资源实现。
ActionSet 仍然作为通用 runtime 能力保留,但当前 manager 主流程主要使用顺序 Task 和 ActionSequence。
当前 motor 控制有三类退出语义:
WAIT_ZERO_VELOCITY:退出后进入零速闭环等待。WAIT_HOLD_TORQUE:退出后进入WAIT + hold torque,保持同步带对滑块的压紧状态,直到下一条 belt 指令覆盖。KEEP:退出后保持当前输出不变,直到下一条命令覆盖。
当前 manager 还会通过 /dart/manager/fire_count 输出成功完成 fire_preload 的次数。
任务分支使用 fire_count 判断是否为首发:
fire_count == 0:首发流程fire_count > 0:后续流程recover会将fire_count清零
任务执行失败时会触发 on_task_failure(),该函数会将输出置零,保证系统安全,并将状态机置为 ERROR。