[ODE] Funny Friction problems

Dave Lloyd dave at chaos.org.uk
Wed Sep 24 23:29:36 MST 2003


I'm probably going out on a limb here as an ODE newb meself, but ODE 
contacts are generated for points and not a patch as might be a little 
more physical. As your wheel (a sphere) interpenetrates the road 
surface, the contact points are generated where the sphere intersects 
the surface. I'm not sure how evenly distributed these are but you may 
end up with an uneven set of points that will tend to expel the sphere 
from the road surface pushing it in a preferred direction.  You might 
achieve the desired results by playing around with the CFM and ERP 
parameters.

smythst wrote:

>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;
>}
>
>
>_______________________________________________
>ODE mailing list
>ODE at q12.org
>http://q12.org/mailman/listinfo/ode
>  
>



More information about the ODE mailing list