ODE講座16: 圧力センサを作ã‚ã†ï¼
 
haltiã•ã‚“ã‹ã‚‰ã®å¾¡è³ªå•ã«ã‚ã£ãŸã‚ˆã†ã«é–¢ç¯€ã«ã‹ã‹ã‚‹ãƒˆãƒ«ã‚¯ã‚„力を調ã¹ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã¯ã‚ã‹ã‚Šã¥ã‚‰ããªã£ã¦ã„ã¾ã™ï¼Ž
 ODEã§ã¯é–¢ç¯€ã«ã‹ã‹ã‚‹ãƒˆãƒ«ã‚¯ãªã©ã‚’ã™ãå–å¾—ã§ãã¾ã›ã‚“.å–å¾—ã™ã‚‹ãŸã‚ã«ã¯dJointSetFeedbackã§é–¢ç¯€ã‚’指定ã—ã¦ã‹ã‚‰dJointGetFeedbackã§æƒ…å ±ã‚’å–å¾—ã—ã¾ã™ï¼Žã“れã¯ãƒ‘フォーマンスをå‘上ã•ã›ã‚‹ãŸã‚ã§ã™ï¼Žå¸¸ã«å…¨ã¦ã®é–¢ç¯€ã«ã‹ã‹ã‚‹åŠ›ã¨ãƒˆãƒ«ã‚¯ãŒå¿…è¦ãªã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“よã.
-
void dJointSetFeedback (dJointID, dJointFeedback *);
力ã¨ãƒˆãƒ«ã‚¯ã®æƒ…å ±ã‚’å–å¾—ã™ã‚‹é–¢ç¯€ã‚’dJointIDã§æŒ‡å®šã™ã‚‹ï¼Ž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ã®å€¤ã‚’ãŸãŸã出ã—ã¦ã„ã¾ã—ãŸï¼Ž
ãªãŠï¼Œãƒ—ãƒã‚°ãƒ©ãƒ ã§ã¯ï¼’ã¤ã®ãƒœãƒƒã‚¯ã‚¹ã®ã†ã¡ï¼Œä¸‹ã‚’圧力センサã¨ã¿ãªã—ã¦ã„ã¾ã™ï¼Ž
// sensor.cpp by Kosei Demura 2006-7-26
#include <ode/ode.h>
#include <drawstuff/drawstuff.h>
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<numc; 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;
}