上一篇,我们把 Android、Linux 主控、MCU 和硬件之间的关系重新梳理了一遍。

其中有一个很重要的结论:

机器人并不是简单的 Android → Linux → MCU 三级流水线,而是按照能力归属进行分层。

例如:

Android
负责业务、人机交互,以及部分业务外设

Linux 主控
负责导航、任务、底盘、回充等机器人核心能力

MCU
负责实时硬件执行

但是一旦这些能力划分清楚,马上又会出现一个新的问题:

谁有资格调用这些能力?

因为一台真正的服务机器人,很少只有一个控制入口。

它可能同时存在:

机身 Android 控制屏

用户手机 App

云端后台

机器人自主任务

维护人员

安全系统

比如机器人正在自动巡航。

此时机身 Android 发送:

STOP_TASK

手机 App 又发送:

RETURN_TO_CHARGE

云端还有一个任务:

CONTINUE_PATROL

那么问题来了:

机器人到底应该听谁的?

这已经不是 TCP、MQTT 或 Command 怎么发送的问题。

而是一个更高层的问题:

当前到底是谁拥有机器人的控制权?


一、服务机器人为什么天然存在多个控制入口?

先把一台服务机器人常见的控制入口重新画出来:

                手机 App
                    ↓
                  Cloud
                    ↓
                    │
                    │ Remote
                    ▼
机身 Android ───→ Linux 主控 ←── AUTO Task
     Local              ↑
                        │
                  Maintenance

再往下:

Linux 主控
    ↓
Navigation / Task / Chassis
    ↓
MCU
    ↓
Hardware

可以看到:

Linux 主控并不是只接收 Android 一种来源的 Command。

它可能同时接收到:

本地控制

远程控制

自主任务

维护控制

所以服务机器人从架构上就是:

一个多控制入口系统。


二、第一个入口:机身 Android,本地控制 LOCAL

机器人机身通常有一块 Android 控制屏。

现场用户可能通过它:

开始任务

停止任务

选择点位

打开柜门

返回充电

查看机器人状态

通信链路通常是:

机身 Android
      ↓ TCP
Linux 主控

这种控制有几个特点:

距离近

延迟低

不依赖公网

操作者就在机器人旁边

所以通常可以把这种控制来源理解成:

LOCAL

也就是:

本地控制。


三、第二个入口:手机 App,远程控制 REMOTE

用户手机和机身 Android 完全不同。

手机可能距离机器人:

几十米

几公里

甚至几百公里

所以通常不会:

手机
↓ TCP
Linux 主控

而是:

手机 App
    ↓ HTTPS
Cloud
    ↓ MQTT
Linux 主控

例如:

手机 App
↓
RETURN_TO_CHARGE
↓
Cloud
↓
Robot

这种就属于:

REMOTE

也就是:

远程控制。


四、第三个入口:机器人自己的自主任务 AUTO

机器人还可能完全不需要人在当前时刻操作。

例如:

每天 10:00 自动巡航

每隔 2 小时巡检一次

低电量自动回充

收到某个事件自动执行任务

这时候指令可能来自:

Task Scheduler

Task Engine

Event Engine

例如:

10:00

↓

创建 PATROL_TASK

↓

Navigation

↓

GO_TO_POINT_A

↓

GO_TO_POINT_B

这个过程中:

手机没有点击。

机身 Android 也没有点击。

是机器人系统自己在执行。

这种模式可以理解成:

AUTO

也就是:

自主控制。


五、第四个入口:维护模式 MAINTENANCE

机器人开发和售后过程中,还存在一个非常特殊的控制入口:

MAINTENANCE

例如工程师需要:

测试左轮

测试右轮

读取传感器原始值

控制某个电机

单独打开柜门

校准设备

测试灯光

升级固件

这些操作很多并不是正常业务 Command。

比如正常运行时:

Navigation
↓
ChassisController

控制底盘。

但是维护人员可能需要:

直接测试 Chassis

如果两套控制同时存在:

Navigation
↓
setVelocity()

Maintenance
↓
setVelocity()

机器人就可能不知道应该听谁。

所以进入维护模式以后,通常需要对普通业务控制做限制。

例如:

进入 MAINTENANCE

↓

暂停普通业务任务

↓

禁止新的远程业务控制

↓

关闭 AUTO Task

↓

把部分设备能力交给维护模块

这就是维护模式存在的意义。


六、所以机器人至少存在四种典型模式

现在可以先得到:

LOCAL

REMOTE

AUTO

MAINTENANCE

但这里一定要注意:

它们不是四种通信协议。

不是:

LOCAL = TCP

REMOTE = MQTT

AUTO = ?

它们表达的是:

机器人当前处于什么控制场景。

比如:

LOCAL
=
现场人员正在控制

REMOTE
=
允许远程控制

AUTO
=
机器人自主执行

MAINTENANCE
=
工程维护状态

这是业务控制概念。

而不是通信概念。


七、ControlMode 和 CommandSource 不能混在一起

这里有一个非常关键的区分。

很多项目刚开始可能只设计:

mode = LOCAL

mode = REMOTE

mode = AUTO

然后通过 mode 判断所有事情。

但实际上还不够。

因为:

当前模式

和:

这条 Command 从哪里来

是两个概念。

可以分别设计:

ControlMode

和:

CommandSource

例如:

ControlMode:

LOCAL

REMOTE

AUTO

MAINTENANCE

CommandSource:

LOCAL_ANDROID

MOBILE_APP

CLOUD

AUTO_TASK

MAINTENANCE_TOOL

SAFETY_SYSTEM

为什么要分开?

因为:

mode = AUTO

并不代表:

机身 Android 什么都不能做。

例如机器人正在 AUTO 巡航。

现场用户点击:

STOP_TASK

这条 Command 很可能仍然应该允许执行。

所以真正的判断不是:

AUTO
→
拒绝所有其他入口

而应该是:

当前 ControlMode

+

CommandSource

+

CommandType

+

机器人当前状态

一起判断。


八、机器人不能采用“最后一个 Command 赢”

假设机器人当前 AUTO 巡航。

系统产生:

GO_TO_POINT_A

手机远程又发送:

RETURN_TO_CHARGE

机身 Android 紧接着发送:

STOP_TASK

如果系统采用:

谁最后发
谁生效

机器人行为会非常不可预测。

因为:

AUTO

REMOTE

LOCAL

背后的业务含义完全不同。

机器人不能把它们当成三个普通消息。

所以需要一个非常重要的概念:

Control Authority

也就是:

控制权。


九、什么叫“控制权”?

控制权可以理解成:

当前哪个控制来源有资格改变机器人的核心行为。

例如:

currentMode = REMOTE

可能表示:

当前允许:

手机 / Cloud

控制:

导航

任务

回充。

而:

AUTO Task

此时可能只能暂停。

或者根本不能创建新的任务。

如果:

currentMode = MAINTENANCE

则可能禁止:

REMOTE START_TASK

AUTO PATROL

所以控制模式本质上是在帮助系统回答:

当前谁可以控制哪些能力?


十、读取状态和控制状态不是一回事

这里也要特别区分。

多控制入口并不意味着:

只有拥有控制权的人才能看到机器人。

例如当前:

LOCAL

现场 Android 正在控制机器人。

手机 App 仍然可以:

查看位置

查看电量

查看任务

查看故障

这些属于:

Read

但是手机此时发送:

GO_TO_POINT

属于:

Write / Control

就可能被拒绝。

所以:

状态查看权限

≠

机器人控制权限

这一点对于多端机器人系统非常重要。


十一、Command 本身也应该区分是否可以抢占

机器人 Command 也不是完全平等的。

例如:

GET_STATUS

基本不会影响当前任务。

而:

GO_TO_POINT

会改变导航目标。

STOP_TASK

会中断当前业务。

不同 Command 可以拥有不同的:

Control Policy

例如 AUTO 模式下:

GET_STATUS
允许

STOP_TASK
允许

GO_TO_POINT
拒绝

DEBUG_MOTOR
拒绝

而 MAINTENANCE 模式:

DEBUG_MOTOR
允许

AUTO_START_TASK
拒绝

所以真正成熟的控制系统不能只判断:

source == LOCAL ?

还需要看:

你到底想做什么。


十二、控制规则更像一个矩阵

可以用一个简单示意来理解:

                     LOCAL   REMOTE   AUTO   MAINTENANCE

GET_STATUS             ✓       ✓       ✓         ✓

START_TASK              ✓       ✓       ✓         ×

GO_TO_POINT             ✓       ✓       ✓         ×

STOP_TASK               ✓       ✓       ✓         ✓

DEBUG_MOTOR             ×       ×       ×         ✓

这只是一个示意。

不同机器人产品的规则可能完全不同。

但是这个模型很重要:

控制权限通常是 Mode + Source + Command 共同决定的。

而不是:

LOCAL 永远大于 REMOTE

这么简单。


十三、本地控制是不是一定比远程控制优先?

不一定。

有些机器人:现场操作优先。

例如:

服务机器人

医疗机器人

有人机交互屏的机器人

现场人员距离机器人最近。

本地控制可能拥有更高业务优先级。

但是另外一些:

无人值守设备

云端调度机器人

工业机器人系统

核心任务可能本来就来自:

云端调度。

所以不能写死:

LOCAL > REMOTE > AUTO

更准确应该是:

由产品的 Control Policy 决定。


十四、但是有一种优先级比较特殊:Safety

虽然:

  • LOCAL
  • REMOTE
  • AUTO
  • MAINTENANCE

谁高谁低,可以根据产品变化。

但是:

Safety

是另外一个层级。

例如:

急停

防跌落

碰撞

驱动器故障

电机过流

危险状态

这些不能和普通业务 Command 平等竞争。

比如机器人正在:

REMOTE

云端不断下发:

继续前进

但现场突然触发:

EMERGENCY_STOP

机器人必须:

停止

不能说:

REMOTE 当前拥有控制权
所以忽略急停

所以安全保护必须独立于普通业务控制权。


十五、STOP_TASK 和 EMERGENCY_STOP 也不是一回事

这两个概念很容易混淆。

STOP_TASK

属于:

业务停止。

例如:

结束巡航任务

停止 Navigation

更新 Task 状态

平滑停止

回到 IDLE

而:

EMERGENCY_STOP

属于:安全动作。

它的第一目标是:

立刻停止危险运动

至于:

  1. 任务状态保存没有?
  2. 云端同步没有?
  3. 页面有没有更新?

都是后续问题。

所以一定要记住:

STOP_TASK
≠
EMERGENCY_STOP

十六、Android 直接连接的外设也存在控制权问题

上一篇我们讲到:

Android 可能通过:

Serial

USB

RS485

直接控制:

柜门

灯光

打印机

扫码器

那么这些设备是否也需要控制权?

还是要看:能力归属。

例如:

打印机

只服务机身 Android 本地业务。

那它基本就是:

Android Capability

不需要 Linux 管理控制权。

但是:

柜门

如果同时支持:

机身开门

手机远程开门

自主任务开门

即使物理上:

柜门 MCU

接在 Android 串口,它逻辑上已经成为:机器人共享能力。

这时候就需要考虑:

统一的控制权管理。

所以:

物理上接在哪里,并不能直接决定逻辑控制权属于谁。


十七、能力归属决定最终控制权归属

这个结论可以和第六篇联系起来。

例如:

Navigation

能力拥有者:

Linux

那么最终:谁能调用 Navigation,应该由 Linux 决定。

例如:

LOCAL Android:
GO_TO_POINT

↓

Linux:
允许 / 拒绝

Cloud:

RETURN_TO_CHARGE

↓

Linux:
允许 / 拒绝

AUTO:

PATROL

↓

Linux:
允许 / 拒绝

最终执行导航的是 Linux。

所以:

Linux 才拥有当前导航控制状态的最终事实。

这也是一个非常重要的架构原则:

Capability Owner 应该拥有该能力最终的控制权判断。


十八、这时候 Linux 主控里会自然出现 Control Arbiter

随着:

LOCAL

REMOTE

AUTO

MAINTENANCE

越来越多,Linux 主控不能让所有模块:

直接调用 Navigation。

否则可能变成:

TCP Handler ─────────→ Navigation

Cloud Handler ───────→ Navigation

AutoTask ────────────→ Navigation

Maintenance ─────────→ Chassis

每个入口都自己决定能不能执行。

系统很快就会混乱。

于是需要一个统一角色:

Control Arbiter

也就是:

控制权仲裁器。

可以先简单理解成:

LOCAL ───────────┐
                 │
REMOTE ──────────┤
                 │
AUTO ────────────┼→ Control Arbiter
                 │
MAINTENANCE ─────┘
                       ↓
                Robot Capability

所有核心控制 Command:

都先进入这一层。


十九、Control Arbiter 到底判断什么?

例如收到:

GO_TO_POINT
source = REMOTE

Control Arbiter 可以判断:

当前 ControlMode 是什么?

Command Source 是谁?

当前控制权属于谁?

当前任务是什么?

这个 Command 是否允许抢占?

机器人当前状态是否允许?

最终给出:

ALLOW

或者:

REJECT

例如:

REJECT

reason = LOCAL_CONTROL_ACTIVE

这时候远程 App 就知道:

不是网络失败。

也不是机器人掉线。

而是:

机器人当前明确不允许远程接管。


二十、Control Arbiter 和 Command Center 不是一个东西

这也是前几篇概念串起来以后很容易混淆的地方。

上一篇补充篇里我们讲过:

Command Center

它主要管理:

CommandId

Pending

Timeout

Retry

Result

它解决的是:

这条 Command 的生命周期是否可靠。

而:

Control Arbiter

解决的是:

这条 Command 当前有没有资格执行。

所以:

Command Center
≠
Control Arbiter

例如本地 Android:

Command Center

↓

TCP

↓

Linux Command Handler

↓

Control Arbiter

↓

Navigation

Android 可以可靠地把:

GO_TO_POINT

送到 Linux。

但是:

可靠送到,不代表一定允许执行。


二十一、服务机器人为什么尤其需要 Robot 端仲裁?

因为服务机器人存在一条非常特殊的链路:

机身 Android
↓ TCP
Linux

它完全可以绕过 Cloud。

与此同时还有:

手机
↓
Cloud
↓
Linux

以及:

AUTO Task
↓
Linux

也就是说:

多个控制入口最终真正汇聚的位置是:

Linux 主控

所以无论 Cloud 前面做过什么判断:

Linux 都必须拥有最终的本地控制权状态。

例如 Cloud 认为:

REMOTE
允许回充

但是就在这一刻:

现场人员已经通过 Android 切换:

LOCAL

Cloud 的状态可能还没同步。

Linux 却知道:

currentMode = LOCAL

所以 Linux 应该能够:

REJECT
REMOTE RETURN_TO_CHARGE

这就是:

本地事实必须由机器人本地掌握。


二十二、那 Cloud 还要不要做控制权判断?

当然要。

例如手机 App 发起远程控制时:

Cloud 同样需要判断:

这个用户有没有权限?

设备是不是属于他?

是不是已经有另一个远程操作者?

当前有没有冲突任务?

当前远程 Control Lease 是否有效?

所以:

Cloud 也可能存在:

Control Arbiter

这时候就会出现:

Cloud Control Arbiter

↓

Robot / Linux Control Arbiter

它们是不是重复?

并不是。

因为:

它们检查的是两个不同层级的问题。

但是这个问题已经比“服务机器人多控制入口”更进一步了。

它涉及:

Cloud、Robot / Linux、甚至 MCU

之间的多级控制仲裁。

所以这一篇先不继续展开。


二十三、这一篇先建立一个核心模型

到这里,我们先把服务机器人的多入口控制模型建立起来:

                 LOCAL
            机身 Android
                  │
                  │
                  ▼

REMOTE ─────→ Control Arbiter ←──── AUTO
Cloud / App                         Task Engine

                  ▲
                  │
             MAINTENANCE
                  │

                  ↓
           Robot Capability

          Task / Navigation

                  ↓
               Chassis

核心就是:

多个控制入口不能直接竞争机器人能力。

中间必须有统一的:

Control Policy

和:

Control Arbiter

二十四、总结

服务机器人相比只有远程手机控制的设备,一个明显的复杂点就是:

它同时存在本地控制和远程控制。

再加上:

AUTO

MAINTENANCE

Safety

以后,就形成了真正的:

多控制入口系统。

典型控制来源包括:

LOCAL
机身 Android

REMOTE
手机 / Cloud

AUTO
机器人自主任务

MAINTENANCE
维护工具

但:

ControlMode

和:

CommandSource

要分开。

真正决定 Command 是否允许执行的,通常是:

ControlMode

+

CommandSource

+

CommandType

+

RobotState

共同决定。

所以机器人不能:

谁最后发 Command
就听谁的

而需要:

Control Arbiter

统一判断:

ALLOW

或

REJECT

对于:

Navigation

Task

Chassis

ReturnToCharge

这类 Linux 主控拥有的核心能力,

Linux 通常应该成为:

机器人本地控制权的最终事实源。

而前面我们讲过的:

Command Center

负责的是:

Command 生命周期。

这一篇新增的:

Control Arbiter

负责的是:

Command 有没有资格执行。

到这里,新的问题也出现了:

手机远程控制首先经过 Cloud。

Cloud 自己是不是也需要做一次 Control Arbiter?

Linux 为什么还要再做一次?

下面的 MCU 又为什么还要保留急停、碰撞、防跌落这些本地安全判断?

也就是说:

为什么机器人不是只有一个控制权仲裁器,而可能存在 Cloud、Linux、MCU 多级仲裁?

这个问题值得单独讲。

下一篇先增加一篇补充篇:

补充篇

《机器人为什么需要多级控制仲裁?Cloud、Linux 与 MCU 分别管什么》

专门把:

Cloud
业务上能不能下发?

↓

Linux
机器人当前能不能执行?

↓

MCU
物理上能不能安全执行?

这三级关系彻底讲清楚。

Logo

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

更多推荐