[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