學習 / 實作
具身智能實踐(七):搬運規則,為什麼會誤停正常下降?
具身智慧 · 工程案例
21回合MuJoCo對照:下降需要自己的抓取契約。用正常誤停、舊包報警與晚下降殘留接觸,拆開監測範圍、停止動作和最終放置。
瀏覽統計暫不可用
本文目錄 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,剛捕獲的新包 |
不是通信過期,也不是接觸丟失。它正確執行了一條放錯階段的規則。 最後方塊仍懸在夾爪中,未進入主動釋放,也未通過放置驗收。
分階段策略和僅搬運策略沒有報警,正常回合的狀態與控制軌跡完全一致。這裡支持的結論是:在本場景的正常下降中,移除搬運高度條件避免了這次誤停;不是所有高度約束都應該刪除。
圖來自實際控制紀錄。部分曲線重合;右圖方塊下降並不等於按計劃完成了主動釋放。
5. 方塊進了托盤,為什麼仍不能說過程正確?
早下降鬆爪條件中,三種策略的最終放置都通過。但僅搬運策略完全沒有監測下降,不曾報警;另外兩種策略在5.642s檢出接觸異常,隨後保持目標,方塊仍因重力落進了下方托盤。
若只匯總“成功次數”,這三種明顯不同的過程會被記成一樣。最終放置驗收只能回答:末尾0.5s是否在目標範圍、靜止、沒有手指接觸,而且此前曾抬升;它沒有要求方塊必須以計劃動作落地,也沒有衡量碰撞沖擊。
這不是應該偷偷調整驗收規則、讓結果更漂亮的理由。原規則和原結果都保留,再把缺失的過程要求寫出來,才知道下一輪要驗證什麼。
6. 晚下降:報警正確,停止動作仍有問題
6.2s強制鬆爪時,分階段策略在6.242s停止。到9.2s末尾,方塊已經接觸托盤底部,但仍同時接觸左右兩指,不滿足“無手指接觸”的放置條件。
紀錄顯示,夾爪停止在較低位置;240ms鬆爪故障結束後,保持的閉爪目標重新施加,留下殘余手指接觸。這不是經過設計的重新抓取,也不能寫成“系統成功救回了物體”。本輪記錄的接觸和目標支持這個解釋,但沒有額外測量接觸力或證明所有碰撞過程。
反過來看照搬策略,它在6.002s就因為高度條件誤停,早於6.2s故障,之後方塊反而落入托盤並通過驗收。不能把這個更早的停止算成“更快檢出鬆爪”。
同一張結果表里,一個策略誤報後最終通過,另一個策略正確報警後最終未通過。所以監測判斷與退出動作必須分別評估,不能只用終點結果替它們排序。
7. 丟包和重送:到達時間不能替代捕獲時間
下降丟包與重送舊包時,分階段策略都在5.642s報警。最新接納取樣來自5.582s,年齡恰好60ms。重送條件中的12份舊包雖然到達了,卻不滿足序號和捕獲時間同時遞增的要求,因此沒有刷新年齡。
這裡有兩個不同的時間量:壞取樣確認跨度是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/figurescontrol.csv保留每2ms的決策依據,states.jsonl與trajectory.csv每20ms保留物理取樣。events.json查首次停止,summary.json查逐格驗收。完整測試的 E7_EVIDENCE 設置方法見工程說明。
10. 下一步:先定義停止之後做什麼
接下來最值得做的不是增加更多監測閾值,而是分別定義:下降故障後的退出動作、主動釋放後的狀態要求,以及恢復次數或冷卻約束。保持、受控釋放、撤離可能產生不同後果,應凍結各自前提,再用同樣故障時刻對照。
本輪仍使用固定時間表決定階段、單一時鐘與模擬真值,沒有視覺、ROS2、學習策略、真機或全任務安全證明。完整VL01及M4/M5繼續保持未完成。已有證據支持的改進很具體:規則要隨階段解釋;報警、動作和終點驗收,要各自留下證據。
寫給未來的自己合上文章前,留下一點自己的理解。
你的私人學習便箋,只存在目前瀏覽器,不會上傳或公開。清理瀏覽器資料會遺失,請匯出留存。三種語言共用這篇文章的便箋。
繼續探索
繼續探索
- 工程案例
具身智能實踐(六):恢復門控與路徑重規劃,各自解決了什麼?
30回合消融對照:重規劃把首次目標跳變從50–97毫米降至約0.25毫米,卻沒有提高本矩陣的放置成功率。用原始紀錄拆開恢復證據、動作連續性與任務結果。
接下來,走哪條路?
- 具身實作(四):訊息還在到,觀測已經過期了 →
45回合MuJoCo對照,分離取樣間隔、異常計數與觀測年齡;理解舊訊息為何掩蓋真實鬆爪,以及時間門檻仍有哪些限制。
- 具身智能實踐(六):恢復門控與路徑重規劃,各自解決了什麼? →
30回合消融對照:重規劃把首次目標跳變從50–97毫米降至約0.25毫米,卻沒有提高本矩陣的放置成功率。用原始紀錄拆開恢復證據、動作連續性與任務結果。
依據文章關聯與同主題已發布內容整理,不使用隨機推薦。