ジョイント (Joint)

ジョイントを使用することで2つのボディの間に拘束 (constraint) を設定し、相互の関係を定義できます。

サンプルコード (ジョイントの作成と設定)

hinge = dJointCreateHinge( world, 0 );   // ジョイントの作成
dJointAttach( hinge, body1, body2 );     // ジョイントで2つのボディを接続

dJointSetHingeAnchor( hinge, 0, 0, 0 );  // 中心点の設定
dJointSetHingeAxis( hinge, 1, 0, 0 );    // 回転軸の設定

デモプログラム (demo_hinge)

ジョイントの種類

一般的なジョイント
種類 イメージ パラメータ 自由度 対偶
ボール
(A ball-and-socket joint)
  • Anchor (軸の位置)
3
ヒンジ
(A hinge joint)
  • Anchor (軸の位置)
  • Axis (軸の方向)
  • Angle (角度)
  • AngleRate (角速度)
1 回転
スライダー
(A slider joint)
  • Axis (軸の方向)
  • Position (位置)
  • PositionRate (速度)
1 直進
ユニバーサル
(A universal joint)
  • Anchor (軸の位置)
  • Axis1 (軸1の方向)
  • Axis2 (軸2の方向)
  • Angle1 (角度)
  • Angle2 (角度)
  • AngleRate1 (角速度)
  • AngleRate2 (角速度)
2 回転×2
ヒンジ2
(A hinge-2 joint)
  • Anchor (軸の位置)
  • Axis1 (軸1の方向)
  • Axis2 (軸2の方向)
  • Angle1 (角度)
  • Angle1Rate (角速度)
  • Angle2Rate (角速度)
2×2 回転×2
特殊なジョイント
種類 イメージ パラメータ
固定
(A fixed joint)
  なし
接触
(A contact joint)
  • Contact point (接触面の性質)
角度モーター
(An angular motor joint)
  • Mode (モード)
  • NumAxes (軸の数)
  • Axis (軸の方向)
  • AxisRel (相対回転モード)
  • Angle (角度)
  • AngleRate (角速度)

ジョイントの作成・破棄 (Create)

ジョイントを作成するには、それぞれのジョイントの種類に対応した関数を使用します。

このときdWorldIDにはジョイントが格納されるワールドを、dJointGroupIDにはジョイント グループを指定します。ただし一般的なジョイントはグループ化する必要がないため、通常dJointGroupIDは0とします。

一般的なジョイントの作成
種類 関数
ボール (Ball)
dJointCreateBall( dWorldID, dJointGroupID );
ヒンジ (Hinge)
dJointCreateHinge( dWorldID, dJointGroupID );
スライダー (Slider)
dJointCreateSlider( dWorldID, dJointGroupID );
ユニバーサル (Universal)
dJointCreateUniversal( dWorldID, dJointGroupID );
ヒンジ2 (Hinge2)
dJointCreateHinge2( dWorldID, dJointGroupID );
特殊なジョイントの作成
種類 関数
固定 (Fixed)
dJointCreateFixed( dWorldID, dJointGroupID );
接触 (Contact)
dJointCreateContact(
    dWorldID,
    dJointGroupID,
    const dContact *   // 接触面の定義
    );
角度モーター (Angular Motor)
dJointCreateAMotor( dWorldID, dJointGroupID );

破棄

ジョイントを破棄するときは、その種類に関係なくdJointDestroy()を使用します。

ワールドを破棄したときには、そこに格納されるジョイントも自動で破棄されます。またジョイント グループを破棄したときには、そ含れジョイントも自動で破棄されます。よって通常は、明示的にジョイントを破棄する必要はありません。

void dJointDestroy ( dJointID );

2つのボディの接続 (Attach)

dJointAttach()により、2つのボディをジイントにり接続できます。

指定したジョイントがすでに他のボディの接続に使用されていた場合には、そのボディの接続は解除されます。

body1またはbody2に0が指定された場合には、他方のボディは静的な環境 (static environment) と接続され移動しなくなります。

void dJointAttach (
    dJointID joint,   // 接続するジョイント
    dBodyID body1,    // 接続されるボディ1
    dBodyID body2     // 接続されるボディ2
    );

ジョイントによって接続されているボディの取得

dJointGetBody()によって、dJointAttach()で接続されたボディを調べられます。

引数indexでは次の定数で、調べる対象のボディを指定します。

  • 0 … dJointAttach()のbody1
  • 1 … dJointAttach()のbody2
dBodyID dJointGetBody ( dJointID, int index );

indexに0と1を指定し2つのボディについて調べた場合、得られる結果には次の3通りの意味があります。

  • 両方のボディのIDが0以外 … ボディ同士を接続している
  • 両方のボディのIDが0 … 何も接続していない
  • 一方のボディのIDが0 … ボディと静的な環境を接続している

ボディ同士が接続されているか確認 (dAreConnected)

dAreConnected()とdAreConnectedExcluding()によって、指定の2つのボディがジョイントによって接続されているか確認できます。

接続されている場合には1、さもなければ0が返されます。

int dAreConnected ( dBodyID body1, dBodyID body2 );

dAreConnectedExcluding()では、引数のjoint_typeで例外を設定できます。ここで指定したジョイントは確認対象から除外されるため、特定のジョイントで接続されているかどうかを確認できます。

これはおもに、ボディに接触ジョイントを設定するかどうかの判断に使用されます。

int dAreConnectedExcluding ( dBodyID body1, dBodyID body2, int joint_type );
joint typeの定数
定数 説明
dJointTypeNone  
dJointTypeNull  
dJointTypeBall ボール
dJointTypeHinge ヒンジ
dJointTypeSlider スライダー
dJointTypeUniversal ユニバーサル
dJointTypeHinge2 ヒンジ2
dJointTypeFixed 固定
dJointTypeContact 接触
dJointTypeAMotor 角度モーター
dJointTypeLMotor  
dJointTypePlane2D  
dJointTypePR PR
dJointTypePU PU
dJointTypePiston ピストン

中心点、回転軸、回転角

各ジョイントには、その中心点と回転軸の設定・取得を行う関数があります。例外がボールとスライダーで、それぞれ回転軸と中心点がありません。

中心点 (Anchor point)

中心点はx、y、zの3成分を絶対座標で指定します。回転軸は軸方向をx、y、zの軸ベクトルで指定します。

軸が1つであるにもかかわらず中心点を取得する関数が2つあるジョイントは、計算誤差により2つのボディに対してその位置がずれることがあるためです。なおそのような計算誤差は、ERPの値を調整することで抑えられます。

位置、角度 (Position、Angle)

PositionやPositionRateといった位置や速度に関する関数は、取得のみを行えます。また力とトルクは別の関数になります。

各パラメータの設定・取得を行う関数一覧

※下表では関数名の一部を省略しています。正確には、

  • dJointSetXx
  • dJointGetXx

のようなdJoint~の形式となります。

種類   中心点 (Anchor) 回転軸 (Axis) 位置、角度 (Position,Angle)
ボール
Set
  • BallAnchor
  • BallAnchor2
--- ---
Get
  • BallAnchor
  • BallAnchor2
---
ヒンジ
Set
  • HingeAnchor
  • HingeAnchorDelta
  • HingeAxis
  • HingeAxisOffset
---
Get
  • HingeAnchor
  • HingeAnchor2
  • HingeAxis
  • HingeAngle
  • HingeAngleRate
スライダー
Set ---
  • SliderAxis
  • SliderAxisDelta
---
Get
  • SliderAxis
  • SliderPosition
  • SliderPositionRate
ユニバーサル
Set
  • UniversalAnchor
  • UniversalAxis1
  • UniversalAxis1Offset
  • UniversalAxis2
  • UniversalAxis2Offset
---
Get
  • UniversalAnchor
  • UniversalAnchor2
  • UniversalAxis1
  • UniversalAxis2
  • UniversalAngles
  • UniversalAngle1
  • UniversalAngle2
  • UniversalAngle1Rate
  • UniversalAngle2Rate
ヒンジ2
Set
  • Hinge2Anchor
  • Hinge2Axis1
  • Hinge2Axis2
---
Get
  • Hinge2Anchor
  • Hinge2Anchor2
  • Hinge2Axis1
  • Hinge2Axis2
  • Hinge2Angle1
  • Hinge2Angle1Rate
  • Hinge2Angle2Rate
PR Set
  • PRAnchor
  • PRAxis1
  • PRAxis2
---
Get
  • PRAnchor
  • PRAxis1
  • PRAxis2
  • PRPosition
  • PRPositionRate
  • PRAngle
  • PRAngleRate
PU Set
  • PUAnchor
  • PUAnchorDelta
  • PUAnchorOffset
  • PUAxis1
  • PUAxis2
  • PUAxis3
  • PUAxisP
---
Get
  • PUAnchor
  • PUAxis1
  • PUAxis2
  • PUAxis3
  • PUAxisP
  • PUPosition
  • PUPositionRate
  • PUAngles
  • PUAngle1
  • PUAngle1Rate
  • PUAngle2
  • PUAngle2Rate
ピストン Set
  • PistonAnchor
  • PistonAnchorOffset
  • PistonAxis
  • PistonAxisDelta
---
Get
  • PistonAnchor
  • PistonAnchor2
  • PistonAxis
  • PistonPosition
  • PistonPositionRate
  • PistonAngle
  • PistonAngleRate

力とトルク (Force、Torque)

取得 (Feedback)

ジョイントに働く力とトルクは他のパラメータとは異なり、すぐには取得できません。これは不要な演算を省いてパフォーマンスを向上するためで、取得するにはまずフィードバックを返すように設定する必要があります。フィードバックはdJointFeedback構造体として、

typedef struct dJointFeedback {
  dVector3 f1;  // ジョイントが ボディ1に作用する力
  dVector3 t1;  // ジョイントが ボディ1に作用するトルク
  dVector3 f2;  // ジョイントが ボディ2に作用する力
  dVector3 t2;  // ジョイントが ボディ2に作用するトルク
} dJointFeedback;

のように定義されています。

フィードバックの設定にはdJointSetFeedback()を使用します。これにdJointFeedback構造体のポインタを渡すことでフィードバックが有効となり、逆に0を渡すことでこの機能を無効にできます。

void dJointSetFeedback ( dJointID, dJointFeedback * );

フィードバックはシミュレーションのステップごとに計算され、このdJointFeedback構造体のポインタを通して力とトルクを取得できます。

ジョイントに設定せれているdJointFeedback構造体の取得

ジョイントに設定せれているdJointFeedback構造体のポインタは、dJointGetFeedback()で取得できます。フィードバックの設定時にdJointFeedbackを保持しているならば、この関数によって取得する必要はありません。なおフィードバックが設定されていない場合は、0が返されます。

dJointFeedback *dJointGetFeedback ( dJointID );

加算 (Add)

スライダーやピストンのような直線運動するものには力、それ以外はトルクになります。

力 (Force)

void dJointAddSliderForce ( dJointID joint, dReal force );
void dJointAddPistonForce ( dJointID joint, dReal force );

トルク (Torque)

void dJointAddHingeTorque ( dJointID joint, dReal torque );
void dJointAddPRTorque ( dJointID j, dReal torque );
void dJointAddPUTorque ( dJointID j, dReal torque );

2つの軸を持つジョイントは、トルクを2つ指定します。

void dJointAddUniversalTorques ( dJointID joint, dReal torque1, dReal torque2 );
void dJointAddHinge2Torques ( dJointID joint, dReal torque1, dReal torque2 );

これらの関数はボディの力の関数 (dBodyAddForce、dBodyAddTorque) のただのラッパーであり、接続されているボディに対してそれらの関数により力が加算されます。

その他のパラメータ (Parameter)

設定

void dJointSetBallParam ( dJointID, int parameter, dReal value );
void dJointSetHingeParam ( dJointID, int parameter, dReal value );
void dJointSetSliderParam ( dJointID, int parameter, dReal value );
void dJointSetUniversalParam ( dJointID, int parameter, dReal value );
void dJointSetHinge2Param ( dJointID, int parameter, dReal value );
void dJointSetFixedParam ( dJointID, int parameter, dReal value );
void dJointSetAMotorParam ( dJointID, int parameter, dReal value );

取得

dReal dJointGetBallParam ( dJointID, int parameter );
dReal dJointGetHingeParam ( dJointID, int parameter );
dReal dJointGetSliderParam ( dJointID, int parameter );
dReal dJointGetUniversalParam ( dJointID, int parameter );
dReal dJointGetHinge2Param ( dJointID, int parameter );
dReal dJointGetFixedParam ( dJointID, int parameter );
dReal dJointGetAMotorParam ( dJointID, int parameter );

引数parameterで下表の定数を用いて対象とするパラメータを指定します。

parameterの定数
定数 説明 範囲 既定値
dParamLoStop 角度または位置の下限。-dInfinityで制限が無効となる。 -πより大きな値 -dInfinity
dParamHiStop 角度または位置の上限。dInfinityで制限が無効となる。dParamLoStopより小さいと、dParamLoStopの制限も無効となる。 πより小さな値 dInfinity
dParamVel 目標とする速度または角速度    
dParamFMax dParamVelを達成するために発生する最大の力またはトルク。0とすると停止する。 0以上 0
dParamFudgeFactor 停止状態から動作を始めるときに発生する、過大な力を抑制する。これは実装上の問題であり、このパラメータはそれをごまかす (fudge)。 0 ~ 1 1
dParamBounce 反発係数。0とするとまったく弾まない。 0 ~ 1  
dParamERP 停止するとき以外のERP 0.1~0.8 0.2
dParamCFM 停止するとき以外のCFM 10⁻⁹~1 10⁻¹⁰
dParamStopERP 停止するときのERP 0.1~0.8 0.2
dParamStopCFM 停止するときのCFM 10⁻⁹~1 10⁻¹⁰
dParamSuspensionERP サスペンションのERP (ヒンジ2のみで有効)    
dParamSuspensionCFM サスペンションのCFM (ヒンジ2のみで有効)