目录
- 引
- 一、那个让开发者抓狂的瞬间
- 二、物理架构:指令到底去哪了?
- 三、架构第一关:输入源仲裁
- 四、架构第二关:McAction 状态机
- 五、架构第三关:拒绝码(REASON)
- 六、排查清单:从架构视角看问题
引
先扔一张脑图,看看启元T1的控制架构到底分了哪几层。很多开发者觉得指令发过去,机器人就该动,其实这中间隔了好几道“安检”。
一、那个让开发者抓狂的瞬间
你写了段代码,调用启元T1的走跑接口,发了一条“向前移动”。返回值是成功的,日志干干净净。但机器人纹丝不动。
你查了网络,没问题。ros2 node list能看到你的节点,ros2 topic hz显示数据在稳定输出。甚至你确认了McLocomotionVelocity确实打到了/aima/mc/locomotion/velocity上。T1就是不动。
这不是Bug。这是启元T1的控制架构在“合法地”忽略你。
启元的SDK里有个aimdk_msgs包,里面定义了各种接口。走跑控制属于底层运动控制(mc)层。在这个架构里,指令发出去只是第一步,能不能被执行,得看运控板上的控制中枢给不给过。
二、物理架构:指令到底去哪了?
要看懂这个问题,得先看看启元T1的物理架构。它不是一块板子跑到底的,而是双板设计。
你的代码跑在大脑板上,它通过 FastDDS 把指令发给了运控板。运控板收到指令后,不是立刻让电机转,而是得先过几道关。
三、架构第一关:输入源仲裁
试想一下,如果遥控器、App、你的代码同时发送“向前走”的指令,机器人听谁的?为了解决这个冲突,启元在运控架构里设计了一套输入源仲裁机制。
这套机制遵循三条硬规则:
这里的架构设计很有意思。优先级不是一个连续值,而是分段抢占的。
- 100 - 80:系统级(如急停、底层保护)。
- 79 - 60:高级控制(如工业遥控器、App)。
- 59 - 40:中级控制(语音、手势)。
- 39 - 20:SDK 二次开发。也就是你写的代码。
- 19 - 0:备用/研发调试。
当你发指令时,如果系统的遥控器正握着控制权,你的指令优先级不够,架构层会直接静默丢弃它,不报错。更坑的是,如果你在发一次指令后,1000ms 内没发下一次(心跳断了),看门狗机制触发,控制权自动释放,机器人就停住了。
四、架构第二关:McAction 状态机
假设你现在抢到了控制权,指令成功度过了第一关。第二关是状态机校验。
启元底层有一个叫McAction的状态机。这个状态机定义了机器人的 18 种运动状态,并且规定了极其严格的跳转逻辑。
为什么要做这么复杂的状态机架构?为了防呆。
如果机器人现在是PASSIVE(零力矩急停)状态,你直接发走跑指令,它不仅不会走,还可能直接摔了。架构上强制要求你先切到STAND(位控站立),等站稳了(状态变成RUNNING),才能切到WALK(走跑模式)。
也就是说,你的代码发完指令后,不能当甩手掌柜,必须得用GetMcAction去轮询,确认底层状态真的完成了跳转,再发下一步的动作。很多开发者不查状态直接发,指令就被状态机拦截了。
五、架构第三关:拒绝码(REASON)
如果状态机校验没通过,或者遇到了别的问题,架构底层会返回一个拒绝码。这套拒绝码有 30 个枚举值,基本覆盖了所有可能出问题的情况。
这些拒绝码在CommonState.reason字段里返回。从架构角度看,它们分了四个大类:
- 环境安全类:前方有障碍物、低电量限制、正在充电中。
- 形态模式类:当前形态不支持、机器人需要处于双足站立状态。
- 任务调度类:其他任务正在运行、机器人已经是目标状态。
- 配置资源类:动作不在白名单、无可用技能列表。
你的代码得去解析这个reason,判断是重新发、等一等、还是直接放弃。不解析这个字段,你永远不知道指令到底是被谁拦下的。
六、排查清单:从架构视角看问题
所以,当你的 T1 “假装听不见”时,别去查网络延迟,也别去怀疑 FastDDS 丢包。这套架构的防呆设计决定了,得按下面的顺序排雷:
这套控制架构看起来有点繁琐,但在实际部署里是必须的。大脑板上的模型可以随便崩,但运控板上的状态机和仲裁机制必须能兜底。有了这套分层防呆机制,才能保证无论上面的代码怎么写,底层电机都不会乱转。这大概就是控制架构里“防呆”的另一面:它防住了不安全的动作,但也要求开发者必须遵守它的规则,去查状态、去解析返回码。
启元机器人开发者社区:https://dev.primebot.com/