用 Robostral Navigate 做具身导航,最先要定的不是模型参数,而是三件事:外部要喂给它哪些观测、它交回什么形式的动作或轨迹、以及什么任务根本不该交给它。通常这类模型处在“观测→动作”的中间层,建图、全局定位、底盘急停这些活仍由上下游模块承担。下面按任务定义、输入输出契约、最小循环、日志排查、边界清单五步走一遍,每步都给出可验证的动作。
Robostral Navigate 通常只接收已经对齐好的观测和目标点,输出动作序列或局部轨迹,不负责建图、全局定位与安全兜底。接入前先把坐标系、时间戳、维度三项契约写死,再跑一次空场景确认数据能进能出;如果任务需要长距离全局重规划、密集动态避让或硬性安全保证,应把这些留给上层规划器和底盘控制器,而不是继续调模型。
把导航任务拆成观测、动作和终止条件
把导航模型当成完整机器人系统,是接入阶段最常见的错位。建议先写一张任务定义卡片,明确五件事,卡片写不出来就说明任务还没收敛:
- 任务目标:到达指定目标点、跟随目标,还是走通一条固定走廊?
- 环境范围:室内静态、室内有行人,还是室外非结构化路面?
- 观测输入:RGB、深度、里程计、IMU、二维激光各有哪些,频率与坐标系分别是什么?
- 期望动作或轨迹输出:离散动作、速度指令,还是未来若干步的轨迹点?
- 成功与失败终止条件:距目标小于阈值且姿态满足要求算成功;超时、碰撞风险、连续多帧无有效输出算失败。
终止条件尤其容易被跳过。没有终止条件的导航任务,在日志里表现为循环下发指令却从不收尾,排查时会误判成模型输出异常。先写清终止条件,再对齐接口字段。
对齐 Robostral Navigate 的输入输出契约
这一步只确认两件事:哪些数据必须由外部提供,哪些结果需要下游模块消费。表里拿不准的字段直接写“待查”,按实际 SDK 或服务端配置核对,不要靠猜填。
| 字段 | 内容示例 | 由谁提供 | 不确定时 |
|---|---|---|---|
| 传感器类型 | RGB、深度、二维激光、里程计 | 外部采集模块 | 按模型输入层实际通道确认 |
| 坐标系 | map / odom / base_link | 外部标定与发布方 | 待查:模型期望哪一系 |
| 时间戳 | 单调时钟或仿真时间 | 采集模块 | 待查:单位与同步方式 |
| 位姿格式 | 四元数或欧拉角,x/y/z + yaw | 定位模块 | 待查:顺序与手系 |
| 目标点格式 | 坐标系 + 位置 + 朝向 | 上层任务下发 | 待查:是否含容差字段 |
| 输出表示 | 离散动作 / 速度指令 / 轨迹点 | Robostral Navigate | 待查:单步还是多步 |
契约确定后,输出表示决定下游怎么接:如果是速度指令,直接下发底盘;如果是轨迹点,通常需要交给轨迹跟踪模块。两者混用会导致控制频率错配。
写一个最小推理循环骨架并跑通空场景
骨架只求跑通数据链路,接口名用占位符,按实际服务替换。建议放在一个独立脚本里,先不接底盘。
# 占位骨架,接口名按实际 SDK 替换
obs = collect_observation( # 全部由外部提供
rgb=frame, depth=depth_img,
odom=odom_msg, imu=imu_msg,
stamp=now_monotonic(),
)
goal = {"frame": "map", "xyz": [x, y, z], "yaw": yaw}
req = {
"model": "<NAV_MODEL_ID>",
"observation": obs,
"goal": goal,
"history": [], # 是否必填、长度上限:待查
"max_steps": 1,
}
t0 = now_monotonic()
resp = nav_client.infer(req) # 占位接口
latency = now_monotonic() - t0
log.info({
"in_shape": shape_of(obs),
"goal": goal,
"out_type": resp.get("type"),
"out_len": len(resp.get("actions", [])),
"latency_ms": latency,
})
apply_or_publish(resp["actions"])
跑的顺序是先空场景、再一条直线场景。空场景验证的是请求能返回、字段不报错;直线场景验证输出方向与预期一致。这一步的目标不是导航效果,而是确认输入能进、结果能出,并把输入形状、输出类型、单步耗时记下来,作为后面的基线日志。
在仿真日志里定位输入输出不匹配
多数失败可以先归到数据格式、坐标系或频率上,而不是模型本身。按下面三类检查点过一遍日志,通常比换参数更快定位:
- 时间戳跳变:观测时间戳与目标时间戳差值超过采样周期,或出现回退,多半是两个模块用了不同时钟源,仿真时间与系统时间混用是常见原因。
- 坐标系不一致:位姿在 odom 系而目标点按 map 系解释,表现是输出方向整体偏一个固定角度,且偏角不随时间漂移。
- 维度不匹配:深度图尺寸或通道数、动作维度、history 长度与预期不符,通常直接报 shape 错误或返回空动作。
修正方式一般是改配置而不是改代码:统一时钟源、显式声明坐标系、在发送前做一次维度断言。改完后复跑同一段仿真,对比两次日志里的输入形状和输出长度是否一致,一致再往下走。
整理任务边界与停止条件清单
下面的清单用来判断何时该改任务定义或补感知,而不是继续调模型:
- 适用:已有定位与地图、目标在观测可达范围内、观测频率稳定、以局部避障和短时到达为主的任务。
- 不适用或需先补感知:缺少全局定位、需要长距离重规划、动态人群密集、对安全有硬性要求的场景。
- 退化条件:传感器掉帧、目标点长期在观测范围外、连续多帧输出为空或明显超出运动能力。
- 需要人工接管的信号:指令速度超过设定上限、模型输出与底盘反馈方向相反、避障距离小于安全阈值、无有效输出持续超过设定帧数。
出现这些信号时,稳妥的处理顺序是先回到任务定义卡片,确认目标和环境范围是否写错,再补齐缺失的感知通道,最后才考虑调整模型侧参数。把安全兜底放在底盘控制器的独立规则里,不依赖模型输出,通常比在模型层反复试参数更可控。