Ejemplo n.º 1
0
int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = 0;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  if(argc==2)
    {
        fn.path_to_textures = argv[1];
    }

  // create world
  dInitODE2(0);

  int i;
  contactgroup.create ();
  world.setGravity (0,0,-0.5);
  dWorldSetCFM (world.id(),1e-5);
  dPlane plane (space,0,0,1,0);

  for (i=0; i<NUM; i++) {
    body[i].create (world);
    dReal k = i*SIDE;
    body[i].setPosition (k,k,k+0.4);
    dMass m;
    m.setBox (1,SIDE,SIDE,SIDE);
    m.adjust (MASS);
    body[i].setMass (&m);
    body[i].setData ((void*)(size_t)i);

    box[i].create (space,SIDE,SIDE,SIDE);
    box[i].setBody (body[i]);
  }
  for (i=0; i<(NUM-1); i++) {
    joint[i].create (world);
    joint[i].attach (body[i],body[i+1]);
    dReal k = (i+0.5)*SIDE;
    joint[i].setAnchor (k,k,k+0.4);
  }

  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dCloseODE();
  return 0;
}
Ejemplo n.º 2
0
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  // exit without doing anything if the two bodies are connected by a joint
  dBodyID b1 = dGeomGetBody(o1);
  dBodyID b2 = dGeomGetBody(o2);
  if (b1 && b2 && dAreConnected (b1,b2)) return;

  // @@@ it's still more convenient to use the C interface here.

  dContact contact;
  contact.surface.mode = 0;
  contact.surface.mu = dInfinity;
  if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom))) {
    dJointID c = dJointCreateContact (world.id(),contactgroup.id(),&contact);
    dJointAttach (c,b1,b2);
  }
}
Ejemplo n.º 3
0
static void simLoop (int pause)
{
  if (!pause) {
    static double angle = 0;
    angle += 0.05;
    body[NUM-1].addForce (0,0,1.5*(sin(angle)+1.0));

    space.collide (0,&nearCallback);
    world.step (0.05);

    // remove all contact joints
    contactgroup.empty();
  }

  dReal sides[3] = {SIDE,SIDE,SIDE};
  dsSetColor (1,1,0);
  dsSetTexture (DS_WOOD);
  for (int i=0; i<NUM; i++)
    dsDrawBox (body[i].getPosition(),body[i].getRotation(),sides);
}
Ejemplo n.º 4
0
int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;

  if (argc >= 2 ) {
    for (int i=1; i < argc; ++i) {
      if (  0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) )
        Help (argv);

      if (  0 == strcmp ("-p", argv[i]) || 0 == strcmp ("--PRJoint", argv[i]) )
        type = dJointTypePR;

      if (0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) {
        int j = i+1;
        if ( j+1 > argc      ||  // Check if we have enough arguments
             argv[j] == '\0' ||  // We should have a path here
             argv[j][0] == '-' ) // We should have a path not a command line
          Help (argv);
        else
          fn.path_to_textures = argv[++i]; // Increase i since we use this argument
      }
    }
  }

  dInitODE2(0);

  world.setERP (0.8);

  space = dSimpleSpaceCreate (0);
  contactgroup = dJointGroupCreate (0);
  geom[GROUND] = dCreatePlane (space, 0,0,1,0);
  dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]);
  dGeomSetCollideBits (geom[GROUND], catBits[ALL]);

  dMass m;

  // Create the body attached to the World
  body[W].create (world);
  // Main axis of cylinder is along X=1
  m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]);
  m.adjust (Mass1);
  geom[W] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]);
  dGeomSetBody (geom[W], body[W]);
  dGeomSetCategoryBits (geom[W], catBits[W]);
  dGeomSetCollideBits (geom[W], catBits[ALL] & (~catBits[W]) & (~catBits[JOINT]) );
  body[W].setMass(m);





  // Create the dandling body
  body[D].create(world);
  // Main axis of capsule is along X=1
  m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]);
  m.adjust (Mass1);
  geom[D] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]);
  dGeomSetBody (geom[D], body[D]);
  dGeomSetCategoryBits (geom[D], catBits[D]);
  dGeomSetCollideBits (geom[D], catBits[ALL] & (~catBits[D]) & (~catBits[JOINT]) );
  body[D].setMass(&m);


  // Create the external part of the slider joint
  geom[EXT] = dCreateBox (space, extDim[X], extDim[Y], extDim[Z]);
  dGeomSetCategoryBits (geom[EXT], catBits[EXT]);
  dGeomSetCollideBits (geom[EXT],
                       catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) );

  // Create the internal part of the slider joint
  geom[INT] = dCreateBox (space, INT_EXT_RATIO*extDim[X],
                          INT_EXT_RATIO*extDim[Y],
                          INT_EXT_RATIO*extDim[Z]);
  dGeomSetCategoryBits (geom[INT], catBits[INT]);
  dGeomSetCollideBits (geom[INT],
                       catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) );


  dMatrix3 R;
  dGeomID id;
  // Create the first axis of the universal joi9nt
  geom[AXIS1] = dCreateGeomTransform (space);
  //Rotation of 90deg around y
  dRFromAxisAndAngle (R, 0,1,0, 0.5*PI);
  dGeomSetRotation (geom[AXIS1], R);
  dGeomSetCategoryBits (geom[AXIS1], catBits[AXIS1]);
  dGeomSetCollideBits (geom[AXIS1],
                       catBits[ALL]  & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]);
  id = geom[AXIS1];
  dGeomTransformSetGeom (geom[AXIS1],  dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) );


  // Create the second axis of the universal joint
  geom[AXIS2] = dCreateGeomTransform (space);
  //Rotation of 90deg around y
  dRFromAxisAndAngle (R, 1,0,0, 0.5*PI);
  dGeomSetRotation (geom[AXIS2], R);
  dGeomSetCategoryBits (geom[AXIS2], catBits[AXIS2]);
  dGeomSetCollideBits (geom[AXIS2],
                       catBits[ALL]  & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]);
  id = geom[AXIS2];
  dGeomTransformSetGeom (geom[AXIS2],  dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) );


  // Create the anchor
  geom[ANCHOR] = dCreateBox (space, ancDim[X], ancDim[Y], ancDim[Z]);
  dGeomSetCategoryBits (geom[ANCHOR], catBits[ANCHOR]);
  dGeomSetCollideBits (geom[ANCHOR],
                       catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) );



  if (body[W]) {
    body[W].setPosition(0, 0, 5);
  }


  if (geom[EXT]) {
    dGeomSetPosition (geom[EXT], 0,0,3.8);
  }
  if (geom[INT]) {
    dGeomSetPosition (geom[INT], 0,0,2.6);
  }
  if (geom[AXIS1]) {
    dGeomSetPosition (geom[AXIS1], 0,0,2.5);
  }
  if (geom[AXIS2]) {
    dGeomSetPosition (geom[AXIS2], 0,0,2.5);
  }

  if (geom[ANCHOR]) {
    dGeomSetPosition (geom[ANCHOR], 0,0,2.25);
  }

  if (body[D]) {
    body[D].setPosition(0,0,1.5);
  }



  // Attache the upper box to the world
  dJointID fixed = dJointCreateFixed (world,0);
  dJointAttach (fixed , NULL, body[W]);
  dJointSetFixed (fixed );

  if (type == dJointTypePR) {
    dPRJoint *pr = new dPRJoint (world, 0);
    pr->attach (body[W], body[D]);
    pr->setAxis1 (0, 0, -1);
    pr->setAxis2 (1, 0, 0);
    joint = pr;

    dJointSetPRAnchor (pr->id(), 0, 0, 2.5);
  }
  else {
    dPUJoint *pu = new dPUJoint (world, 0);
    pu->attach (body[W], body[D]);
    pu->setAxis1 (1, 0, 0);
    pu->setAxis2 (0, 1, 0);
    pu->setAxisP (0, 0, -1);
    joint = pu;

    dJointSetPUAnchor (pu->id(), 0, 0, 2.5);
  }


  // run simulation
  dsSimulationLoop (argc,argv,400,300,&fn);

  delete joint;
  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);
  dCloseODE();
  return 0;
}
Ejemplo n.º 5
0
// called when a key pressed
static void command (int cmd)
{
  switch (cmd) {
case 'h' : case 'H' : case '?' :
      printKeyBoardShortCut();
      break;

      // Force
  case 'q' : case 'Q' :
      body[D].addForce(40,0,0);
      break;
  case 'w' : case 'W' :
      body[D].addForce(-40,0,0);
      break;

  case 'a' : case 'A' :
      body[D].addForce(0,40,0);
      break;
  case 's' : case 'S' :
      body[D].addForce(0,-40,0);
      break;

  case 'z' : case 'Z' :
      body[D].addForce(0,0,40);
      break;
  case 'x' : case 'X' :
      body[D].addForce(0,0,-40);
      break;

      // Torque
  case 'e': case 'E':
      body[D].addTorque(0.1,0,0);
      break;
  case 'r': case 'R':
      body[D].addTorque(-0.1,0,0);
      break;

  case 'd': case 'D':
      body[D].addTorque(0, 0.1,0);
      break;
  case 'f': case 'F':
      body[D].addTorque(0,-0.1,0);
      break;

  case 'c': case 'C':
      body[D].addTorque(0,0,0.1);
      break;
  case 'v': case 'V':
      body[D].addTorque(0,0,0.1);
      break;

      // Velocity of joint
  case ',': case '<' : {
      dReal vel = joint->getParam (dParamVel3) - VEL_INC;
      joint->setParam (dParamVel3, vel);
      std::cout<<"Velocity = "<<vel<<"  FMax = 2"<<'\n';
    }
    break;

  case '.': case '>' : {
      dReal vel = joint->getParam (dParamVel3) + VEL_INC;
      joint->setParam (dParamVel3, vel);
      std::cout<<"Velocity = "<<vel<<"  FMax = 2"<<'\n';
    }
    break;

  case 'l': case 'L' : {
      dReal aLimit, lLimit, fmax;
      if (  joint->getParam (dParamFMax) ) {
        aLimit = dInfinity;
        lLimit = dInfinity;
        fmax = 0;
      }
      else {
        aLimit = 0.25*PI;
        lLimit = 0.5*axDim[LENGTH];
        fmax = 0.02;
      }

      joint->setParam (dParamFMax1, fmax);
      joint->setParam (dParamFMax2, fmax);
      joint->setParam (dParamFMax3, fmax);

      switch (joint->getType() ) {
        case dJointTypePR : {
          dPRJoint *pr = reinterpret_cast<dPRJoint *> (joint);
          pr->setParam (dParamLoStop, -lLimit);
          pr->setParam (dParamHiStop, -lLimit);
          pr->setParam (dParamLoStop2, aLimit);
          pr->setParam (dParamHiStop2, -aLimit);
        }
        break;
        case dJointTypePU : {
          dPUJoint *pu = reinterpret_cast<dPUJoint *> (joint);
          pu->setParam (dParamLoStop1, -aLimit);
          pu->setParam (dParamHiStop1, aLimit);
          pu->setParam (dParamLoStop2, -aLimit);
          pu->setParam (dParamHiStop2, aLimit);
          pu->setParam (dParamLoStop3, -lLimit);
          pu->setParam (dParamHiStop3, lLimit);
        }
        break;
        default: {} // keep the compiler happy
      }
    }

    break;

  case 'g': case 'G' : {
      dVector3 g;
      world.getGravity(g);
      if (  g[2]< -0.1 )
        world.setGravity(0, 0, 0);
      else
        world.setGravity(0, 0, -0.5);

    }

case 'p' :case 'P' : {
      switch (joint->getType() ) {
        case dJointTypeSlider : {
          dSliderJoint *sj = reinterpret_cast<dSliderJoint *> (joint);
          std::cout<<"Position ="<<sj->getPosition() <<"\n";
        }
        break;
        case dJointTypePU : {
          dPUJoint *pu = reinterpret_cast<dPUJoint *> (joint);
          std::cout<<"Position ="<<pu->getPosition() <<"\n";
          std::cout<<"Position Rate="<<pu->getPositionRate() <<"\n";
          std::cout<<"Angle1 ="<<pu->getAngle1() <<"\n";
          std::cout<<"Angle1 Rate="<<pu->getAngle1Rate() <<"\n";
          std::cout<<"Angle2 ="<<pu->getAngle2() <<"\n";
          std::cout<<"Angle2 Rate="<<pu->getAngle2Rate() <<"\n";
        }
        break;
        default: {} // keep the compiler happy
      }
    }
    break;
  }
}
Ejemplo n.º 6
0
//===========================================================================================
//! \brief シミュレーションオブジェクトを作成
void create_world( void )
//===========================================================================================
{
  // acrobot の回転軸(以下,支柱)は ここでは 直方体(Box)にしています.
  const dReal param_h0     = 0.05; // 支柱(直方体)の高さ[m]
  const dReal param_wx0    = 0.05; // 同幅(x)
  const dReal param_wy0    = 0.80; // 同幅(y)
  const dReal param_z0     = 1.20; // 支柱の垂直位置[m]

  const dReal param_l1     = 0.50; // 第1リンク(支柱に近いリンク)の長さ[m]
  const dReal param_d1     = 0.15; // 同直径[m]
  const dReal param_l2     = 0.50; // 第2リンク(支柱に近いリンク)の長さ[m]
  const dReal param_d2     = 0.15; // 同直径[m]

  const dReal density      = 1000.0;  // 各リンクの密度[kg/m^3]. 参考(?)`人体の密度' は 900~1100 kg/m^3 (wikipedia)

  int i;
  contactgroup.create (0);
  world.setGravity (0,0,-9.8);  // 重力 [m/s^2]
  dWorldSetCFM (world.id(),1e-5);
  plane.create (space,0,0,1,0); // 地面(平面).

  i=0; {
    body[i].create (world);
    body[i].setPosition (0.0, 0.0, param_z0); // 支柱の中心座標
    dReal xx=param_wx0, yy=param_wy0, zz=param_h0;
    dMass m;
    m.setBox (density,xx,yy,zz);
    body[i].setMass (&m);
    LinkBase.create (space,xx,yy,zz);
    LinkBase.setBody (body[i]);
  }
  i=1; {
    body[i].create (world);
    body[i].setPosition (0.0, 0.0, param_z0-0.5*param_l1); // リンク1の中心座標
    dReal rad=0.5*param_d1, len=param_l1-2.0*rad;
    dMass m;
    m.setCappedCylinder (density,3,rad,len);  // direction(3): z-axis
    body[i].setMass (&m);
    Link1.create (space,rad,len);
    Link1.setBody (body[i]);
  }
  i=2; {
    body[i].create (world);
    body[i].setPosition (0.0, 0.0, param_z0-param_l1-0.5*param_l2); // リンク2の中心座標
    dReal rad=0.5*param_d2, len=param_l2-2.0*rad;
    dMass m;
    m.setCappedCylinder (density,3,rad,len);  // direction(3): z-axis
    body[i].setMass (&m);
    Link2.create (space,rad,len);
    Link2.setBody (body[i]);
  }

  i=0; {
    const dReal *pos = body[0].getPosition();
    joint[i].create (world);
    joint[i].attach (body[0],body[1]);
    joint[i].setAnchor (pos[0],pos[1],pos[2]); // 回転中心=支柱の中心(=原点)
    joint[i].setAxis (0.0,1.0,0.0); // 回転軸=y軸
    // joint[i].setParam (dParamHiStop, +0.5*M_PI); // 関節の可動範囲を制約するときに使う
    // joint[i].setParam (dParamLoStop, -0.5*M_PI); // acrobot の場合は省略
  }
  i=1; {
    const dReal *pos = body[1].getPosition();
    joint[i].create (world);
    joint[i].attach (body[1],body[2]);
    joint[i].setAnchor (pos[0],pos[1],pos[2]-0.5*param_l1); // 回転中心=リンク1とリンク2の間
    joint[i].setAxis (0.0,1.0,0.0); // 回転軸=y軸
  }
  base_joint.create(world);
  base_joint.attach(body[0].id(),0); // 支柱(body[0]) と 平面(0)の間の固定リンク.支柱が固定される.
  base_joint.set();
}