[ODE] Funny Friction problems

smythst smythst at tcd.ie
Wed Sep 24 20:37:46 MST 2003


Aloha again all. Yee must be sick of me by now, but thanks for all the help so 
far.

I've run into a bit of a conundrum with friction in ODE. I've pasted the code 
below (and yes it's very untidy, but I'm only getting used to ODE, so this is 
just a test). The problem, after I remove all forces from the car body, it 
keeps on rolling forever, but I have friction set at dInfinity, what's up?





#include "ode/ode.h"
#include "drawstuff/drawstuff.h"

#ifdef MSVC
#pragma warning(disable:4244 4305)  // for VC++, no precision loss complaints
#endif

/* select correct drawing functions */

#ifdef dDOUBLE
#define dsDrawBox dsDrawBoxD
#define dsDrawSphere dsDrawSphereD
#define dsDrawCylinder dsDrawCylinderD
#define dsDrawCappedCylinder dsDrawCappedCylinderD
#endif


/* some constants */
#define SCALE  (3.0f)	/* scale all objects by this factor */
#define NUM 5			/* car body + 4 wheels */
#define SIDE (2.0f)		/* side length of a box */
#define CARBODYMASS (20.0)	/* mass of a carbody */
#define WHEELMASS (0.933f)	/*mass of each wheel*/
#define RADIUS (0.1732f)	/* wheel radius */
#define FORCE (0.1f)	/* the force to be applied on a key press*/
#define DENSITY (1.9f)
#define SCALE  (3.0f)	/* scale all objects by this factor */


/* dynamics and collision objects */

static dWorldID world;
static dSpaceID space;
static dBodyID body[NUM];			//[0] = car body, [1] = FL wheel, [2] = FR wheel, 
[3] = RL wheel, [4] = RR wheel
static dJointID joint[NUM-1];		//FL-body,FR-body,RL-body,RR-body
static dJointGroupID contactgroup;
static dJointGroupID joints;
static dGeomID components[NUM];		//[0] = car body, [1] = FL wheel, [2] = FR 
wheel, [3] = RL wheel, [4] = RR wheel
static double sides[3] = {SIDE,SIDE/2,SIDE/8};	//the sides of the car body
static int x = 0,y = 0,z = 0;
static int scalar = -1;



/* this is called by dSpaceCollide when two objects in space are
 * potentially colliding.s
 */

static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  /* exit without doing anything if the two bodies are connected by a joint */
  dBodyID b1,b2;
  dContact contact;

  b1 = dGeomGetBody(o1);
  b2 = dGeomGetBody(o2);
  if (b2 && b2 && dAreConnected (b1,b2)) return;

  contact.surface.mode = 0;
  contact.surface.mu = dInfinity;
  contact.surface.mu2 = 0;
  if (dCollide (o1,o2,0,&contact.geom,sizeof(dContactGeom))) {
    dJointID c = dJointCreateContact (world,contactgroup,&contact);
    dJointAttach (c,b1,b2);
  }
}


/* start simulation - set viewpoint */

static void start()
{
  static float xyz[3] = {2.1640f,-1.3079f,1.7600f};
  static float hpr[3] = {125.5000f,-17.0000f,0.0000f};
  dsSetViewpoint (xyz,hpr);
}


/* simulation loop */

static void simLoop (int pause)
{
  int i;
  if (!pause) {
    static double angle = 0;
    angle += 0.05;
    dBodyAddForce (body[0], x*FORCE,y*FORCE,z*FORCE);
	if(x > 10) x = 10;
	if(x < -10) x = -10;
	if(y > 10) y = 10;
	if(y < -10) y = -10;
    dSpaceCollide (space,0,&nearCallback);
    dWorldStep (world,0.05);


    /* remove all contact joints */
    dJointGroupEmpty (contactgroup);
  }

  dsSetColor (1,1,0);
  dsSetTexture (DS_WOOD);
  dsDrawBox(dBodyGetPosition(body[0]), dBodyGetRotation(body[0]), sides);
  for(i = 1; i < NUM; i++){

	dsDrawSphere(dBodyGetPosition(body[i]),dBodyGetRotation(body[i]),RADIUS);
  }
}


static void command(int cmd){

	switch(cmd){
	case 'w':
		x += 1;
		break;
	case 's':
		x -= 1;
		break;
	case 'a':
		y -= 1;
		break;
	case 'd':
		y += 1;
		break;
	case 'q':
		x=y=z=0;
		break;
	case 'p':
		z += 1;
		break;
	case 'l':
		z -= 1;
		break;

	case 'x':
		dJointDestroy(joint[0]);
		break;
/*	case 'z':
		joint[0] = dJointCreateBall(world,joints);
		dJointAttach(joint[0],body[0],body[1]);
		break;
		*/

	}
}



int main (int argc, char **argv)
{
	int i;
	dMass m;

	/* 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/textures";

	/* create world */

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

	for(i = 0; i < NUM; i++){
		body[i] = dBodyCreate(world);
	}
	//Tha car body
	dBodySetPosition(body[0],0,0,2*RADIUS);
	dMassSetBox(&m,DENSITY, sides[0], sides[1], sides[2]);
	dMassAdjust(&m,CARBODYMASS);
	dBodySetMass(body[0],&m);
	components[0] = dCreateBox(space, sides[0], sides[1], sides[2]);
	dGeomSetBody(components[0], body[0]);

	//Front left wheel
	dBodySetPosition(body[1], sides[0]/2,(sides[1]/2),-RADIUS);
	dMassSetSphere(&m,DENSITY,RADIUS);
	dMassAdjust(&m,WHEELMASS);
	dBodySetMass(body[1],&m);
	components[1] = dCreateSphere(space,RADIUS);
	dGeomSetBody(components[1],body[1]);

	//Front Right wheel
	dBodySetPosition(body[2], sides[0]/2,-(sides[1]/2),-RADIUS);
	dMassSetSphere(&m,DENSITY,RADIUS);
	dMassAdjust(&m,WHEELMASS);
	dBodySetMass(body[2],&m);
	components[2] = dCreateSphere(space,RADIUS);
	dGeomSetBody(components[2],body[2]);

	//Rear Left wheel
	dBodySetPosition(body[3], -(sides[0]/2),sides[1]/2,-RADIUS);
	dMassSetSphere(&m,DENSITY,RADIUS);
	dMassAdjust(&m,WHEELMASS);
	dBodySetMass(body[3],&m);
	components[3] = dCreateSphere(space,RADIUS);
	dGeomSetBody(components[3],body[3]);

	//Rear Right wheel
	dBodySetPosition(body[4], -(sides[0])/2,-(sides[1]/2),-RADIUS);
	dMassSetSphere(&m,DENSITY,RADIUS);
	dMassAdjust(&m,WHEELMASS);
	dBodySetMass(body[4],&m);
	components[4] = dCreateSphere(space,RADIUS);
	dGeomSetBody(components[4],body[4]);

	for (i=0; i<NUM - 1; i++) {

		joint[i] = dJointCreateHinge2 (world,joints);
		dJointAttach (joint[i],body[0],body[i+1]);
		dJointSetHinge2Anchor(joint[i], 
*(dBodyGetPosition(body[i+1])),*(dBodyGetPosition(body[i+1]) + 1), 
*(dBodyGetPosition(body[i+1]) + 2));
		dJointSetHinge2Axis1 (joint[0],0,0,1);
		dJointSetHinge2Axis2 (joint[0],0,-1*scalar,0);
#ifdef FREEFRONTWHEELS
		if(i > 1){
#endif
			dJointSetHinge2Param (joint[i],dParamLoStop,0);
			dJointSetHinge2Param (joint[i],dParamHiStop,0);
#ifdef FREEFRONTWHEELS
		}
#endif
		scalar *= -1;

	}




	/*
	for (i=0; i<NUM; i++) {

		body[i] = dBodyCreate (world);
		k = i*SIDE;
		dBodySetPosition (body[i],k,k,0);
		dMassSetBox(&m,DENSITY,SIDE,SIDE,SIDE);
		dMassAdjust (&m,MASS);
		dBodySetMass (body[i],&m);
		sphere[i] = dCreateBox(space,SIDE,SIDE,SIDE);
		dGeomSetBody (sphere[i],body[i]);
	}
	for (i=0; i<(NUM-1); i++) {

		joint[i] = dJointCreateBall (world,joints);
		dJointAttach (joint[i],body[i],body[i+1]);
		k = (i+0.5)*SIDE;
		dJointSetBallAnchor (joint[i],k,k,k+0.4);
		//dJointSetBallParam(joint[i],dParamLoStop, -60);
		//dJointSetBallParam(joint[i],dParamHiStop,60);
	}*/

	/* run sim */
	dsSimulationLoop (argc,argv,640,480,&fn);

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

	return 0;
}




More information about the ODE mailing list