學習 / 實作
具身智能實踐(十三):下降中斷之後,應該從哪一步恢復?
具身智慧 / 探索 · 工程案例
18 個 MuJoCo 回合與同步回放,將階段契約接入恢復預算,區分正常下降誤停、物理放置和控制器終止。
這篇之後,已經有了哪些結果?
保留本文發表時的結論與下一步構想;以下是已發布的後續內容,不代表所有侷限皆已解決。
繼續探索
繼續探索
瀏覽統計暫不可用
本文目錄 9
從乾淨環境重現 · 本篇固定版本
以下為 Windows PowerShell,Python 3.12。使用新目錄;不要在有未儲存改動的工程裡切換版本。每篇固定提交不同,首篇的舊提交不包含後續實驗。
git clone https://github.com/VirtualSelect/hohoo-embodied-agent.git hohoo-embodied-agent-study
cd hohoo-embodied-agent-study
git checkout ad2e33523e8e5580da90ae914e1cccf765c8d1b1
python -m venv .venv
$py = '.\.venv\Scripts\python.exe'
& $py -m pip install -r requirements-lock.txt
& $py experiments/vl01_phase_recovery/run.py --out outputs/my-run
& $py experiments/vl01_phase_recovery/audit.py outputs/my-run預期得到原始軌跡、摘要與稽核結果。請使用新的輸出目錄,避免覆蓋舊結果;不同實驗對既有目錄的處理並不相同。E8–E10 共用一組實驗入口。以上指令不呼叫模型;先執行數值部分,影片回放依正文單獨執行。
排錯:找不到實驗目錄先核對提交;匯入失敗檢查解譯器與安裝環境;OpenGL 錯誤僅影響需要渲染的步驟。Linux/macOS 將解譯器替換為 .venv/bin/python,尚未在這些平台複測。
查看本篇固定程式碼 ↗上一輪發現,下降階段即使暫時失去觀測,transfer-only 門控也不會響應。擴大監控範圍似乎很直接:讓下降也使用同一套抓取檢查。
但搬運要求方塊保持一定高度,下降本來就要把它放低。把條件直接複製過去,正常運動會被當成故障。這一輪把階段契約、恢復視窗和恢復軌跡真正接在一起,檢查系統在什麼時候暫停、憑什麼恢復、恢復到哪一步。
先看回放:三個控制器遇到同一次間斷
影片來自已經保存的 MuJoCo 狀態。每畫面同一時刻讀取同一取樣 tick,沒有重新運行物理來拼接“更好的結果”。左側只監控搬運,中間讓下降重用搬運規則,右側使用階段感知規則。
這一組觀測間斷發生在 6.10~6.34 秒。中間控制器在間斷發生之前,已經因為正常下降誤停;左側無視間斷繼續執行;右側暫停,重新積累證據後繼續下降。
凍結了哪些條件
沿用同一桌面、雙指夾爪、方塊與目標盒,物理步長 2ms,每回合 12 秒。沒有訓練策略,沒有接入 ROS2 或真實機器人。
| 條件 | 干預 |
|---|---|
| 無故障 | 不注入干預 |
| 搬運間斷 | 4.60~4.84 秒不交付觀測包 |
| 下降前段間斷 | 5.60~5.84 秒不交付觀測包 |
| 下降後段間斷 | 6.10~6.34 秒不交付觀測包 |
| 下降永久間斷 | 5.60 秒起不再交付觀測包 |
| 下降鬆爪 | 5.60~5.84 秒強制夾爪張開,觀測仍正常 |
每種條件對照三個策略,共 18 回合。干預按絕對模擬時間注入;控制策略一旦改變軌跡,同一個時段不保證遇到完全相同階段。分析必須查看 scheduled_phase 和事件記錄,不能只看條件名稱。
所有策略保留最多兩次恢復、至少 400ms 暫停、800ms 恢復截止時間。終止後統一保持當時目標,不混入上一輪的不同退出動作。
哪個條件應該屬於哪個階段
| 策略 | 搬運時檢查 | 下降時檢查 |
|---|---|---|
| transfer-only | 雙指接觸、抓取誤差、方塊高度 | 不檢查 |
| reuse-transfer | 同上 | 直接複製搬運規則 |
| phase-aware | 雙指接觸、誤差小於 5cm、方塊高於 12cm | 雙指接觸、誤差小於 5cm |
下降去掉高度下限,不意味著下降時什麼都不檢查。接觸、相對位置誤差和觀測新鮮度仍然有效。是否已經正確放置,使用最後 500ms 的物理記錄另行驗收,不能用“下降階段允許低高度”代替完成條件。
HOLD 不能覆蓋被中斷的階段
執行狀態有 running / hold / aborted,作業階段有 transfer / lower / release。它們是兩套不同維度。
當下降進入 HOLD 時,需要保存 interrupted_phase=lower。如果下一輪將這個欄位改成 hold,控制器就丟失了判斷觀測和重建軌跡的上下文。
本輪僅在正常執行、作業階段改變時更新上下文;暫停期間保留原階段。暫停截止時間也不會因為上層傳入了 release 或 hold 而重新開始。
if self.state == 'running' and phase != self.context:
self.context = phase
self.bad_since = None暫停後的恢復證據繼續沿用之前的要求:必須是 HOLD 之後采集、時間連續、仍然新鮮的合格觀測視窗。只是其中“合格”的定義現在依賴被中斷階段。
恢復下降,不應該再升回搬運高度
舊恢復路徑總是先回到 18cm 搬運終點,再做下降。現在根據保存的階段選擇路徑:
搬運中斷:當前測量夾爪位置 → 搬運終點 → 下降 → 鬆爪 → 後退
下降中斷:當前測量夾爪位置 → 下降終點 → 鬆爪 → 後退第一段統一用 0.5 秒平滑連接。這裡是固定目標的簡單軌跡拼接,不是避障規劃、重抓取或最優控制。起點使用恢復時測量的夾爪位置,避免假設機器人仍處在原計畫位置。
實測:下降後段的 400ms 暫停
階段感知策略在後段間斷中留下以下事件:
| 事件 | tick | 模擬時間 |
|---|---|---|
| 觀測變舊,進入 HOLD | 3071 | 6.142s |
| 新的連續合格視窗開始 | 3171 | 6.342s |
| 滿足暫停下限,恢復 lower | 3271 | 6.542s |
恢復後從當時夾爪位置直接繼續下降,最終方塊中心高度約 25.98mm,接觸目標盒底,最後 500ms 滿足沿用的放置條件。
相比之下,reuse-transfer 在 6.002s 就因高度下降而進入 HOLD,6.802s 因無法重新滿足搬運高度而終止。這發生在 6.10s 注入觀測間斷之前。因此不能把這個失敗歸因於斷流;無故障組也在同一時刻誤停。
物理上在盒里,不代表控制流程完成
下面報告的是物理放置驗收,不是成功率估計。固定場景每格只運行一次,沒有隨機初始化或統計置信區間。
| 條件 | transfer-only | reuse-transfer | phase-aware |
|---|---|---|---|
| 無故障 | 滿足 | 不滿足,誤停 | 滿足 |
| 搬運間斷 | 滿足,恢復 1 次 | 不滿足,下降誤停 | 滿足,恢復 1 次 |
| 下降前段間斷 | 滿足,未監控 | 不滿足,恢復後誤停 | 滿足,恢復 1 次 |
| 下降後段間斷 | 滿足,未監控 | 不滿足,干預前已誤停 | 滿足,恢復 1 次 |
| 下降永久間斷 | 滿足,未監控 | 不滿足,終止保持 | 不滿足,終止保持 |
| 下降鬆爪 | 滿足 | 滿足,但已終止 | 滿足,但已終止 |
兩個地方不能省略說明。
永久丟失觀測時,transfer-only 仍然完成了固定軌跡。 這證明這個場景的開環軌跡碰巧足夠,不證明“忽略觀測更安全”。階段感知策略在 5.642s 暫停、6.442s 終止,方塊停留在約 157.81mm,未完成放置。
鬆爪故障時,方塊剛好在盒子上方落下。 兩個監控下降的控制器都檢測到接觸失敗並終止,但方塊最終滿足物理驗收。這不是控制器成功恢復,也不是設計好的鬆爪策略。若只統計“方塊是否在盒里”,就會把偶然落入目標的事故獎勵為成功。
本輪 18 回合中有 12 回合滿足物理驗收;其中 2 回合控制器處於終止狀態。後續評價至少應分別保留物理結果、觀測合規性和控制器生命周期,不能合成一個未經定義的成功數字。
如何確認這些不是畫出來的結論
歸檔包含 108,000 行控制與觀測記錄、10,800 個可回放狀態、54 份原始檔案。審計重新計算最終放置條件、檢查觀測間斷與鬆爪注入時段、核對恢復視窗和預算,並驗證 18 組策略比較在首次決策分歧之前的物理軌跡一致。
8 個契約測試覆蓋低高度下降、低高度搬運、暫停階段保留、絕對截止時間、釋放階段不觸發新門控、接觸失敗、恢復路徑和預算耗盡。
回放呼叫 mj_forward 根據已保存的 qpos/qvel 更新可視狀態,不呼叫 mj_step 產生新的實驗軌跡。MuJoCo 模擬文檔解釋了這兩個操作的區別。回放是證據的展示方式,不增加實驗樣本數。
重現與邊界
在 hohoo-embodied-agent 倉庫的現有 MuJoCo 環境執行:
python -m unittest discover -s experiments/vl01_phase_recovery -p test_gate.py
python experiments/vl01_phase_recovery/run.py --out evidence/my-run
python experiments/vl01_phase_recovery/audit.py evidence/my-run
python experiments/vl01_phase_recovery/replay.py --evidence evidence/my-run本次運行使用 MuJoCo 3.3.7、NumPy 2.2.6、Python 3.12.14。回放需要現有的 imageio/FFmpeg 與可用渲染環境。
結果只覆蓋固定模擬、固定目標和上述干預。它沒有證明真實硬件安全,沒有解決永久缺測後的安全撤離,也沒有重抓取。完整 VL01 與更高階段里程碑仍未完成。
接下來最值得驗證的不是再提高一個總分,而是將“完成”契約接入當前階段恢復鏈:什麼時候允許宣布完成,終止後偶然落入目標應當如何記錄,完成後觀測失效又該如何撤銷狀態。 這一輪先把恢復階段與物理結果分開,給後續組合留下可審計的基礎。
寫給未來的自己合上文章前,留下一點自己的理解。
你的私人學習便箋,只存在目前瀏覽器,不會上傳或公開。清理瀏覽器資料會遺失,請匯出留存。三種語言共用這篇文章的便箋。
下一篇已發布內容:具身智能實踐(十四):方塊落進盒子,就能宣布任務完成嗎? →
目前學習位置
探索 / 具身智能
- ○ 具身智能實踐(十二):恢復預算耗盡之後,夾爪應該做什麼?
- ○ 具身智能實踐(十三):下降中斷之後,應該從哪一步恢復?
- ○ 具身智能實踐(十四):方塊落進盒子,就能宣布任務完成嗎?
繼續探索
繼續探索
接下來,走哪條路?
- 具身智能實踐(十二):恢復預算耗盡之後,夾爪應該做什麼? →
12 個 MuJoCo 回合與三畫面回放,對比保持、鬆爪、鬆爪後退,區分終止決定與實際退出後果。
- 具身智能實踐(十一):已經放好了,為什麼還要撤銷“完成”? →
七條 MuJoCo 軌跡與雙畫面回放,將歷史完成事件和當前有效狀態分開,保留傳感誤報與過期邊界。
- 具身智能實踐(七):搬運規則,為什麼會誤停正常下降? →
21回合MuJoCo對照:下降需要自己的抓取契約。用正常誤停、舊包報警與晚下降殘留接觸,拆開監測範圍、停止動作和最終放置。
依據文章關聯與同主題已發布內容整理,不使用隨機推薦。