逆運動学(IK)は,剛体関節系において剛体が目標位置に到達するよう関節を制御する機能です.
Springheadでは,関節系のヤコビアンを用いたIK機能が使用可能です. 物理シミュレーションの1ステップごとに関節系のヤコビアンを計算し,それに基づいて剛体を目標位置・姿勢に近づけるような各関節の角速度を計算します. シミュレーションを続けることで,最終的に剛体が目標位置・姿勢となった状態が得られます.
Springhead上の剛体関節系に対してIKを使用するには,少々下準備が必要です. 次のように3つの剛体が直線状につながった関節系を例にとって解説します.
IKを使用するには,まずIKに用いるための関節を「アクチュエータ」として登録する必要があります.
// given PHSceneIf* phScene // given PHSolidIf* solid1, solid2, solid3 // given PHHingeJointIf* joint1 (solid1 <-> solid2) // given PHHingeJointIf* joint2 (solid2 <-> solid3) PHIKHingeActuatorDesc descIKActuator; PHIKHingeActuatorIf* ikActuator1 = phScene->CreateIKActuator(descIKActuator); ikActuator1.AddChildObject(joint1); PHIKHingeActuatorIf* ikActuator2 = phScene->CreateIKActuator(descIKActuator); ikActuator1.AddChildObject(joint2);
PHIKHingeActuatorIfはPHHingeJointIfに対応するアクチュエータクラスです.
次に,関節系の親子関係を登録します.親アクチュエータに,子アクチュエータを登録します.
ikActuator1.AddChildObject(ikActuator2);
また,IKを用いて到達させる先端の剛体を「エンドエフェクタ」として登録する必要があります.
PHIKEndEffectorDesc descEndEffector; PHIKEndEffectorIf* ikEndEffector1 = phScene->CreateIKEndEffector(descEndEffector); ikEndEffector1.AddChildObject(solid3);
最後に,剛体関節系の親子関係において,エンドエフェクタの直接の親にあたるアクチュエータに対し,エンドエフェクタを登録します.
ikActuator2.AddChildObject(ikEndEffector1);
この例では solid1 -(joint1)-> solid2 -(joint2)-> solid3 のように関節が接続されていますから,関節系の末端である solid3 をエンドエフェクタにした場合,直接の親にあたるアクチュエータは joint2 に対応するアクチュエータ,すなわち ikActuator2 ということになります.
ここまでの作業で,生成されたオブジェクトの関係は以下のようになっているはずです.
これで下準備は終わりです.
目標位置をセットし,IKエンジンを有効にするとIKが動き始めます.
// solid3 goes to (2, 5, 0) ikEndEffector1->SetTargetPosition(Vec3d(2, 5, 0)); phScene->GetIKEngine()->Enable(true); ... phScene->Step(); // IK is calculated in physics step ...