學習 / 實作

具身智能實踐(六):恢復門控與路徑重規劃,各自解決了什麼?

具身智慧 · 工程案例

30回合消融對照:重規劃把首次目標跳變從50–97毫米降至約0.25毫米,卻沒有提高本矩陣的放置成功率。用原始紀錄拆開恢復證據、動作連續性與任務結果。

進階 · 14 分鐘 · 更新於 2026-09-30

瀏覽統計暫不可用

本文目錄 9
跳至正文 ↓

上一輪把“確認物體仍被抓住”和“重新規劃剩余路徑”一起加進了恢復策略。結果可以說明組合有效,卻回答不了:究竟是證據檢查避免了錯誤恢復,還是軌跡改變改善了動作?

這輪把兩個開關拆開。最重要的結果有兩條:在四對固定條件中,重規劃將首次恢復目標的跳變從 50.285–97.055mm 降至 0.245–0.263mm;但四種主動恢復組合都完成了五個非掉落條件,沒有觀察到放置成功率提升。

這不是矛盾。是否應該恢復、恢復後發出什麼目標、最終是否放好方塊,是三個不同的問題。

固定版本程式碼 · 30回合原始證據 · 獨立指標

1. 為什麼需要拆開兩個開關?

假設一次搬運通信中斷後,方塊仍在夾爪裡。恢復連接時,可能發生兩類錯誤:

  • 證據錯誤:收到的是舊包,程式卻把它當成“現在仍然抓著”。
  • 目標錯誤:已經確認可以繼續,但直接追趕舊時間表中的目標,跳過了停止期間沒走完的一段路。

前者應該由恢復門控處理;後者應該由路徑處理。只比較“舊策略”和“全套新策略”,會把兩項改動混在一起。因此本輪采用2×2組合,再加一個不恢復的保守參照。

門控 舊時間表 wallclock 重規劃 replan
收到即恢復 receipt 收到合法包就繼續舊時間表 收到合法包就從當前位置重建路徑
重新驗收 revalidate 新證據持續成立後繼續舊時間表 新證據持續成立後從當前位置重建路徑

鎖存停止 latched 只保留舊時間表這一格,因為它根本不會恢復,額外開關路徑沒有意義。這裡的 wallclock 是原軌跡使用的絕對模擬時間,不是電腦的真實時鐘。

2. 30回合具體控制了什麼?

五種組合分別跑六個條件,共30回合;每格一次、無隨機種子,不做泛化成功率估計。另有18回合E5回歸,用來檢查接入新實驗時沒有改變舊結果,不能把它們當作額外18個E6樣本。

項目 固定值
場景 同一笛卡爾夾爪、方塊、托盤與初始狀態
物理/控制步長 2ms
觀測取樣 20ms
故障開始 4.8s,搬運階段
通信間斷 [4.8, 5.04),240ms
過期門檻 包齡達到60ms
恢復確認 至少100ms連續有效捕獲,間隔不超過20ms
最長停止等待 600ms,期限優先於同tick恢復
重建搬運段 1.5s,再接下降、鬆爪、撤離和穩定
回合終點 10.8s

六條件沿用E5:無擾動、固定40ms延遲、每第三包延遲80ms形成亂序、通信間斷、間斷後重送舊正常包、間斷同時鬆爪。最後一項實際改變執行器開合,方塊仍由接觸與重力運動,沒有改寫物體位置。

模擬記錄來自 Linux、Python 3.12.14、MuJoCo 3.3.7、NumPy 2.2.6;接入時在 Windows 對原始碼、原始記錄和測試重新核驗。本機稽核不算新一輪物理模擬。

3. “目標跳變”不是“夾爪瞬移”

恢復判定發生在tick r 的物理步之後。因此這一行仍使用停止時保持的目標,r+1 才發出恢復後的第一個目標。

本輪記錄兩個距離:

J = || target[r+1] - target[r] ||₂
E = || target[r+1] - measured_hand[r] ||₂

J 回答“控制器下一步的目標突然變了多少”;E 回答“這個目標離恢復瞬間實測夾爪有多遠”。兩者都只取XYZ,不混入夾爪開合量。

夾爪實際位置由物理引擎和執行器跟蹤決定,目標跳變不能寫成機械臂瞬間移動了同樣距離。紀錄中的手部速度也只是2ms位置差分,不是完整速度、加速度或沖擊安全認證。

實現的關鍵分支很小:

if path_mode == "wallclock":
    return path, None

previous = np.array([*hand, float(grip)])
rest = [("transfer", 1.5, [.24, .12, .18, .033])] + base.schedule(0)[5:]
return segments(rest, tick * DT, previous), previous

重規劃以實測位置起步,重設後續時間表;它不是避障算法,也不是逆運動學求解。路徑幾何與重新定時一起改變,後面的差異不能歸結為純幾何作用。

4. 同樣的門控,換一條恢復路徑

下面只比較相同條件、相同門控、第一次恢復的路徑差異。獨立稽核確認了第一次決策前的狀態與控制前綴一致。

條件 門控 舊時間表 J/mm 重規劃 J/mm
通信間斷 收到即恢復 50.285 0.263
通信間斷 重新驗收 71.433 0.245
舊包重送 收到即恢復 50.285 0.263
舊包重送 重新驗收 97.055 0.245

重規劃與舊時間表的比值為0.25%–0.52%,四對均滿足預設的“不超過一半”門檻。這是四對確定性記錄的描述,沒有置信區間,也不外推到其他機械臂。

同門控四對恢復目標跳變:左側舊時間表為50至97毫米,右側重規劃約0.25毫米;左右橫軸刻度不同

兩幅子圖使用不同橫軸范圍,便於讀出小數值;應對照數字,不能直接用條形長度比較比例。圖與上表均來自 metrics.json。

為何重新驗收配舊時間表反而跳得更遠?它等待更長的有效證據窗口,舊軌跡卻繼續按絕對時間推進。例如舊包重送下,重新驗收到5.302s才恢復,直接續舊時間表會追趕更靠後的目標。更嚴格的證據檢查,不會自動讓軌跡銜接更平順。

舊包重送時,兩種門控下的目標、實測夾爪位置和包齡變化;實線與虛線對照舊時間表和重規劃

這是紀錄繪圖,不是相機觀測。上排為世界坐標x,下排為最新包齡;圖例中的 target 是目標,measured 是實測位置。

5. 有好包,還不等於有完整確認窗

舊字段 unsupported_resumes 只統計“恢復時包齡≥60ms,或抓取謂詞為假”。它沒有覆蓋完整100ms確認窗的所有要求。

通信間斷剛結束時,receipt 收到一份新鮮正常包就恢復,所以該計數為0;但只有一個樣本,確認跨度仍是0ms。新增 missing_full_window_resumes 把這個差別單獨記下來。

條件/門控 每條路徑的恢復次數 舊/壞包恢復 缺完整確認窗
通信間斷 / 收到即恢復 1 0 1
舊包重送 / 收到即恢復 9 8 9
通信間斷 / 重新驗收 1 0 0
舊包重送 / 重新驗收 1 0 0

重新驗收要求每個用於確認的包到達時都新鮮、捕獲晚於當前停止、捕獲順序遞增、相鄰間隔≤20ms、跨度≥100ms,且恢復時最新包仍新鮮並支持抓取。抓取謂詞仍是雙側接觸、方塊高度>0.12m、與夾爪中心距離<0.05m。

計數為0只說明它所定義的失敗沒有出現,不能代替其他前置條件。

6. 重規劃為什麼不能救回掉落?

在通信間斷並鬆爪條件中,四種組合表現如下:

組合 恢復次數 舊/壞包恢復次數 最終放置
收到即恢復 + 舊時間表 6 6 未完成
收到即恢復 + 重規劃 72 72 未完成
重新驗收 + 舊時間表 0 0 未完成,等待到期後中止
重新驗收 + 重規劃 0 0 未完成,等待到期後中止

72次尤其容易被誤讀為“重規劃讓系統更危險”。實際上,繼承的門控只在 transfer 階段監測。舊時間表較快進入 lower,之後不再觸發搬運階段的停止;重規劃每次恢復都重置搬運段,因此在被監測階段暴露更久,反復觸發同一循環。

所以72對6同時包含門控范圍、階段停留時間和閉環反饋的影響。它揭示一個真實缺口:只在一個階段監測,不能代表全任務安全;但不能把差異歸因於路徑幾何本身。

重新驗收的兩個組合均在600ms等待期限中止,不再恢復。這個停止符合協議,卻不是“放置成功”,也不是重抓取。

7. 完整矩陣與時間代價

條件 鎖存停止 收到/舊路徑 收到/重規劃 驗收/舊路徑 驗收/重規劃
無擾動 放置 放置 放置 放置 放置
40ms延遲 放置 放置 放置 放置 放置
亂序 放置 放置 放置 放置 放置
通信間斷 中止 放置 放置 放置 放置
舊包重送 中止 放置 放置 放置 放置
間斷並鬆爪 中止 未放置 未放置 中止 中止

“放置”按原協議驗證末尾0.5s:位置在托盤范圍內、高度正確、速度<0.02m/s、沒有手指接觸,且此前曾抬升。只是把物體移動到目標附近不算。

本輪四種主動恢復組合都完成了五個非掉落條件。因此不能宣稱重規劃提高了放置成功率。它還延後了部分回合:舊包重送、重新驗收這對中,首次持續放置窗口的結束時刻從7.322s變成8.622s。該時間從20ms取樣紀錄估計,不是無限精度的完成時刻。

8. 證據怎樣核驗,讀者怎樣重現?

獨立稽核不導入 Gate,從原始CSV、狀態與接收包重算:30個完整矩陣格、180份回合檔案、12份原始碼/協議指紋、24組鎖存前綴、12組同門控路徑前綴。前綴最大絕對差為0;102次恢復逐條檢查,重新驗收的4次實際恢復均有有效確認窗。

另18回合E5回歸的離散結果與舊證據一致,狀態/速度/控制最大差為約1.09×10⁻¹⁴,低於預定1×10⁻¹⁰門檻。檔案一致性與假設成立分開:合法資料即使不支持假設,也應該保留。

在工程根目錄,先稽核現有記錄;跨平臺用臨時副本恢復到已知雜湊對應的換行,不重寫原始證據:

.venv/Scripts/python -m unittest discover -s experiments/vl01_recovery_ablation -p 'test_*.py'
.venv/Scripts/python experiments/vl01_recovery_ablation/portable-audit.py evidence/recovery-ablation-20260930/e6-final

本機30項測試通過。要重新模擬,使用從未存在的目錄,保留舊記錄:

.venv/Scripts/python experiments/vl01_recovery_ablation/run.py --out runs/e6-my-run
.venv/Scripts/python experiments/vl01_recovery_ablation/audit.py runs/e6-my-run
.venv/Scripts/python experiments/vl01_recovery_ablation/render.py runs/e6-my-run

Linux將解釋器路徑換成 .venv/bin/python。control.csv 每2ms記錄控制,trajectory.csv 和 states.jsonl 每20ms記錄物理狀態;events.json 看決定,replans.json 看重規劃起點。歸檔提交固定整套材料;manifest仍保留原執行的基線提交與未提交狀態,不將歸檔時間冒充執行時間。

9. 下一步應該修什麼?

優先問題已經很具體:下降與釋放階段是否也需要自己的監測和恢復條件?反復恢復是否需要次數或冷卻約束? 這些應先定義協議,再用固定故障相位對照驗證,而不是直接加更多機器人模型。

本輪仍是同一場景、模擬真值、同一時鐘與固定故障,沒有視覺、ROS2、時鐘偏差、重抓取、學習策略或真機驗證,完整M4/M5不因此完成。可以支持的結論是:恢復門控檢查“可不可以繼續”,重規劃改善這組記錄中的目標銜接;它們都不能單獨代表任務已經安全完成。

寫給未來的自己合上文章前,留下一點自己的理解。

你的私人學習便箋,只存在目前瀏覽器,不會上傳或公開。清理瀏覽器資料會遺失,請匯出留存。三種語言共用這篇文章的便箋。

繼續探索

繼續探索

  1. 工程案例

    具身智能實作(五):通訊恢復了,為何還不能立刻繼續搬運?

    18回合 MuJoCo 對照:舊正常包使基線反覆啟停卻最終成功;以連續新證據與剩餘路徑規劃重新定義恢復。

    12 分鐘已發布
  2. 工程案例

    具身實作(四):訊息還在到,觀測已經過期了

    45回合MuJoCo對照,分離取樣間隔、異常計數與觀測年齡;理解舊訊息為何掩蓋真實鬆爪,以及時間門檻仍有哪些限制。

    14 分鐘已發布
  3. 實驗 / 012

    E6 / 恢復門控與路徑消融

    把重新驗收與路徑重新規劃拆開:哪些差異來自證據,哪些來自恢復後的目標?

    已完成
  4. 專案 / 003

    Hohoo 具身實驗

    七輪MuJoCo教學對照:從拾取偏移到階段契約,保留原始軌跡、決策與獨立稽核。

    實驗中

接下來,走哪條路?

依據文章關聯與同主題已發布內容整理,不使用隨機推薦。

← 全部文章