Question about the Code in btRaycastVehicle

Post Reply
Alemarius Nexus
Posts: 5
Joined: Mon Jul 14, 2014 5:38 pm

Question about the Code in btRaycastVehicle

Post by Alemarius Nexus »

Hi,

I'm currently trying to get started with a vehicle simulation using Bullet. I want to start with a raycast vehicle and am currently looking at the btRaycastVehicle code. I have some questions about parts of this code and I hope someone can explain the maths and/or physics to me.

First off, there is this code in btRaycastVehicle::rayCast(btWheelInfo& wheel):

Code: Select all

btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS );

btVector3 chassis_velocity_at_contactPoint;
btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition();

chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos);

btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint );

if ( denominator >= btScalar(-0.1))
{
    wheel.m_suspensionRelativeVelocity = btScalar(0.0);
    wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1);
}
else
{
    btScalar inv = btScalar(-1.) / denominator;
    wheel.m_suspensionRelativeVelocity = projVel * inv;
    wheel.m_clippedInvContactDotSuspension = inv;
}
I don't really understand what this code means. I mean, projVel is the projection of the velocity at the wheel-ground contact point onto the contact normal. This means, it points in the direction of the contact normal. The denominator supposedly is the cosine of the angle between contact normal and wheel direction, and as the contact normal is normally "opposed" (kind of) to the wheel direction, the usual case is the "else" clause. But what exactly is this "inv" variable supposed to mean, and why do you multiply projVel by it? I guess m_suspensionRelativeVelocity should be the velocity in the direction of the suspension spring, but that's not the direction in which projVel points.

Maybe I will find some other parts that are unclear to me. But for now, it would be great if someone could enlighten me on this one.


Thanks in advance!
lunkhound
Posts: 99
Joined: Thu Nov 21, 2013 8:57 pm

Re: Question about the Code in btRaycastVehicle

Post by lunkhound »

So this code is part of calculating the suspension force for the wheel. Part of the calculation is done in this code, the rest is done elsewhere (nice and confusing). The "inv" variable is basically a scaling factor for the suspension force.

When the vehicle is sitting level on flat ground, inv is 1, if the vehicle is tipped with respect to the ground normal, inv increases and eventually is clamped to 10 when the vehicle is tipped almost all the way over (84 degrees or so, the invcos(0.1)).
The suspension of a vehicle allows the wheels to move with respect to the vehicle chassis to help absorb shocks, but the suspension doesn't allow the wheels to move equally well in all directions--it has a preferred direction. It seems to me that this scaling factor is an adhoc way of stiffening the suspension when the force on the wheels varies from the "preferred direction" of the suspension.
Alemarius Nexus
Posts: 5
Joined: Mon Jul 14, 2014 5:38 pm

Re: Question about the Code in btRaycastVehicle

Post by Alemarius Nexus »

Ok, I've taken my time to fiddle around with it a bit and I think I understand that part now. Thanks!

Another thing that confuses me is the following. From btRaycastVehicle::updateSuspension(...), this is done per wheel:

Code: Select all

btScalar force;
//	Spring
{
    btScalar	susp_length			= wheel_info.getSuspensionRestLength();
    btScalar	current_length = wheel_info.m_raycastInfo.m_suspensionLength;

    btScalar length_diff = (susp_length - current_length);

    force = wheel_info.m_suspensionStiffness
        * length_diff * wheel_info.m_clippedInvContactDotSuspension;
}

// Damper
{
    btScalar projected_rel_vel = wheel_info.m_suspensionRelativeVelocity;
    {
        btScalar	susp_damping;
        if ( projected_rel_vel < btScalar(0.0) )
        {
            susp_damping = wheel_info.m_wheelsDampingCompression;
        }
        else
        {
            susp_damping = wheel_info.m_wheelsDampingRelaxation;
        }
        force -= susp_damping * projected_rel_vel;
    }
}

// RESULT
wheel_info.m_wheelsSuspensionForce = force * chassisMass;
if (wheel_info.m_wheelsSuspensionForce < btScalar(0.))
{
    wheel_info.m_wheelsSuspensionForce = btScalar(0.);
}
I understand what's going on with the spring force and damping, but why is "force" multiplied by the chassis mass in the RESULT block? I mean, as the name suggests, "force" is already a force and not an acceleration, so why multiply by mass? Without this multiplication, the force seems to be way to low, still I don't get why we can just multiply by the mass here.
lunkhound
Posts: 99
Joined: Thu Nov 21, 2013 8:57 pm

Re: Question about the Code in btRaycastVehicle

Post by lunkhound »

The "force" variable could be renamed "accel" or something like that and it would make more sense.

If the mass wasn't multiplied in there, then it would effectively need to be folded into the spring and damping constants. That's inconvenient because it would mean that if you changed the vehicle's mass, you'd also need to update the spring and damping constants also, or the suspension behavior would change (vehicle would ride lower or higher, etc).
Post Reply