ODEã§å¦ã¶C言語2 [Step6: ã¾ã¨ã‚]
ODEã§å¦ã¶C言語2ã®Step6ã§ã™ï¼Žä»Šå›žã§æœ€çµ‚回ã¨ãªã‚Šã¾ã™ï¼ŽODEã®ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®ç”Ÿæˆæ³•ã¨ç°¡å˜ãªåˆ¶å¾¡ã®ã‚µãƒ³ãƒ—ルプãƒã‚°ãƒ©ãƒ ã‚’å¦ã³ã¾ã—ょã†ï¼Ž
ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¯æˆ‘々ã®å‘¨ã‚Šã§ã¯ã€æŠ˜ç•³ã¿æºå¸¯ã®ãƒ’ンジやドアã®è¶ç•ªã«ç›¸å½“ã—ã¾ã™ã€‚å°é›£ã—ãã„ã†ã¨ã€ï¼’ã¤ã®ãƒœãƒ‡ã‚£ã®ä½ç½®ã‚„姿勢をã‚る一定ã®é–¢ä¿‚ã«ä¿ã¤æ‹˜æŸãŒã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¨ãªã®ã§ã™ã€‚ODEã§ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¨æ‹˜æŸã‚’åŒã˜æ„味ã§ä½¿ã£ã¦ã„ã¾ã™ã€‚
ODEã®ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆï¼ˆé–¢ç¯€ï¼‰ã¯ï¼’ã¤ã®ãƒœãƒ‡ã‚£(剛体,body)ã‚’ã¤ãªã’ã‚‹ã‚‚ã®ã§ã™ã€‚1ã¤ã®ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã§ï¼“個以上ã®ãƒœãƒ‡ã‚£ã‚’ã¤ãªã’ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã—,1個ã®ãƒœãƒ‡ã‚£ã ã‘ã‚’ã¤ãªã’ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“.必ãšï¼’個ã®ãƒœãƒ‡ã‚£ã‚’1ã¤ã®ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã§ã¤ãªã’ãªã‘れã°ãªã‚Šã¾ã›ã‚“.
ã¾ãŸï¼ŒODEã®ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã¯æ‘©æ“¦ãŒã‚りã¾ã›ã‚“ã—,å¯å‹•域をè¨å®šã—ãªã„ã¨+dInfinity(+ç„¡é™å¤§)ã‹ã‚‰-dInfinity(-ç„¡é™å¤§ï¼‰ã¾ã§å›žè»¢ã¾ãŸã¯ç§»å‹•ã—ã¾ã™ï¼Žè§’度ã¯[rad]ã§ã™ï¼Ž
- ジョイントã®ä½¿ã„æ–¹
- ***ジョイントã®ç”Ÿæˆã€€ã€€ã€€ã€€ã€€ã€€dmJointCreate***()
- ***ジョイントã¨ãƒœãƒ‡ã‚£ã®çµåˆã€€ dJointAttach(dJointID, dBodyID, dBodyID)
- ***ジョイントã®ä¸å¿ƒç‚¹ã‚’è¨å®šã€€dJointSet***Anchor()
- ***ジョイントã®å›žè»¢è»¸ã‚’è¨å®šã€€dJointSet***Axis()
上ã§***ã«ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®ã‚¿ã‚¤ãƒ—ãŒå…¥ã‚Šã¾ã™ã€‚タイプã«ã¯Hinge(ヒンジ)ã€Slider(スライダー)ãŒã‚りã¾ã™ã€‚サンプルプãƒã‚°ãƒ©ãƒ ã§ã¯ãƒ’ンジジョイントã¨ç›´å‹•å¼ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã‚’使ã„ã¾ã™ï¼Ž
- ジョイントã®ãƒ‘ラメータè¨å®š
- å¯å‹•域ã®è¨å®š
dJointSetHingeParam(dJointID, dParamLoStop, å¯å‹•域ã®ä¸‹é™ï¼‰;
dJointSetHingeParam(dJointID, dParamHiStop, å¯å‹•域ã®ä¸Šé™ï¼‰; - 目標角速度ã¨ãれを実ç¾ã™ã‚‹ãŸã‚ã®æœ€å¤§ãƒˆãƒ«ã‚¯ã®è¨å®š
dJointSetHingeParam(dJointID, dParamVel, 目標角速度);
dJointSetHingeParam(dJointID, dParamFMax, 最大トルク);
パラメータã¨ã—ã¦ã¯ã€é–¢ç¯€å¯å‹•域ã®ä¸‹é™ã‚’示ã™dParamLoStopã€ä¸Šé™ã‚’示ã™dParamHiStopã€è§’速度(ヒンジジョイント)ã¾ãŸã¯é€Ÿåº¦(ç›´å‹•å¼é–¢ç¯€ï¼‰ã‚’示ã™dParamVelã€æœ€å¤§ãƒˆãƒ«ã‚¯ã‚’示ã™dParaFMaxãªã©ãŒã‚りã¾ã™ã€‚ãªãŠã€ODEã§ã¯é–¢ç¯€ã«ãƒ¢ãƒ¼ã‚¿ãŒæ¨™æº–ã§çµ„ã¿è¾¼ã¾ã‚Œã¦ã„ã‚‹ã®ã§ã€dParamVelã‚„dParaFMaxを指定ã™ã‚‹ã¨é–¢ç¯€ãŒå‹•ãã¾ã™ã€‚
ソースコード
å°‘ã—é•·ããªã‚Šã¾ã™ãŒï¼Œã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’掲載ã—ã¾ã™ï¼Žã“ã®ã‚³ãƒ¼ãƒ‰ã¯ä»Šã¾ã§ç¿’ã£ãŸï¼Œã‚ーæ“作関数,シミュレーションã®å†ã‚¹ã‚¿ãƒ¼ãƒˆï¼Œãƒœãƒ‡ã‚£ã¸åŠ›ã‚’åŠ ãˆã‚‹ãªã©ã®ã»ã‹ã«ï¼Œã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã®ç”Ÿæˆã¨åˆ¶å¾¡æ³•ãªã©ç°¡å˜ãªã‚²ãƒ¼ãƒ やシミュレータを作るãŸã‚ã«å¿…è¦ãªã“ã¨ã¯ä¸€é€šã‚Šå…¥ã£ã¦ã„ã¾ã™ï¼Ž
/* step6 */
#define START_X 0.0
#define START_Y 0.0
#define START_Z 0.1
dmObject torso, leg[2], ball;
static int STEPS = 0; // シミュレーションã®ã‚¹ãƒ†ãƒƒãƒ—æ•°
double S_LENGTH = 0.0; // スライダー長
double H_ANGLE = 0; //ヒンジã®è§’度
// ãƒãƒœãƒƒãƒˆã®ç”Ÿæˆ
void createMonoBot()
{
int i;
double l_leg = 0.75; // é•·ã•
double m_leg = 1.0; // 質é‡
double r_leg[2] = {0.05, 0.03}; // åŠå¾„
double m_torso = 100.0; // 胴体ã®è³ªé‡
double r_torso = 0.25; // 胴体ã®åŠå¾„
double l_torso = 0.2; // 胴体ã®é«˜ã•
double r_ball = 0.11; // ボールã®åŠå¾„
double m_ball = 0.5; // ボールã®è³ªé‡
double p_ball[3] = {START_X, START_Y+2*l_leg+0.1, START_Z}; // ボールã®ä½ç½®
double p_torso[3] = {START_X, START_Y, START_Z}; // ä½ç½®
double p_leg[2][3] = {{START_X, START_Y+0.5*l_leg, START_Z},
{START_X, START_Y+l_leg, START_Z}
};
double p_anchor[3] = {START_X, START_Y, START_Z};
double R[12]; // 回転行列
static double red[3] = {1.0, 0.0, 0.0}; // 色
static double color_leg[2][3] = {{0.0, 0.0, 1.0},{1.3, 1.3, 1.3}};
dRSetIdentity(R); //回転行列をå˜ä½è¡Œåˆ—ã§åˆæœŸåŒ–
dmCreateSphere(&ball, p_ball,R,m_ball, r_ball, red); // ボールã®ç”Ÿæˆ
dmCreateCylinder(&torso,p_torso,R,m_torso,r_torso,l_torso,red); // 胴体ã®ç”Ÿæˆ
dRFromAxisAndAngle(R, 1, 0, 0, M_PI/2);
for (i = 0; i < 2; i++)
{
dmCreateCapsule(&leg[i],p_leg[i],R,m_leg,r_leg[i],l_leg,color_leg[i]); // 脚ã®ç”Ÿæˆ
}
// ヒンジジョイント
leg[0].joint = dmJointCreateHinge();
dJointAttach(leg[0].joint, torso.body,leg[0].body);
dJointSetHingeAnchor(leg[0].joint, p_anchor[0],p_anchor[1],p_anchor[2]);
dJointSetHingeAxis(leg[0].joint, 0, 0, 1);
// スライダージョイント
leg[1].joint = dmJointCreateSlider();
dJointAttach(leg[1].joint, leg[0].body,leg[1].body);
dJointSetSliderAxis(leg[1].joint, 0, 1, 0);
dJointSetSliderParam(leg[1].joint, dParamLoStop, -0.25);
dJointSetSliderParam(leg[1].joint, dParamHiStop, 0.25);
}
// ヒンジジョイントã®åˆ¶å¾¡
static void controlHinge(dReal target)
{
static dReal kp = 10.0, fmax = 1000;
dReal tmp = dJointGetHingeAngle(leg[0].joint);
dReal diff = target - tmp;
if (diff >= M_PI) diff -= 2.0 * M_PI; // diffãŒ2πよりå°ã•ã
if (diff <= - M_PI) diff += 2.0 * M_PI; // diffãŒ-2πより大ãã
dReal u = kp * diff;
dJointSetHingeParam(leg[0].joint, dParamVel, u);
dJointSetHingeParam(leg[0].joint, dParamFMax, fmax);
}
// スライダã®åˆ¶å¾¡ プãƒã‚°ãƒ©ãƒ 2.4
static void controlSlider(dReal target)
{
static dReal kp = 25.0; // 比例定数
static dReal fmax = 1000; // 最大力[N]
double tmp, u;
tmp = dJointGetSliderPosition(leg[1].joint); // スライダã®ç¾åœ¨ä½ç½®
u = kp * (target - tmp); // 残差
dJointSetSliderParam(leg[1].joint, dParamVel, u);
dJointSetSliderParam(leg[1].joint, dParamFMax, fmax);
}
// シミュレーションã®ãƒªã‚»ãƒƒãƒˆ
static void resetSim()
{
STEPS = 0; // ステップ数ã®åˆæœŸåŒ–
H_ANGLE = 0.0; // ヒンジ角度ã®åˆæœŸåŒ–
S_LENGTH = 0.0;
if (STEPS != 0) dmClose(); // シミュレーションã®çµ‚了
dmInit(); // シミュレーションã®åˆæœŸåŒ–
createMonoBot();
}
// ã‚ーæ“作
void command(int cmd)
{
switch (cmd)
{
case 'j':
S_LENGTH = 0.25;
break;
case 'l':
S_LENGTH = - 0.25;
break;
case 'i':
H_ANGLE += 0.25;
if (H_ANGLE > M_PI) H_ANGLE = -M_PI;
break;
case 'm':
H_ANGLE -= 0.25;
if (H_ANGLE < -M_PI) H_ANGLE = M_PI;
break;
case 'r':
resetSim();
break;
case 'a':
dBodyAddForce(torso.body, 0, -500, 0);
break;
case 'w':
dBodyAddForce(torso.body, -500, 0, 0);
break;
case 'd':
dBodyAddForce(torso.body, 0, 500, 0);
break;
case 'x':
dBodyAddForce(torso.body, 500, 0, 0);
break;
case 's':
dBodySetLinearVel(torso.body, 0, 0, 0);
dBodySetAngularVel(torso.body, 0, 0, 0);
break;
default :
printf("key missed \n");
break;
}
}
void simLoop(int pause) /*** シミュレーションループ ***/
{
int i;
int s = 1000; // è·³èºã™ã‚‹å‘¨æœŸ(ステップ)
if (!pause)
{
printf("STEPS=%d \n",STEPS++); // ステップ数
// スライダーã®ä¼¸ç¸®
//if ((0 <= (STEPS%s)) && ((STEPS%s) <= 10)) S_LENGTH = 0.6;
//else if ((11 <= (STEPS%s)) && ((STEPS%s) <= 15)) S_LENGTH = 0.0;
controlSlider(S_LENGTH); // スライダージョイントã®åˆ¶å¾¡
controlHinge(H_ANGLE); // ヒンジジョイントã®åˆ¶å¾¡
dmSimStep(); // シミュレーションを1ステップ進ã‚ã‚‹
}
dmDraw(&ball); // ãƒœãƒ¼ãƒ«ã®æç”»
// ãƒãƒœãƒƒãƒˆã®æç”»
dmDraw(&torso); // èƒ´ä½“ã®æç”»
for (i = 0; i < 2; i++)dmDraw(&leg[i]); //è„šã®æç”»
STEPS++;
}
int main() /*** main関数 ***/
{
dmInit(); // ODEã®åˆæœŸåŒ–
resetSim(); // ãƒãƒœãƒƒãƒˆã®ç”Ÿæˆ
dmLoop(800, 600, simLoop, command); // シミュレーションループ ウインドウã®å¹…,高
dmClose(); // ODEã®çµ‚了
return 0;
}
ホームワーク
- step6-100726.zipをダウンãƒãƒ¼ãƒ‰ã—ã¦å®Ÿè¡Œã—ã¦ã¿ã¾ã—ょã†ï¼Ž
- サンプルプãƒã‚°ãƒ©ãƒ を改良ã—ã¦ãƒ“リヤードをプレイã™ã‚‹ãƒãƒœãƒƒãƒˆã‚’作りã¾ã—ょã†ï¼Ž
