Isaac Sim 實戰筆記 GitHub

28 · 誤差怎麼累積,以及為什麼加一層補償常常讓事情更糟

一台車連續搬運:取貨、走、放貨、再取下一顆。第一趟乾淨俐落,第二趟就放不進去了。

直覺的處理是「加一層補償」——量到歪了幾度,下次命令就先反著轉幾度。這一篇要說明的是:那層補償在相當多情況下不但無效,而且會製造一個新的失敗模式,而它失敗的樣子跟原本的問題完全不像。

推導的終點是一句話:

能被補償的是誤差的「表現」,不是誤差的「來源」。 補償改的是世界座標裡的角度,而決定成敗的常常是接觸面之間的相對角——那個量,命令碰不到。

驗證狀態:內容來自一段現地場域的 Isaac Sim 6.0 調校(2026-08)。所有數字都是實測值,連同量測條件一起列。⚠ 補償實驗的關鍵資料是 n=1 每點,能支持「非零就壞」這個定性結論,不足以支持任何定量關係——文中逐處標明。

1. 誤差在哪裡產生:不在你以為的那一刻

先看一次完整搬運裡,被搬物與叉齒的相對角怎麼變:

取貨結束     rel  −90.3    ✅ 完美
載運中       rel −100.3 → −94.8 → −79.1    ← 振盪 ±10°
放貨第一步   rel  −82.0    ← 歪已經定型
放貨全程     rel  −82.3    (九個步驟,一動不動)

誤差不是在放貨那一刻產生的。 取貨結束時是完美的,是載運途中被注入,然後車一停,靜摩擦把它凍結在當下的相位。放貨的九個步驟裡它只動了 0.3°。

這件事改變了整個排查方向。放貨放不好,直覺會去調放貨;而真正在管事的是載運段的動力學。

另一個實驗把這一點釘死了:靜置 200 秒,讓它「自己回正」——rel 從 −82.0 只移到 −82.3。時間不會治好它。

2. 開環系統撐得住幾趟,可以直接算

撐得住幾趟 ≈ 容差 ÷ 單趟誤差

實測:單趟 yaw 誤差約 6°,容差 3° → 兩趟就爆。與實測完全吻合。

這條算式的用處是它會擋掉一整類無效的努力。只要單趟殘留不為零,累積就是必然——把單趟誤差從 13.0° 降到 9.9°(那次修的是根因,不是補償),分母變小了,但沒有變成零,所以連續搬運仍然會發散,只是慢一點。

對照組同樣清楚:另一組批次每輪都從場景原始狀態 RESET 開始,而且目標永遠有一個方正的基準——誤差不跨趟累積,所以它一直穩。它穩不是因為物理參數比較好,是因為它根本沒有在做連續搬運。

拿「會 RESET 的批次」的成功率去代表「連續搬運」的穩定度,是在測不同的東西。

3. 補償有害:三個點的實驗

給放貨命令一個 yaw 偏置,看棧板最後落在哪裡。判準是落點 x:在架上是 ≈5.10,在叉齒上是 ≈3.62

批次 命令偏置 叉齒實際轉了 落點 x 放下了嗎
gn0 0.0° 5.113
gn4 −4° 3.3° 3.595 🔴 沒有
gn8 −8° 7.1° 3.643 🔴 沒有

兩件事同時成立:

  1. 補償確實被執行了。 命令 −4° 轉了 3.3°、命令 −8° 轉了 7.1°,增益約 0.86,接近線性。
  2. 只要非零,棧板就完全放不下去,留在叉齒上。

第 1 點很重要,因為它排除了最省事的解釋。同一天稍早有三次是「參數讀得到、程式改到了、build 成功,只有行為沒變」——那是17 篇講的無聲失效。這一條不是那一類:車真的轉了。 補償生效之後才產生新的失敗模式,這正是「補償反而讓事情更糟」的意思。

gn0 那一列是正對照:0° 成功,證明失敗是補償本身導致,不是放貨機構整體失靈。

n=1 每點。 兩個非零點都失敗、失敗樣態相同(都留在齒上),而 0° 成功——這個對照夠支持「非零就壞」,不夠支持「增益恰為 0.86」

4. 「餘裕比較大應該就補得動」——這個直覺是錯的

先前的推測是:某些階段的插入餘裕寬得多,補償在那裡可能可行。

上面那組實驗就是在最寬的情境(空通道)、用最小的角度(4°)做的。一樣失敗。

推測被推翻了。而且連帶推翻了另一個更早的歸因:先前有一次補 7° 讓第三顆完全沒放成,被歸因為「那個階段間隙太窄」——窄不窄不是重點,因為在最寬的地方一樣過不去。

真正的幾何差距在另一個地方,而它大到不能互相外推:

動作 移動的東西 要進的開口 單邊餘裕
放貨 棧板(寬 ~1.06 m) 通道 只有幾十 mm(相鄰間隙實測 4~15 mm)
取貨 叉齒(寬 137 mm) 叉孔(307 mm) 85 mm

差一個量級。同一套補償邏輯套到不同幾何餘裕的地方,結果可以完全相反——取貨端補得動,不代表放貨端補得動。

歪斜的代價可以直接算:1.056 m 見方的物件轉 θ 時,掃過的包絡寬是 1.056 × (cosθ + sinθ)。4° 時 +71 mm、8° 時 +136 mm。而放貨端的單邊餘裕只有幾十 mm。補 4° 換來 71 mm 的額外寬度,而你只有 15 mm 可用——補償本身就是那個把它卡住的原因

(這條計算的形式與22 篇的姿態包絡是同一個:決定成敗的不是物件的尺寸,是它掃過的空間。)

5. 為什麼命令補不動:相對角與世界角是兩件事

補償在世界座標裡轉車身,而放貨要的也是世界角——所以理論上應該有效。它確實有效地轉了。問題在於轉了之後開口就進不去了

更根本的一層是:當摩擦把被搬物與叉齒連成近乎剛性時,兩者的相對角是旋轉不變量——車怎麼轉,相對角都不動。想靠命令把被搬物「擺正」到叉齒上,在純命令的範圍內沒有解。

⚠ 這裡有一個推理範疇的陷阱,值得單獨記:曾經有一份分析用「相對角是旋轉不變量」去論證補償不可行。那句話本身沒錯(相對角確實動不了),但它講的是相對角,而放貨要的是世界角——兩者不同,所以那個論證推不出那個結論。結論碰巧對,理由完全不對。

理由錯的正確結論,跟錯誤結論一樣危險,因為它會在下一個情境被錯誤地套用。

6. 補償的通則:它的前提會過期,而它不會自己失效

最一般化的一句是這條:

為了繞過某個問題而調的參數,根因修好之後要收回去。 補償性的調整會在根因消失後變成新的阻礙,而且它看起來完全合理。

這與23 篇的「捷徑的前提會過期而捷徑不會自己失效」是同一條規則的兩個面。差別在於捷徑通常有註解說明它在繞過什麼,而補償看起來像正經的控制邏輯,沒有人會想到要拆掉它。

還有一個獨立的實例:某一輪的 y 方向補償補過頭 +178 mm,整輪報廢。開環系統下,每個動作只有一次機會,補過頭也沒有機會發現——沒有驗證後重試的路徑,一次錯就是全錯。

7. 結論的邊界

不要把這一篇讀成「補償這個做法不可行」。實測支持的是:

在現行實作下,放貨端的角度補償有害。

還沒排除的機制、以及沒被試過的做法,都應該留在檯面上。例如:硬擋式的端擋機構試過並撤回(它把原本能過的階段打掉了),但「導引斜面」沒有試過——斜面在接觸時產生側向分力把物件推正,而不是硬擋,那是不同的機構,不該被端擋的失敗一起否定。

一次補償失敗,不能推廣成否定所有機構解。

8. 真正有效的那條路:截斷傳遞,不是修正誤差

補償想做的是「把已經歪掉的擺正」。有效的做法是另一個方向:

不試圖把物件擺正,而是下一趟取貨時對準它現在的樣子。 誤差留在那裡,但不再往下傳。

這一層的價值不是把東西擺正,是讓誤差不再累積。就算每次放貨都留下 8°,系統也是穩定的——因為每趟取貨都重新參照物理真值,不會第三趟就爆。

開環累積 vs 有界穩態,這是兩種完全不同的系統行為,而區別只在於「下一趟的參考點是什麼」:

參考點 行為
補償(修正誤差本身) 上一趟的規劃值 誤差累積,容差 ÷ 單趟誤差 趟後失敗
重新對準(截斷傳遞) 這一趟的物理真值 有界,不隨趟數發散

「驗證後重試」這條路在補償出局之後也要重新定義:原本的設計是「超出容差就重取重放,把上次誤差當這次的補償量」,而那個回授路徑不存在了。重試只會得到另一個隨機相位,不會收斂到「正」。 它還有一個弱版本可用——重試不是為了修角度,是為了換一次抽樣

9. 方法論:推翻既有斷言之前,先算清楚方向

這個專案裡最貴的一次判斷失誤不是技術的,是流程的:

一度以為某個舊判決的前提已經不成立、要重測。方向搞反了:摩擦係數從 0.70 提到 1.4 讓連接更剛,那個結論只會更成立,不會被推翻。

教訓寫成規則:

要推翻既有斷言之前,先算清楚新條件是往哪個方向推。 看到「前提變了」就準備重測,而沒問「變的方向是強化還是削弱那個結論」。

另一條同樣可複用:

所有以 pass/fail 為依據的證偽判決都要重看。

有一批實驗判「補償無效」用的是 pass/fail。改用連續量重測之後,結論碰巧一樣,但真正的因果完全不同——不是「作動器沒反應」,而是「作動器有效,但生效之後反而放不下去」。這兩件事的下一步動作完全不同:前者去查控制鏈,後者去查幾何。

pass/fail 判準會把「沒生效」與「生效但有害」壓成同一個結果。27 篇講的是同一個病在失效分類上的樣子。

10. 檢查清單


延伸閱讀:29 長跑才會浮現的問題(誤差注入的一個根因是模擬時鐘與牆鐘分歧)、27 失效模式分類學23 物理模擬不可以偷懶24 把「會瞬移的底盤」換成「真的有輪子的車」