Roll influence bug (+ possible fix)

dahart
Posts: 4
Joined: Mon Sep 28, 2009 8:42 pm

Roll influence bug (+ possible fix)

Post by dahart »

Just found a minor bug in the roll influence handling code in btRaycastVehicle.cpp. I'm including the patch I used to fix it for me, in case that helps, but I make no claims as to whether my fix is correct or fast. ;)

This applies to Bullet version 2.77.

wheelInfo.m_rollInfluence is used to dampen the vertical component of the friction contact force on the vehicle, so that the new contact force is closer to the same height as the vehicle's center of mass, thus inducing less roll. The problem is that the rel_pos (relative position of the contact point) is a world-space offset from the center of mass, and damping the vertical/Y component of this offset is only valid on flat ground. If your vehicle is driving in any direction on an incline, the new contact point might actually be further away from the relative height of the center of mass. The observed behavior is that when turning quickly on a ramp, the vehicle rolls into the ramp; doing exactly what we were trying to avoid! The solution is to put the contact point offset into local space, then apply roll influence, and transform back into world space to apply the friction force.

Note that they way I applied this fix changes the fwd/back (accel/decel) behavior as well as the side forces, because I'm applying the roll influence before either force is used. This was intentional on my part (to keep my car from doing wheelies), but might not be correct for others.

A similar change probably needs to happen to rel_pos2, regarding the force that is applied to the ground, but since I don't have any moving ground, I haven't bothered to try to fix it.

--- btRaycastVehicle-bug-2.77.cpp 2010-09-07 18:38:16.000000000 -0600
+++ btRaycastVehicle-fixed-2.77.cpp 2010-10-25 12:09:50.233339900 -0600
@@ -677,8 +677,10 @@
{
btWheelInfo& wheelInfo = m_wheelInfo[wheel];

- btVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS -
- m_chassisBody->getCenterOfMassPosition();

+ btTransform worldToChassis = getChassisWorldTransform().inverse();
+ btVector3 relPosLocal = worldToChassis * wheelInfo.m_raycastInfo.m_contactPointWS;
+ relPosLocal[1] *= wheelInfo.m_rollInfluence;
+ btVector3 rel_pos = getChassisWorldTransform() * relPosLocal - m_chassisBody->getCenterOfMassPosition();


if (m_forwardImpulse[wheel] != btScalar(0.))
{
@@ -694,7 +696,6 @@

btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];

- rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
m_chassisBody->applyImpulse(sideImp,rel_pos);

//apply friction impulse on the ground

--
David.
dahart
Posts: 4
Joined: Mon Sep 28, 2009 8:42 pm

Re: Roll influence bug (+ possible fix)

Post by dahart »

One more caveat, my fix is only correct when the car is driving on the ground, e.g., all wheels in contact.

The real, more general solution, is to use the ground normal to apply roll influence. I think that is probably the "right" way; to avoid inducing roll the applied force needs to be parallel to the ground and at the same height relative to the ground as the vehicle's center of mass, right?

--
David.