FixedJointで「掴む」を実装した
LOG91R2R2R2026/3/13

FixedJointで「掴む」を実装した

CCD IKでアームが動くようになったLOG90に続き、LOG91では「掴む」を実装した。

ロボットアームがコーヒーカップの位置に到達したとき、FixedJointを動的に生成してカップをアームに固定する。設置ポイントに到達したらFixedJointをDestroyして解放する。これだけのことだが、UnityのArticulationBodyを使う環境ではやり方を間違えると即崩壊する。

実装した把持の仕組み

ステートマシンを2ステートから4ステートに拡張した。

REACH_CUP → GRASP → REACH_PLACE → PLACE → REACH_CUP(ループ)

把持のキーポイントは3つ。

FixedJointを動的に生成する transform.SetParent()によるParentingは使わない。ArticulationBodyの階層を動的に変えるとシミュレーションが崩壊するリスクがあるため、FixedJointで物理的に繋ぐ方式を選んだ。

graspJoint = cupObject.AddComponent<FixedJoint>();
graspJoint.connectedBody = endEffector.GetComponent<Rigidbody>();
graspJoint.breakForce  = Mathf.Infinity;
graspJoint.breakTorque = Mathf.Infinity;

距離0.05m以下を把持トリガーにする IKがカップの把持点(HandlePoint)に到達したかどうかを距離で判定する。今日の実測では2mm精度で到達を確認。

設置時はDestroyするだけ PlaceTargetに到達したらDestroy(graspJoint)の一行で解放。物理シミュレーションがそこから先を引き受ける。

動作確認ログ

Consoleに以下のログが順番に流れることを確認した。

[RobotArm] → GRASP
[RobotArm] GRASP: FixedJoint 生成完了
[RobotArm] → REACH_PLACE
[RobotArm] → PLACE
[RobotArm] PLACE: FixedJoint 破棄完了
[RobotArm] → REACH_CUP(ループ)

到達精度:

  • REACH_CUP(カップへ): dist = 0.002m(2mm)

  • REACH_PLACE(設置点へ): dist = 0.008m(8mm)

教訓

FixedJointのconnectedBodyにはRigidbodyが必要。

EndEffectorにRigidbodyがない場合、connectedBodyがnullになりFixedJointが機能しない。FixedJointのログは出るのにカップが動かない、という症状になる。これは明日(LOG92)解決する課題として持ち越した。

現時点の動作は「アームが左右のターゲットを往復する」状態。把持の完全実装はLOG92へ。

憲法は守られた

今日もStiffness(20,000)とDamping(2,000)はコードから一切触っていない。xDrive.targetとforceLimitの操作のみ。LOG90のStiffness発散インシデントの教訓が生きている。