2026 机器人工程实例(七):Nav2 到站了,任务却没完成——AMR 载货导航中的托盘滑移与验收闭环 Nav2 返回SUCCEEDED小车也停在目标点附近。按普通导航演示的标准这个节点已经可以收尾了。可我们给这次运行的最终判定却是FAIL。原因不在路径规划托盘在运输过程中相对车载甲板滑了5.2158 mm超过预先设定的5 mm保持门限。它随后又被保持机构拉回到约 2.5 mm但最大滑移已经发生不能拿终点的一帧画面把这次越界抹掉。这篇文章记录的就是一次“导航成功搬运失败”的本地 MuJoCo ROS 2 Nav2 实验以及我们如何把失败定位到车辆、甲板、托盘和验收逻辑之间。一、先说清楚实验范围场景是一台搭载托盘的 AMR在同一 MuJoCo 物理世界中接受 Nav2 速度命令完成一段约0.6 m的站内短程导航。报告来自本地运行p4-nav2-v7-03不是根据预期日志编造的例子。但有一条边界必须放在前面这次运行的货物是场景初始化时放好的不是人形机器人供盘、机械臂装料、车辆接货之后接着跑出的完整订单。地图来自已知场景的静态先验也不能把它称为这次重新完成了 SLAM。本文只讨论带初始载荷的导航与验收。导航系统回答的是“车有没有执行目标”搬运系统还要回答“货有没有跟着车、有没有安全停下”。我们为后者单独设了物理判据。二、第一层结果导航确实到了这次运行的 Nav2 worker 报告为SUCCEEDED目标被接受也确实产生了非零运动命令。独立的仿真真值检查给出项目本地实测判定Nav2 actionSUCCEEDEDPASS到站位置误差0.14786 m小于 0.25 mPASS车辆停车速度0.00000235 m/s小于 0.01 m/sPASS车辆停车窗口位移0.000000043 m小于 0.005 mPASS运输姿态许可全程有效PASS也就是说不应把这次失败甩给“Nav2 没到点”。车动了、到了、停了真正没有通过的是载货判据。当次报告中的关键字段可以压缩成这样nav2_succeeded PASS independent_arrival PASS physical_stop PASS transport_posture_authorized PASS tray_retained FAIL commissioning_result FAIL三、第二层结果车停住了不代表托盘始终稳住了如果只计算托盘的世界坐标位移车一开动托盘当然也在移动这个数值不能说明它相对甲板有没有滑动。我们的判据先把托盘位置转到甲板局部坐标系再与起始位置比较p_rel(t) R_deck(t)^T · [p_tray(t) - p_deck(t)] slip_max max_t ‖p_rel,xy(t) - p_rel,xy(0)‖项目中的核心计算相当于下面这段为便于阅读做了变量整理非独立运行脚本deftray_position_in_deck(data):traydata.body(c_payload)deckdata.body(c_deck)rotationdeck.xmat.reshape(3,3)return(tray.xpos-deck.xpos) rotation initialtray_position_in_deck(data).copy()# 每次物理采样后记录当前位置整段运行结束再取最大值。slip_maxmax(np.linalg.norm(sample[:2]-initial[:2])forsampleintray_positions_in_deck)tray_retainedslip_max0.005这里看的是整段运输的峰值不是终点位移。p4-nav2-v7-03在仿真时间约 7.41 s 时出现5.2158 mm的起步尖峰后来被保持机构拉回约2.5 mm。如果只拍终点截图读者很可能以为“一直很稳”如果只看峰值不交代回收过程又会误以为托盘持续滑走。两种写法都不准确。我们选择保留原来的5 mm门限所以结论很直接车辆到站 PASS托盘保持 FAIL整体 FAIL。四、我以为“开慢一点”就能解决结果更糟第一反应很自然降低运动加速度托盘应该滑得更少。于是我们保留世界、货物和原验收门限换成一个低加速度候选再跑一次。结果并没有按直觉走。运行到站误差最大托盘相对滑移现象v7 基础档p4-nav2-v7-030.14786 m5.2158 mm起步尖峰随后部分回收v7 低加速度档p4-nav2-v7-04-retained0.07374 m约 11.46 mm逐步累积末端没有回收到站误差变小了滑移却扩大到两倍多。低加速度档不是“同一种失败更轻一点”而是换了一种失败形态托盘相对甲板一点点单向爬移最终越过保持机构的恢复范围。这至少否定了一个过于简单的解释不能仅凭一次失败就认定是“加速度太大”更不能把 Nav2 的速度参数调低当作已经验证的修复。五、长距离失败又差点把我们带向另一个错误结论随后车辆尝试驶向更远的接收工位。在约4.63 m行程的运行中甲板偏航达到−0.011011 rad越过原定的±0.01 rad姿态门限。保护逻辑随即锁存并停下任务。这里也有一个容易写错的地方停下时车辆距目标约 0.6077 m不代表 Nav2 规划失败或“只能开到这里”。这次目标尚未被完整执行是姿态保护门先拒绝了继续运输。起初长行程伴随更大滑移很容易让人下结论“路越长托盘越容易滑。”我们又做了两组受控对照都走约 4.63 m对照控制方式托盘相对滑移D1单段纯直行0.133 mmD2纯直行拆成八段包含七次段间停车0.078 mm两组对照的甲板偏航也都接近零。于是“单纯因为距离长”以及“单纯因为启停次数多”都站不住。更值得怀疑的是Nav2 实际命令流里的转向分量与被动甲板、托盘保持机构的耦合。但继续压低角速度也没有直接解决问题另一档 Nav2 转向保守配置到站误差0.1545 m、到站仍 PASS滑移却达到8.362 mm。因此这里可以说“转向命令流相关”不能说已经找到一个调小角速度就能治好的参数。六、后续改进到哪里了后续机构候选 v10 在另一次带初始载荷的导航运行中把最大相对滑移降到4.812 mmtray_retained首次通过原5 mm门限Nav2 到站误差为0.1455 m。这说明“托盘保持”这一项并非永远无解。但那次报告的整体结果仍是FAIL其当时使用的货物停车判据未通过。更晚的证据审计发现旧版以货物接触点的速度上界直接代表“货物是否停止”可能高估贴着工装的振动因此项目后来把该门改为基于货物本体中心的位移差分速度同时保留旧速度上界作为诊断字段。本文不把旧报告的 0.0454 m/s 或 0.0209 m/s 写成“货物本体真的以该速度持续滑动”。这也意味着v10 通过了托盘保持门不等于整套订单已完成新口径也不能反过来把旧报告自动改判为 PASS。每一次判定都必须绑定当次代码、世界和报告。七、这次实验真正给我的启发机器人项目里的“成功”至少有三层导航成功Nav2 action 完成车辆真值到站。载货成功运输全程托盘不越过相对滑移门姿态与支撑持续有效。任务成功停车后货物状态合格并真正完成卸货、交接和订单确认。把第 1 层当成第 3 层演示会很好看工程却可能过不了下一站。我们的p4-nav2-v7-03正好是一个反例Nav2 到站、车辆停稳都是真的托盘曾经越过 5 mm 门也是真的。让两个事实同时留在报告里比选一个好看的结论更有用。当前异构机器人工作站仍在继续开发。本文的运行是初始化载荷的短程验证不是从人形供盘到接收端卸货的完整连续订单更不是实机安全认证。