學習 / 實作

具身智能實踐(七):搬運規則,為什麼會誤停正常下降?

具身智慧 · 工程案例

21回合MuJoCo對照:下降需要自己的抓取契約。用正常誤停、舊包報警與晚下降殘留接觸,拆開監測範圍、停止動作和最終放置。

進階 · 13 分鐘 · 更新於 2026-10-01

瀏覽統計暫不可用

本文目錄 10
跳至正文 ↓

搬運方塊時,要求“方塊中心高於12公分”很合理:它用來確認方塊仍被抬著。但任務進入下降階段後,方塊本來就應該越來越低。把同一條規則繼續打開,會發生什麼?

這輪21回合給出了一個直接反例:方塊仍被雙指夾持、與夾爪中心只差7.874公釐,卻在正常下降到6.002秒時被判為抓取異常。 去掉下降階段的搬運高度條件後,正常軌跡能完成放置;但故障後的保持動作仍有缺口,晚下降鬆爪條件最終留下了手指接觸。

因此這篇不把“覆蓋更多階段”直接寫成“系統更安全”。我們分別檢查三個問題:規則在當前階段是否合適,報警是否發生在真實故障之後,最後的物理狀態是否滿足任務要求。

固定版本程式碼 · 21回合原始紀錄 · 獨立審計與逐格指標

1. 上一輪留下的不是“多加一個判斷”

E6恢復消融發現,舊門控只在搬運階段工作。路徑重新定時後,控制器停留在被監測階段的時間也發生變化,反覆恢復次數因而不能只歸因於路徑幾何。

直接把 phase == "transfer" 改成 phase in ("transfer", "lower"),看似補上了下降監測,其實同時帶來了新的問題:原判斷中的每個條件,到了下降階段還成立嗎?

這裡把“階段契約”理解為一組當前階段應滿足的條件。它是本實驗中的明確判據,不是經過形式化證明的機器人安全契約。

條件 搬運時的作用 下降時是否沿用
雙指接觸方塊 支持仍在夾持的判斷 是,主動釋放前仍要求夾持
方塊距夾爪中心小於5cm 排除已明顯脫離的狀態 是
方塊中心高於12cm 確認抬升後的搬運狀態 否,下降必然經過這個高度
最新接納取樣年齡小於60ms 防止拿舊證據當當前狀態 是

去掉高度條件只改變下降判據,搬運判據保持不變。主動釋放後,失去手指接觸反而是預期動作,不能繼續把它當作同一種抓取故障。

2. 先把恢復關閉,隔離這一個問題

本輪不疊加E6的恢復與重新規劃。三種策略使用同一固定時間表、同一初始狀態和同一報警後動作:鎖存停止,保持報警時的致動器目標,後續不恢復。

這樣可以檢查監測範圍與判據,而不讓不同恢復路徑重新改變階段時長。它是一輪獨立消融,不是聲稱完整E6控制器已經升級並通過回歸。

策略 搬運監測 下降監測
僅搬運 transfer-only 完整搬運判據 不監測
照搬 reuse-transfer 完整搬運判據 完整搬運判據,包括高度
分階段 phase-aware 完整搬運判據 雙指接觸、距離、年齡;不要求搬運高度

三者都在計劃的主動釋放階段結束抓取監測。釋放後的狀態仍由最終放置驗收檢查,但沒有實現獨立的釋放安全監測。

核心差異在程式碼里很短:

contact = {"left_pad", "right_pad"} <= set(packet["contacts"].split("|"))
retained = contact and packet["grasp_error"] < self.error
height_required = phase == "transfer" or self.policy == "reuse-transfer"
return retained and (not height_required or packet["cube_z"] > self.height)

判據只讀取傳入的觀測包,不直接訪問物理引擎。觀測來自MuJoCo真值,這與相機識別、觸覺估計或真機傳感器不同。

3. 21個回合具體怎么跑?

七個條件各跑三種策略,每格一次確定性執行,無隨機種子。這不是用21個獨立隨機樣本估計泛化成功率。

項目 本輪設置
環境 Windows 11、Python 3.12.14、MuJoCo 3.3.7、NumPy 2.2.6
物理/控制步長 2ms
觀測取樣周期 20ms
搬運 / 下降 / 主動釋放 4.0–5.5s / 5.5–6.5s / 6.5–7.2s
回合終點 9.2s,包含撤離和穩定階段
抓取異常確認 連續壞取樣的捕獲跨度至少40ms
新鮮度門檻 最新接納取樣年齡達到60ms即報警
報警後的動作 從下一控制步開始保持目標;沒有恢復

七條件分別是:無故障;4.8s搬運鬆爪;5.6s下降早期鬆爪;6.2s下降後期鬆爪;5.6s起下降丟包;同一時段重送故障前舊包;5.6s的一次空接觸報告。鬆爪、丟包和重送持續240ms,空報告窗口20ms,只影響一個取樣。

鬆爪故障只把夾爪致動器目標改為打開,不改寫方塊位置。故障窗口結束後,恢復該策略當時的夾爪目標。因此即使已停住平移,原來的閉爪目標仍可能重新施加。這一點會解釋後面的失敗。

MuJoCo的控制向量與物理狀態是不同層次;改變致動器目標後,接觸與運動仍由模擬推進。可對照官方模擬循環說明及位置致動器定義。保持目標不等於把物體凍結在空間中。

4. 正常下降:規則本身制造了誤報

正常條件下,照搬策略在5.962s出現第一份不滿足高度條件的取樣,40ms後,於6.002s停止。此刻實際紀錄是:

物理量 記錄
方塊中心高度 110.687mm
方塊與夾爪中心距離 7.874mm
手指接觸 左、右兩指都有
觀測年齡 0ms,剛捕獲的新包

不是通信過期,也不是接觸丟失。它正確執行了一條放錯階段的規則。 最後方塊仍懸在夾爪中,未進入主動釋放,也未通過放置驗收。

分階段策略和僅搬運策略沒有報警,正常回合的狀態與控制軌跡完全一致。這裡支持的結論是:在本場景的正常下降中,移除搬運高度條件避免了這次誤停;不是所有高度約束都應該刪除。

正常下降中照搬策略在6.002秒誤停;早下降鬆爪後三種策略的方塊都落向托盤。叉號為首次停止,陰影為計劃下降階段

圖來自實際控制紀錄。部分曲線重合;右圖方塊下降並不等於按計劃完成了主動釋放。

5. 方塊進了托盤,為什麼仍不能說過程正確?

早下降鬆爪條件中,三種策略的最終放置都通過。但僅搬運策略完全沒有監測下降,不曾報警;另外兩種策略在5.642s檢出接觸異常,隨後保持目標,方塊仍因重力落進了下方托盤。

若只匯總“成功次數”,這三種明顯不同的過程會被記成一樣。最終放置驗收只能回答:末尾0.5s是否在目標範圍、靜止、沒有手指接觸,而且此前曾抬升;它沒有要求方塊必須以計劃動作落地,也沒有衡量碰撞沖擊。

這不是應該偷偷調整驗收規則、讓結果更漂亮的理由。原規則和原結果都保留,再把缺失的過程要求寫出來,才知道下一輪要驗證什麼。

6. 晚下降:報警正確,停止動作仍有問題

6.2s強制鬆爪時,分階段策略在6.242s停止。到9.2s末尾,方塊已經接觸托盤底部,但仍同時接觸左右兩指,不滿足“無手指接觸”的放置條件。

紀錄顯示,夾爪停止在較低位置;240ms鬆爪故障結束後,保持的閉爪目標重新施加,留下殘余手指接觸。這不是經過設計的重新抓取,也不能寫成“系統成功救回了物體”。本輪記錄的接觸和目標支持這個解釋,但沒有額外測量接觸力或證明所有碰撞過程。

反過來看照搬策略,它在6.002s就因為高度條件誤停,早於6.2s故障,之後方塊反而落入托盤並通過驗收。不能把這個更早的停止算成“更快檢出鬆爪”。

同一張結果表里,一個策略誤報後最終通過,另一個策略正確報警後最終未通過。所以監測判斷與退出動作必須分別評估,不能只用終點結果替它們排序。

7. 丟包和重送:到達時間不能替代捕獲時間

下降丟包與重送舊包時,分階段策略都在5.642s報警。最新接納取樣來自5.582s,年齡恰好60ms。重送條件中的12份舊包雖然到達了,卻不滿足序號和捕獲時間同時遞增的要求,因此沒有刷新年齡。

下降丟包和舊包重送時,最新接納取樣年齡持續增加,分階段策略在60毫秒門檻停止;故障結束後年齡恢復但停止不自動解除

這裡有兩個不同的時間量:壞取樣確認跨度是40ms,年齡門檻是60ms。丟包從5.600s的命令步開始,第一份故障後步末取樣原應在5.602s;5.642s報警距該步末時刻40ms,卻距最新好取樣60ms。報告延遲時必須說明起點。

在一次空報告條件中,分階段策略下一次就收到正常取樣,壞跨度被清除,沒有停機。照搬策略後來仍在6.002s誤停,原因是高度,不是那份已經恢復的空報告。

8. 完整矩陣:不要只看最後一列

單元格分別記錄“首次停止 / 最終放置”。“不停止”表示沒有報警,不等於已驗證過程安全。

條件 僅搬運 照搬 分階段
正常 不停止 / 通過 6.002s抓取 / 未通過 不停止 / 通過
搬運鬆爪 4.842s抓取 / 未通過 4.842s抓取 / 未通過 4.842s抓取 / 未通過
下降早鬆爪 不停止 / 通過 5.642s抓取 / 通過 5.642s抓取 / 通過
下降晚鬆爪 不停止 / 通過 6.002s誤停 / 通過 6.242s抓取 / 未通過
下降丟包 不停止 / 通過 5.642s過期 / 未通過 5.642s過期 / 未通過
下降舊包重送 不停止 / 通過 5.642s過期 / 未通過 5.642s過期 / 未通過
一次空報告 不停止 / 通過 6.002s誤停 / 未通過 不停止 / 通過

兩個下降鬆爪條件中,分階段策略從首個故障後取樣到停止均為40ms。本矩陣沒有證明增加監測提高了放置成功率;它暴露的是舊監測範圍的空缺、機械復制判據的誤報,以及保持動作的不足。

9. 怎樣核驗與復現?

執行程式碼與協議先提交,再運行21格;manifest記錄干凈工作區、版本和來源指紋。獨立審計器不導入監測器或MuJoCo,從記錄重算:

  • 105份逐回合檔案與10份原始碼/協議指紋。
  • 故障窗口、實際接收包、舊包丟棄、取樣年齡與壞取樣跨度。
  • 停止時刻、下一步保持目標、最終放置和主動釋放是否進入。
  • 七條件各三對策略,共21組首次決策分歧前的狀態/控制前綴。

13項監測測試與8項證據審計、篡改檢出測試通過。篡改測試只修改臨時副本中的目標、觀測、事件、狀態或結果,確認審計會報錯;不改變原始證據。審計檢查記錄一致性,不重算全部接觸力,也不替代對模擬器的驗證。

從工程根目錄審計已歸檔資料:

python experiments/vl01_phase_contracts/audit.py evidence/phase-contracts-20261001
python -m unittest discover -s experiments/vl01_phase_contracts -p test_monitor.py -v

重跑時使用沒有存在過的目錄,避免覆蓋歷史;運行前提交原始碼和協議,使manifest記錄可復現版本。虛擬環境需使用上述MuJoCo版本。

python experiments/vl01_phase_contracts/run.py --out runs/e7-my-run
python experiments/vl01_phase_contracts/audit.py runs/e7-my-run --out runs/e7-my-run/audit.json
python experiments/vl01_phase_contracts/plot.py runs/e7-my-run --out runs/e7-my-run/figures

control.csv保留每2ms的決策依據,states.jsonl與trajectory.csv每20ms保留物理取樣。events.json查首次停止,summary.json查逐格驗收。完整測試的 E7_EVIDENCE 設置方法見工程說明。

10. 下一步:先定義停止之後做什麼

接下來最值得做的不是增加更多監測閾值,而是分別定義:下降故障後的退出動作、主動釋放後的狀態要求,以及恢復次數或冷卻約束。保持、受控釋放、撤離可能產生不同後果,應凍結各自前提,再用同樣故障時刻對照。

本輪仍使用固定時間表決定階段、單一時鐘與模擬真值,沒有視覺、ROS2、學習策略、真機或全任務安全證明。完整VL01及M4/M5繼續保持未完成。已有證據支持的改進很具體:規則要隨階段解釋;報警、動作和終點驗收,要各自留下證據。

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

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

繼續探索

繼續探索

  1. 工程案例

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

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

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

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

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

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

    E7 / 下降階段的抓取契約

    搬運規則直接延伸到下降,會漏報、誤報還是改變最終放置?

    已完成
  4. 專案 / 003

    Hohoo 具身實驗

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

    實驗中

接下來,走哪條路?

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

← 全部文章