[ODE] Bug in ODE !

Marco Vienup Marco at vienup.de
Sun Aug 1 13:31:10 MST 2004


Hi,
since some days I try to understand the results from the dJointGetFeedback
function.
I set up a small example at the end of the mail. I would be very amused if
someone
could take a look on it !
At the moment I am pretty sure that ode calculates the torques wrong or sets
the wrong
values in the struct. The torques oscillate between positive and negative
values, even
if there is no motion in the simulation ! And the values are definite wrong.
Maybe I am
just to stupid to understand it. But I hope someone here is able to
interpret the results.

Thanks
Marco



#define DENSITY (5.0)		// density of all objects
#define GPB 3			// maximum number of geometries per body
#define MAX_CONTACTS 4		// maximum number of contact points per body


static dWorldID world;
static dSpaceID space;
static dJointGroupID contactgroup;


static dBodyID bodyA;
static dGeomID geomA;
static dBodyID bodyB;
static dGeomID geomB;
static dJointID hinge;
static dJointFeedback feedback;

static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  int i;
  // if (o1->body && o2->body) return;

  // exit without doing anything if the two bodies are connected by a joint
  dBodyID b1 = dGeomGetBody(o1);
  dBodyID b2 = dGeomGetBody(o2);
  if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return;

  dContact contact[MAX_CONTACTS];   // up to MAX_CONTACTS contacts per
box-box
  for (i=0; i<MAX_CONTACTS; i++) {
    contact[i].surface.mode = dContactBounce | dContactSoftCFM;
    contact[i].surface.mu = dInfinity;
    contact[i].surface.mu2 = 0;
    contact[i].surface.bounce = 0.1;
    contact[i].surface.bounce_vel = 0.1;
    contact[i].surface.soft_cfm = 0.01;
  }
  if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,
			   sizeof(dContact))) {
    dMatrix3 RI;
    dRSetIdentity (RI);
    const dReal ss[3] = {0.02,0.02,0.02};
    for (i=0; i<numc; i++) {
      dJointID c = dJointCreateContact (world,contactgroup,contact+i);
      dJointAttach (c,b1,b2);
      dsDrawBox (contact[i].geom.pos,RI,ss);
    }
  }
}

static void start()
{

}

static void command (int cmd)
{

}

void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb)
{
	pos=dGeomGetPosition(geomA);
    R  =dGeomGetRotation(geomA);

	dVector3 sides;
    dGeomBoxGetLengths(geomA, sides);
    dsDrawBox(pos, R, sides);

	pos=dGeomGetPosition(geomB);
    R  =dGeomGetRotation(geomB);

    dGeomBoxGetLengths(geomB, sides);
    dsDrawBox(pos, R, sides);
}

static void simLoop (int pause)
{
	dSpaceCollide (space,0,&nearCallback);

	dWorldStep (world, 0.001);

	//Calculate hinge velocity
	dReal Gain = 0.1;
	dReal TruePosition = dJointGetHingeAngle(hinge);
	dReal DesiredPosition = 0;
	dReal Error = TruePosition - DesiredPosition;

	dReal DesiredVelocity = Error * Gain;

	//Set parameter
	dJointSetHingeParam(hinge, dParamFMax, 100.0);
	dJointSetHingeParam(hinge, dParamVel, -DesiredVelocity);

	//Read feedback
	dJointFeedback* fb=dJointGetFeedback(hinge);

	//Get hinge axis
	dVector3 axis;
	dJointGetHingeAxis(hinge, axis);

	//Calculate torque
	double torque1=(fb->t1[0]*axis[0])+(fb->t1[1]*axis[1])+(fb->t1[2]*axis[2]);
	double torque2=(fb->t2[0]*axis[0])+(fb->t2[1]*axis[1])+(fb->t2[2]*axis[2]);

	printf("t1: %f t2: %f v:%f\n", torque1, torque2, DesiredVelocity);

  // remove all contact joints
    dJointGroupEmpty (contactgroup);

    drawGeom (0,0,0,false);
}

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 = "D:/ode-0.5/drawstuff/textures";

  // create world
  world = dWorldCreate();
  space = dHashSpaceCreate (0);
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world, 0, 0, -1.0);
  dWorldSetCFM (world,1e-5);
  dCreatePlane (space,0,0,1,0);


  //Create Bodys
  bodyA = dBodyCreate(world);
  bodyB = dBodyCreate(world);

  //Set Position
  dBodySetPosition(bodyA, 0.0, 0.0, 1.5);
  dBodySetPosition(bodyB, 0.0, 1.0, 2.5);

  //Set Rotation
  dMatrix3 R;
  dRFromAxisAndAngle(R, 0.0, 0.0, 0.0, 0.0);
  dBodySetRotation(bodyA, R);
  dBodySetRotation(bodyB, R);

  //Create Mass Box
  dMass m;
  dMassSetBox(&m, DENSITY, 1.0, 1.0, 1.0);

  //Create Geom
  geomA=dCreateBox(space, 1.0, 1.0, 1.0);
  geomB=dCreateBox(space, 1.0, 1.0, 1.0);

  //Add Geom and Body
  dGeomSetBody(geomA, bodyA);
  dGeomSetBody(geomB, bodyB);

  dBodySetMass(bodyA, &m);
  dBodySetMass(bodyB, &m);

  //Reset Mass
  dBodyGetMass(bodyA, &m);
  dMassAdjust(&m, 10.0);
  dBodySetMass(bodyA, &m);

  dBodyGetMass(bodyB, &m);
  dMassAdjust(&m, 1.0);
  dBodySetMass(bodyB, &m);

  //Create Hinge
  hinge=dJointCreateHinge(world, 0);
  dJointAttach(hinge, bodyA, bodyB);
  dJointSetHingeAnchor(hinge, 0, 0.5, 2.0);
  dJointSetHingeAxis(hinge, 1.0, 0, 0);

  //Set Feedback pointer
  dJointSetFeedback(hinge, &feedback);

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

  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);

  return 0;
}


---
Marco Vienup
Tel: 0177/7963323
Mail: Marco at Vienup.de



More information about the ODE mailing list