第 6 篇:Android、机器人主控、MCU 与硬件到底如何分层?
前面几篇,我们已经把机身 Android 与 Linux 机器人主控之间的通信基本串起来了:
TCP 长连接
↓
心跳、掉线检测与重连
↓
粘包、半包与协议解析
↓
Command、Ack、Timeout、Retry
↓
Command Center 与 Command Handler
到了这里,一个新的问题出现了:
Linux 主控收到 Android 发来的指令以后,机器人到底是怎么真正动起来的?
比如 Android 发送:
OPEN_DOOR
到底是谁打开柜门?
Android 发送:
SET_LIGHT_ON
到底是谁控制灯光?
Android 发送:
GO_TO_POINT
最终又是谁让机器人的轮子真正转起来?
刚开始理解机器人架构时,很容易把整个系统画成一个简单的三级结构:
Android
↓ TCP
Linux 主控
↓ CAN / 串口
MCU
↓
真实硬件
这个模型没有错。但它还不够完整。
因为真实机器人里还经常存在另外一种情况:
Android
↓ 串口 / USB / RS485
外设 MCU / 控制板
↓
柜门 / 灯光 / 打印机 / 扫码器等
也就是说:
机器人内部并不是所有硬件都必须经过 Linux 主控。
真正重要的不是:
Android 能不能直接连硬件?
而是:
这个硬件能力到底应该属于哪一层?
这一篇,我们就把 Android、Linux 主控、MCU、底盘和各种外设之间的职责重新梳理清楚。
一、先把服务机器人整体架构画完整
前面我们已经明确:
服务机器人里通常存在两个上层交互端。
一个是:
机器人机身上的 Android 控制屏。
另一个是:
用户手机里的 App。
所以整个架构可以先理解成:
用户手机 App
Android / iOS / KMP
↓
HTTPS / MQTT
↓
云端平台
↓
MQTT / HTTPS
↓
Linux 主控
↑ ↓
TCP CAN / 串口
↑ ↓
机身 Android 底盘 MCU
│ ↓
│ 电机 / 编码器
│
串口 / USB / RS485
↓
业务外设控制板
↓
柜门 / 灯光 / 打印机 / 扫码器
这张图和简单的:
Android
↓
Linux
↓
MCU
相比,多了一条非常重要的支路:
Android
↓
业务外设
所以机器人软件架构并不是一条单向流水线。
更准确地说,它是一套:
按照职责划分的多控制节点系统。
二、先区分机器人里的两个 Android
机器人项目里经常会同时出现两个 Android。
第一个是:
机器人机身 Android 控制屏
它属于机器人本体的一部分。
通常负责:
本地 UI
任务选择
地图展示
设备状态
扫码
打印
柜门操作
业务流程
运维设置
第二个是:
用户手机 App
它通常负责:
远程设备管理
远程任务
机器人状态查看
历史数据
告警
远程控制
两者最大的区别是:
机身 Android :本地控制入口。
手机 App :远程控制入口。
所以:
机身 Android
↓ TCP
Linux 主控
和:
手机 App
↓ Cloud
↓
Linux 主控
是两条不同的控制链路。
但是它们最后都会进入:
机器人真正的能力层。
三、Android 的核心职责仍然是业务与交互
虽然 Android 可以直接串口控制某些硬件,但这并不改变 Android 最主要的角色。
Android 仍然主要负责:
业务与人机交互。
例如用户在机器人屏幕点击:
前往会议室
Android 应该表达:
GO_TO_POINT
pointId = meeting_room
而不是:
左轮 PWM = 120
右轮 PWM = 115
用户点击:
开始巡航
Android 应该表达:
START_PATROL
而不是直接控制电机。
因为:
去哪里
开始什么任务
执行什么业务
属于业务语义。
而:
轮子怎么转
导航怎么规划
如何避障
属于机器人核心控制能力。
所以对于:
- 导航
- 底盘
- 定位
- 任务
- 回充
这类能力,Android 更应该调用 Linux 主控提供的:
机器人能力接口。
四、Linux 主控负责机器人核心能力
Linux 主控通常是整台机器人的核心控制节点。
它可能负责:
任务状态机
SLAM
定位
导航
路径规划
底盘控制
核心传感器
回充
设备状态
机器人安全状态
云端通信
例如 Android 发送:
GO_TO_POINT
pointId = 10
Linux 主控可能需要:
读取目标点位
↓
检查地图
↓
检查当前定位
↓
启动导航
↓
规划路径
↓
持续获取 Pose
↓
输出运动目标
↓
控制底盘
↓
监测导航结果
最后再向 Android 返回:
NAVIGATION_START
↓
NAVIGATING
↓
ARRIVED
所以可以简单理解:
Android
负责:
用户想让机器人做什么
Linux 主控
负责:
机器人如何完成这件事
五、MCU 又负责什么?
再往下,就是 MCU。
例如:
STM32 或者 其他单片机。
MCU 和 Linux 擅长的事情并不一样。
Linux 更擅长:
复杂业务
网络
任务调度
导航
算法
文件系统
多线程
MCU 更擅长:
实时控制
GPIO
PWM
电机
编码器
传感器采集
硬件时序
低级总线通信
所以可以理解成:
Linux
决定:
机器人应该怎么做
↓
MCU
负责:
让硬件真正按照要求执行
六、底盘就是一个典型的 MCU 控制子系统
机器人底盘通常包含:
底盘控制器
MCU
电机驱动
编码器
IMU
轮子
急停
电源系统
典型结构:
Linux 主控
↓ CAN / 串口
底盘控制器
↓
电机驱动
↓
电机 / 轮子
Linux 可能发送的是:
linearVelocity = 0.5 m/s
angularVelocity = 0.2 rad/s
而不是:
左轮 PWM = 123
右轮 PWM = 118
底盘 MCU 再根据目标速度处理:
左右轮速度
PID
编码器反馈
电机控制
所以传统意义上的底盘更像:
机器人的运动执行子系统。
七、底盘通常不会直接和云端通信
对于传统底盘来说:
底盘 MCU
通常不会直接:
MQTT
↓
Cloud
真正连接云端的通常是:
Linux 主控
所以远程控制可能是:
手机 App
↓
Cloud
↓
Linux 主控
↓
导航 / 任务
↓
底盘控制器
↓
电机
例如手机发起:
RETURN_TO_CHARGE
并不是:
Cloud
↓
直接控制电机
而是:
Cloud
↓
Linux 主控
↓
创建回充任务
↓
导航系统
↓
底盘运动
所以:
云端负责远程业务与任务。
Linux 主控负责机器人核心控制。
底盘负责运动执行。
八、为什么有些“底盘”看起来又像 Linux 设备?
现在很多厂商卖的并不是简单底盘。
而是:智能底盘。
里面可能已经集成:
ARM / 工控机
Linux
ROS / ROS2
SLAM
Navigation
雷达
底盘 MCU
电机
这时候外部开发者看到的可能就是:
Android
↓ TCP / API
智能底盘
于是很容易产生一种感觉:
底盘是不是其实就是一个 Linux 服务?
更准确地说:
不是底盘 MCU 变成了 Linux,而是厂商把 Linux 主控和传统底盘一起封装成了“智能底盘产品”。
传统结构:
Linux 主控
↓
底盘 MCU
↓
电机
被厂家封装以后:
智能底盘
所以以后看到“底盘”这个词,最好先判断:
它只是运动控制器,还是已经包含 Linux 主控?
这是两个完全不同的东西。
九、但机器人内部并不是所有硬件都要经过 Linux
前面这些内容容易给人一个感觉:
Android
↓
Linux
↓
MCU
↓
所有硬件
真实机器人往往并不是这样。
Android 本身也可能通过:
UART
USB Serial
RS485
USB
GPIO
直接连接一些业务外设。
例如:
Android
↓ 串口
柜门控制板
或者:
Android
↓ USB
扫码器
或者:
Android
↓ USB
打印机
甚至:
Android
↓ RS485
灯光 / 托盘控制器
这些设计完全合理。
十、为什么 Android 可以直接控制这些外设?
因为这些设备和 Android 上层业务流程 往往绑定得非常紧。
例如云柜机器人:
用户扫码
↓
Android 获取扫码结果
↓
校验业务
↓
打开柜门
↓
页面提示取货
↓
关闭柜门
↓
业务结束
如果柜门控制板本身就直接连接 Android:
Android
↓ Serial
柜门 MCU
那么没必要为了“架构漂亮”强行绕成:
Android
↓ TCP
Linux
↓ Serial
柜门 MCU
后者反而增加了:
- 通信链路
- 依赖关系
- 故障点
- 处理延迟
所以:
分层不是为了多加一层。
分层真正的目的是:
让能力归属合理。
十一、什么硬件更适合 Linux 主控?
一般来说,如果这个能力属于:
机器人核心运动与自主运行能力
更适合 Linux 主控统一管理。
例如:
底盘
导航
定位
SLAM
避障
核心雷达
回充
核心运动传感器
安全控制
因为即使:
- Android App 崩溃
- Android 页面切换
- Android UI 卡住
机器人核心运动能力仍然应该继续正常运行。
例如机器人正在自主巡航:
Android App 崩溃
不应该导致:
底盘立即失控
所以:
机器人核心控制能力不能依赖 UI 进程存在。
十二、什么硬件可以直接属于 Android?
与 HMI 和业务交互 关系更强的设备,则完全可以由 Android 直接管理。
例如:
扫码器
读卡器
打印机
部分柜门
灯带
业务按钮
USB 摄像头
某些托盘控制器
身份证阅读器
这些硬件本身就是:
Android 业务终端的一部分。
例如:
扫码
↓
业务校验
↓
开柜
↓
打印凭证
整条业务都发生在 Android 上。
这时候让 Android 直接控制对应外设,反而最自然。
十三、所以应该把机器人硬件分成两类
可以先做一个简单抽象:
机器人硬件
│
┌──────────────┴──────────────┐
│ │
核心机器人能力 业务交互外设
│ │
Linux 主控 Android
│ │
CAN / 串口 串口 / USB
│ │
MCU MCU
│ │
底盘 / 电机 / 核心传感器 柜门 / 打印 / 扫码等
这里并不存在绝对规定。
真正要判断的是:
这个能力到底属于机器人核心运行,还是属于 Android 业务交互?
十四、Android 直接串口控制硬件,不等于 ViewModel 直接写串口
例如 :Android 控制柜门。
最简单的代码可能是:
ViewModel
↓
serialPort.write(
AA 10 03 01 ...
)
短期看起来很方便。
但是这样意味着,ViewModel 已经知道:
串口协议
包头
Command
柜门编号
Checksum
这实际上又把:
业务层 和 硬件协议层 混在了一起。
所以即使 Android 直接控制硬件:
仍然应该分层。
十五、Android 直接控制外设时,也应该有 Hardware Adapter
例如柜门可以这样设计:
UI
↓
ViewModel
↓
DoorRepository
↓
DoorController
↓
DoorHardwareAdapter
↓
SerialPort
↓
柜门 MCU
业务层只知道:
openDoor(3)
而:
DoorHardwareAdapter
才知道真正协议:
AA 10 03 01 FF XX
这样以后:
- 串口协议变化
- 柜门板更换
- 设备厂家变化
只需要修改:
DoorHardwareAdapter
上层业务基本不用动。
十六、所以“业务协议与硬件协议分离”仍然成立
之前我说 ,Android 不应该知道 MCU 的:
AA 10 03 01 ...
这个结论仍然成立。
但需要把表达修正为:
不是 Android 不能直接控制 MCU,而是 Android 的业务层不应该直接依赖 MCU 协议。
例如下面这种完全合理:
ViewModel
↓
DoorController.openDoor(3)
↓
DoorSerialAdapter
↓
SerialPort
↓
MCU
因为:
业务层
仍然不知道:
硬件协议细节
这才是关键。
十七、Linux 这一侧也是同样的思想
Linux 主控控制底盘也一样。
业务层不应该直接:
sendCanFrame(...)
更合理的是:
Navigation
↓
ChassisController
↓
ChassisHardwareAdapter
↓
CAN
↓
底盘 MCU
导航模块只关心:
setVelocity(v, w)
而:
ChassisHardwareAdapter
负责转换成具体: CAN Frame。
所以无论硬件接在: Android 还是 Linux
架构思想其实完全一样:
业务能力
↓
Controller
↓
Hardware Adapter
↓
具体协议
↓
真实硬件
十八、一个机器人里可能同时存在两套硬件控制链路
这才是非常真实的一种机器人架构。
例如:
Linux 主控
/ \
/ \
底盘控制 核心传感器
CAN / Serial CAN / Serial
↓ ↓
MCU MCU
↓ ↓
电机 / 编码器 雷达等
机身 Android
│
├── TCP ─────────────→ Linux 主控
│
├── Serial ──────────→ 柜门控制板
│
├── USB ─────────────→ 扫码器
│
└── USB ─────────────→ 打印机
这并不代表架构混乱。
只要:
职责划分清楚。
就完全没有问题。
十九、一个“打开柜门”可能有两种实现
例如第一种机器人:
柜门属于 Linux 管理。
那么:
Android
↓ TCP
Linux
↓ Serial
柜门 MCU
Android 调用:
OPEN_DOOR
Linux 再执行。
另外一种机器人:
柜门控制板直接接 Android。
那么:
Android
↓ Serial
柜门 MCU
Android 业务层调用:
doorController.openDoor(3)
最终由:
DoorSerialAdapter
生成硬件协议。
两种方案都可以。
关键要看:
柜门能力属于谁?
谁掌握业务状态?
谁需要在 Android 离线时继续控制它?
这个能力是否被其他控制入口共享?
这些问题决定:
它应该挂在哪一层。
二十、如果多个入口都需要控制这个硬件怎么办?
这时候能力归属就更重要了。
假设柜门不仅:
机身 Android
需要控制。
手机 App 也需要:
远程开门。
机器人自主流程也可能需要:
自动开门。
如果柜门只存在:
Android → Serial
那远程控制就必须:
手机 App
↓
Cloud
↓
Linux
↓
Android
↓
Serial
↓
柜门
系统可能开始复杂。
这种情况下就需要重新考虑:
柜门是不是应该成为机器人主控统一能力?
因此是否让 Android 直接控制,并没有绝对答案。
一个很实用的判断方式是:
谁应该成为这个硬件能力的事实拥有者?
如果它主要属于 Android 本地业务:
放 Android。
如果它属于机器人全局能力,并且多个入口都需要使用:
放 Linux 主控通常更合适。
二十一、所以分层真正依据的不是“谁能连接硬件”
Android 技术上可以:
串口。
Linux 当然也可以:
串口。
所以不能简单地说:
能连接
=
应该归它管理
真正应该看:
能力归属
生命周期
实时性
安全性
多入口复用
故障隔离
是否需要脱离 Android 独立运行
例如:
底盘:
即使 Android 挂了也要安全工作。
所以更适合 Linux + MCU。
打印机:
主要服务 Android 页面业务。
所以直接由 Android 控制很合理。
这才是真正的架构判断。
二十二、再看手机 App,它永远不应该直接知道底层协议
用户手机 App 距离机器人更远。
通常是:
手机 App
↓
Cloud
↓
Linux
它更不应该知道:
CAN
UART
GPIO
MCU Command
手机只应该表达:
START_TASK
OPEN_DOOR
RETURN_TO_CHARGE
甚至再往上:
创建巡航任务
开始配送任务
越往系统外层:业务语义应该越高。
越往硬件底层:协议和控制细节才越来越具体。
二十三、机器人软件其实是一组不同层级的能力
做到这里,可以把整个机器人理解成:
用户业务层
手机 App / 机身 Android UI
↓
机器人业务能力
任务 / 巡航 / 开门 / 回充
↓
核心控制能力
Linux 主控 / Navigation / Chassis
↓
硬件能力
Controller / Hardware Adapter
↓
通信协议
TCP / CAN / Serial / RS485 / USB
↓
设备
MCU / 电机 / 传感器 / 外设
但是:
这些层级是逻辑层级,不代表物理连接一定是一条直线。
例如:
Android UI
↓
DoorController
↓
Serial
↓
柜门
完全可以绕过 Linux。
而:
Android UI
↓ TCP
Linux
↓
Navigation
↓ CAN
底盘
也完全合理。
这就是:
逻辑分层和物理拓扑不是一回事。
二十四、这是这一篇最重要的修正
如果只用一句话总结:
不是:
Android → Linux → MCU → 硬件,所有指令都必须逐级向下。
而应该是:
Android、Linux 和 MCU 按职责分层,不同硬件根据能力归属连接到最合适的控制节点。
例如:
机器人核心能力
→ Linux
业务交互能力
→ Android
实时硬件执行
→ MCU
而:
Hardware Adapter
负责隔离具体硬件差异。
这样理解以后,机器人真实项目中的各种硬件拓扑就不会显得矛盾了。
二十五、Android、Linux、MCU 可以这样记
Android
主要负责:
- 业务与人机交互。
- 同时可以直接管理 与 Android 业务强相关的局部外设。
例如:
扫码器
打印机
读卡器
部分柜门
部分灯光
Linux 主控
负责:
机器人核心能力与全局协调。
例如:
任务
导航
SLAM
定位
底盘
回充
核心设备状态
云端通信
MCU
负责:
实时硬件执行。
例如:
电机
编码器
GPIO
传感器
锁控
执行机构
所以不是:
Android
↓
Linux
↓
MCU
这么简单。
更准确的是:
Linux
机器人核心能力
↓ ↓
MCU MCU
↓ ↓
底盘 核心硬件
Android
业务与交互
│
├── TCP → Linux
│
└── Serial / USB → 业务外设
二十六、一个成熟机器人架构真正要做到什么?
最后再往架构层抽象一步。
真正重要的不是:
硬件到底接 Android 还是 Linux
而是做到:
第一,能力归属清楚
谁负责这个能力?Android?Linux 还是 MCU?
第二,业务和协议解耦
业务调用:
openDoor()
而不是:
write(AA 10 03 ...)
第三,硬件变化被隔离
例如:
DoorHardwareAdapterV1
↓
DoorHardwareAdapterV2
而不是整个业务一起修改。
第四,核心机器人能力不依赖 UI
Android 崩溃:
机器人底盘、导航、安全控制仍然能够维持正确状态。
第五,多入口控制时有统一能力归属
机身 Android
手机 App
云端
自主任务
都可能调用同一个机器人能力。
不能每一个入口都各自实现一套硬件控制。
二十七、总结
这一篇最重要的不是记住一张:
Android
↓
Linux
↓
MCU
的图。
而是理解机器人真正的分层原则:
按能力和职责分层,而不是简单按物理连接分层。
机器人核心链路通常是:
机身 Android
↓ TCP
Linux 主控
↓ CAN / 串口
底盘 MCU
↓
电机 / 编码器
但同时也完全可能存在:
机身 Android
↓ Serial / USB / RS485
业务外设 MCU
↓
柜门 / 打印机 / 扫码器 / 灯光
所以:
Android 可以直接串口控制硬件。
关键不是:
Android 能不能控制。
而是:
这个能力应该归谁负责?
同时,无论硬件最终连接 Android 还是 Linux,都应该坚持:
业务能力
↓
Controller
↓
Hardware Adapter
↓
硬件协议
↓
真实设备
避免:
ViewModel
↓
直接拼 ByteArray
↓
写串口 / CAN
因此一个更加准确的服务机器人架构是:
手机 App
↓
Cloud
↓
Linux 主控
↑ ↓
TCP CAN / Serial
↑ ↓
机身 Android 核心 MCU
│ ↓
│ 底盘等
│
Serial / USB
↓
业务外设 MCU
↓
柜门 / 打印 / 扫码等
做到这里,我们已经不再只是讨论:Android 怎么控制硬件。
而是在回答一个更本质的问题:
一台机器人里的不同能力,应该由谁拥有、谁执行、谁对最终状态负责?
而一旦机器人同时存在:
- 机身 Android
- 手机 App
- 云端后台
- 自主任务
- 维护人员
这些入口,下一个问题马上就来了:
多个入口同时想控制机器人时,到底听谁的?
下一篇:第 7 篇
《服务机器人如何处理多种控制入口:LOCAL、REMOTE、AUTO 与安全优先级》
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)