上一篇我们读了 Q1 的「身体说明书」——那份藏在官方 URDF 里的骨架档案,26 段骨架、22 个关节、16.9 公斤。这次往里走一层:身体之上,是让这具身体能听、能说、能动、也能拒绝你的软件系统。

研究一个 ROS2 机器人系统的架构,有条公开的捷径:不用拆机、不用搞到源码,读它对外暴露的接口定义就够了。分布式系统里,接口就是「宪法」——哪些能力开放、以什么方式开放、谁优先谁排队、什么情况下拒绝你,全部写死在消息定义文件里,一行都赖不掉。

Q1 的 SDK(q1-sdk v1.0.0.0)里有个 aimdk_msgs 包,装着机器人对外的全部接口定义。这篇文章带你把它们盘完。读法和上一篇一样:所有数字来自接口文件原文,出处随文标注。

一、先盘家底:54 个文件、两种类型、五层目录

接前两篇的环境(Windows 11 + WSL2 Ubuntu 22.04 + ROS2 Humble + q1-sdk v1.0.0.0),两条命令就能验明家底:

source ~/workspace/sdk_q1/install/setup.bash
ros2 interface list | grep aimdk | wc -l

输出:54。

在这里插入图片描述
54 个接口全部可被 ros2 工具链识别。实测环境:WSL2 Ubuntu 22.04 + ROS2 Humble + q1-sdk v1.0.0.0(与前两篇同一环境)。

这 54 个接口文件分两种类型,类型即通信方式(这是 ROS2 的基本法,也是读架构的第一把钥匙):

  • 36 个 .msg(消息)——走 topic,「广播流」。发布者只管往外发,谁爱听谁订阅,典型如传感器状态:机器人每秒广播一次触摸事件,你不听它也照发。
  • 18 个 .srv(服务)——走 service,「请求-响应」。你必须收到答复才算数,典型如下命令:让机器人播一段语音,它会告诉你成没成、预计播多久。

再看目录结构,54 个文件分成五层(数字为 msg + srv,来源:aimdk_msgs 包目录清点):

在这里插入图片描述

层接口数管什么
common7 msg地基:统一的消息头、状态码、拒绝理由
hal13 msg + 9 srv硬件抽象:电池、关节、触摸、音频、相机、灯
mc11 msg + 6 srv运动控制:动作档位、预设动作、输入源
interaction4 msg + 3 srv交互:语音合成播报、表情、关机
agent1 msg智能体:语音识别结果

目录即架构图。 不用看一行实现代码,五层目录已经把这台机器人的「部门编制」交代清楚了:管硬件的、管运动的、管说话的、管思考的,还有一层给全员立规矩的。下面逐层拆。
在这里插入图片描述

二、common 层:先立规矩,再干活

7 个文件,全是「格式合同」:RequestHeader / ResponseHeader / MessageHeader 三种消息头,加上 CommonRequest / CommonResponse / CommonTaskResponse 三种通用信封。任何一层发消息,都得套这个信封。在这里插入图片描述

最有意思的是 CommonState——统一的任务状态码。它先定义了 10 个状态(成功 / 失败 / 中止 / 超时 / 无效 / 手动 / 未就绪 / 等待中 / 已创建 / 运行中),然后紧跟一个 reason 字段和 30 条拒绝理由码。机器人拒绝执行你的指令时,不是沉默,而是给你一个编号。原文精选(来源:aimdk_msgs/msg/CommonState.msg):

编号拒绝理由
1开箱状态中
2开机自检中
5低电量限制
6正在充电中
7动作不在白名单
10~14前方 / 后方 / 左方 / 右方 / 上方有障碍物
15其他任务正在运行
19无法执行任务,机器人需要处于双足站立状态
24室内模式下暂不支持该动作
26当前机型不支持该功能
28当前动画不可打断
30当前状态不满足变形/动作执行条件

细读这张表能看出产品形态:连「上方有障碍物」都单独给了编号(机器人要跳跃、要起身),「正在充电中」会拒绝你(充电时不出工),「室内模式」有单独的动作白名单(客厅里不许撒欢)。

在这里插入图片描述

更重要是设计态度:拒绝也要给出可查的理由。消费电子产品拒绝你的时候往往只有一声「叮」,而这里拒绝是一门 30 条的词典——排障时查表就行,不用猜。这是把「可调试性」写进了协议层。

三、hal 层:把每块硬件翻译成标准词

hal(Hardware Abstraction Layer,硬件抽象层)是接口最多的层,13 个 msg + 9 个 srv,每块硬件一份「字典词条」。挑四个有讲头的:

Bms(电池管理):一个字段 status,是个 32 位整数,0~28 每一位都是一个状态开关——充电过流、放电过流、电池短路、电芯过压/欠压、总电压过压/欠压、温感开路、充放电温度超限、最大压差超限、MOSFET 禁止充/放电、均衡线电阻超限、电池充满……外加循环次数、总充放电累计(mAh)、均衡线电阻(mΩ)、电池温度。一条消息就是电池包的完整体检报告,精确到电阻单位。

TouchState(触摸):定义了 10 种触摸事件——单击、双击、三击、四击、五击、六击,超过六次归为「多击」,再加向左滑、向右滑。对,六连击是协议里明文存在的。注释还写明传感器位置因机型而异:Q1 在头部,T1 在背部和胸部。这正是第一篇里我们双终端实测链路用的那条消息——当时它还只是屏幕上每秒刷新的 event_type: 1,现在你知道那只是它十种表情之一。

JointCommand / JointState(关节):命令里除了常规的位置/速度/力矩,还有 stiffness(刚度)和 damping(阻尼)——这是阻抗控制的标志性参数:不但能命令关节「到哪儿」,还能命令它「多硬」。手臂被外力推开时是硬顶还是顺从回弹,就调这两个数。而状态回传里除了位置,还有 coil_temp(线圈温度)和 motor_temp(电机温度)——电机烧毁前会有先兆,协议层已经把体温计插好了。

SetServo(舵机):一个看似平淡的舵机服务,注释里藏着结构性信息——位置范围 0~90 度,0 度是四足形态的位置,90 度是双足形态的位置,速度按「步」计,1 步 0.225 度。Q1 的四足↔双足变形不止是软件里的动作指令,底下还有一套物理舵机机构在锁形态。硬件的「户口」骗不了人。

四、mc 层:61 个动作档位,和 5 个被删掉的动作

mc(Motion Control,运动控制)层是考古富矿。核心是 McAction 这一个文件:61 个有效动作档位,按编号分段,像一座规划好的城市(来源:aimdk_msgs/mc/action/McAction.msg,逐项清点):

编号段数量内容
1~33急停类:被动模式、阻尼模式(断力卸能,安全优先)
10~226形态切换:四足↔双足,常规/带旋转/前空翻三种翻法
100~12122四足动作:握手、坐下、跳舞、前空翻、后空翻、俯卧撑、跳跃、伸展、模仿……
200~30311双足动作:越障、太空步(206)、奔跑、模仿、全身控制、上肢录制
1001~101919Q 系列专属:折叠收储、站起、入座/离座、室内轻柔步态、室外越障、超能跑步模式

而这座城里还有 5 块「拆掉的楼」——官方注释原文标注「(删除)」的动作:

  • 204 双足原地旋转
  • 205 双足下腰
  • 209 双足羽生结弦
  • 210 双足劈叉
  • 400 双足转圈舞

「羽生结弦」大概率指花滑运动员的标志性动作编排。为什么删?接口文件不会说,但「删」这个动作本身说明:这些动作被实现过、评估过,然后出于稳定性或安全考虑下了架。接口文件的注释区,就是产品决策的施工现场——上一篇 URDF 里被注释掉的 mesh 碰撞,这一篇被注释掉的羽生结弦,同一个考古乐趣。

这一层还有三样东西值得停一下:

  • McPresetMotion:37 个预置动作档(含恢复默认姿态),从挥手、握手、碰拳、比心、拥抱、拒绝、加油,到四个拍照姿势和一个「三连拍」——演示和互动场景的动作库。
  • McTaskSource:9 种动作触发源——APP、云端、遥控器、SDK、agent、自动任务引擎、MC 内部自动切换、Insta360 相机、其他。一台机器人身上有九个「可能下指令的角色」,这为下一节埋下伏笔。
  • SetMcMotion 服务:模仿动作的参数里有 onnx 模型路径——模仿动作是神经网络模型驱动的,文件里还留着 MIMIC_QY / MIMIC_LC(灵创)/ 开源模仿等多套模型入口。AI 不只在大脑板上,也长在运动控制层。

五、interaction 层:连「说话」都要排队

如果说过往的印象里机器人说话是「播放一段音频」,这一层会刷新认知。PlayTts(语音播报服务)的请求里有个 priority_level 字段,定义了六级播报优先级(来源:aimdk_msgs/interaction/msg/TtsPriorityLevel.msg,以下注释为官方原文):

级别常量名场景
L1BACKGROUND后台
L2SERVICE主动服务
L4MISSION任务
L6INTERACTION交互(默认档)
L8WARNING危险预警
L10SAFETY生命安全

六级之外还能用 priority_weight 在同级内微调权重。

在这里插入图片描述

配套细节一层扣一层:音频播放(AudioFile)另有 media_role 体系——系统告警 100、提示音 80、对话语音 60、音乐 40,任何非音乐角色开播,音乐会自动压低音量(ducking),和手机导航播报压低音乐是同一套哲学。

请求里还必带 domain(调用方标识)和 trace_id(调用链追踪 ID),响应里除了成败,还有预估播报时长——方便上层编排「说完这句话就做下一个动作」。

这层还有个「特权通道」的例子:ShutdownTask(关机服务)不走 CommonRequest,走 TokenCommon——必填 source(来源标识)和 token(令牌)。关机是要令牌的。让机器人闭嘴可以排队,让机器人躺下必须出示证件——权限的松紧,全在接口设计里。

回头看 mc 层那 9 种触发源,再配上运动输入源的 priority(0~100)和 timeout(默认 1000ms,来源:McInputSource.msg,注释列出的输入源为 rc / vr / app_proxy / interaction / pnc),架构意图就完整了:手机 APP、语音、云端、遥控器、VR 可能同时指挥一台机器人,「谁先谁后」必须写成协议,而不是靠社交默契。

在这里插入图片描述

六、agent 层:只有一个文件的顶层

五层里最小的层:agent(智能体层)只有一个 AsrResult——语音识别结果(识别文本、置信度、是否最终结果、语言)。topic 名 /aima/agent/asr_result。

怎么读这个「1」?先说清边界:这不是说机器人的大脑只有语音识别——官方指南 §1 写明大脑板上跑着核心算法与供应商程序。接口数量刻画的是** v1.0.0.0 版本对第三方开发者开放的边界**:大脑侧目前只把语音识别结果这条「感官流」放了出来。

和上一篇 URDF 里那个焊死的腕关节对照着看,是同一个设计哲学的两面:腕关节是结构上的预留车位,agent 层是协议上的预留楼层——目录建好了、命名规范立好了(topic 前缀 /aima/agent/ 与其他四层完全一致),后续版本往上加接口时,接入方一行代码都不用改结构。

七、三机一体:你的电脑和机器人是「平等节点」

最后把视角拉高。这套接口跑在什么硬件上?官方指南 §1 给出了架构:三台设备,同一条消息总线——

  • 开发 PC(Ubuntu 22.04):跑你的 SDK 程序
  • 运控板(10.1.1.100):HAL / MC / 交互基础服务——第三、四、五节拆的那些接口,家在这里
  • 大脑板(10.1.1.101):核心算法、供应商程序——agent 层的来处

关键在连接方式:三者经局域网 FastDDS 总线互联,是对等节点,没有主从。你的电脑和机器人内部的两块板,说同一种语言、订同一套宪法——这正是第一篇里「无真机验证」能成立的原理:当时我们在两个终端里自发自收 TouchState,那其实就是这套三机架构的微缩沙盘,把终端 A 换成真机器人,链路一字不变。

顺带一个命名彩蛋:接口注释里的 topic 名有清晰规律——/aima/agent/asr_result、/aima/hal/touch/state……/aima/<层>/<模块>/<对象>,看到 topic 名就能反推它属于哪一层。总线上的门牌号,本身就是一张架构索引。

在这里插入图片描述

在这里插入图片描述

八、亲手盘一遍:五条命令

本文开头用过的盘点命令,完整版在这(环境同前两篇,全部实测):

source /opt/ros/humble/setup.bash
source ~/workspace/sdk_q1/install/setup.bash

# 1. 接口总数(期望输出 54)
ros2 interface list | grep aimdk | wc -l

# 2. 触摸的十种事件(第三节的 TouchState 原文)
ros2 interface show aimdk_msgs/msg/TouchState

# 3. 六级播报优先级(第五节的原文,官方中文注释直接可见)
ros2 interface show aimdk_msgs/srv/PlayTts

# 4. 30 条拒绝理由(第二节的原文)
ros2 interface show aimdk_msgs/msg/CommonState

# 5. 61 档动作清单 + 5 个被删动作(第四节的原文,搜"删除")
ros2 interface show aimdk_msgs/msg/McAction

在这里插入图片描述

没有真机也能跑——这些命令读的是编译后的接口定义,不连机器人。跑一遍,本文的每个数字你都能在屏幕上亲手验证。

结语:接口即架构

54 个文件盘完,Q1 的软件骨架立起来了:

  • 五层目录是部门编制:common 立规矩、hal 管硬件、mc 管运动、interaction 管表达、agent 留着思考;
  • 30 条拒绝理由是可调试性的态度:拒绝不给编号的系统,排障全靠猜;
  • 六级播报优先级 + 输入源 0~100 优先级是多主仲裁的方案:九个触发源抢一台机器人,规则写进协议;
  • 令牌关机、白名单动作、室内模式是安全边界:越是「躺下」这种大动作,门禁越严;
  • 一个文件的 agent 层是版本边界,也是预留楼层。

下一篇,我们让这些接口真正跑起来——SDK 的 examples 目录里躺着 19 个 Python + 19 个 C++ 示例程序,挑几个接上仿真环境实跑。纸面架构到运行代码,就差这一步。


互动一题:McAction 里被官方删掉的 5 个动作——原地旋转、下腰、羽生结弦、劈叉、转圈舞——你最希望哪个在后续版本回来?(我投羽生结弦一票。)评论区聊聊,另外本文所有数字都可以用第八节的命令亲手验证,欢迎跑完回来抓 bug。

Logo

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

更多推荐