Sign in to follow this  
lonewolff

Trouble calculating acceleration

Recommended Posts

Hi Guys,

I am trying to calculate acceleration due to gravity for a game I am making. So, far I have come up with this;


[code]#include<windows.h>
#include<iostream>

double a=9.8;
double v=0,u=0,t=0,tslf,currenttick,lasttick;

int main()
{
lasttick=GetTickCount();

while(true)
{
currenttick=GetTickCount();
tslf=currenttick-lasttick;
lasttick=currenttick;

t=t+(tslf/1000);
v=u+a*t;
u=v;

system("cls");
std::cout<<"Time since last frame: "<<tslf<<"ms\r\n";
std::cout<<"Velocity: "<<v<<" M/Sec \r\n";

Sleep(1000);
}

return 0;
}[/code]

This is working as I intended. But, if I change the Sleep() time to a different value eg. Sleep(10), then the acceleration results vary. With Sleep(10) the calcualted velocity blows out by 10.

I can't figure out why this is as the clock is sampled on each loop.

Any help would be awesome.



Share this post


Link to post
Share on other sites
GetTickCount() is a pretty low-res timer, so using it will only produce stable results if the time between each loop is high (does Sleep(2000) work as expected?). Look in to the windows performance timer.

Share this post


Link to post
Share on other sites
Sleep(1000) results (Secs / Result)

0 [b] 0[/b]
1.01399 [b]9.93711
[/b]2.02797 [b]39.7483[/b]
3.04197 [b]99.3708
[/b]4.05595 [b]198.742
[/b]5.06993 [b]347.798
[/b]6.08392 [b]556.476
[/b]7.0979 [b]834.714[/b]
8.11189 [b]1192.45[/b]
9.12588 [b]1639.62
[/b]10.1399 [b]2186.16

[/b]Sleep(2000)

0 0
2.01236 19.7212
4.02474 78.8848
6.03711 197.212
8.04949 394.424
10.0619 690.243


So, at 10 seconds the results are totally different.

I have just tried with the high performance query counter and the results are the same as above (give or take).

Share this post


Link to post
Share on other sites
[color=#1C2837][size=2][color=#000000]t[/color][color=#666600]=[/color][color=#000000]t[/color][color=#666600]+([/color][color=#000000]tslf[/color][color=#666600]/[/color][color=#006666]1000[/color][color=#666600]);[/color][/size][/color]
I guess this is your problem:

it should simply be

t=tslf/1000.0f;

What's that "u" for? it doesnt do anything.

you can just take it out and do:

v+=a*t

Share this post


Link to post
Share on other sites
To elaborate - t is the time elapsed since the program started, so a*t would the total velocity, not the change in velocity. You're adding it to the velocity from the previous iteration, so you want the change in velocity, not the total velocity. You would need either:

[code]v = a*t;[/code]

or

[code]v = u + a*tslf/1000;
u = v;[/code]

the first of which calculates the velocity all over again from the total time and the second of which updates it each iteration using the velocity in the previous iteration. I would recommend the second, as it's more flexible - you're not limited to constant acceleration, as you'll still get the correct result if you change a from iteration to iteration.

(edit: now uses code tags)

Share this post


Link to post
Share on other sites
The reason for the 'u' is that it is part of the physics equation for acceleration;

v=u+a*t

So, that is why I had it in there.

I tried your suggestion but the results are still off.

Sleep(2000) - 10.0619 sec 295.819

Sleep(1000) - 10.1399 sec 546.539

The amount of sleep time is directly impacting the results. More sleep, lower values. Less sleep, higher values :(

Share this post


Link to post
Share on other sites
I see what is happening. The results for the 1sec sample are correct.

But, when you change the sample rate the velocity is only getting accumulated at that time.

So a 1sec sample will give 147 at the 5 second mark. But if you do a 5sec sample it will only be 49 as v=u+at. 49=0+9.8*5.

The velocity gained due to acceleration isnt being added. Now, I have to figure out how to take that into account. :blink:

Share this post


Link to post
Share on other sites
[quote name='lonewolff' timestamp='1313227604' post='4848561']
I tried your suggestion but the results are still off.

[/quote]

no you havent

[code]

#include<iostream>

using namespace std;

double a=9.8;
double v=0,u=0,t=0,tslf,currenttick,lasttick;

int main()
{
lasttick=GetTickCount();
int c=0;
int tt=0;
while(true && tt<10000)
{
currenttick=GetTickCount();
tslf=currenttick-lasttick;
lasttick=currenttick;

t=(tslf/1000.0f);
v+=a*t;



std::cout<<"T"<<tt<<"ms\r\n"<<endl;
std::cout<<"Velocity: "<<v<<" M/Sec \r\n"<<endl;

Sleep(500);
c++;
tt+=tslf;
}

return 0;
}

[/code]
[color="#1C2837"][font="CourierNew, monospace"] [/font][/color]

compile, run and see yourself

Share this post


Link to post
Share on other sites
[quote name='lonewolff']49=0+9.8*5[/quote]
I think that's actually correct.

[quote name='lonewolff']But, when you change the sample rate the velocity is only getting accumulated at that time.[/quote]
That's not what's going on here; the thing you mention can be an issue other times, but it shouldn't matter here because your acceleration is constant. The Sleep(1000) results that you posted are actually wrong - notice that if you plot them you'll get a curved line, and v = u + v*t should be a straight line, just like y = m*x + b.

v = u + a*t is correct, but you're using it incorrectly. u is the initial velocity, a is the acceleration, and t is the amount of time you spend accelerating. You're using it each step, so:

> u is the velocity at the start of the step, which you have correct.
> a is 9.8, which isn't a problem.
> t should be the amount of time that passes [i]on the step you're calculating[/i]. Your t is the amount of time that's passed [i]since the start of the simulation[/i]. This is wrong because your u is from the start of the step, not the start of the simulation.

You've already got the amount of time that passes on the step - you store it as tslf. You need to use tslf/1000 instead of t when you update the velocity with v = u + v*t. That's the second method I mentioned in my post above.

Incidentally, you can correct it a different way, as kunos suggested. The velocity starts out at 0, you can leave t the way you have it and use u = 0; that way everything is correct again because both u is at the start of the simulation and t is measured from the start of the simulation. That's the first method in my post above.

I hope that helps!

Share this post


Link to post
Share on other sites
@Kunos - Yes I have and you are wrong...

I have worked it out. I can work out the distance travelled at any point in time. So, from that I can work out the velocity at any time given the following equations.

[size="2"]s=u*t+0.5*(a*(t*t));

v=u*u+2*a*s;

v=sqrt(v);[/size]

So, the results are now solid and accurate no matter what the sample rate.

Share this post


Link to post
Share on other sites
[quote name='lonewolff' timestamp='1313231612' post='4848580']
@Kunos - Yes I have and you are wrong...

I have worked it out. I can work out the distance travelled at any point in time. So, from that I can work out the velocity at any time given the following equations.

[size="2"]s=u*t+0.5*(a*(t*t));

v=u*u+2*a*s;

v=sqrt(v);[/size]

So, the results are now solid and accurate no matter what the sample rate.
[/quote]

[img]http://public.gamedev.net/public/style_emoticons/default/blink.gif[/img]



lol

whatever dude

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this