上一篇我们讲到:

机身 Android 与 Linux 主控通过 TCP 通信时,一条可靠机器人指令不能只是:

send(command)

它还需要管理:

CommandId / Sequence

Pending

Ack

Timeout

Retry

Result

幂等

当这些能力逐渐集中以后,我们可以把 Android 里的这一层抽象成:

Command Center

也就是:

指令中心。

但是写到这里,一个非常有意思的问题出现了。

以前做割草机器人时,手机 App 也会控制机器人:

开始割草

暂停

继续

停止

回充

为什么当时手机 App 里似乎没有这样一个:

Command Center

难道割草机器人不需要:

Ack

Timeout

Retry

幂等

这些机制吗?

当然不是。

继续把两套架构放在一起看就会发现:

服务机器人和割草机器人都需要指令中心。

真正不同的是:

指令中心部署在什么位置。


一、先看服务机器人:Android 就是直接控制端

我们第二季目前讨论的服务机器人是:

机身 Android
      ↓ TCP
Linux 主控
      ↓
MCU
      ↓
硬件

Android 本身就是机器人上的本地控制终端。

用户点击:

打开柜门

Android 直接生成:

OPEN_DOOR
sequence = 1001

通过 TCP 发送给:

Linux 主控

因此 Android 很自然就需要维护:

Sequence

PendingCommand

Ack Timeout

Retry

Result

于是架构可以抽象成:

机身 Android

┌──────────────────┐
│  Command Center  │
│                  │
│ CommandId        │
│ Pending          │
│ Timeout          │
│ Retry            │
│ Lifecycle        │
└────────┬─────────┘
         │
        TCP
         │
┌────────▼─────────┐
│ Linux 主控       │
│ Command Handler  │
└────────┬─────────┘
         │
      机器人能力

这里:

Command Center

就在:

Android。


二、为什么 Command Center 会放在 Android?

因为这个架构里:

Android

就是直接指令发起端。

它知道:

用户刚才点了什么。

它知道:

这条 Command 的 Sequence。

它也直接接收:

Ack

Result。

因此维护:

PendingCommand

非常自然。

例如:

1001
OPEN_DOOR
WAIT_ACK

Android 收到:

ACK 1001

更新:

ACKED

收到:

RESULT 1001 SUCCESS

结束:

Command Lifecycle

所以在这种:

本地一对一直接控制

场景下,

Command Center 可以放得非常靠近控制端。


三、再看割草机器人,架构完全不一样

割草机器人远程控制通常不是:

手机 App
↓
TCP
↓
割草机器人

而更接近:

手机 App
   ↓ HTTPS
云端
   ↓ MQTT
割草机器人

机器人执行以后,再:

割草机器人
   ↓
云端
   ↓
手机 App

例如用户点击:

开始割草

App 实际执行的可能更像:

POST /mowing/start

也就是说:

手机 App 首先是在向:

Cloud

发起一个业务请求。


四、真正给割草机下发 Command 的是谁?

继续向下看。

云端收到:

开始割草

以后,可能会执行:

校验用户

↓

校验设备

↓

创建任务 / 指令

↓

生成 commandId / taskId

↓

保存状态

↓

通过 MQTT 下发机器人

于是:

Cloud
        START_MOWING
     ────────────────>
            Robot

这时候真正直接面对机器人执行端的:

其实已经不是:

手机 App

而是:

Cloud

所以:

CommandId

Pending

Timeout

Retry

Result

这些能力真正更加合适的位置就变成了:

云端

五、于是割草机器人也存在 Command Center

只是位置不同。

可以抽象成:

手机 App
    │
    │ HTTPS
    ▼

┌──────────────────┐
│      Cloud       │
│                  │
│  Command Center  │
│                  │
│ commandId        │
│ Pending          │
│ Timeout          │
│ Retry            │
│ Result           │
│ Task State       │
└────────┬─────────┘
         │
        MQTT
         │
┌────────▼─────────┐
│ Mower Robot      │
│ Command Handler  │
└────────┬─────────┘
         │
       执行任务

所以割草机器人不是:

没有指令中心。

而是:

指令中心从客户端移动到了云端。


六、为什么不能让手机 App 自己做割草机 Command Center?

假设:

Pending

Timeout

Retry

全部由手机 App 管理。

会有什么问题?

比如用户点击:

开始割草

然后:

手机退出 App。

或者:

手机断网。

甚至:

手机直接关机。

难道机器人任务生命周期就没人管了吗?

显然不能。

割草机器人执行任务可能持续:

几十分钟

几小时

所以它的 Command 生命周期必须独立于:

手机 App 生命周期

而云端本身:

长期在线

非常适合承担:

指令状态

任务状态

超时

重试

历史结果

所以对于远程机器人:

Command Center

放在云端会更加合理。


七、手机 App 在割草机器人里负责什么?

那手机 App 是不是就完全不管 Command 了?

不是。

它仍然负责:

用户发起操作

展示操作中状态

显示任务结果

订阅机器人最新状态

但是它不需要承担:

机器人指令生命周期的最终事实源

例如:

手机 App
↓
开始割草
↓
Cloud

Cloud 返回:

请求已接受
taskId = 888

后面 App 主要观察:

CREATED

DISPATCHED

RUNNING

PAUSED

RETURNING

COMPLETED

FAILED

所以 App 更像:

任务操作端 + 状态展示端。


八、服务机器人和割草机器人的区别终于清楚了

把两套架构放在一起。

服务机器人本地控制

用户
 ↓
机身 Android
 ↓
Command Center
 ↓ TCP
Linux 主控
 ↓
Command Handler
 ↓
机器人执行

这里:

Command Center
=
Android

割草机器人远程控制

用户
 ↓
手机 App
 ↓ HTTPS
Cloud
 ↓
Command Center
 ↓ MQTT
Robot
 ↓
Command Handler
 ↓
机器人执行

这里:

Command Center
=
Cloud

所以两者的本质差异并不是:

有没有指令中心

而是:

指令中心在哪里

九、继续抽象:所有指令系统都可以分成两端

现在可以进一步把具体机器人去掉。

抽象以后,其实就是:

┌────────────────────┐
│   Command Center   │
│                    │
│ create             │
│ commandId          │
│ pending            │
│ timeout            │
│ retry              │
│ lifecycle          │
└──────────┬─────────┘
           │
       通信协议
           │
┌──────────▼─────────┐
│  Command Handler   │
│                    │
│ receive            │
│ validate           │
│ deduplicate        │
│ execute            │
│ idempotency        │
│ result             │
└──────────┬─────────┘
           │
       机器人能力

一个负责:

管理指令。

一个负责:

执行指令。


十、Command Center 负责什么?

Command Center 更关注:

Command 怎么创建

CommandId 怎么生成

有没有 Pending

多久算 Timeout

是否允许 Retry

现在处于什么状态

最终 Result 是什么

它关心的是:

指令生命周期。

例如:

CREATED

↓

SENT

↓

ACKED

↓

EXECUTING

↓

SUCCESS

或者:

SENT

↓

TIMEOUT

↓

RETRY

↓

FAILED

十一、Command Handler 负责什么?

机器人执行侧更加关注:

收到 Command

↓

解析

↓

校验

↓

判断是否重复

↓

判断当前机器人是否允许执行

↓

调用机器人能力

↓

返回 Result

例如:

OPEN_DOOR

Linux 主控需要:

检查 sequence

↓

是否已经执行过

↓

没有

↓

DoorService.openDoor()

↓

MCU

↓

返回 SUCCESS

所以:

Command Handler 解决的是:

这条指令如何安全、正确地执行。


十二、为什么两边都要保存 CommandId?

这是实现可靠性的关键。

例如:

Command Center:

commandId = 1001

第一次发送:

1001
OPEN_DOOR

执行端:

Command Handler

收到以后记录:

1001 → SUCCESS

结果返回过程中丢失。

Command Center:

TIMEOUT

于是重试:

1001
OPEN_DOOR

Command Handler 发现:

1001

已经执行过。

于是:

不重复执行

直接返回:

SUCCESS

这时候:

Command Center
+
Command Handler

共同完成了:

可靠重试 + 幂等。


十三、服务机器人和割草机器人只是部署位置不同

现在再看两套系统。

服务机器人:

Command Center
运行在 Android

Command Handler
运行在 Linux 主控

割草机器人:

Command Center
运行在 Cloud

Command Handler
运行在机器人主控

于是可以得到一个很重要的架构结论:

Command Center 是一个逻辑角色,而不是固定属于某个平台的软件模块。

它可以运行在:

Android

Cloud

Linux 主控

甚至独立的调度服务

具体放哪里,要看:

控制链路

网络拓扑

任务持续时间

客户端生命周期

可靠性要求

十四、本地控制为什么更靠近机器人?

服务机器人机身 Android:

Android
↕ TCP
Linux

就在同一台机器人内部。

特点是:

低延迟

长期连接

一对一

本地网络

控制实时性高

所以 Command Center 放在 Android:

路径最短。


十五、远程控制为什么更靠近云端?

割草机器人:

App
↓
Internet
↓
Cloud
↓
Internet
↓
Robot

特点是:

设备长期在线

手机可能随时退出

任务持续时间长

需要历史记录

需要多客户端同步

所以 Command Center 放在云端:

更稳定。


十六、这也解释了为什么机器人云平台需要“指令中心”

如果以后平台中只有:

一台割草机器人

云端 Command Center 可能只是:

某个 Spring Boot 模块。

但如果以后变成:

1000 台机器人

10000 台机器人

那么:

Command Center

本身就可能逐渐变成一个明确的平台能力。

例如负责:

指令创建

设备路由

MQTT 下发

回执

超时

重试

幂等

状态持久化

指令历史

这时候架构就可能变成:

App
 ↓
API
 ↓
Task Service
 ↓
Command Service
 ↓
MQTT Broker
 ↓
Robot

也就是说:

我们现在从 Android TCP 里抽象出来的 PendingCommand,最终可以一路演化成云平台里的 Command Service。


十七、Task Center 和 Command Center 又是什么关系?

这里再提前埋一个后面云平台会遇到的问题。

任务和指令不是同一个概念。

例如:

巡航一圈

是一个:

Task

但这个任务执行过程中可能产生很多 Command:

START_NAVIGATION

GO_TO_POINT_A

GO_TO_POINT_B

RETURN_CHARGE

所以可以理解成:

Task Center
     ↓
产生 / 编排
     ↓
Command Center
     ↓
Robot

Task 关心:

业务目标。

Command 关心:

具体控制动作。

这两个概念以后到了机器人云平台里会越来越重要。


十八、回头再看两种机器人,很多东西其实已经统一了

服务机器人:

Android
Command Center
     ↓ TCP
Linux
Command Handler

割草机器人:

Cloud
Command Center
     ↓ MQTT
Robot
Command Handler

虽然:

TCP

和:

MQTT

完全不同,

部署位置也不同。

但上层架构其实都是:

指令产生

↓

生命周期管理

↓

可靠传输

↓

执行端去重

↓

机器人执行

↓

结果返回

所以:

通信协议可以不同,但可靠指令模型可以复用。


十九、机器人指令架构真正应该关心什么?

当我们不再只盯着:

TCP
MQTT

以后,会发现真正需要解决的是:

谁创建 Command?

谁拥有 commandId?

谁维护 Pending?

谁判断 Timeout?

谁负责 Retry?

谁负责幂等?

谁保存 Result?

谁是这条指令的最终事实源?

这些问题确定以后:

Command Center 应该部署在哪里,

其实也就基本确定了。


二十、总结

服务机器人和割草机器人看起来采用了完全不同的通信架构。

服务机器人:

机身 Android
     ↓ TCP
Linux 主控

割草机器人:

手机 App
   ↓ HTTPS
Cloud
   ↓ MQTT
Robot

但继续抽象以后会发现:

两套系统都需要可靠的指令管理机制。

可以统一成:

Command Center

↓

Communication

↓

Command Handler

↓

Robot Capability

其中:

服务机器人:

Android
=
Command Center

Linux 主控:

Command Handler

而割草机器人:

Cloud
=
Command Center

Robot:

Command Handler

因此真正的区别不是:

有没有指令中心。

而是:

指令生命周期由谁负责,以及这个指令中心部署在哪一层。

本地强控制场景:

Command Center
更靠近机器人

远程设备控制场景:

Command Center
更靠近云端

大型机器人平台继续发展以后:

Command Center

甚至可能进一步成为独立的平台服务。

从这一点也能看到:

我们现在虽然是在讲:

Android TCP

但真正逐渐建立起来的,已经不是一个 Android 通信模块。

而是一套:

可以从移动端一直复用到云平台的机器人可靠指令架构。

下一篇回到原来的主线:

第 6 篇

《Android、机器人主控、MCU 与硬件到底如何分层?》

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐