从任务提交到路径分发的最小闭环

ROS2

Posted by Bruce Lee on 2025-04-20

从任务提交到路径分发的最小闭环

ros2-fleet-coordinator本身并不是一开始就瞄准复杂调度,冲突消解,Nav2全栈集成. 相反,它先做了一件更基础,但也更关键的事情: 先把一个多机器人车队系统里面最小可运行闭环搭起来.

这个闭环可以描述为:有机器人周期性上报自身状态/有任务入口可以提交取货点和放货点/有中心管理器选择空闲机器人/有路径规划器给出图上的waypoint路径/有机器人执行节点按waypoint逐步推进并汇报完成

如果从工程分析角度看,这个项目当前并不是在解决"最优车队调度"问题,而是在解决另一个更前置的问题: 如何把任务流,状态流,路径流真正接起来,形成一个能跑通的系统过程

这一点很重要. 因为很多项目在初期阶段很容易陷入两个极端: 要么只有架构图,没有真实流动起来的数据/要么只有零散节点,但是节点之间没有形成完整闭环

而这个项目当前版本,恰恰是在补这条最基本的链路.


工程分解: 为什么它拆成5个包

该项目workspace下面有5个包: fleet_msgs/fleet_manager/ robot_agent/path_planner/fleet_bringup

这个拆法其实非常典型,但重点不在于"典型",而在于职责边界比较清楚.

fleet_msgs

它不是功能节点,而是接口层. 这里统一放消息,服务,动作定义.

这类包的意义在于: 把系统里的公共契约抽出来/避免manager,planner,agent之间互相嵌入对方的数据假设/后续扩展字段时,修改位置集中

如果没有这一层,常见现象就是每个节点自己拼topic内容,系统耦合会快速失控.

fleet_manager

它是中心调度节点,但当前版本更准确的说法是: 任务受理 + 空闲机器人选择 + 调用路径规划 + 发布分配结果

注意这里它还不是严格意义上的高级调度器. 目前策略比较朴素,更像first-idle dispatcher.

robot_agent

每个机器人对应一个执行节点. 它负责: 上报状态/接收分配/模拟沿route逐点前进/上报idle/executing/completed状态迁移

所以它本质上是一个局部执行状态机.

path_planner

这里做了一件刻意简化的事情: 在离散waypoint图上做BFS路径规划.

这说明项目当前关注点不是连续空间导航,而是任务级协调.

fleet_bringup

负责launch和demo配置.

这类包常常被低估,但对于ROS项目来说,bringup本身就是"可运行工程"的一部分. 没有它,系统就只是一堆源码.


先看核心问题: 它到底在打通什么

README.md, STATUS.md, BUGS.md和几个核心node的实现看,这个项目此前真正存在过的主要问题是: 任务虽然能在fleet_manager内部排队,但是没有真正发起路径规划,没有真正下发给机器人,也没有真正形成执行-完成反馈

这类问题在工程里很常见. 表面上看,你已经有: task queue/robot state/planner包/agent包

但这些部件只是"存在",并不代表它们已经形成闭环.

所以这个项目当前最关键的修复不是某个算法优化,而是把以下通路补齐:

submit_task -> manager选择机器人 -> 请求planner -> 发布assignment -> robot_agent执行 -> 回传completed

这件事情比看起来更重要,因为只有这条路径真的跑通了,后面才有资格谈: 冲突检测/优先级调度/任务重分配/更复杂的导航接入


过程模型: 这个系统的最小状态机是什么

如果借用之前分析小型模拟器/状态模型的视角,这个项目也可以被压缩成一个"过程状态机".

它不是只关心某个函数输出什么,而是关心: 一个任务进入系统后,状态如何在不同节点之间迁移

粗略可以写成:

(任务未提交, 机器人idle, 无分配)
-> (任务进入pending队列)
-> (manager选择一个idle robot)
-> (planner返回route_waypoints)
-> (manager发布TaskAssignment)
-> (robot_agent进入executing)
-> (robot_agent逐点推进current_waypoint)
-> (robot_agent发布completed)
-> (manager把该机器人重新视为idle)

这说明这个项目当前分析重点应该放在"状态迁移是否合法",而不只是"某段代码是否能编译".


fleet_manager做的事情: 不是复杂,而是关键

fleet_manager内部当前有几个关键动作: 订阅robot_states/维护每个robot的最新状态/提供submit_task服务/周期性尝试给pending task分配机器人/调用plan_route服务/发布task_assignments

这个节点的关键点在于,它把"任务队列逻辑"和"路径规划逻辑"分开了.

也就是说,manager自己不算路径,而是通过service向planner请求结果. 这种分离有两个直接好处: manager只负责调度语义,planner只负责路径语义/后续如果替换BFS为A*/Dijkstra或者更复杂的reserve-aware planner,manager层可以尽量不动

但是这个设计也有一个很明显的现象: 当前manager是同步依赖planner结果的

即,没有route就没有assignment. 这对当前V1是合理的,因为系统还在追求最小正确性. 但后续如果planning latency上来,就会逼着系统继续分层.

另一个值得注意的实现细节是,manager在机器人刚被分配任务但agent还没有来得及发出执行状态时,会尽量保留已有assignment状态,避免刚分配就被后续idle消息覆盖.

这种逻辑说明作者已经意识到: topic系统里的状态不是原子切换的,中心节点必须处理分配状态和回传状态之间的时间缝隙

这其实是一个很实际的工程点.


path_planner为什么选择BFS

很多人看到路径规划,第一反应就是: 为什么不是A*.为什么不是Dijkstra .为什么不直接上Nav2

但从当前项目阶段看,BFS恰恰是一个很合理的选择.

因为这个系统当前地图不是连续空间地图,而是waypoint graph. 在图边没有权重差异的情况下,BFS就是最小正确解.

这里的核心不是算法先进性,而是: 路径可解释/行为确定/调试成本低/能快速验证manager和agent之间的任务通路

这体现出一个很清楚的工程判断: 当前项目优先验证协调闭环,而不是优先堆叠复杂导航能力

另外,planner当前把任务拆成两段: start -> pickup/pickup -> dropoff

然后再拼接route. 这也说明当前系统的任务模型是非常明确的,它不是泛化任务执行器,而是偏transport task模型.


robot_agent的意义: 用最小执行器把闭环闭上

robot_agent现在不是接机器人底盘,也不是控制真实导航栈. 它做的是更朴素但更必要的事情: 接收TaskAssignment/保存route_waypoints/定时推进route index/更新current_waypoint/发布executing/completed/idle

如果单看代码,它很像一个简化执行器. 但从工程位置看,它承担了一个非常重要的角色: 把静态任务分配,转化成动态状态反馈

如果没有这层,manager永远只能停留在"我认为已经分配了"这个层面,而不是"系统已经执行并回来了".

这个节点还有一个值得注意的小设计:

它除了读取初始x/y,还支持waypoint_positions参数,并且内置了一份fallback map.

这说明作者其实在处理一个现实问题: 状态消息里不仅要告诉别人我在哪个waypoint,还要给出可消费的位置表示

虽然当前只是demo坐标,但接口已经往更真实的robot state形式靠拢了.


为什么说这个项目当前更像"离散事件协调系统"

如果从分析视角看,这个项目虽然挂在ROS 2和机器人名下,但是V1的本质更接近: 一个基于topic/service的离散事件协调系统

原因在于它当前主要处理的不是连续控制量,而是:robot是否idle/task是否pending/route是否规划成功/当前waypoint推进到了哪里/task是否completed

所以项目当前真正的复杂度,主要在以下三件事: 跨节点状态一致性/请求/发布时序/assignment生命周期管理

这也是为什么它现在文档里反复强调"先验证完整assignment and completion flow". 因为这个阶段最怕的不是算法弱,而是系统状态前后对不上.


当前限制和遗留问题

根据STATUS.mdBUGS.md,这个项目目前仍然有几个非常清楚的边界:

1. 还没有冲突检测/预约

也就是说,多个机器人是否会争用同一节点或边,当前没有系统性约束.

这意味着现有planner给出的只是"对单机器人可行",还不是"对整个fleet全局可行".

2. 调度策略还是first-idle

现在的manager更像最小dispatcher,并没有考虑: 距离代价/电量/优先级竞争/已有任务负载

所以它目前的目标不是优化调度,而是先确保dispatch path成立.

3. 运行时验证受sandbox环境限制

项目文档明确记录了DDS socket权限问题. 这意味着: build能做/launch启动能做/节点内topic行为能部分看到/但CLI驱动的完整service discovery和端到端验证,在当前沙箱里受阻

这个问题很关键. 因为它告诉我们,当前未完成的验证不一定是代码错误,也可能是运行环境阻断. 遗留问题和现象1: 在ROS 2项目中,"节点能启动"和"系统闭环已被完整验证"不是一回事

遗留问题和现象2: 对于多节点系统,环境限制有时会伪装成代码缺陷,必须把环境问题单独记账


这个项目为什么值得继续往下做

我觉得这个项目当前最合理的地方,恰恰在于它没有一开始就追求太大.

它先把系统压到下面这个规模: 图是离散的.planner是BFS.agent是模拟执行.scheduler是first-idle.bringup里只有少量demo节点

这种压缩不是能力不足,而是一种工程节奏控制. 因为多机器人系统真正危险的地方在于: 你很容易同时引入调度复杂性,导航复杂性,并发复杂性,通信复杂性和环境复杂性

一旦这些复杂性同时进入系统,那就不是"难调试",而是根本不知道问题属于哪一层.

而当前这个项目的好处是,它把问题分层得比较干净: 先确认接口层成立/再确认任务闭环成立/再去碰冲突控制/再去碰更强调度/最后再考虑重型导航集成

这条路径是比较稳的.


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. All the images used in the blog are my original works or AI works, if you want to take it,don't hesitate. Thank you !