Skip to main content
GameDev.net gamedev.net
🔒 Locked

Basic Car physics problem

Started by jujunosuke Jun 15, 2010 at 2:26 AM 10 replies 2.5k views
Original Post
jujunosuke
jujunosuke
Hello !

First, i am very happy to do my first post here !
Second, please forgive my bad english.
I should had study it more at school hehe...

Here is my problem,
i try to apply this nice tutorial to my game :
http://web.archive.org/web/20060220062712/http://home.planet.nl/~monstrous/tutcar.html

I have some problem about some values.

I don't understand what is the first u vector ?

For the line :
Ftraction = u * Engineforce,

Also, for the line :

a = F/M
is this F = Flong ?


Here is my code for at moment :
I run 30 fps.

I just want to care about straight line acceleration, so no .y values.


//===========================================//  VARIABLES//===========================================private var engineForce:Number=1;private var Mass:Number=1000;		private var FtractionX:Number=0;private var FlongX:Number=0;private var FdragX:Number=0;private var FrrX:Number=0;		private var velocityX:Number=0;private var speedX:Number=0;		private var accelerationX:Number=0;private var carPositionX:Number=0;		private var Cdrag:Number=0.4257;private var Crr:Number=12.8;//===========================================//  ADD FORCES//===========================================private function addForces():void {        FtractionX = engineForce;				speedX = Math.sqrt(velocityX * velocityX);				FdragX = - (Cdrag * velocityX * speedX);	FrrX = - (Crr * velocityX);				FlongX = FtractionX + FdragX + FrrX;				accelerationX = FlongX / Mass;				velocityX = velocityX + (30 * accelerationX);				carPositionX = carPositionX + (30 * velocityX);}//===========================================//  LOOP//===========================================private function loop(e:Event):void {	addForce();	car.x=carPositionX;}


loop() function is called every 30fps.


Thank you for reading !
I hope i can get some help !

cia.
unbird
unbird
from the link:
Quote:
where u is a unit vector in the direction of the car's heading


A unit vector is a vector with length 1. In this context (as long as it's 2D), it tells you the current orientation of the car. For your case, since you're only dealing with x-movement, u = 1.

Quote:
a = F/M
is this F = Flong ?


Yes. What happens here is the application of the d'Alembert's principle. Basically you add all forces together first and calculate the resulting acceleration from the sum.

By the way, I think your update is wrong:

carPositionX = carPositionX + (30 * velocityX);


If that 30 means your FPS then the formula is not correct. What you need is a (delta) time, whereas FPS is a frequency (frames per second).

x_new = x + time * velocity;

(You can check the physical units (meter and seconds here): [m] + [s] * [m/s] = [m] + [m] = [m] ).

So your formulas should rather look this way:

  ...  deltaTime = 1 / fps;  velocityX = velocityX + (deltaTime * accelerationX);  carPositionX = carPositionX + (deltaTime * velocityX);


What language is this ?

Hope that helps

unbird
jujunosuke
jujunosuke
Hello unbird.

Thank you very much for you very fast reply, and for your help.

I change the code and it looks like it is working !
Also, thank you for your explanations, i found them very easy to understand.

I can se that you have much experience in this domain because just by viewing the tutorial and my lines of code, you was able to understand where i was wrong.
waow.


I am using Flash for my experimentation.
Here is a very fast view of the program :
http://www.timelessconcept.com/flashLab/car.swf

I did it very fast so it may be buggy (The wheel stop rotating after a moment for exemple).

But the visual application help me to see what's happen for real.


Basically it looks like the Frr is higher than the Fdrag at first, and then the Fdrag is getting stronger (as the tutorial said).

also

Quote:

There is no need to put a maximum speed anywhere in the code, it's just something that follows from the equations. This is because the equations form a kind of negative feedback loop. If the traction force exceeds all other forces, the car accelerates. This means the velocity increases which causes the resistance forces to increase. The net force decreases and therefore the acceleration decreases. At some point the resistance forces and the engine force cancel each other out and the car has reached its top speed for that engine power.



This is also verified.

But, something looks wrong with the numbers ?
aren't they too strong ?
Is everything's normal ?


Sorry again for my bad english.
unbird
unbird
Quote:
But, something looks wrong with the numbers ?


No, I think you got the formulas right now. You just have used a very high engine "power". When you start, the acceleration goes up to 300. If this is in SI-units, then thats about 30g, i.e. very deadly for a human driver [smile].

Since you can pretty much feed any numbers in a simulation (the constants) you can get any magnitude back (even infinity!). In real life this unlikely happens, an engine with that power would rather explode or destroy the gears.

unbird

PS: And welcome to the forum.
jujunosuke
jujunosuke
That is right !

The numbers was too strong but the mechanic worked.
To proove it, i did a screenshot of the curves that i obtain.

http://img268.imageshack.us/img268/8383/tempbd.png

The yellow is Cdrag (Air resistance)
And the Purple is Crr (Rolling Resistance)

The blue line is Cdrag+Crr.


Anyway, thanks for your great help !
Very appreciated.


Maybe ill update the post later because, i still have a lot of work to do, and i think i will face another problems soon :D

see you !
jujunosuke
jujunosuke
Ok, it wasn't that long before i get another problem :/

I am still using the same tutorial as reference :
http://regedit.gamedev.pl/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html


I am confuse about getting the good amount of torque.

It become unclear to me because some values need each other in order to work.
Also, i don't know how to get the proper curve for the torque. (LS1 Torque/Power Schema)

To get my curve, in the X axis, i just add +5 rpm every frames. (I start from 0)
And the Y axis represent the engine torque.


So if i understand the example, the rpm red line is 6000 ?
And the information we have is at 4400 rpm, we get 350 lb-ft = (475 N.m);

So if i do 4400 / 350 i obtain 12,57;

This is where is get stuck.
By doing this calcul, i get a linear curve.


Like torque = rpm / 12.57;

:/

Thanks for any help.
jujunosuke
jujunosuke
Quote:

The relationship torque versus rpm is not a linear relationship, but is usually provided as a curve known as a torque curve (the exact shape and height of the curve is specific for each engine type, it is determined by engine tests).


Does this mean that if i don't know the engine test of a car, i cannot get the (rpm/torque) curve ?
unbird
unbird
Sorry for the late answer, I had to work.

Quote:
Does this mean that if i don't know the engine test of a car, i cannot get the (rpm/torque) curve ?


You sort of answered your question by yourself [smile]. Basically, yes, if you want a "realistic" behaviour: As the article says: The relationship is not linear, but has a peak somewhere. This is actually the reason cars have several gears: Since you don't want to waste energy, you (should) drive at the optimal rpm.

So you have to provide this curve in one way or another. For instance take some real test data as a lookup table. Just make sure you get a smooth curve, i.e. no disontinuities. You will probably want to interpolate, at least linearly.

There probably exists a model for rpm/torque-rate, i.e. some formula. For experiments you can also define one on your own. A clamped quadric function could do the trick:

f(x) = max * (1 - ((x - xoptimal)/xwidth)^2 )

(I hope I got that right), where x is the rpm, max is the maximum torque, xoptimal the rpm where the torque reaches the peak and xwidth the half width of the parabola (measured where it reaches zero). Make sure you clamp, so you don't get negative values.
jujunosuke
jujunosuke
Quote:
Sorry for the late answer, I had to work.

I am very happy that someone take his own time to answer me, so please do not be sorry.

Quote:

You sort of answered your question by yourself.

Yeah, i do that very often :D


Ok, i get it !

I don't want something that much realistic, i don't have that much experience in car physics so basically i can only achieve something arcade oriented.

At least, i would like to be able to change gear properly.
Also for example, is i start from 0 with the 5th gear, i would like that my car almost doesn't start. (or very very slowly).

But i think that the code you gave me is a good base !

by the way, what does mean ^2 ? (parabola) ?

Thank you very much again !!
unbird
unbird
with ^2 I meant this:

f(x) = max * (1 - ((x - xoptimal)/xwidth)2 )

So yeah, just a square of the value on the left. Should have mentioned that this was pseudo-code of some sort.

Dont know how you code powers in Flash. For integer exponents you can either create a temporary variable and multiply it repeatedly with itself or provide a function. Don't know if Flash has a power operator integrated in the syntax, but probably that Math object you are using provides a power function with arbitrary arguments, something like
power = Math.pow(base, exponent);

jujunosuke
jujunosuke
Thanks to you i have been able to understand more and more everything.

And the tutorial doesn't look as difficult as it was the first day :D

I implemented your quadric function and the curve look like this :
http://img708.imageshack.us/img708/1072/torquerpm.jpg


AT 1000 RMP : 237.01
AT 4400 RPM : 349.99
AT 6000 RPM : 325.39

It work like a charm !


Just to verify, but i think these values are correct.

var f = 350 * (1 - ((car.rpm - 4400) / 6000) * ((car.rpm - 4400) / 6000));

350 and 4400 are the max torque/rpm value of the corvette C5 spec.
And 6000 is the red line. (rpm limit).



So right know, i have all the keys to finish my program !
I hope i wont fail ;)

Thanks for your help !
unbird
unbird
You're welcome.

Looks good. One hint though:
Quote:
var f = 350 * (1 - ((car.rpm - 4400) / 6000) * ((car.rpm - 4400) / 6000));

You take the red-line rpm for xwidth, I'd rather take the (absolute) difference to the optimal rpm (either to the redline or the minimum), so
var xwidth = 6000 - 4400;var f = 350 * (1 - ((car.rpm - 4400) / width) * ((car.rpm - 4400) / width));

But since it fictional anyway, it shouldn't matter that much. And don't forget to clamp. Scalar values should not be negative:
f = Math.max(0, f);

(Or however you clamp in Flash.)

unbird

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.