How to make a stable car physics?

Started by
23 comments, last by bmarci 10 years, 2 months ago


Basically whay happens is that the car starts jerking left to right and gains speed, its like I need to reset the value, this is why I use it as a local variable and set it to zero at initialization. The same goes with slip ratio.

You can abandon slip angle relaxation, since it doesn't affect wheel rotation. It'll oscillate but you won't see it,

At least you'll see if the problem is in there :)


I wish it were 2004 when there were al lsorts of private sim projects and sourcecodes to learn from. I remember some demos made with newton physics engine but they are all gone now.

Ohh, yes, good old days.

I think the source of an early version of Racer is still available.

Also you may want to check out REC.AUTOS.SIMULATORS google group, and search for "Car Physics". Lots of interesting topics :)

Advertisement


You can abandon slip angle relaxation, since it doesn't affect wheel rotation

Well if I abandon it and use the regular slipangle formula then there is alot more jerking. This is why I started using the SAE method.

As for racer, this is the game that inspired me to do my own sim stuff back in the day and I have learned alot fro mracers old source, tho it has some pretty messy code, but its a pleasure t ostill have it online.
And yeah I have been at the gropu but totally forgot it. Thanks for reminding it!


As for the sim itself, I switched back to spring force only ( I used to use it but for some reason started using the total suspension force) Ad everything seems to work far better now. Was able to drift the car with ease. Dunno why I made such a change before. Thanks for pointing this out.


Well if I abandon it and use the regular slipangle formula then there is alot more jerking. This is why I started using the SAE method.

Yes, much more, but should not be seen :) The wheels constantly get like (Fy) +1000N, -1000N, +1000N, -1000N ... and at the end of the simulation step they will remain at the same spot.


As for racer, this is the game that inspired me to do my own sim stuff back in the day and I have learned alot fro mracers old source, tho it has some pretty messy code, but its a pleasure t ostill have it online.

Me too, but unfortunately when it first came out around 2001, I didn't understand the first thing from it, I wasn't "smart" enough, physics wise. Reading the the "Physics of Racing Series", packed with funny units like, foot-pounds and slugs, didn't help too much either :D So I just dropped the topic..


And yeah I have been at the gropu but totally forgot it. Thanks for reminding it!

Lucky you, I haven't even head of it until maybe a year ago :)

Anyway, maybe you could help me too;

As I mentioned I'm rewriting the whole driveline and the torque transfer is not getting to work. Especially with inertias and accelerations.

What I achieved so far.

The whole driveline has 2 states: The clutch is locked or not.

1:

If locked, the output torque is calculated down to each wheels (only locked diff for now)

The wheels are accelerated with their inertia (not effective)

Based on the wheels angular velocity I calculate the engine speed.

The clutch has a maximum torque that it can transfer based on the pedal (clutch_factor)

If the torques going through the clutch exceed the maximum, it gets unlocked.

2:

The clutch is slipping, the output torque accelerates the flywheel with the effective inertia (engine to wheel)

Transfer the torque to the wheels and accelerate them with their self inertia as with locked clutch.

All the torques from engine and back from the wheels are clamped to the current max clutch torque (see above)

Also while the clutch is not locked both parts get the clutch torque to reduce the difference in angular velocities.

Once the velocity difference (engine/gearbox) switches sign, the clutch is locked again

Probably this is the method we all use, but:

Not sure where should I use effective inertias and where not, and which?

For example at the wheel

wheel_acc=(T_Drive+T_Road_reaction+T_Brake) / Inertia

this is the method that seems to work, but where is the inertia from the wheel to the engine

If I make it like:

acc=(T_Drive+T_Road_Reaction) / Inertia_engine_to_wheel;

anv_vel+=acc*dt;

acc=T_Brake / Inertia_wheel_to_engine;

ang_vel+=acc*dt;

It "sucks" big time, so to say... I have pain keeping the car on the road even moving straight.

Calculating the t_road_reaction with t_brake even worse.

I don't have a clue yet, just trying different variations hoping for any of them will work. wacko.png


Yes, much more, but should not be seen smile.png The wheels constantly get like (Fy) +1000N, -1000N, +1000N, -1000N ... and at the end of the simulation step they will remain at the same spot.

Thats what I thought, but the force seems to be constant to one side with sae formula, like -100N per wheel.
If I use the standard formula then there is jerking because of the small ocalisions I guess, the slip angle at rest is jumping from -10 deg to 10 deg (just example values) If I cut the longitudinal speed to 0 at some low speed value then there still is that jerking. Dunno what Im doing wrong.


Me too, but unfortunately when it first came out around 2001, I didn't understand the first thing from it, I wasn't "smart" enough, physics wise. Reading the the "Physics of Racing Series", packed with funny units like, foot-pounds and slugs, didn't help too much either biggrin.png So I just dropped the topic..


Exactly the same to me biggrin.png and I started my coding with Blitz3d even made a small demo to racesimcentral biggrin.png
Now I have steped my game into c# and c++ world


Anyway, maybe you could help me too;

Sure thing smile.png
First of all, if you are using the common method of angular velocity simulation that counts in road torque, drive torque, braking torque.

As I found out then You cant simulate locked diff's with ease, the simplest Differentials you will simulate are open Differentials.
As I understand by locked you are doing this:
leftWheel = driveTorqueFromDriveline * 0.5f;
rightWheel = driveTorqueFromDriveline * 0.5f;

This Is the simplest differential you can model, but it will simulate open differentials.

Sure if you initialise wheels with a if sentence you can do locked differentials, but I'm not sure if its the way to use.

This is what I had in mind(in your wheel class):
if(driveTorque=0)

angularVelocity -= rollingAngularDelta:

This simply makes sure that there is no rolling torque applyed when there is driving torque. But id go for the first method and simulate open differentials at start and then advance to a locked differential through some modifications that read roling torque from the wheels, so you can easly simulate LSD differentials this way smile.png I havent done this myself yet, but I am using viscous lsd differentials (simplest diffs you can make with the firstly Described wheel code)
It goes something like this (writing from memory):
speedDifferene=leftSpeed-rightSpeed;
leftWheel = (driveTorqueFromDriveline - speedDifferene*lockingTorque) * 0.5f;
rightWheel = (driveTorqueFromDriveline + speedDifferene*lockingTorque) 0.5f;

I know it wasnt what you asked but As for the driveline, I'll write you a PM about this (have to go right now).


Thats what I thought, but the force seems to be constant to one side with sae formula, like -100N per wheel.

One more thing that I just realized a couple of months ago:

It happened to me that I started tweaking the tire curve so it fitted my needs and later realized it wasn't symmetric any more.

Why is that important?

In your situation when the wheel produces +90/-90 slip angles the tire formula returns different forces.

This is basically true for any slip angles: Pacejke(SA=10).Fy != Pacejka(SA=-10).Fy

This causes your car to turn better left than right or vice versa, also it could start sliding one direction when stopped.

So I came up with the idea of flipping the curve depending on the side of the car. Left tires use the standard calculations and the right side negates the inputs and so the outputs.

In case of a right side tire:

In Pacejka calculation:

SA=-SA

Calculate as usual

Fy=-Fy

Mz=-Mz


This Is the simplest differential you can model, but it will simulate open differentials.

Hmmm this makes sense, as I'm checking the code there is nothing that prevents the wheels from accelerate away from each other.


Sure if you initialise wheels with a if sentence you can do locked differentials, but I'm not sure if its the way to use.
This is what I had in mind(in your wheel class):
if(driveTorque=0)
angularVelocity -= rollingAngularDelta:

This simply makes sure that there is no rolling torque applyed when there is driving torque. But id go for the first method and simulate open differentials at start and then advance to a locked differential through some modifications that read roling torque from the wheels, so

And how about accelerating the output parts of the diff instead of the wheels? Thus locked diff could be made easily.


The suspension forces are all those you mentioned, but the load is spring only (k*x).

I was browsing my code yesterday, and I'd correct myself:

I have a separate mass for the car body and for the wheels.

So my tire load is the suspension force (see above) and I add the force that the wheel generates due to gravity.

Transform the gravity vector (probably 0,-9.81,0) to the tire space and add the vertical component to the suspension force (k*x)


Transform the gravity vector (probably 0,-9.81,0) to the tire space and add the vertical component to the suspension force (k*x)


So it would be like:
weight = 20 * 9.81;
load = suspSpringForce + weight;
Right?

Also I corrected my pacejka combining method, and now my slip angle and ratio calculations produce a bit better values(without relaaxation lengths). But I still have to use some damping values, otherwise id run into some numerical occlisions causing the car to jitter alot.

Heres some code:

w=tireVelocity;
u=lonVelocity;
v=latVelocity;

damping = Clamp01( localVelocityMagnitude/ 4.0f );
slipRatio = (w - u) / Abs(u) * damping;
slipAngle = Atan(v/Abs(u)) * damping;

This works quite ok, but the car is still slightly sliding forwards and to the right. Looking at the telemetry I see this:

(wheels: front left, front right, rear left, rear right)
->First frame:
sr: -0.02, -0.02, -0.02, -0.02
sa: -0.02, 0.02, 0.02, -0.02
Fz: 2112.88, 2112.87, 1944.72, 1944.72
Lon: -1228.94, -1228.93, -1146.63, -1146.62
Lat: 13.24, -13.24, -11.57, 11.59

->Second frame:

sr: 0.01, 0.01, 0.01, 0.01
sa: 0.01, -0.01, -0.01, 0.01
Fz: 2127.98, 2127.97, 1929.89, 1929.89
Lon: 1220.38, 1220.37, 1112.45, 1112.45
Lat: -13.13, 13.13, 11.17, -11.18
As I notice the jumping in sr and sa is about 0.02 in the first frame, its exactly the same as my simulation deltaTime (50hz)
But the second frame looks to be half of it (dunno if there is any sense) But this I guess is causing the movement, if the jump would be from -0.02 to 0.02 the car would not move from its position.

But the secodn thing is that if the road is angled, the car starts to slide. If I use the method described here (the sae damping) for low speeds the slip ratio gets better, but still jumps a little. When I use the lateral version I get some strange springi action after a stop in sideways (example a drift fail etc.).

So is there a cure for this behaviour?

Also, bmarci, Are you applying suspensiopn froces in world cordinates or car/wheel cordinates? As I understand suspension forces should be applyed in world cordinates, am I right?


So it would be like:
weight = 20 * 9.81;
load = suspSpringForce + weight;
Right?

Basically yes, but the "weight" vector can change depending on the wheel orientation, eg: on sloped surface it's smaller.


As I notice the jumping in sr and sa is about 0.02 in the first frame, its exactly the same as my simulation deltaTime (50hz)

Uhh-Uhh,

The 50Hz seems quite a big timestep, especially for stiff suspensions and tire. I'd suggest 500-1000Hz :)


Also, bmarci, Are you applying suspensiopn froces in world cordinates or car/wheel cordinates? As I understand suspension forces should be applyed in world cordinates, am I right?

Yes, I apply every forces in world space but calculate them in their own, tire forces in tire space...etc

If your physics engine supports eg: body->ApplyForceInBodySpace() you can use that and you save some tansformation since some of the forces are already in body space.

You can apply the suspension force at the attachment point at first.

It's an interesting topic because not all forces are applied at the contact point. And depending on the suspension geometry different forces act on the various suspension links, and this is the point where you get nowhere with your super formulas without exact knowledge of race car suspension setups.

So my rule of thumb is, simplify, simplify, simplify... :)


The 50Hz seems quite a big timestep, especially for stiff suspensions and tire. I'd suggest 500-1000Hz


This is strange, because when I go from a fixed timestep of 0.02 to 0.002, a 500hz simulation (1/0.002) I get a pretty bouncy suspension with 50k springs.

How are you calculating your suspension compression? Is it normalized or in it's range, because when I normalize it (from range of 0 to 1) I get to stiff suspension with 50k springs... Also as for dampers, are you calculating the velocity over time like (compression-lastcompression)/timestep?

Currently I'm applying all the force to the contact patch position so I can get some bodyroll with realistic cg heights. Will try applying suspensions force at the spring connection position, see if something changes or not, one thing I'm thinking of is to angle the force towards tire contact patch to get some sort of physically correct feedback with it, dunno if it would work like i'm thinking hehe..


How are you calculating your suspension compression? Is it normalized or in it's range,

No, I use it as a length of compression in meters.


Also as for dampers, are you calculating the velocity over time like (compression-lastcompression)/timestep?

Exactly.


one thing I'm thinking of is to angle the force towards tire contact patch to get some sort of physically correct feedback with it, dunno if it would work like i'm thinking hehe..

First I just simply made a "spring" with damper, only one, that I dropped from 2-3 meters. No side forces, just vertical spring on a flat ground, and see how does it behave.

It is at least good to see the suspension in controlled envitonment.

A simple vertical model should work fine, adding angle to it just makes it more "difficult" because the forces don't neccesarily act along that axis, at least not at the contact point.

This topic is closed to new replies.

Advertisement