跳转至

第 10 章 案例与排障

前十章的每一条判据,最终都要在一条完整链路上被检验;每一次失败,也都要能被归到某一条判据上。本章给出一个端到端案例的完整设置与统计结果(32 次尝试,逐段判定),并把前面各章暴露过的故障整理成可查的清单。所有读数取自运行环境 ROS 2 Humble + MoveIt 2 2.5.10 + ros2_control 2.54.3 的 panda 样本 demo(mock 硬件,无六维力传感、无物理接触),因此结论只到链路与几何层,不含真实抓取力学。

端到端链路的分段判定:

flowchart LR
    p["感知"] --> plan["规划"] --> ex["执行"] --> touch["接触"]
    touch --> verdict["逐段判定:失效集中在哪一段"]

1. 案例设置与判据定义

任务:把 35–85 mm 立方的工件从桌面一处抓到固定放置点 (0.35, 0.20)。序列即第 6 章的 11 段(开爪 → 接近 → 直线插入 → 闭合 → attach → 抬起 → 搬运 → 直线下降 → 张爪 → detach → 回退),每段独立判定:

段类型 判据
规划段(approach / transport) 动作返回码 SUCCESS
直线段(insert / lift / place_down / retract) fraction > 0.99 且执行返回码成功
夹爪段(open / close / open2) 以 /joint_states 的位置读数判定(第 6 章:结果体存在一拍滞后)
场景段(attach / detach) /apply_planning_scene 返回 success
端到端 全部 11 段通过,且放置时刻的末端到位误差 ≤ 15 mm

随机化:工件中心 x ∈ [0.38, 0.62] m、y ∈ [−0.34, 0.34] m、边长 ∈ [35, 85] mm(均匀分布,固定随机种子,32 个样本)。抓取几何按第 6 章:预抓取在工件中心上方 0.21 m、工具垂直向下、闭合位置取半宽 + 3 mm、直线插入行程固定 0.1066 m(使指尖落到工件中心高度)。

边长超过 80 mm 的样本在候选阶段就被几何判据拒绝(跨度大于夹爪 80 mm 行程),本轮 32 个样本中有 2 个属此类;它们不计入失败,而记为“预期拒绝”——这正是第 6 章判据应当发挥作用的地方:把不可能成功的样本挡在昂贵的规划之前。

2. 分段结果与区间

30 个进入执行的样本,各段通过情况(Wilson 95% 区间):

段 通过 比例 95% 区间
open / close / open2 30/30 1.000 [0.886, 1.000]
approach 30/30 1.000 [0.886, 1.000]
attach / detach 30/30 1.000 [0.886, 1.000]
transport 30/30 1.000 1.000
place_down 30/30 1.000 1.000
insert 10/30 0.333 [0.192, 0.512]
lift 28/30 0.933 [0.787, 0.982]
retract 28/30 0.933 [0.787, 0.982]
端到端 8/30 0.267 [0.142, 0.444]

两条统计层面的注意。其一,端到端 26.7% 这个数字几乎完全由插入一段决定(10/30 通过,其余段都在 93% 以上):链路的可靠性不是各段的均匀乘积,而是最弱一段的函数——不做分段记录,这条结论根本无法得出,而只看总成功率就会去找错方向(比如怪规划器)。其二,30 个样本给出的区间仍然很宽(端到端 [0.14, 0.44]);用它做“成功率 27%”的断言是不负责任的,样本量要往上百走才能把区间压到工程可用的宽度。

3. 失效集中在哪一段

按边长分层后,失效结构立刻清楚了:

分层 样本 插入通过 端到端
边长 ≤ 60 mm 16 10(0.625,[0.386, 0.815]) 8(0.500,[0.280, 0.720])
边长 > 60 mm 14 0([0.000, 0.215]) 0

0 通过不是随机波动(14 次全败的区间上界只有 21.5%),原因是几何的。把插入完成度按“边长 × 下降深度”扫一遍(每次先规划回到预抓取位姿再测,max_step = 5 mm):

预抓取高度 link8 = 0.510 m;指尖在 link8 下方 0.1034 m
边长 \ 下降深度      60    80   100   107   115   (单位 mm,1.00 = 整段无碰撞)
   40 mm        1.00  1.00  1.00  1.00  1.00
   50 mm        1.00  1.00  1.00  1.00  1.00
   60 mm        1.00  0.81  0.65  0.59  0.56
   70 mm        1.00  0.75  0.60  0.55  0.52
   80 mm        0.92  0.71  0.57  0.55  0.50

读法:夹具完全张开时两指内侧相距 80 mm,工件 60 mm 时单侧只剩 10 mm 横向间隙,下降越深、手指与工件顶边越接近;到 50 mm 及以下则整段都走得动。案例里固定的 106.6 mm 行程对 >60 mm 的工件必然撞到顶边(完成度 0.5–0.6),于是插入段被判据拒绝,后面即使各段都“成功”也谈不上完成任务。

修法是把固定行程换成按工件尺寸计算的深度:可插深度 = f(工件宽度, 夹爪张开, 指尖长度),或者干脆“下降到余量高度后改用带力/电流判据的柔顺插入”(第 8 章)。这一处改动预计把端到端瓶颈直接消掉,而它来自分层统计,不来自调规划器——这就是分段统计的实际价值。

lift 与 retract 各 2 次不通过属于同一族问题:路径穿过刚放置/刚抓起的工件附近空间(放置后物体作为世界物体留在原地,第 6 章)。

4. 到位误差的口径

放置时刻的末端到位误差:平移中位 3.88 mm、95 分位 4.99 mm、最大 5.00 mm;姿态中位 2.59°、最大 4.16°。

最大值恰好等于请求里的位置容差 5 mm,这不是巧合。位姿目标在 MoveIt 里是一个区域(第 4 章的约束),采样规划器只需把末端落到区域内,因此实际落点在容差球内近似均匀分布——到位误差由容差设定支配,而不是由控制精度支配。据此有两条口径要求:

  • 报“精度”时必须同时报请求容差;把 4 mm 说成链路精度是错的,它主要是容差的函数。
  • 要真精度,就要闭环:以测量(视觉复检)重新给目标,或以物理层/真机的实际到位反馈做二次收敛(第 7 章 mock 层给不出这个)。

同类混淆还有一处:把 /joint_states 的 120 Hz 读数当作控制器周期(update_rate 实为 100 Hz,两发布者合成),或把 mock 的段内跳变(样本轨迹最大 11.45°)当成跟踪误差(第 7 章)——统计数字的口径不清,比数字本身更有害。

5. 排障清单

按“现象 → 首查 → 判据出处”组织,顺序即现场排查顺序。

现象 首查 依据
规划全线失败,配置没改过 场景残留:未卸下的附着体、上次实验留下的物体 第 7 章第 7 节;本仓库就出现过因残留附着体导致所有请求 INVALID_MOTION_PLAN
返回码是 −27 GOAL_STATE_INVALID 目标本身是否合法(用 /check_state_validity 直接判,别再发规划请求) 第 3、4 章:SRDF 具名组态也可能自碰
返回码 −26 START_STATE_INVALID 起点关节值是否越限位(含 joint_limits.yaml 覆写) 第 1、4 章
失败且耗时≈预算 搜索层问题:不可达、需绕行、预算太小 第 4 章:耗时形态即线索
执行返回 −4 CONTROL_FAILED,无更多信息 起点是否与当前状态一致、joint_names 顺序、航点是否越限、是否曾被取消 第 7 章:这四种注入返回同一个码
换规划器无解、别的规划器有解 planner_id 是否写成配置里的完整键名(如 RRTConnectkConfigDefault),否则退回默认配置 第 4 章的结论:写 RRTConnect 会走“找不到配置、改用默认”的路径
缩放因子没设,规划直接失败 请求里两个缩放因子缺省为 0,Pilz 严格拒绝、OMPL 宽容 第 4 章
放置后一抬就失败 夹爪是否先张开再 detach;闭合位置是否小于工件半宽 第 6 章
抓取几何对但插入总失败 下降行程是否按工件尺寸算,横向间隙是否够 本章第 3 节矩阵
关节单位异常、模型“怪” URDF 关节单位(弧度/米)与度/弧度换算 REP 103(第 1 章)
规划耗时暴增 碰撞几何是否用了渲染网格;octomap 分辨率是否过高 第 3 章
到位“精度”莫名变差 请求容差与测量基准,不是控制 本章第 4 节
力控/插入调不通 关节层是否只暴露位置接口(只能做导纳) 第 8 章
Servo 起来但不动 参数文件是否需 ros__parameters 包裹;话题路径是否被命名空间叠加 第 7 章第 6 节

6. 资源与实时预算

本案例涉及的量级汇总(同一环境,样本臂 panda):

项 量级 出处
单次规划 1–13 ms(无障碍简单场景) 第 4 章
合法性检查 0.3–2.1 ms 第 3 章
场景取回(203 物体,全量组件) 19 ms / 47 KiB 第 3 章
轨迹执行 100 Hz 跟随 第 7 章
一条 11 段任务的耗时 数十秒(含执行) 本章
逆运动学无解 烧满超时(1 s 请求 → 约 1 s 返回) 第 2 章

三条预算判断:任务级链路的瓶颈通常不在求解算力而在执行时间(秒级)与重试(每次失败都可能烧满预算),所以候选过滤与分段判据比优化求解器更能压总时长;场景同步(毫秒级但高频)要按需取组件;octomap 与 mesh 碰撞是内存/CPU 的两个主要上界(第 3 章)。

7. 要点

  • 端到端成功率几乎由最弱一段决定:本案例插入段 10/30,端到端 8/30;不分段记录就找不到瓶颈。
  • 30 个样本的 Wilson 95% 区间是 [0.142, 0.444]——宽度决定了它还不足以作为产线指标,只能作为定位问题的线索。
  • 分层比总值有信息:边长 >60 mm 的工件插入通过率 0/14(区间上界 21.5%),原因是横向间隙(张开 80 mm − 工件宽)与固定下降行程不匹配;边长 × 深度 矩阵是直接有效的诊断工具。
  • 到位误差最大 5.00 mm 恰等于请求容差 5 mm:位姿目标是区域,落点在区域内近似均匀,报精度必须同时报容差与测量基准。
  • 排障先看场景残留,再看返回码族与耗时形态;−4 CONTROL_FAILED 覆盖起点不符、名字乱序、越限、取消四种情况,归因要靠调用方自己的断言。
  • planner_id 要写配置里的完整键名,缩放因子必须显式给出;这两条都是“看起来在跑、其实走默认”的静默失败。
  • 案例的边界要如实写:mock 层不含接触力学与真实节拍,抓取是否成立、滑移与卡滞不在本章结论范围内。

参考文献与延伸阅读

  • Brown, L. D., Cai, T. T., & DasGupta, A. Interval Estimation for a Binomial Proportion. Statistical Science, 2001. DOI
  • MoveIt. 项目门户与文档入口. 文档
  • ros2_control. 文档与控制器接口. 文档