Search code examples
c++physicsunreal-engine4physx

Physics [UE4]: Implement a "maximum compression" for vehicle-suspension


For a given vehicle, I implemented a suspension system on four wheels. The system is based on Hooke's Law.

The Problem: The vehicle should not be able to touch the ground. When driving in a spherical container (inside), the suspension gets compressed up to 100%, making the vehicle chassis touch the underground, which leads to unwanted collisions that throw the vehicle around.

Despite that may being a realistical behaviour, our game aims for an arcade-feeling, so I am looking for a formula to implement a maximum compression, so that the vehicle chassis can't come closer to the underground than X percent of the suspension size at any given moment, without actually simulating a physical contact between the two rigid bodys. Thus, I need to apply a fake force to the suspensions.

My current approach: If the vehicle chassis would in fact touch the suspension base (Sorry, I don't know the proper word to describe this. I mean, when the suspension is at maximum compression), a force equal in magnitude and opposite in direction relative to the force pushing onto the suspension would be applied to the vehicle chassis, forcing it to stop moving downwards.

Therefore, I receive my vehicles world velocity V. To get the downwards-velocity, I get the DotProduct of the velocity and the BodyUpVector.

float DownForceMagnitude = DotProduct(VelocityAtSuspension, BodyUpVector);
FVector DownForce = DownForceMagnitude * BodyUpVector;
FVector CounterForce = -DownForce * WeightOnSuspension;

Okay, this pseudo-code works somewhat fine on even underground, when the vehicle lands on a plane after a jump. Driving on a increasing slope however (like driving on the inside-walls of a sphere), makes the suspension reach maximum compression anyway, so apparently my approach is not correct.

I am now wondering what the cause is. My weight calculation only is simulated by VehicleWeight / 4, since the Unreal Engine 4 has no functionality to receive weight at a given location. I am no physics-pro, so forgive me if this is easy to calculate. Could that be the issue?

I do not need a physically 100% plausible solution, I just need a solution that works, and sufficiently stops the downwards motion of my vehicle chassis.

Any help is appreciated. Greetings,


Solution

  • I had this problem with a futuristic magnetic hovercraft.

    I solved it by reducing the force by ln depending on suspensions extension levels like so:

    y = ln(ln(x+e)) 
    

    where:

    x = Suspension extension lvl in % (-> 0 being fully compressed)
    y = the factor that you multiply the force with
    e = eulers number
    

    Here a graphic to help what it will be like:

    https://ggbm.at/gmGEsAzE

    ln is a very slow growing function thats why it works so great for this.

    You probably want to clamp the values (maybe between 0 and 100 idk exactly how your code behaves and how u want this "break" to behave)

    Tailor the function to your needs, I just wanted to suggest u use the ln like I did to solve this Problem.

    I added e to x first to make it go through 0,0 if u want to make it stop earlier just subtract from x before using ln.

    Also notice depending on when/how you calculate / update your suspension this (and any function applied to the force based on the extension of suspension levels) may not work under some circumstances or at all.