中国企业互动平台
及新兴产业数据库

简约而不简单: 聊聊VDA5050的cancelOrder

发布者:壹悟科技
时间:2024-07-22
收藏
已收藏

简约而不简单: 聊聊VDA5050的cancelOrder

cancelOrder是 VDA5050 协议中一个预定义的标准 InstantAction,它的用途要远比它的字面含义深远。本文试图分别从调度(MC)和 AGV 的视角来解构它的场景和作用,以及一些基本要求。

1 为消息可靠性兜底

上篇文章我们提到过,VDA5050 协议里OrderState不需要 QoS=1或2 的可靠性。当发现 MC 所持有的最新下发的Order和 AGV 上报的不一致时,可以通过cancelOrder成功后重发来达到一致性。

举例说明如上情况:

  • • Case 1: 在一些极端的情况下,比如 MC 下发了 order1,AGV 收到后应该立即上报一个 state(包含了 order1 的信息);如果 AGV 的处理不及时,或因网络故障造成上报的 state 丢失,如果 MC 没有等到下一次 state 上报就判定 order1 已经丢失而下发新的 orderId order2,这时就会出现 MC 与 AGV 状态分裂。(当然,一个设计良好的 MC 应该通过stateRequest来处理这种情况,而不是基于超时机制,这个话题可以专开一篇)

  • • Case 2:MQTT Broker 的重启导致消息丢失,产生类似 Case 1 的情形。

  • • Case 3: (调试阶段) MC 和人工通过同一个 MQTT Broker 向同一个 AGV 下发了不同的 order。

cancelOrder本身的QoS=0,多发几次没关系;直到 AGV 上报cancelOrder的状态为'FINISHED'。甚至发的太猛了没收住,继续发也没关系,你可以通过错误码“noOrderToCancel“来判断当前的状态。

2 是提升效率的一个手段(吗?)

在集群调度中,如果已经指派了一个 AGV_1 执行任务 task_1,在前往的途中调度发现有一个更适合的 AGV_2 可以执行 task_1,这时就需要将 task_1 从原来的 AGV_1 上取消,然后重新指派给新的 AGV_2。从 AGV_1 取消任务用到的指令就是cacelOrder

如上只是理论可行。在壹悟的调度实现里,我们没有使用cancelOrder来实现上述场景的提效,原因如下:

对于任务的执行可以拆分为若干环节,比如 移动+取货+移动+放货,这些不同的环节有些是可直接取消,有些是不可取消的或者需要追加补偿机制来达到取消的目的。

  • • 比如,如果已经取货完成,如果要 cancelOrder 的话需要为它重新分配放货的库位(同时会引入库位的分配权的话题),这样就会增加调度的复杂性,增加大量的分支判断,从安全的角度得不偿失

  • • 可以限制当 AGV 已经执行到不可取消的环节后不允许 cancelOrder,但这样又会增加调度的交互逻辑判断和复杂性。

  • • AGV 对指令集的实现的完备性和可靠性也是一个考虑因素。

3 优雅的取消

对 AGV 的要求

AGV 的运动规划有一个隐含的前提:在任意时刻,从当前位置到 base 的终点(最后一个 node)的距离能够平稳降速至静止。如果 MC 下发的 base 足够的长,那么 AGV 收到 cancelOrder 后, 或者可以在 base 的终点安全停止,或者在 base 靠前的某个点上(这里我们不考虑可以在边上任意点停止的车型)安全停止,取决于 AGV 当前的速度和减速度的限制。

如果被取消的 order 包含了 Action,那么这些 Action 或者被取消,或者 AGV 坚持执行直至完成然后上报,比如取货、放货等操作,一旦开始执行无法取消。

我把 VDA5050 翻译的更直白一些:或者成功或者失败,不要卡在中间状态,中间状态意味着不可调度。

对 MC 的要求

MC 对某个 AGV 下发了cancelOrder后,不应对 AGV 停在哪个位置做任何假设(只要在已经下发的 base 上都可以),而应该等待 AGV 上报cancelOrder完成,然后再基于 AGV 所在位置规划和下发新的order

MC 也不应该对 AGV 是否一定能取消相关的 Action 做任何假设。而应对取消成功和失败分别实现对应的逻辑。