Generating Contact Constraints.

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

Generating Contact Constraints.

Post by bram » Fri Nov 23, 2018 7:36 pm

I would like to have full control over how contact constraints are generated.

This is, so that I can properly model tyre-road interaction.

I want to vary friction dynamically, based on what is happening (how fast does tyre spin, e.g.) and have different friction coefficients for lateral and parallel slides.

In ODE, you automatically get this full control, because the application programmer has the responsibility of generating the contact joints in the nearCallback function.

From what I've been able to find, is that in Bullet I should derive my own class from btCollisionDispatcher?
Is that the way to go?

Do I need to re-implement DispatchAllCollisionPairs() ?

Thanks.

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

Re: Generating Contact Constraints.

Post by Erwin Coumans » Fri Nov 23, 2018 8:17 pm

There are a multiple ways, to name a few: one way is to implement your own near callback. By default, Bullet uses void btCollisionDispatcher::defaultNearCallback.

There is an API for this: btCollisionDispatcher::setNearCallback

Right after the call "collisionPair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatchInfo, &contactPointResult);"
you could modify the all contact points properties.

Another option is to override some global callback functions:

Code: Select all

#include "BulletCollision/CollisionShapes/btPersistentManifold.h"

bool MyContactAddedCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
{
	//do something here, such as adjust friction
	
	return true;//just return true
}

gContactAddedCallback = MyContactAddedCallback;

typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp, void* body0, void* body1);
typedef void (*ContactStartedCallback)(btPersistentManifold* const& manifold);
typedef void (*ContactEndedCallback)(btPersistentManifold* const& manifold);
extern ContactDestroyedCallback gContactDestroyedCallback;
extern ContactProcessedCallback gContactProcessedCallback;
extern ContactStartedCallback gContactStartedCallback;
extern ContactEndedCallback gContactEndedCallback;
You can modify the friction and other contact properties in the gContactProcessedCallback and/or gContactStartedCallback callback.

One more way is to iterate over all contacts, between performing collision detection and solving the constraints, and modifying the contact properties.

bram
Posts: 50
Joined: Sun Nov 23, 2008 4:43 pm

Re: Generating Contact Constraints.

Post by bram » Fri Nov 23, 2018 10:12 pm

Thanks Erwin,

Going with gContactProcessedCallback for now.

I noticed that my gContactStartedCallback was never called though?

So I used gContactProcessedCallback, which does get called.

When setting m_appliedImpulseLaterial1 and m_appliedImpulseLateral2 to 0.0, I expected the tyre to slide friction less on the ground, but I observed no difference.

Is modifying this in ContactProcessedCallback too late, because it has already been used by the solver?

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

Re: Generating Contact Constraints.

Post by Erwin Coumans » Fri Nov 23, 2018 11:54 pm

The m_appliedImpulseLaterial1/2 are the applied impulses after the solver is done.
You can set cp.m_combinedFriction (scalar) and m_lateralFrictionDir1/m_lateralFrictionDir2 (orthogonal directions, projected in the ground plane). There are also cp.m_contactMotion1, cp.m_frictionCFM etc. cp.m_contactMotion1 allows you to set a desired relative velocity, for example create a conveyor belt. cp.m_frictionCFM will add some compliance to the friction (like ODE 'constraint force mixing).

It is best to also set the solver mode to enable SOLVER_ENABLE_FRICTION_DIRECTION_CACHING, so the solver won't overwrite the m_lateralFrictionDir1/2.

See the source code here for details:
https://github.com/bulletphysics/bullet ... .cpp#L1102

bram
Posts: 50
Joined: Sun Nov 23, 2008 4:43 pm

Re: Generating Contact Constraints.

Post by bram » Sat Nov 24, 2018 12:50 am

Thanks Erwin, I appreciate it.

Although I understand it a little better now, it is still not working.
  1. I now get 'Added' callbacks, with the CUSTOM MATERIAL flag set. CHECK.
  2. If I set m_combinedFriction to 0 in that callback, the tyres slide as expected. CHECK.
  3. So lateralFrictionDir1/2 are scaled directions, with a magnitude encoded. CHECK
  4. I added SOLVER_ENABLE_FRICTION_DIRECTION_CACHING and SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION CHECK
So, I expected that by setting lateralDirectionDir1 and Dir2 to something very small, or even (0,0,0), I would see a frictionless tyre-ground contact.
But that's not what happens: setting those two directions have no effect on the simulation for me?

Also note: from that source code snippet you sent: m_lateralFrictionInitialized does no longer exists. It tells me to set it to true.

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

Re: Generating Contact Constraints.

Post by Erwin Coumans » Sat Nov 24, 2018 1:03 am

>> m_lateralFrictionInitialized does no longer exists.

It was replaced by a flag. Try using this instead:

Code: Select all

contactPoint.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED
Also, best to use the gContactProcessedCallback (not added callback, so no need for the CUSTOM MATERIAL flag):
gContactProcessedCallback is always called, while contactAddedCallback is only called when the contact is initially created.

See attached zip file for a modified BasicExample.cpp (copy it in Bullet/examples/BasicDemo and run the Example Browser).
BasicExample.zip
(2.04 KiB) Downloaded 9 times

bram
Posts: 50
Joined: Sun Nov 23, 2008 4:43 pm

Re: Generating Contact Constraints.

Post by bram » Sat Nov 24, 2018 3:25 am

Excellent!

BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED was indeed the missing ingredient.

I can now control tyre/road friction the way I need it.
I'm confident I can now get a nice handling vehicle without having to resort to ray tests as wheels.

Thanks again!

Post Reply