[ODE] rolling friction

Nagymathe Denes denes at invictus.hu
Tue Nov 29 01:04:01 MST 2005


Hi,

Using angular damping may look correct in most situations, but physically it 
isn't (at least you have to check whether the body is touching some surface 
or not to avoid the damping in mid-air). Some while ago i have implemented 
an estimation of rolling resistance by changing the contact point a bit 
further to the direction of the movement. It works pretty well. This code 
fraction comes into nearcallback, just before creating the contact joint.
I have tried two versions; their results are quite similar, but the second 
one is simpler.

#ifdef ROLLING_RESISTANCE
// The basic method for rolling resistance: shift contact point a bit 
forward to get some torque against rolling
// The normal should also be changed; we don't do that yet, but that seems 
unnecessary
// it could be limited to shapes with curved surfaces (sphere, capsule, 
cylinder)
// and/or the factor should be set in the geom or body
// Unsolved issue: spheres still keep their spin around the 'vertical' axis, 
althought they do stop rolling
{
dReal rrfactor = 0.01f;
int j;
//method a:
/* dReal bq[4], dq[4];
dVector3 p1,p2,p3;
dMatrix3 bR;
dWtoDQ (b1->avel,b1->q,dq);
for (j=0; j<4; j++) bq[j] = b1->q[j] + 0.5*dq[j]*rrfactor;
dNormalize4 (bq);
dQtoR (bq,bR);
for (j=0; j<3; j++) p1[j] = nc->geom.pos[j] - b1->pos[j];
dMULTIPLY1_331 (p2,b1->R,p1);
dMULTIPLY0_331 (p3,bR,p2);
for (j=0; j<3; j++) nc->geom.pos[j] -= p3[j] - p1[j];
if (b2)
{
dWtoDQ (b2->avel,b2->q,dq);
for (j=0; j<4; j++) bq[j] = b2->q[j] + 0.5*dq[j]*rrfactor;
dNormalize4 (bq);
dQtoR (bq,bR);
for (j=0; j<3; j++) p1[j] = nc->geom.pos[j] - b2->pos[j];
dMULTIPLY1_331 (p2,b2->R,p1);
dMULTIPLY0_331 (p3,bR,p2);
for (j=0; j<3; j++) nc->geom.pos[j] -= p3[j] - p1[j];
}
*/
//method b:
dVector3 p1,p2;
const dReal *bp = dBodyGetPosition(b1);
const dReal *av = dBodyGetAngularVel(b1);
for (j=0; j<3; j++) p1[j] = nc->geom.pos[j] - bp[j];
dCROSS(p2, =, av, p1);
for (j=0; j<3; j++) nc->geom.pos[j] -= p2[j]*rrfactor;
if (b2)
{
bp = dBodyGetPosition(b2);
for (j=0; j<3; j++) p1[j] = nc->geom.pos[j] - bp[j];
av = dBodyGetAngularVel(b2);
dCROSS(p2, =, av, p1);
for (j=0; j<3; j++) nc->geom.pos[j] -= p2[j]*rrfactor;
}
}
#endif //ROLLING_RESISTANCE 




More information about the ODE mailing list