启元 Q1 的控制中枢:实时与智能为什么分在两块板上——工程师视角拆官方架构文档

判断一套机器人 SDK 值不值得学,先看它的架构文档。
不是看宣传页上的参数,是看它怎么划分计算资源,怎么定义接口边界,怎么把安全和实时性落到具体板子上。启元的《PrimeBot SDK 快速入门与集成指南》第 1 节给了一张架构图,第 5 节给了五层开发者模式,第 6 节给了节点发现排查。把这三节读完,架构的骨架就清楚了。
这篇文章只做一件事,把官方文档里的架构原文拆开,逐段解释它为什么这么设计,以及这些设计对开发者意味着什么。文中的引用都标了文档章节和行号,方便对照。

图 1,启元机器人三块板与四层接口
一、官方架构图里的三块板
《快速入门》第 1 节的原图是这样画的。左边是开发 PC,地址 10.1.1.99,跑 Ubuntu 22.04 和 ROS2 用户程序。中间是运控板,地址 10.1.1.100,跑 HAL 硬件抽象、MC 运动控制和交互基础服务。右边是大脑板,地址 10.1.1.101,跑核心算法、感知、规划和供应商程序。三块板之间用局域网 FastDDS 相连。
文档对三块板的定义很直接。开发 PC 是外部开发者的主要开发与运行环境。运控板是机器人的运动控制大脑,负责底层硬件抽象、运控算法和基础交互服务。大脑板是高阶感知与导航大脑,负责核心 AI 算法、感知、规划。

图 2,官方文档第 1 节的系统架构原文
这段描述里藏着一条硬边界。运控板管实时,大脑板管智能。文档没有明说实时频率,但从职责划分可以推出来。关节控制、硬件抽象、表情语音这些要在确定时间内完成的事情,全部压在运控板上。感知、规划、大模型这些算力重、延迟不稳定的任务,全部推给大脑板。
为什么要分。因为这两类任务的资源模型完全不同。关节闭环要求每一拍都在预算内完成,容不下垃圾回收、模型推理、内存抖动。感知和规划要求算力大、迭代快,可以容忍几百毫秒的延迟。把它们放在同一块板子上,要么实时任务被拖死,要么智能任务被限制。分板是唯一能让两种任务各自舒服的办法。
开发 PC 是第三条边。它既不实时,也不背算力压力,它管人和机器的界面。代码在这里写,日志在这里看,单步验证从这里发起。三块板各干各的,越界的那一天就是出事的开始。
二、四层接口和 25 个接口的分布
官方接口文档《接口说明》第 1 节列了一张 API 表,总共 25 个接口,分在四个模块。
运动控制模块。运控高层接口包括查询运动状态、设置运动状态、设置全身动作、设置预设动作、走跑速度控制、设置输入源、查询输入源、自定义上肢关节控制。运控低层接口包括关节控制命令和关节状态反馈。
交互控制模块。语音控制包括 TTS、音量查询、音量设置、静音查询、静音设置、音频文件播放,还有两个 TCP 音频端口。屏幕控制是表情和视频播放。系统控制是主动关机。
硬件抽象模块。触觉传感器是头部触摸状态。视觉传感器是相机单帧 JPEG 和 RTSP 视频流。电源管理是 BMS 状态。灯语控制是灯带命令。
按通信类型再数一遍。服务 16 个,话题 8 个,RTSP 流 1 个,另外 2 个 TCP 音频端口。这个分布不是随便来的。

图 3,《接口说明》第 1 节 API 表的源文件行号 115 到 146
服务多,说明指令类操作多。指令需要应答,发出去要有人确认,服务的一问一答正好。运动模式、预设动作、TTS、表情、灯带,全是指令,全走服务。
话题 8 个,说明状态流不少。状态不需要应答,持续广播最经济。关节状态、BMS、触摸、ASR 结果,全是状态。
流只有 1 个,它只为大数据而生。视频一帧几百 KB,一秒几十帧,消息总线背不动,走 RTSP 独立管道。音频两个 TCP 端口,一进一出,同样是数据量的问题。

图 4,25 个接口的模块和类型分布
接口分布还能读出架构意图。mc 层服务密集,hal 层话题密集。控制靠指令,反馈靠状态。读 SDK 先读接口分布,再读单个接口,方向感完全不同。
三、DDS 是这套架构的通信底座
官方文档第 2.1.4 节写得很清楚。开发 PC 不会默认接入机器人的 ROS2 分布式通信网络,必须先切开发者模式并重启机器人,才能正常进行 ROS2 通讯。
验证方式也很直接。在不编译 SDK 的情况下,运行 ros2 node list,正常应该列出机器人端的节点,例如 /hal_camera、/hal_audio、/mc_ros2_node。
我在沙箱里用自己写的假机器人节点验证了这条链路。节点名 /fake_robot,6 个服务挂在 /aimdk_5Fmsgs/srv/ 下,2 个话题挂在 /aima/hal/ 下。服务列表和话题列表都能被另一端的 ROS2 命令发现,说明 DDS 的发现机制和命名空间约定是通的。

图 5,真实 ROS2 节点、服务和话题列表
DDS 的价值在去中心化。没有中心服务器,一台设备重启,别的设备照样说话。三块板插在同一局域网里,谁发了什么,其他人能听见。不用写中心服务器,不用配 IP 白名单。
代价也在这里。DDS 的发现依赖网络环境。官方 FAQ 第 6.1 节列了三个排查点。硬件连通性,先 ping 两台板子。ROS_DOMAIN_ID 是否一致,机器人默认通常是 0。多网卡冲突,PC 同时插网线和连 WiFi 时,DDS 可能绑到无线网卡,官方建议网线直连时临时禁用其他网卡。
第 2.1.3 节还提了 UDP buffer。SDK 默认 FastDDS 配置会自动加载 20M UDP socket buffer,避免高频话题丢帧。但内核参数不会由 SDK 自动修改,要开发者自己持久化配置。
这三条不是使用技巧,是架构约束。DDS 把通信做成了广播,广播就依赖网络质量。网络没配好,节点发现不了,后面的所有接口都无从谈起。
四、五层开发者模式,官方把权限拆得很细
《快速入门》第 5 节是整套文档里最值得读的一节。它把开发者权限拆成五层。
第一层是运行模式。Standard 是生产与交付环境,系统全闭环,只运行官方认证业务组件,不接受外部控制指令。Develop 是开发与调试环境,开启外部接入通道,允许注入自定义控制逻辑和算法模型。
第二层是开发方式。API 基于 RESTful 或 gRPC,跨语言、硬件解耦,适合 Web、移动端或低代码平台。ROS2 基于分布式 DDS,适合高频、强时效的节点间通信。文档明确写了,当前版本暂未开放 API 方式,系统默认启用并全局支持 ROS2。
第三层是开发层级。Basic 是无损能力增强,原厂业务与安全策略保持完整,外部指令并发注入。Advanced 是深度逻辑接管,允许关闭特定官方模块,获取系统核心资源,例如传感器裸流、底层运控的独占权。
第四层是领域设置。开发者可以选择接管运动控制、语音交互、作业规划或传感器数据。
第五层是能力配置。原子功能开关集,系统根据勾选自动执行底层配置的动态编排。

图 6,官方文档第 5 节的五层开发者模式
文档还给了一条现状说明。当前版本将领域设置与能力配置暂予合并,目前仅生效运动控制里的低层运控开发选项,后续才逐步上线交互、作业及传感器的原子功能。
这段话很重要。它告诉你,哪些门现在能开,哪些门还没开。你能调 TTS,但还不能接管 TTS。能调和能接管,是两码事。调是从外面叫,接管是把你的逻辑塞进去,让机器人按你的方式说话。
领域与原子功能对照表里只有一行。运动控制,低层运控开发,对应配置项 domains.mc.low_level_dev。功能说明有两条。授权开发者对机器人全身关节进行直接指令下发。机器人本体高层运动控制功能需手动关闭。
这条说明把风险写在了明面上。低层运控开发给你 22 个关节的直接控制权,同时要求你手动关掉高层运动控制。也就是说,安全兜底被你自己拿掉了。这不是给新手准备的开关。
五、运动状态机是架构的骨头
官方接口文档 2.1.1.1 节定义了运动模式控制。Q1 的运动状态不是 bool,是一张状态机。文档里出现了 PASSIVE、STAND、WALK、BIPED_WHOLE_BODY_CTRL 这些状态。
预设动作控制服务 2.1.1.2 节写了两条强制时序前置条件。调用 SetMcPresetMotion 之前,必须先用 SetMcAction 把系统切入 BIPED_WHOLE_BODY_CTRL。发出切换指令后,不能立刻盲发动作,必须写轮询逻辑,通过 GetMcAction 的实时反馈,确认执行态稳定跃迁并停留在 RUNNING,才能下发最终动作。
文档还写了三条特别说明。
第一条,缺失强制稳态拦截机制。服务端不设置稳态检查,在任何极端运动姿态中发出的动画预设指令都会被立即响应下发。业务端必须主动施加安全时序约束。
第二条,防打断模式拒接断言特征。当 interrupt 为 false,且当前系统正处于其他动画序列的播放进程中,服务端会拒接本次新覆盖下发请求。被拦截时接口返回的 state 依然是 RUNNING,调用方无法通过系统态识别失败,必须解析头帧错误码。header.code == 0 代表新请求被正常响应入队,header.code == 1 即被拦截丢弃。
第三条,预设动作列表。Q1 支持 16 个内置动作,3001 招手,3002 握手,3003 碰拳,3004 挥手,3005 开心,3007 双手比心,3008 加油,3010 伸懒腰,3012 到 3014 讲话动作,3018 拥抱,3021 拒绝,3046 到 3048 跳舞动作。另外支持通过 ani_path 加载自定义 CSV 轨迹,采样率必须严格匹配 120fps。
这三条说明把安全责任划给了业务层。服务端不做稳态检查,所以你得自己判断现在能不能挥手。服务端拒接时 state 仍是 RUNNING,所以你得看 header.code。预设动作只能在 WBC 里播,所以你得先切模式再轮询。
这不是文档写得啰嗦,是架构把责任放在了正确的位置。服务端只负责执行,判断交给你。你做得好,机器人不会摔。你做不好,服务端也不会替你兜底。
六、统一响应模型,框架码和业务码分开
《接口说明》的接口公共说明里给了一套统一响应模型。服务调用通常返回 CommonResponse 或 CommonTaskResponse。
响应模型分四层。header 是 RPC 或框架层信息,包含时间戳和返回码 code。status 或 state 是核心业务状态,通过 .value 获取。message 是诊断信息,调用非 SUCCESS 时提供可读的错误描述。task_id 是任务标识,只在 CommonTaskResponse 里提供,用于异步任务追踪。
框架返回码只有两个。0 是 SUCCESS,请求已被底层系统接受并进入执行序列。1 是 FAIL,请求被拦截,原因可能是状态机冲突、资源占用或权限不足。
业务状态码有 10 个。0 未知,1 成功,2 失败,3 中止,4 超时,5 无效请求,6 手动接管,100 未就绪,200 排队中,300 已创建,400 正在运行。
故障原因枚举有 30 个。低电量、开箱状态、开机自检、形态不支持、动作不在白名单、当前模式不支持、前方有障碍物、任务运行中、已经是目标状态、动作不可打断、动画 ID 无效,等等。
这套响应模型是架构的一部分。它把框架层和业务层分开,让你在排查时能分清是通信没通,还是业务规则拒绝。框架码 1 和业务码 2 是两种完全不同的故障,处理方式也不同。
我在假机器人联调时就是按这套模型排的。预设动作返回 header.code 1,业务 state 仍是 RUNNING,说明是防打断拒接,不是通信故障。TTS 返回 success false,业务状态失败,说明是服务内部执行问题。两类问题分开看,排查路径就清楚了。
七、工具链和部署,架构的最后一公里
《快速入门》第 2.1.7 和 2.1.8 节讲了三套工具链。ARM 原生,x86 交叉 ARM,x86 原生。两个目标平台,RK 和 Orin。
交叉编译指南 487 行,连部署前要替换 sysroot 路径都写了。sysroot 是交叉编译的地基。PC 是 x86,板子是 ARM,编译器要在 PC 上生成 ARM 能跑的二进制,就得知道 ARM 系统的库长什么样。sysroot 就是那套库的快照,路径替换错一个字符,编出来的东西板子上跑不起来。

图 7,官方交叉编译指南里的 sysroot 替换
编译本身不复杂。colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release,看到 Summary: X packages finished 就算过。难的是环境。Ubuntu 22.04,ROS2 Humble,colcon,FastDDS 配置,UDP buffer,每一样都要对。
我在沙箱里用的不是 Humble,是 Ubuntu 24.04 加 Jazzy。消息定义那一层是版本无关的,54 个 msg 和 srv 能编过。rclcpp 的行为差异我没有验证,也不装懂。官方文档的目标环境写的是 Humble,读者按文档装 Humble 更稳。
八、这套架构的优点和代价
优点很清楚,边界清晰。
实时归实时,智能归智能。运控板管站,大脑板管看,PC 管开发,DDS 管说话。换一块板子,换一个模型,影响面被限制在一层之内。上层实验失败一百次,下层稳如泰山。这是能快速迭代的架构。
接口分层也带来可迁移性。Q1 和 T1 的示例数量一样,18 个 Python,18 个 C++。换机型,接口名字不用换,硬件差异藏在 HAL 后面。你的 Skill 资产是可迁移的。
代价同样清楚,学习曲线陡。
三块板、四层接口、五层开发者模式、30 个故障原因枚举,这些概念第一次看会晕。官方文档 1185 行,接口文档 12858 行,通读一遍不现实。新手需要一条按需查阅的路径,而不是从头读到尾。
安全责任下放也提高了门槛。服务端不做稳态检查,意味着业务层必须自己写状态判断。这对有经验的团队是自由,对新手是风险。
我的判断是,这套架构适合愿意读文档、愿意写状态机的开发者。它不提供傻瓜式的安全兜底,它提供的是一套边界清晰的工具。你用得好,它能撑起复杂的交互。你用得糙,它也会如实把错误还给你。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)