从一句“去充电桩”到可审计回执:ROSClaw + Nav2 对话导航实践

大模型可以理解“去充电桩”,但它不应该直接控制机器人。本文结合 ROSClaw 的设计理念和一次 Nav2 仿真实践,拆解自然语言指令如何经过能力契约、策略校验、执行器和结果验收,最终变成一张有证据的执行回执。

在这里插入图片描述

1. 问题不只是“让大模型控制机器人”

大模型接入机器人后,最直观的演示通常是:用户说一句话,模型生成一段指令,机器人开始运动。

但从“能动”到“可信地动”,中间还有一段很长的距离。

假设用户说:“去充电桩。”模型能够理解意图,也能查到充电桩坐标,但这并不意味着它应该直接向 /cmd_vel 发布速度。至少还有几个问题必须回答:

  • 当前控制的是仿真机器人还是真机?
  • 目标是否位于地图允许范围内?
  • 谁批准了这次动作,批准是否只对本次请求有效?
  • 指令发送成功,是否等于机器人真的到达?
  • 如果机器人最终偏离目标点,系统应当如何记录?
  • 本次结果以后能否作为记忆或优化依据?

ROSClaw 试图解决的,正是语义规划与物理执行之间的这道鸿沟。它强调三条边界:

请求不等于执行;下发不等于完成;完成必须有证据。

本文先介绍 ROSClaw 的核心思想,再具体说明如何将 Nav2 注册为一个受控能力,让中文对话经过规范路径驱动 TurtleBot3,并以最终位姿误差完成验收。

2. ROSClaw:把语义与物理拆开,再受控地接起来

ROSClaw 论文将系统划分为认知、协调和物理三层。认知层负责低频语义推理与任务分解;协调层把抽象任务映射为具体能力,并在下发前完成约束检查;物理层通过 ROS、驱动和机器人完成高频执行。

在这里插入图片描述

这种设计可以概括为“大脑与小脑解耦”:

  • 大模型擅长理解“要做什么”,但不直接产生底层速度和关节控制;
  • 控制系统负责“怎样执行”,并保持确定的接口、频率和安全边界;
  • 中间层负责能力匹配、策略校验、状态反馈和审计。

论文还提出 e-URDF 物理防火墙。普通 URDF 主要描述连杆和关节关系,e-URDF 则进一步表达运动学、负载、精度等能力约束。抽象任务先经过能力匹配,再在仿真环境中进行动力学和碰撞检查;不满足约束就拒绝并返回认知层重写,通过后才进入物理执行。

在这里插入图片描述

需要说明的是,本文的 Nav2 工程没有运行论文中的 Isaac Lab 预演。这里采用的是同一种“下发前必须过门”的工程原则,但具体门禁落在能力契约、执行模式、策略和执行器查找上。论文框架、ROSClaw 运行时和本文工程实践不能简单视为同一层面的功能。

3. 工程边界:大模型没有硬件权

在工程实现中,一次请求会经过四类角色:

用户 / LLM
    │ 只提出结构化动作
    ▼
rosclaw-agentd
    │ 准入、上下文编译
    ▼
rosclawd
    │ 唯一放行点:许可、账本、动作网关
    ▼
rosbridge / Nav2 / Gazebo
    │ 执行并返回状态
    ▼
ExecutionReceipt

agentd 名字里虽然有 agent,但它仍然没有硬件权。真正能够放行动作的是 rosclawd。外部智能体、聊天界面或 MCP 客户端只能提交动作提案,不能因为报文里写了 approved=true 就获得执行权限。

这条边界非常重要。模型的自然语言回复可能是“已经到达充电桩”,但物理世界是否真的发生变化,只能由执行器观测和回执证明。

3.1 一次动作的三个核心对象

ROSClaw 用三个对象将动作边界固定下来:

  1. ActionEnvelope:描述身体、能力、参数、模式、截止时间和租约。自然语言不能直接充当动作。
  2. Permit:绑定调用者、身体快照哈希和动作原文,并且一次性使用。智能体不能自己给自己签发许可。
  3. ExecutionReceipt:记录终态、证据等级和观测摘要。它才是动作是否完成的权威答案。

其中最容易混淆的是 ACK 和回执。ACK 只代表指令已被接收;机器人有没有到达目标,需要继续观察并通过验收规则判断。

3.2 六种执行模式隔离副作用

ROSClaw 将执行划分为 FIXTURE、DRY_RUN、REPLAY、SIMULATION、SHADOW 和 REAL 六种模式。副作用从左到右逐渐增强。

本文走的是 SIMULATION:允许 Gazebo 中的机器人运动,也允许依据仿真观测生成 TASK_VERIFIED 回执,但这份证据不能被描述成真机完成。REAL 模式还需要有效身体哈希、已验签 Robot Pack、在线守护进程、真实执行器以及一次性许可,缺少任何一项都应失败关闭。

4. 为什么采用双容器

本次实践将系统拆成两个容器,主要原因是运行时版本冲突:ROS 2 Humble 基于 Python 3.10,而 ROSClaw 需要 Python 3.11 及以上。

宿主机 / WSL2(network_mode: host)

┌────────────────────────────┐       WebSocket :9090       ┌──────────────────────────┐
│ ros-sim                    │◄────────────────────────────►│ rosclaw                  │
│ ROS 2 Humble / Python 3.10 │                              │ Python 3.11              │
│ Gazebo + TurtleBot3        │                              │ agentd + rosclawd        │
│ Nav2 + AMCL + RViz2        │                              │ operatord + nav2_mcp.py  │
│ rosbridge_server           │                              │ Robot Pack + 语义地名表  │
└────────────────────────────┘                              └──────────────────────────┘

ros-sim 容器运行 Gazebo Classic、TurtleBot3、Nav2、AMCL、RViz2 和 rosbridge;rosclaw 容器运行控制面及第一方 Nav2 kit。两边通过 ws://127.0.0.1:9090 连接,ROSClaw 一侧不需要导入 rclpy,也不直接加入 DDS 网络。

拆分之后,ROS 环境和智能体运行时可以分别维护,南向接口则稳定在 rosbridge 协议上。

5. 将 Nav2 注册成受控能力

ROSClaw 并不特殊识别“Nav2”这个名字。对控制面来说,它看到的是一份经过签名的 Robot Pack、一份能力契约和一个负责注册工具的第一方 kit。

5.1 Robot Pack 定义能力与证据要求

本项目为导航能力定义了 nav2.navigate_to_pose。Pack 中包含:

  • 能力声明与参数 schema;
  • map-frame-only、bounded-map、bounded-yaw 等策略;
  • 验收契约;
  • 文件校验和与 Ed25519 签名;
  • direct_driver_access = forbidden 和 agent_southbound = daemon_only 等约束。

导航契约 nav2.navigation.v1 要求目标必须包含:

{
  "target_pose": {
    "frame_id": "map",
    "x": -1.2,
    "y": -0.5,
    "yaw": 0.0
  },
  "goal_tolerance": {
    "xy_m": 0.3,
    "yaw_rad": 0.5
  },
  "expected_effect": {
    "kind": "navigate_to_pose"
  }
}

x、y 和 yaw 必须处于规定范围,策略 fallback 为拒绝。模型输出即使语义正确,只要不符合契约,也不能直接进入执行器。

5.2 第一方 kit 提供工具入口

第一方 kit rosclaw.sim.nav2_mcp 启动 nav2_mcp.py,通过 MCP 的 tools/list 将能力 schema 写入工具目录。

小模型可以使用弱类型入口 rosclaw_request_action,由 daemon 在仿真模式下对 JSON 字符串、缺省 frame_id 或自然语言形式的 expected_effect 做有限兜底;能力更强的模型可以直接使用物化后的强类型工具。需要特别强调:这种兜底只适用于 SIMULATION,不会被带到 SHADOW 或 REAL。

自动批准也有严格条件:必须同时满足仿真模式、效果域为 simulation_state、来源为当前第一方 kit,并且仿真策略允许自动批准。自动批准只是省去人工按键,并不会绕过信封、执行器和回执。

6. “去充电桩”究竟经历了什么

当前语义地名表将“充电桩”映射为 (-1.2, -0.5, 0)。完整链路如下:

用户:“去充电桩”
  ↓
LLM 识别地点与导航意图
  ↓
agentd 生成 nav2.navigate_to_pose 动作提案
  ↓
rosclawd 补全并校验 nav2.navigation.v1
  ↓
SIMULATION + 第一方 kit 满足 POLICY_AUTO
  ↓
Nav2NavigationExecutor 经 rosbridge 发送 NavigateToPose goal
  ↓
Nav2 规划路径,Gazebo 中的 TurtleBot3 运动
  ↓
读取最后一条 feedback.current_pose
  ↓
计算位置与航向误差
  ↓
写入 COMPLETED 或 FAILED 的 ExecutionReceipt

在这里插入图片描述

rosbridge 发送的是 nav2_msgs/action/NavigateToPose action,报文使用 id 和 args 字段。时间戳设置为零,避免仿真时钟与墙钟不一致引发 TF 查询超时。

Nav2 返回 SUCCEEDED 仍然不是 ROSClaw 的最终完成状态。系统还会从最后一条 action_feedback.current_pose 取得位姿,计算:

position_error = hypot(actual_x - target_x, actual_y - target_y)
yaw_error      = abs(actual_yaw - target_yaw)

只有位置误差不超过 0.3 m 且航向误差不超过 0.5 rad,回执才会写为 COMPLETED;否则写为 FAILED(NAV2_FINAL_POSE_OUTSIDE_TOLERANCE)。

这里使用最后一条 action feedback,而不是仅依赖 /amcl_pose,原因是机器人停稳后 AMCL 不一定继续发布新位姿。0.3 m 的位置容差也不是随意放宽:TurtleBot3 仿真常见约 0.2~0.25 m 的超调,而 Nav2 自身的 xy_goal_tolerance 约为 0.25 m。如果将外层验收收紧到 0.2 m 以下,很容易出现“Nav2 判定成功,但 ROSClaw 验收失败”。

在这里插入图片描述

7. 让机器人动起来,不等于实验完成

本次演示视频约 101 秒,画面同时展示了对话界面与 RViz。用户发出中文导航请求后,右侧可以观察到全局路径、局部代价地图以及 TurtleBot3 的运动过程;左侧则保留动作处理和结果返回。

请添加图片描述

在这里插入图片描述

当前可用的语义地点包括:

中文说法坐标 (x, y, yaw)
起点 / spawn(-2.0, -0.5, 0)
场地中心(-0.6, 0.5, 0)
充电桩(-1.2, -0.5, 0)
1 号角(1.0, 1.0, 1.57)

这仍然是一张小型仿真地图,并不等于已经具备完整语义地图。它能证明的是:中文地点已经可以映射到受约束的导航目标,并且动作经过 ROSClaw 规范路径执行和验收。

8. 四本账:聊天记录不能充当物理证据

ROSClaw 将记录分为四类,每一类回答不同的问题:

记录回答的问题典型存储
对话账当时说了什么missions.db
运行轨迹调用了谁、耗时多久live.jsonl
物理账许可状态与动作终态ledger.sqlite3
实践账身体上实际发生了什么practice/sessions/

物理账先记录 SUBMITTED 和租约,再进入 STARTED,最后落到 COMPLETED 或 FAILED。账本使用 HMAC 前向链,修改一条记录会破坏后续链路。

实践与记忆则位于执行回执之后,异步消费证据,不阻塞本次导航。当前工程已有仿真和影子模式的实践原料,但长期记忆和自进化流程尚未完整激活。因此,“已经有 Practice”不能写成“系统已经能够持续自我进化”。

9. 同一扇门也可以连接其他机器人

Nav2 不是唯一可以接入 ROSClaw 的执行后端。MuJoCo 中的 UR5e reach 任务也可以使用同样的 ActionEnvelope、许可和回执机制,能力名为 sandbox.reach。

在这里插入图片描述

这说明 Robot Pack 是可插拔的,但不能据此声称已经完成移动操纵或真机机械臂控制。当前成果仍属于仿真验证。未来可以同时挂载 Nav2 Pack 和机械臂 Pack,再进一步研究移动底盘与机械臂的任务协同。

10. 当前成果与边界

目前已经打通的部分包括:

  • 中文对话到 Nav2 的完整导航闭环;
  • 双容器部署和 rosbridge 南向接口;
  • nav2-sim Robot Pack、第一方 kit 与能力契约;
  • 基于最终位姿误差的执行验收;
  • ledger、trace、receipt 和 Practice 原料;
  • MuJoCo 机械臂沿同类控制路径接入的验证基础。

尚未完成的部分同样需要明确:

  • 当前地图较简单,语义地点数量有限;
  • 长期记忆蒸馏和自进化尚未形成持续闭环;
  • 系统仍停留在 SIMULATION,没有完成 REAL 真机路径;
  • 对话到车体启动的端到端响应时间还需要专项优化。

下一步可以沿三条线推进:第一,换成办公区二维地图,加入会议室、工位、茶水间等语义地点;第二,从实践记录中蒸馏可核验事实,逐步接通失败重规划和 Agent 优化;第三,补齐真实执行器、武装与一次性许可,在不降低安全边界的前提下上真机并优化时延。

11. 总结

ROSClaw + Nav2 这次实践的重点,不是证明大模型能够调用一个导航接口,而是证明自然语言动作可以沿一条受控、可拒绝、可验收、可追溯的路径进入物理系统。

大模型负责理解“去哪里”;Nav2 负责规划“怎么走”;ROSClaw 则负责回答“这次动作能不能执行、由谁放行、最后是否真的完成”。

当机器人从演示走向真实环境时,这三句话值得反复强调:

请求不等于执行。
下发不等于完成。
完成必须有证据。


参考资料

Logo

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

更多推荐