ODEã§å¦ã¶C言語 [Step5: æ§‹é€ ä½“]
ODEã§å¦ã¶C言語ã®Step5ã§ã™ï¼Žä»Šå›žã¯æ§‹é€ 体を練習ã—ã¾ã—ょã†ï¼Žæ§‹é€ ä½“ã®æ¦‚è¦ã«ã¤ã„ã¦ã¯æ—¢ã«ã‚ã‹ã£ã¦ã„ã‚‹ã‚‚ã®ã¨ã—,サンプルコードを示ã™ã“ã¨ã«ã‚ˆã‚Šå…·ä½“çš„ãªä½¿ã„方をå¦ã³ã¾ã™ï¼Ž
ODEã§ã¯è¡çªæ¤œå‡ºæ©Ÿèƒ½ã‚’使用ã™ã‚‹ã«ã¯è¡çªæ¤œå‡ºç”¨ã®ã‚¹ãƒšãƒ¼ã‚¹(space)ã¨å‹•力å¦è¨ˆç®—用ã®ãƒ¯ãƒ¼ãƒ«ãƒ‰(world)ã®ï¼’ã¤ã‚’生æˆã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ãれã«ä¼´ã„,物体ã«ï¼’ã¤ã®å±žæ€§ï¼Œã¤ã¾ã‚Šï¼Œå‹•力å¦è¨ˆç®—ã®å¯¾è±¡ã¨ãªã‚‹ãƒœãƒ‡ã‚£(剛体,body)ã¨è¡çªæ¤œå‡ºè¨ˆç®—ã®å¯¾è±¡ã¨ãªã‚‹ã‚¸ã‚ªãƒ¡ãƒˆãƒª(geometry)ã‚’æŒãŸã›ã¦ã„ã¾ã™ã€‚ãªãŠï¼Œå‰›ä½“ã®ã“ã¨ã‚’英語ã§Rigid Bodyã¨ã„ã„,Geometryã¨ã¯å¹¾ä½•å¦çš„ãªå½¢çжã¨ã„ã†æ„味ã§ã™ã€‚
ボディã¨ã‚¸ã‚ªãƒ¡ãƒˆãƒªãŒåˆ¥ã€…ã«å®Ÿè£…ã•れ,別々ã®ãƒ¯ãƒ¼ãƒ«ãƒ‰ã‚„スペースã«å˜åœ¨ã™ã‚‹ãŸã‚ã«ï¼Œä¸¡è€…を関連付ã‘ã‚‹å¿…è¦ãŒã‚りã¾ã™ï¼Žä»¥ä¸‹ï¼Œç‰©ä½“ã®ä½œã‚Šæ–¹ã‚’説明ã—ã¾ã™ï¼Ž
(1) ボディã®ä½œã‚Šæ–¹
ボディã¯ä»¥ä¸‹ã®é †ç•ªã«å¾“ã£ã¦ä½œã‚Šã¾ã™ï¼Ž
- ボディã®ç”Ÿæˆ dBodyID dBodyCreate(dWorldID world);
ボディをワールドworld内ã«ç”Ÿæˆã—,ボディã®IDã‚’è¿”ã—ã¾ã™ï¼Ž - 質é‡ãƒ‘ラメータã®åˆæœŸåŒ– void dMassSetZero(dMass *mass);
質é‡ï¼Œé‡å¿ƒä½ç½®ï¼Œæ…£æ€§ãƒ¢ãƒ¼ãƒ¡ãƒ³ãƒˆãªã©ãŒå…¥ã£ã¦ã„る質é‡ãƒ‘ラメータmassã‚’åˆæœŸåŒ–ã—ã¾ã™ï¼Ž - 質é‡ãƒ‘ラメータã®è¨ˆç®— void dMassSet***Total(dMass *mass, dReal total_mass, … );
***ã«ã¯ãƒœãƒ‡ã‚£ã®ç¨®é¡ž(Shpere, Box, Cylinder, Capsuleãªã©ï¼‰ãŒå…¥ã‚Šã¾ã™ï¼Žmassã¯è³ªé‡ãƒ‘ラメータ,total_massã¯ãƒœãƒ‡ã‚£ã®å…¨è³ªé‡ï¼ŽãªãŠï¼Œå¼•ãæ•°ã¯ãƒœãƒ‡ã‚£ã®ç¨®é¡žã«ã‚ˆã£ã¦é•ã†ã®ã§çœç•¥ã—ã¦ã„ã¾ã™ï¼Žè©³ç´°ã¯API集をã”覧ãã ã•ã„. - ボディã«è³ªé‡ãƒ‘ラメータをè¨å®š void dBodySetMass(dBodyID body, const dMass *mass);
ボディbodyã«è³ªé‡ãƒ‘ラメータmassã‚’è¨å®šã—ã¾ã™ï¼Ž - ボディã®ä½ç½®ã‚’è¨å®š void dBodySetPosition(dBodyID body, dReal x, dReal y, dReal z);
ボディbodyを絶対座標系(x,y,z)ã«è¨å®šã—ã¾ã™ï¼Ž - ボディã®å§¿å‹¢ã‚’è¨å®šã€€void dBodySetRotation(dBodyID, const dMatrix3 R);
ボディbodyã®å§¿å‹¢ã‚’回転行列Rã«è¨å®šã—ã¾ã™ï¼Ž
(2) ジオメトリã®ä½œã‚Šæ–¹
次ã«ã‚¸ã‚ªãƒ¡ãƒˆãƒªã®ä½œã‚Šæ–¹ã‚’紹介ã—ã¾ã™ï¼Žãƒœãƒ‡ã‚£ã¨æ¯”較ã™ã‚‹ã¨ç°¡å˜ã§ã™ï¼Žã‚¸ã‚ªãƒ¡ãƒˆãƒªã®ç¨®é¡žã«å¯¾å¿œã—ãŸä»¥ä¸‹ã®APIを呼ã³å‡ºã™ã ã‘ã§ã™ï¼Ž
- dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
space ã§æŒ‡å®šã•れãŸã‚¹ãƒšãƒ¼ã‚¹ã«x,y,z è»¸ã«æ²¿ã£ãŸé•·ã•lx,ly,lz ã®ç›´æ–¹ä½“ジオメトリを生æˆã—,ãã®ID 番å·ã‚’è¿”ã™ï¼Žç›´æ–¹ä½“ジオメトリã®å‚照点ã¯ãã®é‡å¿ƒã§ã‚る.
- dGeomID dCreateCapsule(dSpaceID space, dReal r, dReal l);
space ã§æŒ‡å®šã•れãŸã‚¹ãƒšãƒ¼ã‚¹ã«åŠå¾„r,長ã•l ã®ã‚«ãƒ—セルジオメトリを生æˆã—,ãã®ID 番å·ã‚’è¿”ã™ï¼Žã‚«ãƒ—ã‚»ãƒ«ã¯æ™®é€šã®å††æŸ±ã®ä¸¡ç«¯ã«åŠçƒã‚’被ã›ãŸã‚ˆã†ãªã‚‚ã®ã§ã‚る.ã“ã®ç‰¹å¾´ã¯è¡çªæ¤œå‡ºã®å†…部コードを拘æŸã‹ã¤æ£ç¢ºã«ã™ã‚‹ã“ã¨ãŒã§ãる.引数ã®length ã«ã¯åŠçƒã®ã‚ャップを入れãªã„.ã‚ャップã®åŠå¾„ã¯å††æŸ±ã®åŠå¾„radius ã¨åŒã˜ã§ã‚る.
- dGeomID dCreateCylinder(dSpaceID space, dReal r, dReal l);
スペースspaceã«åŠå¾„r,長ã•l ã®å††æŸ±ã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’生æˆã—,ãã®ID 番å·ã‚’è¿”ã™ï¼Ž
- dGeomID dCreateSphere(dSpaceID space, dReal r);
åŠå¾„rã®çƒã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’生æˆã—,ãã®ID 番å·ã‚’è¿”ã™ï¼Ž
- dGeomID dCreatePlane(dSpaceID space, dReal a, dReal b, dReal c, dReal d);
å¹³é¢ã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’与ãˆã‚‰ã‚ŒãŸå¼•æ•°ã«ã‚ˆã‚Šç”Ÿæˆã—,ãã®ID 番å·ã‚’è¿”ã™ï¼Žå¼•æ•°space ãŒ0 ã§ãªã‘れã°ï¼Œãã®space ã«å¹³é¢ã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’挿入ã™ã‚‹ï¼Žå¼•æ•°a,b,c,d ã¯å¹³é¢ã®æ–¹ç¨‹å¼ã€€ax+by+cz = d ã®ãƒ‘ラメータã§ã‚る.平é¢ã®æ³•線ベクトルã¯(a,b,c) ã§ã‚り長ã•ã¯ï¼‘ã§ãªã‘れã°ãªã‚‰ãªã„.平é¢ã‚¸ã‚ªãƒ¡ãƒˆãƒªã¯è¨ç½®ä¸å¯èƒ½(non-placeable),ã¤ã¾ã‚Šä½ç½®ã‚„姿勢を定義ã§ããªã„特別ãªã‚¸ã‚ªãƒ¡ãƒˆãƒªã§å¸¸ã«çµ¶å¯¾åº§æ¨™ç³»ã§å®šç¾©ã—ãªã‘れã°ãªã‚‰ãªã„.ã¤ã¾ã‚Šï¼Œå¹³é¢ã‚ªãƒ–ジェクトã¯å¸¸ã«é™çš„ãªç’°å¢ƒã®ä¸€éƒ¨ã¨ã—ã¦ä½¿ã‚れるã“ã¨ã‚’仮定ã—ã¦ã„る.
(3) ボディã¨ã‚¸ã‚ªãƒ¡ãƒˆãƒªã®å¯¾å¿œä»˜ã‘
- void dGeomSetBody(dGeomID geom, dBodyID body);
ジオメトリgeomをボディbodyã«é–¢é€£ä»˜ã‘ã¾ã™ï¼Ž
(4) è¡çªæ¤œå‡ºè¨ˆç®—
è¡çªæ¤œå‡ºè¨ˆç®—ã‚’ã™ã‚‹ãŸã‚ã«ã¯ã€ã‚¹ãƒšãƒ¼ã‚¹spaceã‚’dHashSpaceCreate()ã§ç”Ÿæˆã—ã€ãã®ä¸ã«å‰›ä½“bodyã«å¯¾å¿œã™ã‚‹ã‚¸ã‚ªãƒ¡ãƒˆãƒª を生æˆã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。以下ã®ã‚µãƒ³ãƒ—ルプãƒã‚°ãƒ©ãƒ ã§ã¯ã€53行目ã§çƒã«å¯¾å¿œã™ã‚‹ã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’dCreateSphere()ã§ç”Ÿæˆ ã—ã¦ã„ã¾ã™ã€‚54行目ã§ã€å‹•力å¦è¨ˆç®—ã®å¯¾è±¡ã¨ãªã‚‹ãƒœãƒ‡ã‚£obj->bodyã¨è¡çªæ¤œå‡ºè¨ˆç®—ã®å¯¾è±¡ã¨ãªã‚‹obj->geomã‚’çµã³ã¤ã‘ã¦ã„ã¾ã™ã€‚ã“れ㧠ODEã®ç‰©ä½“ãŒå®Œæˆã§ã™ã€‚
次ã«ã€simLoop関数ã®ä¸ã§ã€dSpaceCollide()を呼ã³å‡ºã—ã¾ã™ã€‚ã“ã®APIã¯è¡çªã—ãã†ãªï¼’ã¤ã®ã‚¸ã‚ªãƒ¡ãƒˆãƒªãŒç™ºç”Ÿã—ãŸã‚‰ã€ãれらを nearCallbacké–¢æ•°ã«æ¸¡ã—ã¾ã™ã€‚ã“ã“ã§ã¯nearCallbacké–¢æ•°ã®æœ¬ä½“ã¯ç¤ºã—ã¾ã›ã‚“ãŒï¼Œã“ã®é–¢æ•°ã§ã€æŽ¥è§¦ç‚¹ã‚’算出ã—ãŸã‚Šã€æŽ¥è§¦ç‚¹ã®æ€§è³ªãªã©ã‚’è¨å®šã—ã¾ã™ã€‚
ã¾ãŸã€69行目ã«ã‚るよã†ã«æŽ¥è§¦ç‚¹ã®é›†ã¾ã‚ŠãŒæ ¼ç´ã•れる入れ物をdJointGroupCreate()ã§ç”Ÿæˆã—ã€ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒ«ãƒ¼ãƒ—ã§æ¯Žå›žã れを31行目ã®ã‚ˆã†ã«dJointGroupEmpty()を使ã£ã¦ç©ºã«ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。
- è¡çªæ¤œå‡ºã«é–¢ã™ã‚‹API
- dSpaceID dHashSpaceCreate(0)
è¡çªè¨ˆç®—用スペースを生æˆã—ã€ãã®ID(è˜åˆ¥å)を返ã™ã€‚ - dGeomID dCreatePlane(dSpaceID space ,dReal a, dReal b, dReal c, dReal d)
spaceã«ax+by+cz=dã®å¹³é¢ã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’生æˆã™ã‚‹ã€‚ - dGeomID dCreateSphere(dSpaceID space, dReal r)
spaceã«åŠå¾„rã®çƒã‚¸ã‚ªãƒ¡ãƒˆãƒªã‚’生æˆã™ã‚‹ã€‚ - void dGeomSetBody(dGeomID geom, dBodyID body)
物体ã®2ã¤ã®å±žæ€§ã§ã‚るジオメトリgeomã¨å‰›ä½“bodyを関連ã¥ã‘る。 - dJointGroupID dJointGroupCreate(0)
接触点ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‚’æ ¼ç´ã™ã‚‹ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã‚°ãƒ«ãƒ¼ãƒ—を生æˆã—ã€ãã®IDã‚’è¿”ã™ã€‚ - void dJointGroupEmpty(dJointGroupID)
æŽ¥è§¦ç‚¹ãŒæ ¼ç´ã•れã¦ã„るジョイントグループを空ã«ã™ã‚‹ã€‚
- dSpaceID dHashSpaceCreate(0)
(5) ソースコード
ã§ã¯ï¼ŒStep4ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã«è¡çªæ¤œå‡ºã«é–¢ã™ã‚‹ã‚³ãƒ¼ãƒ‰ã‚’組ã¿è¾¼ã‚“ã ソースコードを紹介ã—ã¾ã™ï¼Žã“ã®å‡¦ç†ã‚ˆã‚Šãƒœãƒ¼ãƒ«ãŒåœ°é¢ã‚’ã¤ã抜ã‘ãšï¼Œåœ°é¢ã§ã¯ãšã‚€ã‚ˆã†ã«ãªã‚Šã¾ã™ï¼Ž
#include "dm5.h"
dWorldID world; // 動力å¦ã®ä¸–界
dSpaceID space; // è¡çªæ¤œå‡ºç”¨ã‚¹ãƒšãƒ¼ã‚¹
dGeomID ground; // 地é¢
dJointGroupID contactgroup; // コンタクトグループ
typedef struct {
  dBodyID body; // ボディã®ID
  dGeomID geom; // ジオメトリã®ID
  double *pos; // x, y, z [m]
  double *R; // 回転行列 è¦ç´ æ•°4x3
  double r, m; // åŠå¾„ [r], è³ªé‡ [kg]
  float *color; // 色 r,g,b
} MyObject;
MyObject apple;
void dmDraw(MyObject obj) /*** ç‰©ä½“ã®æç”» ***/
{
 dsSetColor(obj.color[0],obj.color[1],obj.color[2]); // 色ã®è¨å®š(r,g,b)
const double *pos = dBodyGetPosition(obj.body); // ä½ç½®ã‚’å–å¾—
const double *R = dBodyGetRotation(obj.body); // 姿勢をå–å¾—
dsDrawSphere(pos,R,obj.r); // çƒã®æç”»
}
void simLoop(int pause) /*** シミュレーションループ ***/
{
dSpaceCollide(space,0,&nearCallback); // è¡çªæ¤œå‡ºé–¢æ•°
dWorldStep(world,0.01); // シミュレーションを1ステップ進ã‚ã‚‹
dJointGroupEmpty(contactgroup); // ジョイントグループを空ã«ã™ã‚‹
dmDraw(apple); // ç‰©ä½“ã®æç”»
}
void dmSphereCreate(MyObject *obj,double p[3], double R[12],
double m, double r, float *color)
{
 obj->m = m;
 obj->r = r;
 obj->pos = p;
 obj->R = R;
 obj->color = color;
 dRSetIdentity(obj->R);
 obj->body = dBodyCreate(world); // ボールã®ç”Ÿæˆ
 dMass mass; // æ§‹é€ ä½“massã®å®£è¨€
dMassSetZero(&mass); // æ§‹é€ ä½“massã®åˆæœŸåŒ–
dMassSetSphereTotal(&mass,obj->m,obj->r); // æ§‹é€ ä½“massã«è³ªé‡ã‚’è¨å®š
dBodySetMass(obj->body,&mass); // ボールã«massã‚’è¨å®š
dBodySetPosition(obj->body,obj->pos[0],obj->pos[1],obj->pos[2]); // ボールã®ä½ç½®(x,y,z)ã‚’è¨å®š
obj->geom = dCreateSphere(space,obj->r); // çƒã‚¸ã‚ªãƒ¡ãƒˆãƒªã®ç”Ÿæˆ
dGeomSetBody(obj->geom, obj->body); // ボディã¨ã‚¸ã‚ªãƒ¡ãƒˆãƒªã®é–¢é€£ä»˜ã‘
}
int main() /*** main関数 ***/
{
// リンゴã®å¤‰æ•°
 double p[3] = {0.0, 0.0, 2.0}; // ä½ç½®
 double R[12]; // 回転行列
 double m = 1.0; // 質é‡
 double r = 0.2; // åŠå¾„
float color[3] = {1.0, 0.0, 0.0}; // 色
dInitODE(); // ODEã®åˆæœŸåŒ–
world = dWorldCreate(); // 動力å¦ç”¨ä¸–界ã®å‰µé€
space = dHashSpaceCreate(0); // è¡çªç”¨ç©ºé–“ã®å‰µé€
contactgroup = dJointGroupCreate(0); // ジョイントグループã®ç”Ÿæˆ
ground = dCreatePlane(space,0,0,1,0); // 地é¢ï¼ˆå¹³é¢ã‚¸ã‚ªãƒ¡ãƒˆãƒªï¼‰ã®ç”Ÿæˆ
dWorldSetGravity(world,0,0,-0.2); // é‡åŠ›è¨å®š
dRSetIdentity(R); //回転行列をå˜ä½è¡Œåˆ—ã§åˆæœŸåŒ–
dmSphereCreate(&apple,p,R,m,r,color); // リンゴã®ç”Ÿæˆ
dmLoop(800, 600); // シミュレーションループ ウインドウã®å¹…,高
dSpaceDestroy(space); // è¡çªç”¨ç©ºé–“ã®ç ´å£Š
dWorldDestroy(world); // 動力å¦ç”¨ä¸–界ã®ç ´å£Š
dCloseODE(); // ODEã®çµ‚了
return 0;
}
(6) ホームワーク
- サンプルコードstep5-090714.zipã‚’ã“ã“ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã—ã¦å®Ÿè¡Œã—よã†ï¼
- step5.cppã¨åŒã˜ãƒ•ォルダã«dm5.cppãŒã‚りã¾ã™ï¼Žãã®ä¸ã«nearCallback関数ãŒã‚り,å発係数をè¨å®šã—ã¦ã„る箇所ãŒ47行目ã«ã‚りã¾ã™ï¼Žä»¥ä¸‹ã®ã‚ˆã†ã«å発係数ãŒ1.0ã«è¨å®šã•れã¦ã„ã¾ã™ï¼Žã“ã®å€¤ã‚’ã„ã‚ã„ã‚変更ã—ã¦æŒ™å‹•を観察ã—ã¦ãã ã•ã„.1.0より大ããã™ã‚‹ã¨ã©ã†ãªã‚Šã¾ã™ã‹ï¼Ÿ è² ã«ã™ã‚‹ã¨ã©ã†ãªã‚‹ã§ã—ょã†ã‹ï¼Ÿã„ãšã‚Œã‚‚,ç¾å®Ÿã«ã¯ã‚りãˆãªã„å発係数ã§ã™ï¼Ž
- contact[i].surface.bounce = 1.0;
- サンプルプãƒã‚°ãƒ©ãƒ ã¯çƒã‚’å¼¾ã¾ã›ã¾ã—ãŸãŒï¼Œã“ã‚“ã©ã¯ç›´æ–¹ä½“ã‚’å¼¾ã¾ã›ã¦ãã ã•ã„.
- 直方体ã®åˆæœŸå§¿å‹¢ã‚’変ãˆï¼Œå°‘ã—æ–œã‚ã«ã—ã¦è½ä¸‹ã•ã›æŒ™å‹•を観察ã—ã¾ã—ょã†ï¼Ž
- ヒント:姿勢を変ãˆã‚‹ã«ã¯ODE本67ページã«ã‚ã‚‹dRFromAxisAndAngle()ã§å›žè»¢è»¸ã®ã¾ã‚りを回転ã•ã›ãŸã¨ãã®å›žè»¢è¡Œåˆ—Rã‚’å–å¾—ã—,ãã‚Œã‚’åˆæœŸå§¿å‹¢ã§è¨å®šã—ã¦ãã ã•ã„.
