ODE講座13:圧力センサを作ã‚ã†ï¼

2006-12-12
By

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

今回㯠ジョイント(関節)ã«ã‹ã‹ã‚‹åŠ›ã‚’å–å¾—ã™ã‚‹æ–¹æ³•を勉強ã—ã¾ã™ï¼Ž

ã“れを応用ã™ã‚‹ã¨ãƒ’ューマノイドロボットã®è¶³è£ã«ä»˜ã‘,ZMPã®è¨ˆæ¸¬ã«åˆ©ç”¨ã™ã‚‹åœ§åŠ›ã‚»ãƒ³ã‚µã‚’ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ãƒˆã§ãã¾ã™ï¼Ž

  • void dJointSetFeedback (dJointID, dJointFeedback *);
    力ã¨ãƒˆãƒ«ã‚¯ã®æƒ…報をå–å¾—ã™ã‚‹é–¢ç¯€JointIDã«dJointFeedback構造体を設定ã™ã‚‹ï¼Ž
    typedef struct dJointFeedback {
    dVector3 f1; // 関節ãŒãƒœãƒ‡ã‚£1ã«åŠã¼ã—ã¦ã„る力
    dVector3 t1; // 関節ãŒãƒœãƒ‡ã‚£1ã«åŠã¼ã—ã¦ã„るトルク
    dVector3 f2; // 関節ãŒãƒœãƒ‡ã‚£2ã«åŠã¼ã—ã¦ã„る力
    dVector3 t2; // 関節ãŒãƒœãƒ‡ã‚£2ã«åŠã¼ã—ã¦ã„るトルク
    } dJointFeedback;
  • dJointFeedback *dJointGetFeedback (dJointID);
    dJointIDã§æŒ‡å®šã—ã¦ã„る関節ã®åŠ›ã¨ãƒˆãƒ«ã‚¯ã®æƒ…報をå–å¾—ã—ã¾ã™ï¼Ž

次 ã«ï¼Œã“ã®APIを使ã£ãŸã‚µãƒ³ãƒ—ルプログラムを紹介ã—ã¾ã™ï¼Žï¼’ã¤ã®ãƒœãƒƒã‚¯ã‚¹ã‚’固定ジョイント(Fixed Joint)ã§ãã£ã¤ã‘,ãã“ã«ã‹ã‹ã‚‹åŠ›ã‚’è¡¨ç¤ºã™ã‚‹ãƒ—ログラムã§ã™ï¼Žãƒœãƒƒã‚¯ã‚¹ã®é‡ã•ãŒå„1kgãªã®ã§ï¼Œz軸方å‘(上方å‘)ã«ã¯9.8Nã®åŠ›ãŒã‹ã‹ã£ã¦ã„れ ã°ç†è«–ã©ãŠã‚Šã§ã™ï¼Žç§ã®ç’°å¢ƒã§ã¯ç†è«–ã©ãŠã‚Š9.8ã®å€¤ã‚’ãŸãŸã出ã—ã¦ã„ã¾ã—ãŸï¼Ž

ãªãŠï¼Œãƒ—ログラムã§ã¯ï¼’ã¤ã®ãƒœãƒƒã‚¯ã‚¹ã®ã†ã¡ï¼Œä¸‹ã‚’圧力センサã¨ã¿ãªã—ã¦ã„ã¾ã™ï¼Žãƒ’ューマノイド足è£ã®åœ§åŠ›ã‚»ãƒ³ã‚µã‚’ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ãƒˆã™ã‚‹å ´åˆã¯ï¼Œä¸‹ã®ãƒœãƒƒã‚¯ã‚¹ã®ã‚µã‚¤ã‚ºã‚’å°ã•ãã—,数を増やã›ã°ã‚ˆã„ã‚ã‘ã§ã™ï¼Ž

[code]
// sensor.cpp by Kosei Demura 2006-7-26
#include
#include

static dWorldID world;
static dSpaceID space;
static dGeomID ground;
static dJointID fixed;
static dJointGroupID contactgroup;
dJointFeedback *feedback = new dJointFeedback;
dsFunctions fn;

typedef struct {
dBodyID body;
dGeomID geom;
dReal radius,length,width,height,mass;
} myLink;
myLink box,sensor;

static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
static int MAX_CONTACTS = 10;
int i;

// 2ã¤ã®ãƒœãƒ‡ã‚£ãŒã‚¸ãƒ§ã‚¤ãƒ³ãƒˆã§çµåˆã•れã¦ã„ãŸã‚‰è¡çªæ¤œå‡ºã—ãªã„
dBodyID b1 = dGeomGetBody(o1);
dBodyID b2 = dGeomGetBody(o2);
if (b1 && b2 && dAreConnected (b1,b2)) return;

dContact contact[MAX_CONTACTS]; //
int numc = dCollide(o1,o2,MAX_CONTACTS,&contact[0].geom,
sizeof(dContact));
if (numc > 0) {
for (i=0; i
contact[i].surface.mode = dContactSoftCFM | dContactSoftERP;
contact[i].surface.mu = dInfinity;  // 摩擦係数
contact[i].surface.soft_cfm = 1e-8;
contact[i].surface.soft_erp = 1.0;
dJointID c = dJointCreateContact(world,contactgroup,&contact[i]);
dJointAttach (c,dGeomGetBody(contact[i].geom.g1),
dGeomGetBody(contact[i].geom.g2));
}
}
}

static void simLoop (int pause)
{
static int steps = 0;

dSpaceCollide(space,0,&nearCallback);
dWorldStep(world,0.01);
dJointGroupEmpty(contactgroup);

feedback = dJointGetFeedback(fixed); // 力ã¨ãƒˆãƒ«ã‚¯æƒ…å ±ã®å–å¾—
printf("%5d Force fx=%6.2f ",steps++,feedback->f1[0]); // x座標æˆåˆ†
printf("fy=%6.2f ",feedback->f1[1]);             // y座標æˆåˆ†
printf("fz=%6.2f \n",feedback->f1[2]);            // z座標æˆåˆ†

// ãƒœãƒƒã‚¯ã‚¹ã®æç”»
dsSetColor(1.0,0.0,0.0);
dReal sides1[] = {box.length,box.width,box.height};
dsDrawBoxD(dBodyGetPosition(box.body),
dBodyGetRotation(box.body),sides1);

// ã‚»ãƒ³ã‚µã®æç”»
dsSetColor(0.0,0.0,1.0);
dReal sides2[] = {sensor.length,sensor.width,sensor.height};
dsDrawBoxD(dBodyGetPosition(sensor.body),
dBodyGetRotation(sensor.body),sides2);
}

void start()
{
static float xyz[3] = {0.0,-3.0,1.0};
static float hpr[3] = {90.0,0.0,0.0};
dsSetViewpoint (xyz,hpr);
}

void setDrawStuff() {
fn.version = DS_VERSION;
fn.start = &start;
fn.step = &simLoop;
fn.command = NULL;
fn.stop = NULL;
fn.path_to_textures = "../../drawstuff/textures";
}

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);

dMass m1;
dReal x0 = 0.0, y0 = 0.0, z0 = 0.0;

// センサ(下ã®ãƒœãƒƒã‚¯ã‚¹ï¼‰
sensor.length = 0.2; sensor.width = 0.2;
sensor.height = 0.2; sensor.mass = 1.0;
sensor.body = dBodyCreate(world);
dMassSetZero(&m1);
dMassSetBoxTotal(&m1,sensor.mass,sensor.length,sensor.width,sensor.height);
dBodySetMass(sensor.body,&m1);
dBodySetPosition(sensor.body, x0, y0, 0.5 * sensor.height + z0);

sensor.geom = dCreateBox(space,sensor.length,sensor.width,sensor.height);
dGeomSetBody(sensor.geom,sensor.body);

// ボックス(上ã®ãƒœãƒƒã‚¯ã‚¹ï¼‰
box.length = 0.2; box.width = 0.2;
box.height = 0.2; box.mass = 1.0;
box.body = dBodyCreate(world);
dMassSetZero(&m1);
dMassSetBoxTotal(&m1,box.mass,box.length,box.width,box.height);
dBodySetMass(box.body,&m1);
dBodySetPosition(box.body, x0, y0, sensor.height + 0.5 * box.height + z0);

box.geom = dCreateBox(space,box.length,box.width,box.height);
dGeomSetBody(box.geom,box.body);

// 固定ジョイント
fixed = dJointCreateFixed(world,0);
dJointAttach(fixed,box.body,sensor.body);
dJointSetFixed(fixed);

// 力ã¨ãƒˆãƒ«ã‚¯æƒ…報をå–å¾—ã™ã‚‹é–¢ç¯€ã‚’指定
dJointSetFeedback(fixed,feedback);

dsSimulationLoop(argc,argv,352,288,&fn);
dWorldDestroy(world);
return 0;
}

[/code]

コメントをã©ã†ãž

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

1,387 views  (Since 2010-08-11)