Is the way I've got velocity setup accurate for simulation?

Started by
4 comments, last by shadow12345 19 years, 11 months ago
I want to know how accurate the way I''ve got velocity setup is. I''m not using an integrator method first of all. Each object in the world has a velocity, and all changes in velocity are due to impulses, not forces. I didn''t want to choose forces because I didn''t want to have to keep track of the amount of time each object has what force being applied to it. Each object has a velocity. Every frame, the Position changes by the Velocity vector * timefrac, where timefrac is the amount of time per frame, and the magnitude of the velocity vector is in feet per second. So if I want to move 5 units per second along the x axis, i set the velocity vector to: (FOOT(5),0,0), and the displacement is (FOOT(5)*timefrac,0,0) where FOOT(x) is a macro converting arbitrary world units into feet. Now, when I want to accelerate, i.e the acceleration due to gravity, I do this for each world object''s velocity: Velocity.y -= FOOT(32) * timefrac and then whatever the final velocity is, I do this: NewPos = OldPos + Velocity * timefrac This *seems* to be working beautifully. I can clamp the frame rate to 5 frames per second with a large timefrac or let it run at a high framerate of 150 and a small timefrac and when I jump up I always seem to go to the same height before falling down. I''ve done some ''ghetto experiments'' trying to measure the distances traveled in a certain time period, and it seems to work no matter what the frame rate with a given acceleration. The thing is, I see all of you guys talking about fancy ''verlet integration'' (which I don''t know what it is) and keeping track of the time period of forces and stuff, and numerical inaccuracies, fixed timesteps and instability. subsequently it seems like my paradigm must be wrong, and ill be crushed if it is
Why don't alcoholics make good calculus teachers?Because they don't know their limits!Oh come on, Newton wasn't THAT smart...
Advertisement
hm... you not even use impulse to speed your objects...
if you would use impulse, you had to divide by the mass of the accelerated object when modifying it''s velocity.

what you do is just modify the objects speed directly. all objects, no matter their mass, would accelerate and break same speed this way (what isn''t right, objects with higher mass should be way harder to change their velocity)

for your way of modifying the velocity (neglecting you don''t take into account the mass of the object), you apply a force over a certain time (the frame time) to your objects. and this is the propper way.

if i am not totally wrong now: (what happens more often than I want to )
impulse = force * fime
so
velocity = force * time / mass = impulse / mass

and as long you don''t want to have an acceleration over a friction of your timeslice it doesn''t matter if you use an impulse or force to accelerate your object.
actually it is easier to calculate the impulse to apply to an object to break it''s velocity down to zero than to calculate the force you have to apply during the NEXT frame (which duration is unknown) to get the same result, that''s why we enabled both methods to accelerate an object during a frame in our physic engine.


-----
The scheduled downtime is omitted cause of technical problems.
-----The scheduled downtime is omitted cause of technical problems.
quote:Original post by shadow12345
I''m not using an integrator method first of all.


You say you aren''t, eh? Hmmmm.

quote:Original post by shadow12345
Velocity.y -= FOOT(32) * timefrac


Surprise! That''s an integrator. . An "explicit" or "simple" Euler integrator to be specific. The very simplest one possible, but still an integrator. The definition of this integrator is when you take a value, velocity or anything, and update it for the new time step by taking the previous time step value and adding the first time derivative of the value and multiplying by the amount of time that passed since the last update. Here, your -FOOT(32) is acceleration, which is the first time derivative of velocity. Therefore, you have a simple Euler integrator for velocity.

quote:Original post by shadow12345
NewPos = OldPos + Velocity * timefrac


So is this. Anytime you update a value by using its first time derivative (velocity is the first time derivative of position) and the time step, you''re using an integrator whether you know it or not. But this one is not simple Euler. Reason being you are using the updated velocity instead of the velocity at the previous time step. Its good to NOT use simple Euler whenever possible, and so this is better than the above. But a Verlet technique would be better still for rigid body dynamics. And, turns out, that is actually pretty easy also.

Now, on to the more badish news. That timefrac, the time per frame, is a non-fixed time step, which leads to difficulties. So, unfortunately, you''re subject to the problems that others have somewhat solved using Verlet integration and fixed time steps. So, I hope you''re not too crushed, .

Now, that said, you have a really, really good start. You''ve done one thing right that lots of people get totally wrong when they write their first physics simulator. You are computing your new velocity first, and are then updating your position using the *new* velocity. You have thus avoided using the dreaded "simple" or "explicit" Euler integration technique FOR YOUR POSITION UPDATE . That''s the right thing to do, though Verlet would be better still.

But, don''t worry about that for now. You can upgrade to Verlet fairly easy, as there are some good docs out there (check the Game Developer Conference archives at www.gdconf.com and www.gamasutra.com for example for the past couple of years). You''re actually doing okay. The biggest thing to worry about next is to get rid of that variable per frame timefrac. This will lead to trouble eventually, probably already has and you''re just getting lucky because your forces are simple (gravity alone wouldn''t cause trouble until collision stuff gets in the way). You do need to read up on using a fixed time step. Its not too hard. Its just a matter of setting timefrac to a constant, say 0.01 (1/100 second) and *leaving* it there. Then, for each frame, only run a physics steps if the actual frame time is > the constant timefrac. Run as many physics steps as you need to catch up, e.g., if the actual frame time is 1/50 sec, then you need to do two physics steps at 1/100 sec timefrac each. If the next frame is then 1/100 sec, just do one physics step for that frame, etc. This might mean there are some frames where you do zero physics steps, some frames when you do 2 or 3. But, the benefit is that you can pick a stable time step and also that your physics calcs are exactly reproduceable every time you run, on any machine, making gameplay repeatable, more predictable, more stable.

Hope this helps!

Graham Rhodes
Principal Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Wouldn’t it be more correct to do the following:

Accel = FOOT(32)

NewPos = OldPos + (Velocity * timefrac) + (Accel * timefrac * timefrac / 2)

Velocity -= (Accel * timefrac)


[edited by - Grain on May 2, 2004 6:22:02 AM]
Thanks for the help! Your posts have greatly cleared this matter up for me. I also appreciate the sources you gave to me grhodes and your particularly lengthy reply and encouragement.

One of the things I thought of that would be nasty to represent with my system is a spring, because as the spring compression changes so does its force and the acceleration of both objects on each and, and as soon as there is a change in their positions, the force of the spring changes because the compression length changes. I guess this is also the same with gravity because it is also based on distance, but very few simulator take that into account.

I guess I've just got more reading to do!

Thanks you guys.

quote:
(gravity alone wouldn't cause trouble until collision stuff gets in the way)

What exactly do you mean by this? I've got it so that the gravity is added to the velocity each frame, and when an object collides with something, it checks for a coefficient of restitution, and if it hit an ENTITY in the BSP then it generates an impulse between the objects along the hitnormal(which works beautifully), but if you say hit an incline plane it takes into account friction, based on the normal force, then accelerates down the plane as you would expect it to.

EDIT1:
quote:
Accel = FOOT(32)

NewPos = OldPos + (Velocity * timefrac) + (Accel * timefrac * timefrac / 2)

Velocity -= (Accel * timefrac)


I am not totally sure. I believe that both methods are equivalent, but this is because gravity is a relatively simple force to represent.
[edited by - shadow12345 on May 2, 2004 1:09:37 PM]

[edited by - shadow12345 on May 2, 2004 1:16:04 PM]

[edited by - shadow12345 on May 2, 2004 1:16:56 PM]

[edited by - shadow12345 on May 2, 2004 1:18:37 PM]
Why don't alcoholics make good calculus teachers?Because they don't know their limits!Oh come on, Newton wasn't THAT smart...
quote:Original post by shadow12345
quote:
Accel = FOOT(32)

NewPos = OldPos + (Velocity * timefrac) + (Accel * timefrac * timefrac / 2)

Velocity -= (Accel * timefrac)


I am not totally sure. I believe that both methods are equivalent, but this is because gravity is a relatively simple force to represent.


They definitely are NOT equivalent. Grain provides the exact solution, yours is an approximation.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

This topic is closed to new replies.

Advertisement