Vehicle Suspension question

hiker
Posts: 83
Joined: Tue Oct 24, 2006 11:52 pm
Location: Australia

Vehicle Suspension question

Post by hiker »

Hi,

while trying to figure out why a wheel in the vehicles of 'SuperTuxKart' sometimes lose contact with the ground (resulting in a sudden rotation of the kart, since only one wheel would deliver the engine force), I stumbled over the following bullet code (btRaycastVehicle.cpp):

Code: Select all

btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
...
        btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius;
        btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
        const btVector3& source = wheel.m_raycastInfo.m_hardPointWS;
        wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
        const btVector3& target = wheel.m_raycastInfo.m_contactPointWS;
So basically raylen defines the length of the vector that's cast for the wheels: the suspension rest length plus the radius of the wheel.
  • Instead of using the suspension rest length, shouldn't the maximum suspension length be used? I.e.

    Code: Select all

    btScalar raylen = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01)+wheel.m_wheelsRadius;
    ? This value (well, withouth wheel radius) is then used a bit further down to clamp the actual suspension length.
  • Talking of maxSuspensionTravelCm: is the default for this (500) appropriate? Seems way too big (assuming 1 unit = 1 m, the suspension can travel by +- 5m ... if I understand the code correctly).
After changing the raylen formula, I kind of solved the problem with one wheel losing contact with the track (but that's of course because of the default of 500 for maxSuspensionTravelCm - I am still tuning the physics parameters).

Cheers,
Joerg
hiker
Posts: 83
Joined: Tue Oct 24, 2006 11:52 pm
Location: Australia

Re: Vehicle Suspension question

Post by hiker »

Hi,

I looked further into this issue, and it appears from the usage of the suspension further down in btRaycastVehicle that:
  • m_suspensionLenght is supposed to be between

    Code: Select all

    wheel.getSuspensionRestLength()-wheel.m_maxSuspensionTravelCm*btScalar(0.01)
    and

    Code: Select all

    wheel.getSuspensionRestLength()
    . This means that the clamping on

    Code: Select all

    maxwheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01)
    is actually wrong. But if the suspension length is larger than getSuspensionRestLength(), the computed suspension force (later on in updateSuspension()) becomes negative, and is then clamped to zero. So at the end this error doesn't matter. If this is correct, wouldn't it be more efficient to use the above limit (i.e. suspensionRestLengt-max_travel to suspensionRestLength) for the call to castRay(), and remove the clamping at all? The call to castRay should only return values in between the extremes.
  • Still the issue with the m_maxSuspensionTravelCm: instead of using 500 as a default, wouldn't it make sense to make getSuspensionRestLength() the default? This way the minimum suspension would connect the wheel to where it is attached at the chassis. With the current default (when it is larger than suspensionRestLength()) the wheel can actually be higher than the chassis (whatever that might mean in reality - a big crash I'd guess :) ), and the chassis will hit the ground easily.
Not big issues (and they can be easily solved by accepting some very minor performance penalty and harder to understand code; and setting appropriate defaults), but I think that many people have problems using the raycast vehicle, and it would be beneficial for bullet to make it easier to understand and use.

Cheers,
Joerg