Advertisement

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

Started by May 21, 2016 02:57 PM
11 comments, last by adriansnetlis 8 years, 3 months ago
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,
You can add a double spring. One controls suspension and second one imitates suspension limit. For the second spring you can apply impulse instead of force, proportional to distance of how far off into spring limit you moved and mass of the vehicle. To be sure that it's in balance check how many suspensions are at limit and scale weight accordingly. There isn't really a way to get mass inertia at arbitrary point but you could get some approximation from velocity at point in axis of suspension, where velocity is higher you will have higher mass on suspension.
Advertisement

Hey BoredEngineer, thanks for for answer. I am not sure if I understood that to 100% but I will try to implement it today and test a bit around, to see if I get the idea of the approach :)

Thanks!

I don't get this point:

float DownForceMagnitude = DotProduct(VelocityAtSuspension, BodyUpVector);
How a velocity can become a force? I'd just use the suspension force at the wheel contact point as reported by the vehicle telemetry (eCHANNEL_SUSPFORCE).
Then applying a counter-force based on the actual suspension force should have a proper effect on the suspension. However, note than "lifting" the vehicle that way will surely have a significant effect in the tire forces: as the actual downforce gets reduced, then the tires will provide less friction and the vehicle will tend to slide easier.
Better solutions for that problem might be (alone or combined):
  • Increasing the suspension travel.
  • Using stiffer springs. Even increasing the spring rate in runtime would be better than applying a force externally.
  • Raising the bottom of the vehicle's collider. It's not necessary that the collider encloses the entire visual mesh.

Hey BoredEngineer, thanks for for answer. I am not sure if I understood that to 100% but I will try to implement it today and test a bit around, to see if I get the idea of the approach :)

Thanks!

What I mean is simulating collision manually. Take a look at code snippets here, just ignore friction part:
http://www.gamedev.net/topic/465248-calculating-impulse-due-to-rigid-body-collision-with-friction/
Hmmm, but before you get there maybe your suspension is not right in the first place. In principal you can make springs so stiff that they will work as almost solid rods. Can you post pseudo code of your suspension?
Advertisement
@ Edy

It was a naming error in my pseudo-code, sorry. It should have been named DownVelocityMagnitude.

@BoredEngineer

Sure, my approach is the following:

float WheelTraceHitDistance = LineTraceResult.HitDistance;

float SuspensionForce; //Basic Suspension Spring Force Constant;

float SuspensionSize; //Trace Length & overall size of the suspension

float SuspensionDampingConstant;

float SuspensionCompression = 1 - (WheelTraceHitDistance / SuspensionSize);
float SuspensionCounterForce = SuspensionCompression * SuspensionForce;
float SuspenionDamping = (Wheel->CurrentSuspensionDistance - Wheel->PreviousSuspensionDistance) / FixedDeltaTime;
SuspensionForce -= SuspensionDamping;
FVector FinalSuspensionForce = BodyUpVector * SuspensionForce;

In principal you can make springs so stiff that they will work as almost solid rods.

This is a correct theory, but in practice PhysX (the underlying physics engine in UE) doesn't handle these cases very good. Too much stiff springs and/or large damper values can incur in numeric instabilities giving the a vehicle a "jittery" behavior even at rest.

In principal you can make springs so stiff that they will work as almost solid rods.

This is a correct theory, but in practice PhysX (the underlying physics engine in UE) doesn't handle these cases very good. Too much stiff springs and/or large damper values can incur in numeric instabilities giving the a vehicle a "jittery" behavior even at rest.

It's not to do with PhysX(or any other engine), but with frequency. At the low frequency at high stiffness and, e.g. 1 cm compression if it applies 15000 force, the car of weight 10000 N(~1020 kg) will receive 1.5 G acceleration. If the frequency is 60 Hz, than it will be


9.8 * 1.5 * (1/60) = 0.245

. If it moves 0.245 m in one frame, it becomes flying. And dampers won't solve it much in this case. However, once we change it to, let's say, 300 Hz:


9.8 * 1.5 * (1/300) = 0.049

. It's 5 cm only. In this specific case(of so stiff springs) it would still make it bounce a bit(actually 3.9 cm is quite a lot. It would be a bit smaller, though, due to dampers), but it would be way less noticeable. At this frequency our eyes would also not notice it. However, most of nowadays computers yet can't handle such a crazy frequencies.

A "solution" might be using another springs at the top part. Once the spring compresses enaugh, a thing joined to the wheel's joint starts to compress the second spring. This spring adds huge additional force pushing tire downwards. The reaction of this pushes car upwards. This spring could use semi-conical shape(and result in non-linear, rather exponentional or similar force basing on compression). I don't know if this is realistic, though. I learnt this method from Racer documentation.

You may also consider that the spring force of the springs may be non-linear depending on spring proprties.

It's not to do with PhysX(or any other engine), but with frequency.

In this case that issue has to do with the implementation in PhysX 3.x. I don't know about other engines.

In previous version (PhysX 2.x) the wheel component was part of the physics core, so it handled stiff spring perfectly. You could even set ridiculously large spring rate values and the suspension would keep perfectly stable, behaving mostly as a hard contact rather than a spring, no matter the actual frequency of the simulation.

This doesn't happen in PhysX 3.x. Here the vehicle code was extracted out of the core physics into a kind of "add-on" module. This module combines a faulty vehicle model with a terrible implementation. One of the consequences is the suspension becoming unstable and/or physically incorrect unless the parameters are combined so they match very specific conditions. Even when those conditions are matched, the suspension exhibits instabilities at some ranges (i.e. large spring rates) due to the faulty implementation.

This topic is closed to new replies.

Advertisement