Advertisement

When you Fix your timestep Do you need to change the physics

Started by October 22, 2015 05:51 AM
8 comments, last by ankhd 9 years, 4 months ago

Hi all.

From FixYourTimeStep. Before fixing the time step the motion code was multiplyng the time delta with acceleration and velocity.

Like this.

//update velocity

m_vVelocity += (acceleration) * timedelta;

//update the position

m_vPos += m_vVelocity * timedelta;

That all sort of worked out hence the Fix Time step, But after the fix my timestep, The objects all stated to jitter when separation is applied.

I tracked it down to the fact, All the forces are small and applying timedelta makes them even smaller like values of V3(0.0003, 0.001, 1.023);

I even downloaded open steer and tested it , On my setup and it has the same behaviour JitterBugs. I also looked at there code and its almost the same small difference on how there ranges(obj radius and the use of the dotproduc for squared) are used.

My question is when using a fixed time step can that timedelta be removed from the calculations.

That would make the forces larger and out of the fractions.


My question is when using a fixed time step can that timedelta be removed from the calculations.

That would make the forces larger and out of the fractions.

No. A fix timestep is just a fix delta time, nothing more. Basically you have:


currentTime = getTime();
lastUpdateTime = ...
timeStep = 20;//in MS

while(lastUpdateTime<currentTime) {
   doPhysicsWithDeltatime(timeStep);
   lastUpdateTime+=timeStep;
}

Physics will often jitter due to different number of steps per frame. Best to counter this by implement a kind of movement smoothing of the rendered object, not the physics object.

Advertisement

It smells that you are trying to use pixels as world coordinates.

I put the time values back in after removing them to see what would happen, Put it this way you get some strange boid movement.

One thing I did notice was open steer uses a Dotptoduct to get a distanceSquared value. This value for me when used is in the millions 2679431.0 then when that is applied to all

obsticles that are near the force becomes so small I it has no effect.

Like this

.


D3DXVECTOR3 offset = ent->m_EntityPtr->GetWorldPos() - m_Vehicle->GetWorldPos();
			
float distanceSquared =  D3DXVec3Dot(&offset, &offset);//D3DXVec3Length(&offset);
			
steeringforce +=  ((offset)/ -distanceSquared);

Is this related to the size of the 3d world or any thing like that, Because if it was a really small world the forces would affect the object is it's wold pos was tiny.

The Steering force is strong in this one.

See I was thinking the size of my world is made up of chuncks of 1024 blocks So i divided the distanceSquared value by 1024 and added max speed and damn thing worked WTH.

What value should be used. or how to pick an acceptable value to create the force.

.


D3DXVECTOR3 offset = ent->m_EntityPtr->GetWorldPos() - m_Vehicle->GetWorldPos();
			
float distanceSquared =  D3DXVec3Dot(&offset, &offset)/1024;//D3DXVec3Length(&offset);
			
steeringforce +=  ((offset * MaxSpeed())/ -distanceSquared);

Why do I need to add crazy large value to get any force.

>> When you Fix your timestep Do you need to change the physics

yes.

you need to make sure that all your data structures are high enough precision to handle V*dt and A*dt type calculations with no loss.

you also need to remember that ET is now a scale factor. so if you used to have a velocity of 10, which moved you 10 units per update, and you have an ET of say 16.666ms (60fps), you've now scaled that 10 movement per update down to 0.01666*10 = 0.1666 units per update.

the correct way to fix things is to calculate the desired real world speed and plug that into your update code. IE set your movement rates so they match the distance scale and the (new) time scale of the game. Movement rate will be in "distance units per second", and ET will be in "seconds" - technically a fraction of a second - such as 0.016666 seconds (at 60 fps).

example: a car is moving at 100Kph. unit of distance is 1 meter. car speed is therefore 100,000/60/60 = 27.777 meters per second. ET is 0.0166666 seconds (60 fps). distance traveled = 0.0166666*27.777 = 0.462969 meters per update.

note how simply multiplying by ET scales a speed of 27.77 meters per update (with no fixed timestep) down to 0.462969 meters per update (with fixed timestep).

the only time you would not have to adjust your update code for fixed timestep is when your non-fixed and fixed update speeds just happened to be exactly the same.

generally speaking, multiplying your original unfixed timestep speed (such as 27.77 meters per update) by the new fixed timestep avergage framerate (such as 60 fps) should correct the situation - but i'm not positive about that.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


When you Fix your timestep Do you need to change the physics?

...
m_vVelocity += (acceleration) * timedelta;
//update the position
m_vPos += m_vVelocity * timedelta;

You need to verify that everything still works. That may or may not require changes.


All the forces are small and applying timedelta makes them even smaller like values of V3(0.0003, 0.001, 1.023);

Any time you start working in small slivers you can experience floating point problems. Catastrohpic cancellation and accumulated floating point error are common issues.

The exact solutions vary based on your implementation details and the specific piece of code.

Beware of mixing big things with small things, as you only get about six decimal digits of precision. As a rough example, adding one to a value in the millions can result in no change to the large value. Shifting that some decimal places, adding 0.0003 to a number in the hundreds probably will not move that floating point value.

Always stay aware of scale, as sometimes a tiny sliver means you are adding the width of a hair or the width of an atom. A few months ago someone was posting an issue on the forum where they were struggling to understand why their code was having problems, when probed for details he revealed a five-digit order of magnitude difference. He was applying forces that made changes on the micrometer scale, the scale of hair width or fingernail width, and expecting visible results on the screen centered on a two-meter figure.

Always be aware of accumulated error; while a floating point number may be precise within six digits but that quickly accumulates. It is often good to make a big change then interpolate across it. It is usually less good to accumulate a large number of those same tiny steps. When you multiply and accumulate the tiny numeric error thousands of times it can make the accumulated numbers totally worthless.

Advertisement

It may depend on the platform you are programming for. By that I mean the speed of the platform. If it's too slow that it can't update to the correct time step, most physics systems compensate for this by doing multiple steps till the simulation is up to date.

If the platform is fast enough for the update rate, then you really won't have to worry about it. In general, it's a better design to let the physics system update as many times as it needs to to catch up, than to let the dt grow too far out of whack where you start encountering frame rate dependencies.

hey all.

I've implemented Norman Barrows recommendations with the time scale. If the 2 lots of 60 in the equation to scale the timedelta are the frame time then

I have it like this. but I had to also add the scale to the forces.

.


//we need to create a time scale to multiply with the fixed time step
//the current fixed time step is 1/30 = 0.03 due to floating point you get 0.029999999
//we need the max speed of the object unit of displacement is 1m = 1000.0
double scaledspeed = (m_dMaxSpeed * 1000.0) * timedelta * timedelta;
double DTScaled = (scaledspeed) * timedelta;

D3DXVECTOR3 avoidforce ;

//needed to add scaled force to the steering is the correct?????????
m_vSteeringForce = Steering->Calculate() * scaledspeed;
						


//Acceleration = Force/Mass
D3DXVECTOR3 acceleration = m_vSteeringForce / m_dMass;

//update velocity
m_vVelocity += (acceleration)* DTScaled;// * timedelta); 

//make sure vehicle does not exceed maximum velocity
m_vVelocity = Truncate(m_vVelocity, MaxSpeed());
			
//update the position
m_vPos += m_vVelocity* DTScaled;

This now allows me to use a mass greater then 2.0 So now my tank can have a mass as near to life like.

But also the Arrive function needed to be changed. The object was over shooting even though it was breaking(slowing down) before hand(before Time Scalepgrade).

It needed to be this, It sort of works

.


dist +=m_dMass;//add this because it was over shooting
double ramped_speed =  MaxSpeed() * (dist / m_dRadius);
double clipped_speed = Min(ramped_speed,  MaxSpeed());
D3DXVECTOR3 desired_velocity = (clipped_speed / dist) * ToTarget;
D3DXVECTOR3 r = desired_velocity - Velocity();

Some thing else I don't understand is the maxfoce.

Say you have a tank that has a mass of 5000.0 Kg and a max speed of 200km what should the max force be or do you play with this value.

Because some times the tank dosen't swing hard enough so I cranked up the force to no affect it was 180 set it to 100000.0 and no change.

The code is based on the book Programming Game AI by example By Mat Buckland(a must have for noobs).

.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Yep. Needed a math lesson.

What was needed was Km/h converted to m/s, Therefore we have 60 minutes in a hour and 60 seconds in a minute give(60*60) 3600 seconds, And also convert the Km to metre Therefore we have 1000m in 1 km, We then can say 3600s ÷ 1000m = 3.6 which can be used to convert km/h to m/s by km/h ÷ 3.6 = m/s or m/s * 3.6 = km/h.

That fixes the speed issue.

But the forces are all normalized directions and when using Acceleration = Force÷Mass, I have to ramp up the forces with a magic number something like 6000.0

or if I just dump the ÷ by mass it works as in the video here. there is a issue at about 0.30 in where object 1 an 2 come head on and turn the same way and they will keep going until they bang into something(I'm resetting them with a mouse click or they will leave the field).

Boids Using Arive and Separation.

The separation is using this Spring Physics this force works the best.

Any ideas on the force÷Mass scaling the force to the nano scale.

This topic is closed to new replies.

Advertisement