← 回專案總覽與驗證系統
第三支手臂:FT5425BL 標準舵機(B1 尺寸、B2 CAD、B3 URDF/MJCF、B4 模擬)
扭矩預算用「維持與 SG90 相同的扭矩佔比」把伸距外推到 306 mm。 實際把靜力算一遍——那個伸距空載就用掉連續額定的 88%。 問題不在算術,在於那個「相同的佔比」本身指的是什麼。
#48 第一支手臂的設計上限其實在連續工況之外 靜默
本頁一直寫著:「用 50% 堵轉當設計上限而不是 100%……以這個標準看, 這支手臂的機構尺寸對 SG90 是合適的,不是勉強。」
做第三支手臂時查到 FT5425BL 的資料同時給了堵轉與額定 (28.5 / 9.5 kg·cm,比值 3.0)。把同樣的比值套回 SG90:
SG90 堵轉 0.176 N·m → 連續約 0.059 N·m
第一支手臂最壞姿態 0.0788 N·m
= 44.7% 堵轉
= 約 134% 連續額定
也就是說,那個「50% 堵轉」的設計上限,本身就在連續工況之外。 第一支手臂撐得住,是因為它只有 70 g 的動件、酬載 4 g, 而且沒有人要求它保持同一個姿勢一小時。
這句話沒有算錯,但它把一個相對標準說成了絕對結論。 「以這個標準看是合適的」——而那個標準是我自己訂的, 訂的時候手上沒有任何一顆馬達的連續額定值可以對照。
影響:第一支手臂不改(它能動,而且用途是展示與教學); 但第三、第四支手臂改以連續額定為基準, 四支手臂的對照報告會把兩種基準並列,不會混在同一欄。
B1 決策:直接驅動,伸距 190 mm
先驗證「標準舵機該不該像 NEMA 17 那樣做成遠端驅動」。 A1 之所以把步進馬達移到底座,是因為它 280 g、是 SG90 的 31 倍。 FT5425BL 只有 67.6 g:
| 酬載 | 直接驅動 | 遠端驅動 | 買到多少 |
|---|---|---|---|
| 100 g | 190 mm | 252 mm | +33% |
| 200 g | 143 mm | 182 mm | +28% |
| 500 g | 不可行 | 80 mm | — |
兩顆舵機只佔靜態力矩的一小部分(306 mm 時 0.31 N·m 中的 0.11 N·m), 遠端驅動只買到 28–33% 伸距,卻要付出兩組同步帶、張緊機構與背隙。 標準舵機留在關節上是對的——這是算出來的,不是照慣例假設的。
| B1 定案 | 值 |
|---|---|
| 傳動 | 直接驅動,每個關節一顆 |
| 伸距 | 190 mm(上臂 105 / 前臂 85) |
| 設計酬載 | 100 g |
| 肩關節力矩 | 0.651 N·m = 69.9% 連續額定、23.3% 堵轉 |
| 舵盤索引 | 25T → 14.4°/齒(整齒約束,同 SG90 的 21T) |
與第一支手臂對照,這才是有意義的比較:
| 手臂 | 伸距 | 酬載 | 扭矩依據 |
|---|---|---|---|
| SG90 | 202 mm | 4 g | 44.7% 堵轉(≈134% 連續) |
| FT5425BL | 190 mm | 100 g | 69.9% 連續額定 |
不是「標準舵機做出更短的手臂」——是伸距相當、酬載 25 倍, 而且待在連續工況內。
B2 CAD:直驅關節的三件事佔同一塊空間
直驅關節有三個東西在同一個位置:舵機、 夾住它的叉臂(屬於下連桿)、 被舵盤帶動的輪轂(屬於上連桿)。 第一版把上連桿畫成從關節軸開始的實心樑,於是三者重疊—— 算圖出來是一根融成一體的柱子,完全看不到關節。
| 問題 | 症狀 | 根因 |
|---|---|---|
| 拓樸重疊 | 算圖是一根柱子 | 三個實體佔同一空間 |
| 前臂裂成 3 個實體 | T0 會擋 | 耳片沒包過關節軸就合攏,跨接槽從端面切穿 |
| 包絡 66.6 而非 40.0 | 沒有斷面有這個寬度 | loft 預設是樣條,斷面突降時外凸 |
| 八個螺栓孔僅 79% 材料 | T10 擋下 | Cylinder 第一個參數是半徑,Ø9 寫成了 Ø18 |
參數掃描:耳片再厚也沒用
T10 報「八個舵盤螺栓孔只有 2 mm 要求的 79%」。 直覺是耳片太薄,於是把耳片厚度從 3.90 加到 6.0、再加到 10.0—— 三次都是 79%。
| 改動 | 結果 |
|---|---|
| 耳片 3.90(基準) | 最低 79%(8 孔) |
| 耳片 6.0 | 最低 79%(8 孔) |
| 耳片 10.0 | 最低 79%(8 孔) |
| 螺栓圓移到 R=13 | 通過 |
| 孔徑縮到 Ø2.2 | 通過 |
後兩列才指出約束是徑向的、不是壁厚。
追進去發現 Cylinder(9.0, 200.0) 的第一個參數是半徑:
我要的是 Ø9 的舵盤讓位孔,實際做出 Ø18,
螺栓孔緣離孔壁只剩 0.61 mm。
不掃參數的話,我會一路加厚耳片而永遠修不好。 「猜一個原因去修」和「量哪個變數真的驅動這個數字」是兩件事。
三個拍出來的數字改為由約束推導
| 常數 | 原本 | 改為 |
|---|---|---|
HUB_H | SB_L*0.85 = 34.51 | 跨接槽 + 2×(螺栓半徑 + R7 邊距) = 35.80 |
END_SOLID | 20.0(硬寫) | 輪轂伸出 + 螺栓位置 + 邊距 = 40.0 |
HORN_BOLT_R | 8.0(硬寫) | 由舵盤孔直徑推導 = 7.85/軸 |
驗證結果
| 層 | 結果 |
|---|---|
| T0 幾何完整性 | 8/8(2 項跳過:尚未產出網格與連桿屬性) |
| T8 可組裝性 | 5/5(螺絲起子伸得到、無干涉) |
| T10 可列印性 | 5/5 |
接上 ArmBundle 只花了三行——這正是當初做那層抽象的目的。
實測質量回推,B1 的尺寸站得住
| 項目 | 質量 g | 力臂 mm | 力矩 N·m |
|---|---|---|---|
| upper_arm | 79.0 | 42.6 | 0.033 |
| forearm | 65.3 | 133.9 | 0.086 |
| j3 舵機 | 67.6 | 105.0 | 0.070 |
| j4 腕舵機 | 67.6 | 190.0 | 0.126 |
| 夾爪 | 50.0 | 190.0 | 0.093 |
| 酬載 | 100.0 | 230.0 | 0.226 |
| 肩關節合計 | 0.633 | ||
67.9% 連續額定(B1 用估計質量算的是 69.9%)。 實測連桿比估計重 10%,但質心比「連桿中點」的假設更靠內 (上臂 42.6 mm 而非 52.5),兩者相抵之後比原估計還好一點。空載 43.7%。
B3 URDF/MJCF:極限有兩個作者
NEMA 17 那支的關節極限只有一個來源——步進沒有自身行程,機構就是極限。 這支相反:舵機有硬性的 180°,怎麼樣都過不去。 所以每個關節的極限是兩個獨立約束的交集:
| 關節 | 機構掃描 | 舵機行程 | 生效 | 綁住的是 |
|---|---|---|---|---|
| j1 迴轉 | ±150° | ±90° | ±90° | 舵機 |
| j2 肩 | ±75° | ±90° | ±75° | 機構 |
| j3 肘 | ±95° | ±90° | ±90° | 舵機 |
取交集不是重點,記錄「哪一邊綁住」才是——兩者的意思相反: 機構綁住代表改幾何可以放寬;舵機綁住代表幾何幫不上忙, 只能重新索引舵盤,而那是拿一端換另一端。 只報一個數字而不說是誰造成的,就會有人去加厚一面牆, 想買一段舵機本來就不會給的行程。
#49 掃出來的肩關節行程是 0°——連續三次,三個不同原因 已修正
掃描把實體轉到干涉為止。前三次跑出來的肩關節範圍是 [+5, −5](負寬度)、然後 [0, 0]、再一次 [0, 0]。 每一次都是不同的原因,而且每修好一個才看得見下一個:
| 第幾次 | 根因 |
|---|---|
| 一:[+5, −5] | 跨接槽用叉臂的半邊長(23.9)挖, 註解卻寫「half-diagonal」——真值是 29.7,叉臂角落卡在輪轂實心區 |
| 二:[0, 0] | 零位就相交 4667 mm³: 舵機截面的 X/Y 寫反了(舵機 40.6 在 X、20.0 在 Y, 我寫成 X=26.8 裝不下、Y=46.6 撞耳片) |
| 三:[0, 0] | 耳片往下伸 34.3,旋轉時最低點掃到軸下 41.5, 而肩軸只在轉盤面上 36——耳片掃到圓盤 |
共通點:這三個數字全是我拍的,不是從它們要配合的東西推導出來的。 改成推導之後:
YOKE_R = √((SB_L/2+WALL)² + (SB_H/2+WALL)²) 叉臂在輪轂座標系掃出的圓盤 HUB_REACH = YOKE_R + 間隙 + 4 耳片必須包過那個圓盤 HUB_SWEPT_R = √((SB_L/2+WALL)² + HUB_REACH²) 耳片自己掃出的半徑 Z_J2 = 轉盤面 + HUB_SWEPT_R + 1.5 肩軸高度
還有一個結構認知的錯誤:我把耳片在關節下方也接起來, 於是叉臂沒有路徑往下接回轉盤——轉盤因此變成 3 個分離的實體。 真實的伺服 U 型接頭是在舵機上方合攏、下方留兩片自由板, 把跨接槽加上向下的開口才對。
#50 docstring 宣稱了 MuJoCo 做不到的事 靜默 已修正
MJCF 產生器的說明寫著速度上限「以關節速度限制放進去」。 MuJoCo 沒有關節速度上限這種東西,而程式也確實沒寫進 XML—— 那句話是一個只存在於散文裡的限制。
0.08 s/60° = 13.1 rad/s,在 190 mm 的手臂上是尖端 2.5 m/s。 忽略它,模擬就會允許手臂做出舵機做不到的動作。
修法:說清楚 MuJoCo 放不下,改由 B4 的模擬迴圈執行——
和步進的發步率上限放在同一個地方。並在 B3 加一條檢查驗
MAX_RADPS 有被匯出,因為只寫在註解裡的限制等於不存在。
B3 驗證層(27 項,變異測試 5/5)
刻意把幾條拆成兩句話,因為「數字對」和「關係對」不是同一件事:
- 極限 = 交集 以及 極限不超出任一來源 ——後者在「兩邊用同樣的錯誤算法」時仍會擋下
- forcerange = 連續額定 以及 forcerange ≠ 堵轉值 ——若哪天有人把 0.932 改標成堵轉,只驗前者不會發現
- 「綁住的是誰」必須與它宣稱總結的兩個範圍相符——過期的欄位比沒有更糟
B4 模擬:伺服的失效不是漂移,是「一直撐著然後燒掉」
步進手臂問的是「有沒有失步」。伺服問不出這個問題——它永遠知道自己在哪。 它的失效安靜得多:撐住、繼續撐、過熱。 所以這一層報的是工作時率,不是漂移。
#51 我把關節速度夾在額定值,藏掉了最該報告的事件 靜默 已修正
#50 說速度上限要在模擬迴圈裡執行。第一版夾在設定點的迴轉速率,
關節本身仍衝到 14.21 rad/s(資料表的 109%)。於是我改夾關節速度——
先夾在 mj_step 之後(沒用,位置已經走完了),
再移到之前。三次都沒對。
追進去看那一刻發生什麼,才發現方向根本錯了:
k=744 肩 -75.13° nefc 0
k=745 肩 -75.36° nefc 1 ← 越過機構極限 -75°,約束啟動
肘速度單步 -9.86 rad/s(≈9863 rad/s²,是致動器上限 913 的十倍)
(ncon 是接觸數;關節極限在 MuJoCo 裡是約束,
不出現在那裡。查錯欄位讓我多繞了一圈。)
那不是舵機在驅動,是手臂撐不住、被重力反驅動、然後撞進極限, 衝擊把前臂甩到 21.7 rad/s。
0.08 s/60° 限制的是舵機能驅動多快,不是別人能對它做多快。 夾住關節速度會把整件事抹掉——而那正是這次模擬最該講的事。 改成分開報「自由運動速度」與「含撞擊速度」,並在撞到極限時明講。
#52 資料表的速度在這支手臂上不能用 已納入設計
照資料表 13.09 rad/s 下指令,酬載 100 g 時:
| 指令速率 | 佔資料表 | 肩峰值 | 佔額定 | 撞極限 | 追蹤誤差 |
|---|---|---|---|---|---|
| 13.09 rad/s | 100% | 0.951 | 102% | 是 | 48.7° |
| 6.54 rad/s | 50% | 0.553 | 59% | 否 | 20.0° |
| 3.27 rad/s | 25% | 0.515 | 55% | 否 | 8.4° |
| 1.31 rad/s | 10% | 0.514 | 55% | 否 | 4.1° |
60° 的肩部動作以滿速下達,會過衝 15° 撞進 −75° 的機構極限, 而且拉到連續額定的 102%。減半就完全不撞,扭矩掉到 59%; 再減到 1/4 幾乎沒有額外好處——50% 就是那個轉折點,是量出來的不是挑的。
這是伺服版的「datasheet 300 rpm 韌體開不出來」: 0.08 s/60° 是空載值,帶著 190 mm 手臂根本跑不到。 B5 的韌體必須限速到這裡。
靜態保持 vs 動態運行:兩個不同的酬載上限
| 問題 | 答案 |
|---|---|
| 空載靜態最壞姿態 | 0.401 N·m = 43% 額定(肩 −75°、肘 −10°) |
| 能保持的酬載上限 | ≈ 235 g |
| 能運行的酬載(滿速) | < 50 g(過衝就撞極限) |
| 能運行的酬載(限速 50%) | 100 g 用 59% 額定 |
「撐得住」和「動得了」是兩個數字,而且差 4 倍以上。 B1 的靜態預算算的是前者——同 #34 那一類: 受限集合的最大值不是可達集合的最大值。
B4 驗證層(10 項)
刻意把「限速有效」拆成三條:會撞極限、限速後不撞、以及扭矩顯著下降。
只驗最後一條的話,一個把限速寫成無效的模型仍會通過。
另外驗「read() 回報的是指令不是軸位置」——
四支手臂裡只有 DM-J4310 報得出真實位置,模型不可以假裝別的做得到。
這支手臂的尺寸是暫定的,而且程式會一直這樣說
上面每一個數字都建立在「額定 9.5 kg·cm」上,
而那個值只有單一經銷商來源,且剛好是堵轉的 1/3。
sizing_ft5425bl.py 每次執行都會印出
BUDGET_UNVERIFIED_BASIS 並說明:真值若是堵轉的 1/4,
伸距要再縮約 10%。
不擋住工作,但也不讓「沒驗證」這件事悄悄消失—— 這跟 #44 那個裝飾了一整段時間的旗標是同一個教訓。