試みたアプローチ(クリックで詳細)
01
anchorRotation
補正
CCD IK修正
✗ 成功率0
02
SetJoint
Positions
物理バイパス
✗ 発振・成功率0
03
ikpy
解析IK
Python外部計算
✗ 座標系ズレ
04
1ジョイントずつ
逐次更新
CCD IK改善
✗ 成功率0
05
確認済み姿勢起点のFKスキャン ← 正解
IK不使用・FK直読み
✓ 481点取得成功
01 — anchorRotation補正
全ジョイントに Anchor Rotation Z=270° が乗っていたため、jt.right(TransformのX軸)とArticulationBodyの実際の回転軸がズレていた。anchorRotation を読み取り専用で参照してワールド空間の回転軸を正しく計算した。方向性は正しかったが、物理遅延の根本問題は解決されなかった。
02 — SetJointPositions
ArticulationBody.SetJointPositions() + Physics.SyncTransforms() で物理エンジンを完全バイパスし、角度を瞬時にセットする。物理遅延問題は解消された。しかし全関節の補正量をまとめて計算してからセットする設計だったため、各ジョイントの計算が干渉して発振が起きた。maxAngleStep=5° に上げたことでさらに悪化した。
03 — ikpy解析IK
URDFから ikpy.chain.Chain を構築し、目標座標→関節角度を数学的に計算。1,066点全点で ik_success=1 が返ったが、実機確認済みPICK角度と比較したところ全関節で大きくズレていた(j0: 実機-46.93° vs ikpy 151.6°)。mechArm 270のURDFとUnity/実機の座標系が異なることが原因。
04 — 1ジョイントずつ逐次更新
1ジョイントの角度を計算 → 即座にSetJointPositions → Physics.SyncTransforms → 次のジョイントへ、という順次処理に変更。発振は解消されたが成功率0は変わらなかった。CCD IKが局所最適解に陥る構造的な問題は、実装の改善では解決できない段階に達していた。
05 — 確認済み姿勢起点のFKスキャン(正解)
LOG137で実機確認済みのPICK角度 [-46.93, 102.74, -43.33, 3.6, -60.11, -30] を起点に、j0(±90°)とj1(±30°)を5°刻みでグリッドサーチ。各角度をSetJointPositionsでセットし、endEffector.transform.position を直接読む。IKを解く必要がない。UnityのFKがすでに正確な答えを計算している。
基準データとの照合(motion_log_fk.csv)
| ステップ |
LOG149実測 EE-X |
LOG150取得 EE-X |
差分 |
| HOME |
0.0000 |
0.0000 |
±0.000 |
| PICK |
0.1609 |
0.1604 |
±0.001 |
| PLACE |
−0.1363 |
−0.1361 |
±0.000 |
LOG149でMotionLogPlayerを使って実測したEndEffector位置と、LOG150のGridAngleScannerMotionLogモードで取得した値がほぼ一致した。
SetJointPositions + Physics.SyncTransforms による瞬時セットが正しく機能していることの検証になった。