Force mode × CCD IK
構造的非互換の解剖
drive.target の「意味」がモードによって変わる。それが発散の根本原因だ。
01 — モードを選んでシミュレーション
Mode A
TARGET MODE
drive.target = 到達したい角度
Unity が自動でそこへ向かう
✓ 動く
Mode B
FORCE MODE
drive.target = トルクの基準点
乖離が大きいほどトルク増大
✗ 発散
TARGET MODE — シミュレーション
frame: 0/200
drive.target
jointPosition
乖離
drive.target
0.0°
jointPos
0.0°
乖離
0.0°
トルク ×1k
0
▶ 再生
↺ リセット
jointPos がほぼ追従する
FORCE MODE — シミュレーション
frame: 0/200
drive.target
jointPosition
乖離(発散)
drive.target
0.0°
jointPos
0.0°
乖離
0.0°
トルク ×1k
0
▶ 再生
↺ リセット
乖離が爆発的に拡大していく
02 — なぜ合わないのか
drive.target の意味がモードで変わる
TARGET MODE
✓ OK
drive.target =
到達角度
Unity が自動でそこへ向かう
Stiffness = 1e+25(内部固定)
FORCE MODE
✗ NG
drive.target =
トルクの基準点
差が大きいほどトルクが増大
Stiffness = 設定値が直接効く
Force mode のトルク計算式
トルク = Stiffness × ( drive.target − jointPosition )
// 乖離 × 20,000 = トルク
乖離が 117° のとき ——
20,000 × 117° =
2,340,000 N·m
のトルクが発生。
これが「爆発的トルク」の正体。
CCD IK の書き方と各モードの相性
drive.target
+=
angle * speed;
// 毎フレーム累積加算 — これが問題の核心
TARGET MODE
✓ 動く
target が少しずつ増える
→ 目標角度への段階的接近
→ 自然に収束する
FORCE MODE
✗ 発散
target が累積し続ける
→ jointPos との乖離が爆発
→ 異常トルク発生
解決するには IK アルゴリズムごと変える必要がある
// Force mode に合う書き方
target_angle =
IK_solve();
// ← 解析的IK / Jacobianベースで一気に計算
drive.target = target_angle;
CCD の「少しずつ積み上げる」ではなく、目標角度を一度に計算してセットする方式が必要。
実機展開時は
ROS + MoveIt
がこれを担う。
03 — 問題の構造まとめ
原因
CCD IK
+= 累積
→
Force mode
target の
意味が違う
→
結果
乖離
爆発
→
解決
Target mode
維持
→
実機
ROS +
MoveIt