
从理解指令到执行动作具身机器人如何构建推理、执行与验证闭环写在最前面1 理解指令先要形成明确的任务2 用任务流和反馈流理解模块协作3 从动作意图到执行请求需要经过哪些条件3.1 先确认控制模式已经就绪3.2 再核对本次动作请求是否被受理4 验证要说明这一次任务完成到了哪里4.1 过程与结束状态需要放在一起判断4.2 回复内容应由任务状态决定5 反馈怎样改变下一步决定6 把运行闭环放进可验证的开发过程参考资料启元机器人开发者社区你好这里是 晓雨的笔记本在所有感兴趣的领域扩展知识感谢你的陪伴与支持~ 欢迎交流机器人开发与具身智能技术写在最前面版权声明本文为原创架构解读遵循 CC BY-SA 4.0 协议转载请注明出处。“请挥挥手完成后告诉我。”对机器人来说这句话包含两个有先后关系的要求执行挥手再根据动作结果作出回应。它需要听清楚指令选对动作确认身体处于合适的控制状态并在执行后判断什么时候可以说“完成了”。我在梳理启元开放资料时最关注的就是这段衔接一条已经理解的指令怎样穿过软件接口变成身体动作身体产生的新状态又怎样回到上层影响下一步决定。沿着这个过程看机器人架构中的模块名称会变得具体每个模块都要向下一环交付可以使用的信息。本文以启元 Q1 SDK v1.0.0.0、配套接口说明和 PrimeConsole 官方资料为依据用上述指令贯穿分析。接口名称与部署关系来自公开资料任务理解、调度和结果判断的组织方式是本文据此展开的应用架构设计。1251 理解指令先要形成明确的任务先看“理解”这一环。机器人接收到的语音需要转成文本但后续程序真正要用的是一个带执行条件的任务。对本例而言目标动作是挥手回复时机是动作完成之后。第二个条件决定了语音回复必须等待结果不能与动作请求同时无条件触发。Q1 的公开 SDK 提供了语音识别结果话题 /aima/agent/asr_result消息类型为 AsrResult。其中text 保存识别文本is_final 区分中间结果与最终结果event_id 用于关联同一次对话交互。23这些字段会直接影响任务入口的设计。比如用户说到“挥手”之后又补了一句“先别开始”中间转写就不足以决定执行。本例可以在收到最终转写后再把动作目标和时间条件一起交给任务层。同一轮语音产生的多次识别结果应按 event_id 做上下文关联避免反复执行但它不是运动服务返回的task_id应用仍需自行维护二者的对应关系。随后任务层需要把日常表达映射到机器人已有的能力。Q1 预设动作列表中挥手对应 Q_WAVE_HAND编号为 3004招手则是另一个动作编号为 3001。这样的能力对应关系应由明确的动作目录约束。2固定场景可以用规则完成这个映射当表达更自由、任务更复杂时可以引入语言模型进行理解和拆解。无论采用哪种方式都应保留同一份任务记录让动作选择、状态跟踪和最终回复围绕同一条指令推进。表 1 给出了本例适合保留的信息。表 1 一条挥手指令在应用中需要保留的信息信息本例中的内容后续用途用户目标挥手并在完成后告知确定动作与回复之间的先后关系指令关联ASR 的 event_id 与最终文本关联本次交互避免重复触发当前步骤准备模式、提交动作、核对结果等决定哪些请求现在可以发送执行记录动作编号、请求回执和返回的 task_id跟踪每次尝试区分受理与拒绝完成条件本次动作过程和结束状态符合预期决定何时可以报告完成ASR 和动作响应字段依据 SDK任务记录为本文设计。event_id 与 task_id 来自不同接口需由应用关联。232 用任务流和反馈流理解模块协作启元 SDK 的公开部署图把开发 PC、运控板和大脑板连接在同一套 ROS2 与 FastDDS 通信体系中。运控板承载硬件抽象层 HAL、运动控制 MC 和基础交互服务大脑板运行核心 AI、感知与规划等程序。开发者的 SDK 程序可以部署在不同设备上通过统一接口与机器人交互。1这段部署关系解释了模块为什么能够分工。任务程序可以先在开发 PC 上运行运动控制仍由机器人侧承担需要搬到板载环境时业务仍围绕同一组接口组织。阅读架构时既要看程序放在哪里也要看它向外提供什么以及依赖谁的反馈。如果把视角从 SDK 扩展到启元公开发布的 AI 能力体系还能看到一层不同的分工PrimeVista 面向视觉、语音等多模态交互PrimeGo 面向多模态感知与跟随PrimeMotion 重点处理运动的稳定性、柔顺性和安全性。启元还提出以机器人 Agent 连接环境感知、语言理解和任务执行。需要区别的是这些属于产品发布时披露的模型定位与研发方向Q1 开放 SDK 则规定了开发者能够访问的接口并支持接入自研或开源模型。不能因为两者职责相近就认定 SDK 已公开这些模型的内部推理流程或认为图 1 的任务调度模块就是启元的内部部署图。[7][8]从本次任务出发可以把协作关系画成图 1。上层负责确定目标、安排当前步骤和核对结果SDK 连接具体的执行能力与观测能力。动作请求沿执行方向传递模式状态、请求回执和关节观测沿反馈方向返回。结果判断更新任务进展后调度层才能决定继续、等待还是结束。这里有两类交互值得分清。Service 用于一次请求与响应例如设置运动模式、提交预设动作Topic 用于订阅持续产生或按事件产生的数据例如语音识别结果和关节状态。一次服务响应可以回答请求是否被接受后续状态数据则帮助应用理解机器人正在发生什么。2当任务进一步涉及外部环境图像也会进入这条反馈链。Q1 SDK 开放了相机图像获取和视频流入口关节话题则提供本体运动状态。图像可以帮助回答目标在哪里、环境发生了什么变化关节状态帮助回答身体运动到了哪里。任务层应按需要使用这些信息并保留观测的时间关系。2因此模块交接不能只传一个动作名称。调度层还要说明动作对应哪次任务、哪些前提已经满足、后续需要等待什么信息。理解模型给出动作建议之后动作适配层负责把这些要求转换成当前机型支持的接口与参数。图 1 围绕同一次任务组织理解、执行与结果反馈依据 Q1 SDK 接口整理的功能协作示意。虚线框是本文提出的应用职责实线框对应开放能力。官方公布的 AI 模型定位不等于本图中的 SDK 服务或上层应用模块。12783 从动作意图到执行请求需要经过哪些条件回到挥手例子。预设挥手已经有明确的动作编号上层无需为这次固定交互重新生成整段关节轨迹。SDK 将 SetMcPresetMotion 描述为预设动画或关节空间轨迹的播放入口它与运动模式切换承担不同职责。23.1 先确认控制模式已经就绪接口说明要求调用预设动作前应先进入 BIPED_WHOLE_BODY_CTRL1005全身动作控制模式再确认模式进入运行态。不同起始姿态并非都允许直接切到目标模式官方示例中的mc_action_switcher.py 会依据允许的状态转移关系规划路径并逐步等待而不是在任意姿态直接发送挥手请求。[2][4]设置模式使用 SetMcAction查询模式使用 GetMcAction。已核对原始 .srv 和 .msg 定义前者返回CommonTaskResponse其中 response.header.code 0 表示调度成功而 response.state.value 1 在该 接口中的具体含义是“action 设置成功开始切换逻辑”。这说明切换已被启动不说明机器人已经稳定进入目标模式实际结果还须由后者读取。[2][9]因此上层需继续查询 GetMcAction 返回的 info.current_action.value 与 info.status.value分别确认目标模式为 1005且状态达到 McActionStatus.RUNNING数值 100。info.switch_ready 也在消息定义中用于标示切换就绪但不能用一次设置调用的成功返回替代实际模式查询。这里的 RUNNING 仅描述运动模式不是挥手动作已完成。图 2 将三个判断分开。[2][9]图 2 把动作请求与对应的执行依据逐项对齐编号与返回结构按 Q1 SDK v1.0.0.0 原始消息定义核对。state.value1 仅说明启动切换RUNNING(100) 说明模式运行header.code0 说明请求调度成功三者均不是单次挥手的完成证明。2493.2 再核对本次动作请求是否被受理模式准备好后应用通过 SetMcPresetMotion 提交挥手请求以 motion.value 3004 指定动作另按需求填写 source、interrupt 等参数。该服务返回 CommonTaskResponse包含 response.header.code、response.task_id 和 response.state。这些是此次请求的回执信息而不是播放完成回调。[2][4][9]比如 interruptfalse 且机器人正在播放另一段动画时接口说明指出新请求可能被拒绝但返回的业务 state 仍可能显示 RUNNING。因此应先检查 response.header.code0 表示调度成功、请求进入执行序列1 表示调度失败在本例中可能是被现有动画占用拦截。再结合 response.state.reason 判断失败原因不能把所有 code1 都归结为动作占用更不能把 RUNNING 当作本次新动作已启动。[2][9]原因并不难理解机器人正在运行动作和这次新请求被接受是两个不同的问题。调度层若只看到“正在运行”就推进到下一步可能会把前一段动画的状态记在新任务上。正确的处理应先保存这次请求的回执再更新对应任务的进展。这些字段必须连同消息类型一起理解CommonState.RUNNING 数值为 400而McActionStatus.RUNNING 是 100前者是业务任务状态后者是运动模式状态。state.reason 还可说明任务占用、当前模式不支持等原因。另一个容易误读的名称是 SetMcAction它属于 ROS2 Service名字中的 Action 不代表已经提供 ROS2 Action 的逐步反馈与最终结果回调。[2][9]4 验证要说明这一次任务完成到了哪里动作被受理之后还剩下文章开头的第二个要求什么时候告诉用户完成了要回答这个问题需要把几种反馈放回各自的语义中。表 2 将请求受理、控制准备和动作结果区分开来。表 2 不同反馈能够支持怎样的判断要回答的问题对应依据可以得出的判断本次请求是否受理SetMcPresetMotion 的 response.header.code结合 state.reason 等业务字段本次请求已被受理或被拒绝目标模式是否就绪GetMcAction 的 current_action 与 status目标控制模式已进入运行态身体是否产生预期运动与本次执行时段对应的关节位置、速度等观测动作过程是否符合预期需要应用判据是否可以报告完成本次动作过程、结束条件和任务有效性均得到核对满足所定义的完成条件后再触发回复前两行是 SDK 接口语义后两行是应用根据公开观测建立的判断。控制模式就绪与单次动作完成需要分别核对。24官方 set_preset_motion.py 示例在收到 SetMcPresetMotion 成功响应后打印 task_id并不会等待这段挥手真正播完。GetMcAction 也只返回当前运动模式的信息不返回单次预设动作的播放进度。核对本版Q1 公开 .srv 目录后没有发现可直接提供这次挥手完成回执的预设动作状态查询服务。因此“完成后告诉我”的最后一步仍需由应用另行设计结果验证而不能直接等同于请求成功。[2][4][9]4.1 过程与结束状态需要放在一起判断一种可以继续实现的做法是在应用独占的动作执行时段内记录动作开始前的关节状态再检查相关关节是否按预期经历挥手过程最后核对结束姿态。Q1 的 /aima/hal/joint/state 话题提供关节名称、位置、速度等数据可以作为这一判断的输入。2同时看过程和结果有实际必要。如果挥手最终回到接近初始的姿态仅比较开始与结束两张状态快照难以区分“完整挥过手”和“始终没有动”。反过来只看到手臂发生运动也不足以确认预定序列已经结束。如果能够取得挥手动作的参考轨迹或关键姿态应用可以检查关节变化是否按预期依次出现再核对末段是否达到设定的结束条件。这里的关节观测只是运动过程证据并非 Q1 SDK 自动提供的“挥手成功”判定。参考轨迹、角度容差、观察窗口和结束阈值都要结合设备版本标定缺少足够证据时状态应保留为待确认而不是由请求成功直接推断动作完成。对挥手这样的例子开发阶段可以结合关节记录与外部观察核对过程。机器人头部相机的视野未必覆盖完整手臂不能默认它总能自行看见动作全貌。将来换成面向物体的任务完成条件还应覆盖环境变化例如目标物体是否到达指定位置这时视觉反馈才承担相应的验证职责。4.2 回复内容应由任务状态决定启元 SDK 的 PlayTts 服务可以将指定文本合成并播放。2 在本例的应用设计中任务调度层应在完成条件满足后再触发“挥手完成”的回复。请求被拒绝时回复的是当前无法开始及可用的原因结果尚未确认时说明仍在核对。用户听到的反馈由任务的实际进展决定。这也解释了验证模块在架构中的位置。它需要把观测整理成调度层能使用的判断例如“模式仍在切换”“本次请求被拒绝”“动作过程已经符合完成条件”。这样的信息才能改变后续行为。5 反馈怎样改变下一步决定一个能处理现场变化的应用需要为正常推进和暂时无法推进的情况分别安排后续步骤。图 3 给出了本例的任务组织方式。中心问题始终是根据当前这次任务和最新反馈下一步现在是否成立。模式还在切换时任务可以停留在“等待模式就绪”按设定的查询节奏与超时条件继续观察。这个阶段无需反复生成新的任务计划也无需重复下发相同动作。已有计划的下一步只是在等待前置条件成立。请求因动作占用被拒绝时任务层需要记录这次请求没有被接受再判断等待是否仍符合用户意图。允许打断与否也属于任务约束。不能为了让新动作立即执行就无条件更改打断策略。如果服务等待超时应用也需要区分“没有收到响应”和“机器人明确拒绝”。前一种情况下请求是否到达执行端可能尚未确认直接重发可能带来重复动作。更合适的步骤是先结合可用状态与记录核对再决定是否进行下一次尝试。还有一类问题来自多轮指令。用户发出了新请求旧请求的回执却晚到。如果应用只按消息到达顺序更新任务就可能把旧动作的反馈归给新动作。因此ASR 的事件关联、应用自己的任务记录和 SDK 返回的任务标识需要建立明确映射。关节数据则要结合本次执行窗口解释不能仅凭“最近收到了一条状态”判断它属于当前任务。在这样的分工下上层推理既可以继续既有计划也可以因条件变化而调整计划。模型适合参与目标理解和复杂步骤选择确定的接口检查可以由明确的程序逻辑完成。动作执行持续产生新状态应用再用这些状态更新对任务的认识推理与执行便有了实际的往返关系。图 3 用最新反馈决定等待、调整或报告完成本文设计的任务调度示意。等待应有超时重试应重新检查条件结果不足时保留待确认状态避免由单一回执直接推导任务完成。6 把运行闭环放进可验证的开发过程运行中的反馈判断还需要开发阶段的验证来支撑。启元 PrimeConsole 官方页面列出了连接与日志、实时视频、方向控制与急停、机器人仿真、动作与表情测试以及 Skill 验证等能力开发页还提供 Q1 的 URDF 和仿真相关资料。56这些工具可以沿着前面的任务过程使用。先检查模型中的关节与运动关系再检查软件是否正确处理最终语音文本、模式切换响应和动作回执随后在真机条件下核对动作过程与结束判据。每一步解决的问题应当清楚仿真中的关节运动合理并不能替代真实设备上的执行结果。对于“挥手完成后告诉我”值得保留一份能够串起全过程的记录本次最终识别文本、任务关联、模式切换及查询结果、挥手请求回执、相关关节观测以及最终为何判定完成或待确认。SDK 集成指南也提供了日志与 ROS2 Bag 数据的导出说明便于回看问题。1有了这份记录排查时就可以沿着交接点定位文本是否理解正确目标模式是否就绪请求是否受理动作过程是否符合预期最后的回复是否提前触发。修复一处问题后再用相同任务和相同判据回看修改效果开发验证也就围绕任务结果形成了回路。回到开头那句简单指令启元开放资料提供了观察这类架构的具体入口语音结果可以被任务程序接收动作可以通过明确的接口提交模式与本体状态可以返回应用。开发者继续完成的工作是把这些信息组织到同一次任务中并规定什么证据允许任务进入下一步。这样机器人说出“完成了”时这句话就能对应到此前的执行过程与结果判断。参考资料主要技术依据为启元官方 SDK 仓库、原始接口定义及开发者页面模型能力定位另参考启元产品页与 2026 年 9 月新品发布会的公开报道。Q1 SDK 字段按仓库原始文件复核2026 年 10 月 19 日。三张图为原创架构示意不代表已完成 Q1 真机实测。**[1] 启元 Q1 SDK《PrimeBot SDK 快速入门与集成指南》。**第 1 章系统架构总览第 6.8 节日志导出与问题反馈。官方仓库中的集成指南**[2] 启元 Q1 SDK《接口说明》。**接口公共说明第 2.1.1.1 节运动模式控制第 2.1.1.2 节预设动作控制关节状态话题第 2.2.1.2 节语音合成第 2.2.1.7 节语音识别第 2.3.2.1 节视觉采集管理单帧图像与视频流。官方仓库中的接口说明**[3] 启元 Q1 SDK 语音识别消息定义。**aimdk_msgs/agent/msg/AsrResult.msg。用于核对 text、event_id、is_final 等字段。AsrResult 消息定义**[4] 启元 Q1 SDK 预设动作示例。**examples/python/set_preset_motion.py重点参照 ensure_ready_state 与 send_motion_request 的模式准备和受理判断。官方预设动作 Python 示例**[5] 启元开发者社区 PrimeConsole 与资料包。**工作台能力介绍以及 Q1 SDK v1.0.0.0 官方下载入口。PrimeConsole 与 SDK 下载页**[6] 启元 Q1 URDF 官方仓库。**Q1 机器人结构描述与仿真资料资料包功能介绍参见开发者社区下载页。Q1 URDF 官方仓库7启元 Q1 探索版官方产品页。Agent 开发可接入自研或开源大模型SDK / HDK / API 开放能力参见 启元 Q1 官方介绍。82026 年 9 月 20 日启元新品发布会公开报道。涉及 PrimeMotion、PrimeGo、PrimeVista 及机器人 Agent 的定位属公开发布层面的技术介绍不代表 SDK 内部实现披露。来源扬子晚报紫牛新闻。9Q1 SDK 原始服务及消息协议文件。SetMcAction.srv、GetMcAction.srv、SetMcPresetMotion.srv、CommonTaskResponse.msg、CommonState.msg、McActionInfo.msg、McActionStatus.msg。核对入口官方 SDK 仓库。本次核对版本Q1 SDK v1.0.0.0 官方资料包。仓库后续可能更新文中字段以该版本为准。启元机器人开发者社区本文涉及的 Q1 SDK、ROS 2 接口和 PrimeConsole 开发资料可通过启元机器人开发者社区查阅。hello这里是 晓雨的笔记本。感谢阅读后续继续分享机器人开发与开源技术实践。