19 · 調參實驗的方法論:讓每一輪機時都產生證據
前面各篇講「參數是什麼、怎麼設、什麼時候生效」。這一篇講另一半:怎麼設計實驗,才能從有限的模擬機時裡得到站得住的結論。素材來自一段連續數週的 6.0 場景調校(堆高機取放棧板的間歇性失穩),裡面每一條都對應至少一次「用錯方法燒掉數小時機時」的實例。
適用範圍不限 Isaac Sim——任何「改一個旋鈕、跑一輪要十幾分鐘、結果帶隨機性」的系統都適用。但物理模擬把三個難點集齊了:單輪時間長、失敗有多種模式、而且旋鈕設下去可能根本沒生效(見 17 篇)。
1. 先問「這個旋鈕接上了嗎」——極端值正對照
在投入任何多輪比較之前,先做一件事:把旋鈕轉到極端值,確認行為有肉眼可見的差異。
正常實驗:摩擦 5.0 vs 4.0,跑 20 輪比統計 ← 還不要做
正對照: 摩擦 0.01 → 棧板應該整顆滑掉 ← 先做這個,一輪就夠
兩個實測案例,一正一反:
- 摩擦綁定:壓到 0.01,棧板從叉齒上整顆掉地上——旋鈕接上了,值得往下測。
- 剛體速度上限:設極端值後行為完全沒變——後續查明 runtime 授權的剛體屬性 PhysX 根本不採用(17 篇 §2.5)。 在那之前,已經有 40 輪實驗把「限速」當成有效變因在比較——那 40 輪裡這個變因 從來沒被施加過,所有「限速無效」的結論都是空的。
正對照失敗的處置寫在實驗計畫裡,而且要事先寫:「極端值沒有可觀測差異 → 整條路線作廢」。這一條在底盤驅動實驗裡真的觸發過一次(max_yaw_rate_deg 降到 1/5、單次轉向耗時完全重疊),當場省下了預計 5 小時的 A/B。
⚠ 極端值要挑「會改變可觀測行為」的方向,不是「數值有寫進去」。回讀成功不是證據——USD 層讀回來的值跟物理引擎實際吃到的值是兩回事。
2. 耦合參數要一起動——PD drive 的教訓
官方 DriveAPI 的力公式(OpenUSD UsdPhysicsDriveAPI):
force = stiffness × (targetPosition − position) + damping × (targetVelocity − velocity)
(超過 maxForce 就截斷;inf = 不限)
增益(stiffness/damping)是在力無上限的前提下調出來的。只把 maxForce 砍下來,阻尼項跟著被截斷,控制器失去煞停能力,定位收不斂——實測兩輪全部停在移動階段逾時,而且「沒觀測到失穩」這個結果是空的:不是不失穩,是車根本沒開始做事。
正解是等比例:stiffness、damping、maxForce 同乘一個係數 s。因為 a = F/m,這等於把整個軸的加速度能力均勻縮放 s,速度剖面形狀不變。等比例 ×1/10 實測功能完整,時間線與基線幾乎重合。
通則:改 A 之前先問「A 的現值是在什麼前提下調出來的」。 前提裡有 B,就要 A、B 一起動。這是柵欄原則的量化版。
2.1 功能包絡:每一檔要用完整工作負載驗,不是單一動作
等比例 ×1/10 用「一趟取貨」煙霧測試通過了,投入 16 輪批次後才發現: 完整循環裡其他形狀的路徑段(貼近層架的短段、從中途位置起步的 mission) 有 3/8 的機率被控制器中止——PD 穩態誤差 ∝ 1/stiffness,而 settle 容差是固定的, 縮放 10 倍後部分段落剛好踩線。「大部分能動、偶爾中止」比「一動就死」危險: 前者會混進批次數據,把功能缺陷偽裝成實驗雜訊。
兩條配套:①掃描的「動作有沒有完成」閘門要跑完整工作負載,單一動作只證明 最簡單的形狀在包絡內;②發現某檔有這種 disqualifying 缺陷時,為它累積樣本的 批次可以當場中止——實用答案已經是「不用它」,省下的機時拿去測還在候選內的檔 (實測這一刀省了 4.5 小時)。批次在跑不代表分析要停,中止的依據常來自批次外的 事後分析。
3. 比較的單位要「同工作量」——總時長是混淆的
降低轉向速率上限後,「整輪 yaw 有變化的時間跨度」從 142 秒變成 540 秒,3.8 倍,看起來完全支持「轉彎變慢了」。但那輪跑到了階段 ③,對照輪停在階段 ②——走的路本來就不一樣多。 換成「單次轉向動作的耗時」之後,差異完全消失(參數其實沒被那條路徑吃進去)。
比較「總量」類指標(總時長、總位移、總失敗數)之前,先確認兩邊做的事一樣多。跑得遠的輪次什麼總量都大,而那與旋鈕無關。
4. 二元判準是統計陷阱——找連續量
「這一輪過/沒過」一輪只產 1 個 bit。基礎失敗率 30% 的系統,要偵測「某改動把它砍半」需要每組約 121 輪——以單輪 20 分鐘計是 40 小時。這不是理論題,是實際燒掉三組各 10 輪(4 小時)之後,回頭算檢定力才發現 n=10 只能偵測「幾乎完全消除」等級的效果,10 輪批次之間的差異全是雜訊。
出路是找一個連續的中間量當判準。案例:放置失敗的判別式是「棧板在叉齒上的橫向滑移量」(mm)——成功輪 +14~+40、失敗輪 +55~+163,41 筆零重疊。連續量每輪產 3 個數值,而且在輪次跑完之前就能讀到,樣本效率比二元判準高一個量級。
配套紀律:
- 同期對照,不用歷史基線。 同一個量的歷史平均 +60.4、同期 OFF 臂平均 +29.5——差了一倍。環境會漂(場景版本、腳本修訂、時段),只有同期交錯的兩臂可比。
- 單輪落在成功區間不是證據。 OFF 臂也會偶爾出 −1 mm 的好輪次。
5. 逐輪交錯,不要「基線在前、實驗在後」
把 8 輪基線跑完再跑 8 輪實驗,任何在中途發生的漂移(重啟、資源狀態、場景污染累積)都會被讀成實驗效果。奇數輪 OFF、偶數輪 ON 逐輪交錯,四種混淆(重啟共線、時序漂移、時段效應、歷史對照不同質)一次消除,而且切臂成本通常是零(reset 本來就會重載組態)。
6. 每輪的閘門:這一輪真的在預期的組態嗎
長批次裡最貴的失敗形態:實驗在基線組態下跑完,毫無症狀。三個實測來源:
| 漏洞 | 實例 |
|---|---|
| reset 抹掉 runtime 授權 | 每輪開頭 reset 重載場景,開跑前下的授權當輪就消失——授權要在每輪 reset 之後重下,且從當輪 log 確認 |
| log 窗口沒限定本輪 | docker logs 不帶 --since 會匹配到上一輪的判定行,守門結構性失效 |
| 驗的是宣告不是生效 | 判準要用「生效證據行」(如 is_physics_material=True 的筆數),不是設定檔內容 |
閘門三件套,寫進批次腳本、每輪自動執行:①本輪 log 窗口確認臂別;②生效證據達預期筆數;③量到的輪數 = 跑過的輪數,少了就標記「不完整資料」。
7. 有效性閘門要在取樣之前
一批 4 輪全都在動作階段就失敗,但因為統計是在動作跑完後才數結果,得到的是 4 筆「無效」而不是 4 筆「沒觸發」。沒有這道區分,這批會被讀成「問題消失了」。每輪先判「這輪有沒有資格產生量測」,再判量測值;沒資格的輪次要單獨計數並回報,不能混進分母。
8. 抓低佔比的失敗模式,先算取樣成本
失敗模式分類後(32 輪:「沒放下」31%、「太淺」9%、其他),想針對 9% 的模式取 3 個樣本,期望要跑約 30 輪 ≈ 10 小時——而主導模式每 3 輪就送 1 個樣本。先攻主導模式不是偷懶,是取樣經濟學。 連續三輪為次要模式設計實驗都拿不到樣本之後,才回頭算這筆帳——帳應該在設計時就算。
9. 間歇性問題的宣告門檻是統計,不是連續幾次沒發生
基礎發生率 30% 之下,連續三輪乾淨的機率是 0.7³ ≈ 34%——什麼都不改也有三分之一的機會看到。實測踩過:靠三輪乾淨寫下「已解決」,後來被連續三輪打臉。宣告效果前先算:「如果什麼都沒變,看到這個結果的機率是多少」,並誠實面對基礎率本身是估計值(r=3/4 與 r=2/3 算出來的 p 差一倍)。
10. 指標要先拿去掃成功那一組
在某次失敗裡看到一個量先動、而且機制講得通 —— 這不足以讓它成為指標。 做進判準之前,先拿它掃成功的那一組。
實例:某次交接失敗的逐筆序列顯示棧板的 pitch 先翻(+0.48 → −0.08),
下一個取樣座位才掉。順序清楚、機制合理,於是「被載期間 pitch 有沒有翻過符號」
被做成前兆判準。掃全部歷史資料之後:18/18 趟都會翻,
包含八趟完全乾淨的交接;兩組的值域完全重疊。零鑑別力,而且會全部報紅。
⚠ 還有一個獨立的坑:那個「全距」被取樣密度污染 —— n 從 13 到 173, 取樣越密、觀察到的極值自然越極端。跨批次比全距本來就不成立。
🔑 單一事件的「時序」與可分類的「統計量」是兩回事,不可互換。 時序要看逐筆序列;統計量要有兩組的分布。
11. 每個經驗判準都要寫出適用範圍
判準是在某一組條件下校準的。條件變了它不會報錯,只會安靜地給錯的綠燈。
實例:一個「垂直座位落在 31~38 mm 就會乾淨交接」的窗口(n=17 全中), 是在放貨高度固定的前提下校準的,而文件沒有寫這個前提。 把高度降 21 mm 之後:座位 +33 落在窗口正中央、另一個前兆也正常, 交接仍然完全失敗,棧板整顆被載回。兩個既有前兆一個都沒示警。
寫判準時把校準條件寫在同一行,不要放在別處的背景說明裡。
12. 結論的標題要自帶樣本量與狀態
n 不夠這件事,通常寫在內文的 ⚠ 裡。問題是標題會被單獨引用、口頭結論會被當成定案。
實例:某個變因第一輪出現大幅移動、而基線四輪零變異,於是標題寫成 「X 確實是 Y 的旋鈕」,內文附註「n=1,要等確認輪」。 確認輪跑出來與基線每個量都無法區分 —— 第一輪是分岔抽到的。 內文的限制沒有阻止任何人(包括作者自己)把它當定案。
規則:確認輪回來之前,不要用「確實」「已查明」「根因」。 寫成「n=1 有大幅移動,確認中」。
13. 檢查清單
開跑一個多輪批次之前:
- [ ] 旋鈕做過極端值正對照,且「無差異 → 路線作廢」寫在計畫裡
- [ ] 有耦合的參數等比例一起動,不單獨砍一個
- [ ] 每一檔用完整工作負載驗過功能包絡(不是單一動作的煙霧測試)
- [ ] 記帳欄位在設計時想好事後要分哪幾類(輪次結局、量測值型別驗證)
- [ ] 判準是連續量;若只有二元判準,先算需要幾輪才有檢定力
- [ ] 逐輪交錯,不用歷史基線
- [ ] 每輪自動閘門:臂別確認(本輪 log 窗口)+ 生效證據 + 輪數對帳
- [ ] 有效性閘門在量測之前,無效輪單獨計數
- [ ] 低佔比模式先算取樣成本
- [ ] 比較用的量是「同工作量」的
- [ ] 中止條件事先寫好(哪一檔跑不動就不往下、極端值無差異就停)
- [ ] 指標拿去掃過成功那一組,確認它真的分得開(不是只在失敗組出現)
- [ ] 每個判準都寫出校準條件,而且寫在判準同一行
- [ ] 結論標題自帶樣本量;確認輪回來之前不用「確實/已查明/根因」
證據等級
本篇的方法論條目全部來自單一專案的實測(2026-07 至 08 的一段場域調校), 每一條至少對應一次「用錯方法燒掉數小時」的實例。方法可複用,數值不可照搬 ——輪數、門檻、樣本量都是那個場景的。
可公開查證的只有一項:joint drive 的 PD 公式,引自
OpenUSD UsdPhysicsDriveAPI。
其餘沒有官方出處,也沒有第二個獨立來源交叉驗證過。
內部回溯用(未公開):docs 147 檢定力計算、153 連續量判別式、155 正對照、 156 交錯 A/B 與歷史基線失效、157 失敗模式分類、158 等比例縮放與中止條件。