Different types of friction.

Post Reply
bram
Posts: 51
Joined: Sun Nov 23, 2008 4:43 pm

Different types of friction.

Post by bram »

My app is coming along nicely, will post video soon.

Currently, I am struggling to get a convincing tyre simulation.
I want to use real tyre shapes (Cylinders) and not the ray-vehicle.

When looking that the demos, I see that there are a lot of different friction types:

Code: Select all

body->setFriction(1.f);
body->setRollingFriction(.1);
body->setSpinningFriction(0.1);
body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(), btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
I understand what Rolling Friction is for, as it is mentioned in API.
Is there a description somewhere how Bullet handles friction?

When I used ODE, I would rely on things like "Force dependent Slip", "Slip directions", "friction pyramid approximation 1" which in the end resulted in a convincing tyre/road interaction.

In Bullet, I see the concept of slip only pop up in the ray cast vehicle?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Different types of friction.

Post by Erwin Coumans »

Latest Bullet uses an implicit friction cone, clamping against lateral friction coefficient (setFriction).
There is still the option to use pyramid friction cone approximation, like ODE.
With setAnisotropicFriction you can have different friction coefficients along 2 orthogonal axis, which may help to simulate wheels.
I would keep rolling friction really low or zero.
You may also want to configure some amount of contact stiffness and damping, to mimic some amount of deformation.

What does "Slip directions" mean?
bram
Posts: 51
Joined: Sun Nov 23, 2008 4:43 pm

Re: Different types of friction.

Post by bram »

Thanks, I found solver mode SOLVER_DISABLE_IMPLICIT_CONE_FRICTION.

But the anisotropic API confuses me.
I expect it to take 2 perpendicular directions, and two scalar values?
One friction value for direction1, another friction value for direction 2?
(That's how ODE does it.)

But Bullet's API seems to take a vector (for direction) and that's it?
Does it assume that in one direction it is zero, and in the other direction it is whatever setFriction() is set to?
If so, it wouldn't work for my case, I think.

About slip directions: I meant friction directions, you can use two, and have a different FDS and different 'mu' for both.
bram
Posts: 51
Joined: Sun Nov 23, 2008 4:43 pm

Re: Different types of friction.

Post by bram »

bram wrote: Wed Nov 21, 2018 8:09 pm But Bullet's API seems to take a vector (for direction) and that's it?
Never mind, I just figured out that it is not a direction vector.
It is three different multiplier values, one for each axis.
bram
Posts: 51
Joined: Sun Nov 23, 2008 4:43 pm

Re: Different types of friction.

Post by bram »

Oops, no, I was wrong again.

It is a direction after all, not a set of scalar values, as can be seen here:

Code: Select all

   98         virtual btVector3       getAnisotropicRollingFrictionDirection() const
   99         {
  100                 btVector3 aniDir(0,0,0);
  101                 aniDir[getUpAxis()]=1;
  102                 return aniDir;
  103         }
Which takes me back to my original question: how are the friction values defined for the two directions?
There is only setFriction() and no setFriction2() or something?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Different types of friction.

Post by Erwin Coumans »

Bullet computes 2 friction directions, orthogonal to the contact normal. You can override those directions in a contactAddedCallback.
By default, Bullet aligns the first friction direction along the projected velocity vector. You can disable this
by adding a solver mode 'SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION'.

The anisotropic friction is a scaling factor in local space of the body, multiplied by the friction lateral.

Code: Select all

btRigidBody* body = createRigidBody(mass, startTransform, colShape);
body->setAnisotropicFriction(btVector3(0, 1, 1), btCollisionObject::CF_ANISOTROPIC_FRICTION);
In this code snippet, the friction along the x direction, in local space of the body, will be zero.

Code: Select all

btRigidBody* body = createRigidBody(mass, startTransform, colShape);
body->setAnisotropicFriction(btVector3(0.5, 1, 1), btCollisionObject::CF_ANISOTROPIC_FRICTION);
In this case, the friction in the local x direction will be 0.5 * lateralFriction, where you set the lateralFriction using setFriction
The friction in the y and z will be 'lateralFriction' since it is not changed, by multiplying by 1.



If you want full control, the easiest is to enable a contact added callback and set the solverMode flag 'SOLVER_ENABLE_FRICTION_DIRECTION_CACHING'.
The contactPoint.m_frictionDirection1 and m_frictionDirection2 will be multiplied by the lateralFriction coefficient.
Note that those friction direction vectors can be scaled, so have anisotropic friction (so they don't need to be unit length).
bram
Posts: 51
Joined: Sun Nov 23, 2008 4:43 pm

Re: Different types of friction.

Post by bram »

Thx,

I can't get the 'Added' callback be actually called. The 'Processed' callback is though.

Code: Select all

        si.m_solverMode =
                SOLVER_USE_WARMSTARTING |
                SOLVER_SIMD |
                SOLVER_RANDMIZE_ORDER |
                SOLVER_DISABLE_IMPLICIT_CONE_FRICTION |
                SOLVER_ENABLE_FRICTION_DIRECTION_CACHING |
                SOLVER_USE_2_FRICTION_DIRECTIONS
                ;

         ....
         
        gContactAddedCallback = contact_added_callback;
        gContactProcessedCallback = contact_processed_callback;

User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Different types of friction.

Post by Erwin Coumans »

The contact added callback is only called if one (or two) of the objects have the btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK set.
(use body->setCollisionFlags() ( body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))

Using only the contact processed callback should work.
Post Reply