Advertisement

Vehicle physics pacejka lateral velocity

Started by February 05, 2022 05:41 PM
21 comments, last by YousefMahmood 2 years, 5 months ago

bmarci said:
I suppose the longitudinalVelocity is the velocity of the car at the position of the tire, and transformed into wheel-space and only taking the longitudinal component of the velocity vector ? Looking at the video, the slip/force values seem good. The low speed instability should completely vanish above 5-10m/s Is your rpm in rad/s?

Oscillations still occur at above 5-10 m/s. (You can see that in the video where the vehicle speed is at 12m/s and the tireforce graphs at the right side of the screen still show rapidly oscillating friction forces. Especially the longitudinal vector.)

The longitudinal velocity is as you said the velocity of the car at the contactpatch (where the suspensionraycast hits the ground) but then projected onto the wheels forward and/or side axis via the dotproduct:

//longitudinal/lateral velocity in wheelspace
//wheelInfo.relContactPos = contactpoint where the suspension hits the ground.
float longitudinalVelocity = glm::dot(rigidbody.getVelocityInLocalPoint(wheelInfo.relContactPos), forwardAxisWheel); //forwardAxisWheel is the wheels forward direction/normal in worldspace
float lateralVelocity = glm::dot(rigidbody.getVelocityInLocalPoint(wheelInfo.relContactPos), sideAxisWheel);

the engines RPM is calculated from the angularVelocity of the wheels (rads/s) to revolutions per minute like so:

float rpm = angularVelocityRadsPerSecond * (60.0f / (2.0f * PI));

It's worth noting that i haven't implemented a proper RPM/torqe curve yet. (So the engine is outputting the same hardcoded torque regardless of its RPM.)

I'm currently not entirely sure if what i have is actually correct or not. Haven't added a friction circle implementation yet so that definitely impacts the result.

What i'm struggling with is how to properly handle the low-speed situation with the slipangle and slipratios. Dampening the forces doesn't really seem to work. (Not to mention skewing the results in the end.) It would be nice to be able to debug all those values (slipangles, ratios, tireforces, etc…) at lower speeds but due to the nature of the formulas this isn't possible. Oh well…

I came across the concept of friction clamps in a GDC talk for Just Cause 4 where they specifically point out how to circumvent the instability issues in vehicles:

here the PDF for that talk:

https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdc2019/presentations/Young_Hamish_Vehicle_Physics_And.pdf

On page 21 he shows how an angular friction clamp is implemented. The issue with that is that this breaks/doesnt model wheel spinning. (Which isn't physically accurate.)

This would maybe solve oscillations but not the tire friction issues (especially slipratios with a denominator near zero) at lower speeds.

Lewa said:
It's worth noting that i haven't implemented a proper RPM/torqe curve yet. (So the engine is outputting the same hardcoded torque regardless of its RPM.)

Instant high torque is not necessarily good for you, at least not if you instantly apply 500Nm from the engine, you'll instantly loose traction.

Lewa said:
What i'm struggling with is how to properly handle the low-speed situation with the slipangle and slipratios. Dampening the forces doesn't really seem to work. (Not to mention skewing the results in the end.) It would be nice to be able to debug all those values (slipangles, ratios, tireforces, etc…) at lower speeds but due to the nature of the formulas this isn't possible. Oh well…

You can dampen the forces or limit things, but it'll result in situations when your car slides down the hill sideways while “standing still”.

From my experience, I never had problems from oscillations. I simulate at high frequency and the lateral “jitter” is not visible (it's there but you don't see it), even at 300Hz it wasn't noticable.

The longitudinal is a bit different, jittering forces will make sure your car is not sliding, so even forces oscillate, you car should look stable. But due to oscillations the wheel angle WILL not be nice. To eliminate this I added damping on the visual only. So the wheel angle was shaking like hell, but I maintained a display angle that was converged to the calculated value.

One more thing about physics frequency;
when you update your car at 250 or 500hz, what about bullet? Is it still at 60hz?
In that case simply adding the calculated force to the physics engine is not good, you'll simply lose the advantages gained by high frequency simulation.

Advertisement

bmarci said:
Instant high torque is not necessarily good for you, at least not if you instantly apply 500Nm from the engine, you'll instantly loose traction.

I'm aware of that. The hardcoded torque is also multiplied with a throttle value (normalised float) so that i can control how much of the power is sent down the driveshaft. (So that shouldn't be an issue for now.)

bmarci said:
The longitudinal is a bit different, jittering forces will make sure your car is not sliding, so even forces oscillate, you car should look stable. But due to oscillations the wheel angle WILL not be nice. To eliminate this I added damping on the visual only. So the wheel angle was shaking like hell, but I maintained a display angle that was converged to the calculated value.

How do you then handle the oscillating friction/forces? Damping the visuals will smooth those out but if you use the actual physical angular velocity (non dampened) for friction calculations the car will still move/start moving on each own due to the instability. You also send the wheels angular velocity (Which gets affected by those oscillations) back to the engine for RPM calculations (which then also oscillates.). You can see in the last video in the engine RPM curve how it also oscillates due to the instability issue. (Which is caused by the oscillating tire forces affecting the wheel.) Normally the engine RPM/curve should be stable.

bmarci said:
when you update your car at 250 or 500hz, what about bullet? Is it still at 60hz? In that case simply adding the calculated force to the physics engine is not good, you'll simply lose the advantages gained by high frequency simulation.

Physics calculations also run at 250Hz-500hz. (They are tied to the engines update loop which also runs at the same framerate.)

const int TICKS_PER_SECOND = 250; //500;
const float tpsDelta = 1.0f / static_cast<float>(TICKS_PER_SECOND);

//called each updateTick
this->physicsWorld->getDynamicsWorld()->stepSimulation(tpsDelta, 1, btScalar(tpsDelta));

Lewa said:
How do you then handle the oscillating friction/forces? Damping the visuals will smooth those out but if you use the actual physical angular velocity (non dampened) for friction calculations the car will still move/start moving on each own due to the instability. You also send the wheels angular velocity (Which gets affected by those oscillations) back to the engine for RPM calculations (which then also oscillates.). You can see in the last video in the engine RPM curve how it also oscillates due to the instability issue. (Which is caused by the oscillating tire forces affecting the wheel.) Normally the engine RPM/curve should be stable.

Actually I don't really care about oscillations, they disappear for me when the car starts rolling. Somehow they cancel each other out at stand still and the car looks and behaves very stable. Fortunately I never had to deal with these problems, it worked nicely from the first day ?
The wheel oscillations are going back to the engine indeed, and I later made some very basic relaxation method to stop wheel jittering. But at low speed you'll need some sort of clutch to prevent stalling, so the whole loop is separated before the low speed oscillations take place, these oscillations are more pronounced with differentials, as I remember.
You can look for the SAE950311 which is about low speed relaxation length method. Unfortunately it's not free, but it also works on the principle of damping the slip values depending on the wheel speed. If you take a look at the racer source (racer.nl) there are also many useful attempts to deal with these problems. (don't forget to read all the documentations and theory you can find on the site ?)

@Lewa I found an old video, when I added that slip ratio damping:
Look the the 4 traction circles;
They only oscillate when the car stops, but even so it doesn't slide back on the slope.
I don't have the code here, but I'll get that formula for you. I found it on the net, so it's not my invention ?

@Lewa So, you can try something like this:

vsx = wheel_speed - ground_speed
vth = <low speed threshold>
slip_ratio = 2 * vsx / (vth + ground_speed^2 / vth)

If the ground speed drops below the low speed threshold you can use this for the slip ratio instead of the default formula.

wheel_speed = angular velocity * radius
ground_speed = forward speed of the wheel
low speed threshold = it depends… somewhere around 5m/s, I could go down to 1m/s while it's still stable.

Advertisement

What kind of a game are you trying to make?

Acosix said:

What kind of a game are you trying to make?

Something with vehicles i suppose ?

bmarci said:

Lewa said:
How do you then handle the oscillating friction/forces? Damping the visuals will smooth those out but if you use the actual physical angular velocity (non dampened) for friction calculations the car will still move/start moving on each own due to the instability. You also send the wheels angular velocity (Which gets affected by those oscillations) back to the engine for RPM calculations (which then also oscillates.). You can see in the last video in the engine RPM curve how it also oscillates due to the instability issue. (Which is caused by the oscillating tire forces affecting the wheel.) Normally the engine RPM/curve should be stable.

Actually I don't really care about oscillations, they disappear for me when the car starts rolling. Somehow they cancel each other out at stand still and the car looks and behaves very stable. Fortunately I never had to deal with these problems, it worked nicely from the first day ?
The wheel oscillations are going back to the engine indeed, and I later made some very basic relaxation method to stop wheel jittering. But at low speed you'll need some sort of clutch to prevent stalling, so the whole loop is separated before the low speed oscillations take place, these oscillations are more pronounced with differentials, as I remember.
You can look for the SAE950311 which is about low speed relaxation length method. Unfortunately it's not free, but it also works on the principle of damping the slip values depending on the wheel speed. If you take a look at the racer source (racer.nl) there are also many useful attempts to deal with these problems. (don't forget to read all the documentations and theory you can find on the site ?)

I've experimented a bit more and i found out that the strength of the oscillations in my case were caused due to a 1:1 gearratio between the engine, driveline and the wheels angular velocity.Increasing/changing those gearratios to higher values solved this somewhat. With damping and an additional rolling resistance this can be mitigated.

Also btw, really nice vehicle demo you've here ?

bmarci said:

@Lewa So, you can try something like this:

vsx = wheel_speed - ground_speed
vth = <low speed threshold>
slip_ratio = 2 * vsx / (vth + ground_speed^2 / vth)

If the ground speed drops below the low speed threshold you can use this for the slip ratio instead of the default formula.

wheel_speed = angular velocity * radius
ground_speed = forward speed of the wheel
low speed threshold = it depends… somewhere around 5m/s, I could go down to 1m/s while it's still stable.

I've tried that but in my case the result wasn't great. (the slipratio was completely off compared to the regular formula causing the tire to loose a lot of traction at lower speeds.)

What i use now is:

float longitudinalVelocity = glm::dot(rigidbody.getVelocityInLocalPoint(wheelInfo.relContactPos), wheelInfo.wheelForwardAxisWS);

if (std::abs(longitudinalVelocity) < 5.0f) //5m/s threshold
{
	float B = 0.91f;
	float wheelSpeed = wheelInfo.angularVelocity * wheelInfo.tireRadius;
	float delta = (wheelSpeed - longitudinalVelocity) - std::abs(longitudinalVelocity) * wheelInfo.slipRatio;
	delta /= B;
	wheelInfo.slipRatio = delta * delta_time;
}
else
{
	wheelInfo.slipRatio = ((wheelInfo.angularVelocity * wheelInfo.tireRadius) - longitudinalVelocity) / std::max(std::abs(longitudinalVelocity), 0.0001f);
}

And that seems to work ok. (Although hard to tell as the car still doesn't handle correctly.)

With regards to the tire friction: I've this weird issue where the car handles really badly and likes to perform full U turns even though i don't accelerate the car with the throttle. This makes the car during slides completely uncontrollable. (It not only performs those full U turns even at low speeds/without much acceleration, steering with the frontal wheels also doesn't really make a difference.)

Here a video of how that looks like:

The engine torque is a bit high but it doesn't seem to be the cause here. (I left it high in order to show the example better. The issue still happens on regular torques and during drifts/slides. It's just much more noticeable with that setup.)

The graphs on the right show the tractionforce (yellow line) and the the velocity of the vehicle at the tires position (blue) in wheel space.

What i do in the video is to steer left or right, accelerate and once the car starts sliding i let go of the throttle and the steering wheel. (You can see when the engine torque drops to zero.) The car still rotates and even increases its angular momentum around the chassis. (you can see it clearly at the end at around 0:50 how it turns.)

What i noticed is that if i manually override the lateral velocity of the front tires to 0 during this U turn maneuvers the car “corrects” itself which looks more natural. I have no idea if that's expected behaviour with the current implementation or if i maybe read out/apply the tire forces incorrectly via the bullet api.) For me it looks like during turning the tire forces at the front should be reversed. (Maybe the inertia is not accounted for if velocities of localpoints are retrieved via the physics API.)

-----------------------

/Edit:

So i was able to capture a similar issue here:

You can see at the 4 second mark how the car suddenly gets an impulse in the opposite spinning direction. This happens due to the lateral tireforces on the front wheels. (You can see the moment the sign of the tireforce changes on the local X axis in wheelspace the impulse happens.) I'm not sure if this is simply a byproduct of the step integration in physics engines (which wouldn't really appear in the real world as is) and thus this has to be handled as a special case or if i simply overlook other/additional aspects of the simulation.

Your new slip ratio method is very similar to the classic relaxation method (referred as SAE950311) Somehow that one didn't work out for me, even I spent about 20 bucks on that ?

Your traction forces (yellow lines) seem a bit off, at this speed they mustn't be that “chunky”, especially on the front wheels. Also, not sure, but the pacejka graphs seem too steep, at low speed they shouldn't reach the max “instantly” (I have to double-check with mine). Apart from that the low speed oscillations are there, but they instantly vanish when the car starts rolling. You should plot the longitudinal pacejkas as well ?

Lewa said:
What i noticed is that if i manually override the lateral velocity of the front tires to 0 during this U turn maneuvers the car “corrects” itself which looks more natural. I have no idea if that's expected behaviour with the current implementation or if i maybe read out/apply the tire forces incorrectly via the bullet api.) For me it looks like during turning the tire forces at the front should be reversed. (Maybe the inertia is not accounted for if velocities of localpoints are retrieved via the physics API.)

The lateral velocities look perefctly fine for me. The direction of forces also look correct, the lateral amplitude is ok, but the longitudinal jumps are too much, they should be gradual at this speed.

You can also try “disconnecting” the engine when you reached enough speed, and see what happens. Engine torque can easily trick you in real life, if you suddenly lift of the throttle you get snap oversteer and spin out at once.

You've probably already checked this but in the off chance you haven't, while your car is turning, are all four tires on the ground?

I ask because I actually encountered this oscillation situation with my rudimentary car physics. I noticed while I'm cornering say to the right (although it happened in both directions), the front right tire and back right tire lifted off from the ground. This caused the car to not turn as much since only two tires were applying friction forces on the car. During the turn eventually gravity would pull the car down and all four tires would make contact which would causes an overall greater cornering force so the car would then turn a bit faster. But this overall greater cornering force then caused the front right and back right tires to lift off again. This loop caused the car to kind of of oscillate back and forth during turning.

I fixed it by simply changing where I apply the friction forces. In the picture below I used to apply them at point A, right where the suspension ray cast (green line) attaches to the car. Now I changed the position to point B. By raising the point up to be in line with the center of the car, any lateral friction forces will not cause the car roll.

Perhaps I could've also fixed the problem by giving the car more mass but my rudimentary physics engine isn't quite setup for rigid bodies with masses yet.

Anyway, this is just what happened with me so sorry if none of this applies to your problem.

This topic is closed to new replies.

Advertisement