ODE講座7:ジョイント(関節)

2006-11-14
By

金沢もã™ã£ã‹ã‚Šå¯’ããªã‚Šãšã‚ã„ガニã€é¦™ç®±ã‚¬ãƒ‹ï¼ˆæ³¨1)ãŒè§£ç¦ã•れã€å¯’鰤(ã‹ã‚“ã¶ã‚Šï¼šæ³¨2)ã¨åœ°é…’(注3ï¼‰ãŒæ—¨ã„季節ã«ãªã£ã¦ã¾ã„りã¾ã—ãŸã€‚

ゲーム開発やロボットã®ç ”究者ã«ã‚‚使ã‚れã¦ã„るオープンソースã®ç‰©ç†è¨ˆç®—エンジンODE(Open Dynamics Engineã€ã‚ªãƒ¼ãƒ—ン ダイナミクスエンジン)を学ã¶ODE講座ã®ç¬¬ï¼—回目ã§ã™ã€‚

今回ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆï¼ˆé–¢ç¯€ï¼‰ã«ã¤ã„ã¦ãŠè©±ã—ã—ã¾ã™ã€‚ å‰å›žèª²é¡ŒãŒå‡ºã¦ã¦ã„ã¾ã—ãŸãŒã§ãã¾ã—ãŸã‹ï¼Ÿã€€ç­”ãˆã¯ã€nearCallback関数ã®ä¸­ã«ã‚ã‚‹
contact[i].surface.bounce = 0.0; // (0.0~1.0) å発係数ã¯0ã‹ã‚‰1ã¾ã§
contact[i].surface.bounce_vel = 0.0; //  跳ã­è¿”りã«å¿…è¦ãªé€Ÿåº¦
ã®å€¤ã‚’0.0より大ãã1.0以下ã«ã™ã‚Œã°ã‚ˆã„ã®ã§ã™ã€‚å発係数ã¯è¡çªå‰ã¨è¡çªå¾Œã®é€Ÿåº¦æ¯”ã§ã—ãŸã­ã€‚

ã§ã¯ã€ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã«ã¤ã„ã¦èª¬æ˜Žã—ã¾ã™ã€‚ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¯æˆ‘々ã®å‘¨ã‚Šã§ã¯ã€æŠ˜ç•³ã¿æºå¸¯ã®ãƒ’ンジやドアã®è¶ç•ªã«ç›¸å½“ã—ã¾ã™ã€‚å°é›£ã—ãã„ã†ã¨ã€ï¼’ã¤ã®ãƒœãƒ‡ã‚£ã®ä½ç½®ã‚„姿勢をã‚る一定ã®é–¢ä¿‚ã«ä¿ã¤æ‹˜æŸãŒã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¨ãªã®ã§ã™ã€‚ODEã§ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¨æ‹˜æŸã‚’åŒã˜æ„味ã§ä½¿ã£ã¦ã„ã¾ã™ã€‚

ジョイントã®ä½¿ã„æ–¹ã¯ä»¥ä¸‹ã®ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚

  1. ***ジョイントã®ç”Ÿæˆã€€ã€€ã€€ã€€ã€€ã€€dJointCreate***()
  2. ***ジョイントã¨ãƒœãƒ‡ã‚£ã®çµåˆã€€dJointAttach()
  3. ***ジョイントã®ä¸­å¿ƒç‚¹ã‚’設定 dJointSet***Anchor()
  4. ***ジョイントã®å›žè»¢è»¸ã‚’設定 dJointSet***Axis()

上ã§***ã«ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®ã‚¿ã‚¤ãƒ—ãŒå…¥ã‚Šã¾ã™ã€‚タイプã«ã¯Hinge(ヒンジ)ã€Ball(ボール)ã€Slider(スライダー)ã€Universal(ユニãƒãƒ¼ã‚µãƒ«)ç­‰ãŒã‚りã¾ã™ã€‚詳ã—ã„ä½¿ã„æ–¹ã¯ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚’å‚ç…§ã—ã¦ãã ã•ã„。

ã•ã£ãã上図ã«ç¤ºã—ã¦ã„る玉ã¨å††æŸ±ã‚’ヒンジジョイントã§çµåˆã—ã¦ã„るオブジェクトãŒãƒã‚¦ãƒ³ãƒ‰ã™ã‚‹ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’以下ã«ç¤ºã—ã¾ã™ã€‚ãªãŠã€å‰å›žã¾ã§ã¨åŒã˜é–¢æ•°ã‚„宣言ã¯çœç•¥ã—ã¦ã„ã¾ã™ã€‚
注1:香箱ガニã¯ãšã‚ã„ガニã®ãƒ¡ã‚¹ã§ã™ã€‚体ã¯ã¨ã¦ã‚‚å°ã•ã„ã®ã§ã™ãŒã€åµãŒè©°ã¾ã£ã¦ã„ã¦è¶…美味ã§ã™ã€‚
注2:脂ãŒä¹—ã£ã¦ç¾Žå‘³ã€‚甘エビもãŠã„ã—ã„ã§ã™ã­ã€‚
注3:石å·ã§ã¯èŠå§«ã€å¤©ç‹—舞ã€ä¸‡æ­³æ¥½ãªã©ãŒå¥½ãã§ã™ãŒã€ç¦äº•ã®é»’é¾ã¯æœ¬å½“ã«è¶…ãŠå‹§ã‚ã§ã™ã€‚ã ã¾ã•れãŸã¨æ€ã£ã¦ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆã§æ³¨æ–‡ã—ã¦ã¿ã¦ã¯ã„ã‹ãŒã§ã™ã‹ï¼Ÿ

[cpp]

// sample3.cpp  by ã§ã‚€
#ifdef  dDOUBLE
#define dsDrawSphere dsDrawSphereD   // å˜ç²¾åº¦ã¨å€ç²¾åº¦ã®æç”»é–¢æ•°ã«å¯¾å¿œã™ã‚‹ãŠã¾ã˜ãªã„
#define dsDrawCapsule  dsDrawCapsuleD
#endif

typedef struct {
  dBodyID body;   //  ボディ(剛体)
  dGeomID geom; //   ジオメトリ(形状)
  dReal   radius, length, mass; // åŠå¾„[m]ã€ã€€é•·ã•[m]ã€ã€€è³ªé‡[kg]
} myLink;

myLink ball, pole;

// simLoopã¯ã“ã®ã‚½ãƒ¼ã‚¹ã§ã¯ã‚ã‹ã‚‰ãªã„ãŒwhileループã«å…¥ã£ã¦ã„ã¦ã€ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®å„ステップã§å®Ÿè¡Œã•れる。

static void simLoop (int pause)
{
  const dReal *pos1,*R1,*pos2,*R2; // é…列ã¸ã®ãƒã‚¤ãƒ³ã‚¿ãŒä»£å…¥ã•れる

  dSpaceCollide(space,0,&nearCallback);  // è¡çªæ¤œå‡ºè¨ˆç®—
  dWorldStep(world,0.01); // 動力学計算を1ステップ(ã“ã“ã§ã¯0.01秒)進ã‚ã‚‹
  dJointGroupEmpty(contactgroup);       //  接触点グループã®å¾Œå§‹æœ«

  // ãƒœãƒ¼ãƒ«ã®æç”»
  dsSetColor(1.0,0.0,0.0);        // 赤色ã®è¨­å®š
  pos1 = dBodyGetPosition(ball.body); // pos1(ä½ç½®ï¼‰ã¯é…列ã®ãƒã‚¤ãƒ³ã‚¿ãƒ¼ã«ãªã£ã¦ã„ã‚‹
  R1   = dBodyGetRotation(ball.body); //  回転行列ã®å–å¾—
  dsDrawSphere(pos1,R1,ball.radius); // çƒã®æç”»

  // å††æŸ±ã®æç”»
  pos2 = dBodyGetPosition(pole.body); // ä½ç½®ã®å–å¾—
  R2   = dBodyGetRotation(pole.body); // å§¿å‹¢ã®å–å¾—
  dsDrawCapsule(pos2,R2,pole.length,pole.radius); // ã‚«ãƒ—ã‚»ãƒ«ã®æç”»
}

// オブジェクトã®ä½œæˆ
void createBallPole() {
  dMass m1;
  dReal x0 = 0.0, y0 = 0.0, z0 = 2.5;

  //玉
  ball.radius = 0.2;  ball.mass   = 1.0;
  ball.body = dBodyCreate(world);
  dMassSetZero(&m1);
  dMassSetSphereTotal(&m1,ball.mass,ball.radius);
  dBodySetMass(ball.body,&m1);
  dBodySetPosition(ball.body, x0, y0, z0);
  ball.geom = dCreateSphere(space,ball.radius);
  dGeomSetBody(ball.geom,ball.body);

  //  カプセル
  pole.radius = 0.025;  pole.length = 1.0;  pole.mass   = 1.0;
  pole.body =  dBodyCreate(world);
  dMassSetZero(&m1);
  dMassSetCapsuleTotal(&m1,pole.mass,3,pole.radius,pole.length);
  dBodySetMass(pole.body,&m1);
  dBodySetPosition(pole.body, x0, y0, z0 - 0.5 * pole.length);
  pole.geom =  dCreateCapsule(space,pole.radius,pole.length);
  dGeomSetBody(pole.geom,pole.body);

  // ヒンジジョイント
  joint = dJointCreateHinge(world, 0);           // ヒンジジョイントã®ç”Ÿæˆ
  dJointAttach(joint, ball.body,pole.body);      // 玉ã®ãƒœãƒ‡ã‚£ã¨å††æŸ±ã®ãƒœãƒ‡ã‚£ã‚’ジョイントã§çµåˆ
  dJointSetHingeAnchor(joint, x0, y0, z0 - ball.radius); // ヒンジジョイントã®ã‚¢ãƒ³ã‚«ãƒ¼(中心点)を設定
  dJointSetHingeAxis(joint, 1, 0, 0);            // ヒンジジョイントã®å›žè»¢è»¸ãƒ™ã‚¯ãƒˆãƒ«ã‚’設定(1,0,0)
}

int main (int argc, char **argv)
{
  setDrawStuff();  // æç”»é–¢æ•°ã®è¨­å®š
  world = dWorldCreate(); // 動力学ワールドã®ç”Ÿæˆ
  space = dHashSpaceCreate(0); // è¡çªè¨ˆç®—スペースã®ç”Ÿæˆ
  contactgroup = dJointGroupCreate(0); // 接触点グループã®ç”Ÿæˆ
  dWorldSetGravity(world,0,0,-9.8);       // é‡åŠ›åŠ é€Ÿåº¦ã®è¨­å®š
  ground = dCreatePlane(space,0,0,1,0);     // 地é¢ç”¨å¹³é¢ã‚¸ã‚ªãƒ¡ãƒˆãƒªã®ç”Ÿæˆ
  createBallPole(); // 玉ã¨ã‚«ãƒ—セルã®ç”Ÿæˆ
  dsSimulationLoop (argc,argv,352,288,&fn);  // シミュレーションループ
  dWorldDestroy (world); // ワールドã®ç ´å£Š

  return 0;
}
[/cpp]

ã“ã®ä¾‹ã§ã¯çމã¨å††æŸ±ã®ãƒœãƒ‡ã‚£ã‚’ヒンジジョイントã§çµã³ã¤ã‘ã¦ã„ã¾ã™ã€‚

ã§ã¯ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’読ã¿ã¾ã—ょã†ã€‚createBallandPall関数ã§ã¯ã¾ãšçŽ‰ã‚’ä½œã‚Šã€ãã®å¾Œã€å††æŸ±ã‚’作りã€ãれã‹ã‚‰ãƒ’ンジジョイントを dJointCreateHinge()㧠生æˆã—ã€dJointAttach()ã§ï¼’ã¤ã®ãƒœãƒ‡ã‚£ã‚’ヒンジジョイントã§çµåˆã—ã¾ã™ã€‚ãã®å¾Œã®dSetHingeAnchor()ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®å›žè»¢ä¸­ 心点ã®ä½ç½®ã‚’設定ã—ã€dJointSetHingeAxis()ã§å›žè»¢è»¸ãƒ™ã‚¯ãƒˆãƒ« を設定ã—ã¾ã™ã€‚ã“ã®ä¾‹ã§ã¯å›žè»¢è»¸ãƒ™ã‚¯ãƒˆãƒ«ã¯(1,0,0)ãªã®ã§ï½˜è»¸æ–¹å‘ã¨ãªã‚Šã¾ã™ã€‚詳ã—ãã¯ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚’å‚照。

ã“れã§ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®ç”Ÿæˆã¯çµ‚ã‚りã§ã™ã€‚今回ã¯ç°¡å˜ã®ãŸã‚ã«ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®ãƒ‘ラメータを設定ã—ã¾ã›ã‚“ã§ã—ãŸãŒã€å¯å‹•åŸŸã‚„æœ€å¤§ãƒˆãƒ«ã‚¯ã€æœ€å¤§è§’速度ã®è¨­å®šãªã©ã‚‚å¯èƒ½ã§ã™ã€‚ã“ã“をクリックã—ã¦ã‚µãƒ³ãƒ—ルプログラムをダウンロードã—ã¦éŠã‚“ã§ãã ã•ã„。

次回ã¯é–¢ç¯€ã®å‹•ã‹ã—方やパラメータã®è¨­å®šæ–¹æ³•を説明ã—ã¾ã™ã€‚ãªãŠã€èª¬æ˜Žã§ã‚ã‹ã‚Šãšã‚‰ã„箇所や質å•ãŒã‚れã°ã‚³ãƒ¡ãƒ³ãƒˆã‚’投稿ã—ã¦ãã ã•ã„。

今回登場ã—ãŸAPI

  • void dJointAttach(dJointID joint, dBodyID body1, dBodyID dBody2)
    剛体body1ã¨body2ã«ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆjointã‚’å–り付ã‘ã‚‹
  • dJointID dJointCreateHinge(dWorldID world, dJointGroupID)
    worldã«ãƒ’ンジジョイントを生æˆã—ã€ãã®ï¼©ï¼¤ç•ªå·ã‚’è¿”ã™ã€‚dJointGroupIDã«ã¯0を入れる。
  • void dJointSetHingeAnchor(dJointID joint, dReal x, dReal y, dReal z)
    ヒンジジョイントã®å›žè»¢è»¸ã®ä¸­å¿ƒç‚¹(x,y,z)を設定ã™ã‚‹ã€‚
  • void dJointSetHingeAxis(dJointID joint, dReal x, dReal y, dReal z)
    ヒンジジョイントã®å›žè»¢è»¸ãƒ™ã‚¯ãƒˆãƒ«(x,y,z)を設定ã™ã‚‹ã€‚

更新履歴
2007-1-22: 本文ã®èª¬æ˜Žã‚’強化ã—ã€ã‚µãƒ³ãƒ—ãƒ«ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã§æ–°ã—ã登場ã—ãŸAPI集を掲載ã—ãŸã€‚

コメントをã©ã†ãž

メールアドレスãŒå…¬é–‹ã•れるã“ã¨ã¯ã‚りã¾ã›ã‚“。

796 views  (Since 2010-08-11)