Sign in to follow this  
Concentrate

How to use Time in a stable manner

Recommended Posts

My mass-spring system starts ok, then when it starts reaching its rest length, it moves faster and faster as time goes on, Since time is getting greater. How do I stabilize the time, so that the mass moves at an constants velocity. Here is the equation that I use( euler )
void calculate()
{				
	const float DAMPING = 0.01f;
	Vector3D changeInLength = box.posVec - restLength;	

	//F = -kx - damp*velVec
	box.forceVec = -STIFFNESS * changeInLength -DAMPING*box.velVec;

	//F = ma:  a = F/m
	box.accelVec = box.forceVec / box.getMass();

	// V = a*t
	box.velVec += box.accelVec * timer.getDiffSec();

	// X = v*t
	box.posVec += box.velVec * timer.getDiffSec();
	
	//adjust rope( just a line )'s length, starts from 0->endPoint
	rope.setEndPoint( box.posVec );
		
	}


The spring starts to reach its rest length faster and faster. Here is what I mean, link [Edited by - Concentrate on December 22, 2009 1:04:31 PM]

Share this post


Link to post
Share on other sites
There could be several reasons why. Euler methods tend to be quite bad when it comes to accuracy and stability. Generally the margin of error increases at bigger time steps, too. Also, there are could be oscillation problems as a mass comes close to the rest position. If these oscillations are not controlled, you will have a runaway effect and your system blows up. Finally, erratic time steps could be also a problem. You may need to filter the time step values in your timer class in order to minimise jittering.

Share this post


Link to post
Share on other sites
Sorry can you explain a bit more?

I think I screwed something up with something, because as I increase the mass
the spring's oscillation lasts longs, meaning that the spring takes longer
to reach its stable state. While, if the mass is low, it gets to its stable state
faster?


I changed it a bit, and looks more stable but its still screwed up, here is what
I have.

void calculate()
{
float dt = timer.getDiffSec();

const float DAMPING = 0.01f;

Vector3D changeInLength = box.posVec - restLength;

//F = -kx
box.forceVec = -STIFFNESS * changeInLength -DAMPING*box.velVec;
//F = ma: a = F/m
box.accelVec = box.forceVec / box.getMass();
// V = a*t
box.velVec += box.accelVec * dt;
// X = v*dt + 1/2 a*dt^2
box.posVec += box.velVec * dt + 1/2.0 * box.accelVec * dt * dt;

//adjust rope( just a line )'s length, starts from 0->endPoint
rope.setEndPoint( box.posVec );

}


Share this post


Link to post
Share on other sites
From your initial post, the way I understood your question is that your system is getting unstable as time goes on. In my response I basically meant your Euler integrator is accumulating errors, just like the red line in this picture. Now if the time step is large (the gap between the red dots), the integration error will be also much greater.

Quote:
I think I screwed something up with something, because as I increase the mass
the spring's oscillation lasts longs, meaning that the spring takes longer
to reach its stable state. While, if the mass is low, it gets to its stable state
faster?

It's been a while since I worked with springs, but sounds about right. More mass means more inertia, therefore the damping system has to work harder (or longer) to bring the mass to rest.

Share this post


Link to post
Share on other sites
Its integration seems ok, but the problem is that as the mass moves towards
its rest length, it move faster and faster. I don't think thats supposed to
happen. This is what i was trying to simulate :

http://www.myphysicslab.com/spring1.html


I'm sorry if I misread something.

Share this post


Link to post
Share on other sites
Quote:
Original post by alvaro
Try making dt a constant and see if that way you get a stable simulation. A variable time step makes things complicated, particularly because you can't reproduce results from one run to another.



Yea, that solved it. Made dt = 1; instead of it equal timer.getDiffMilli().

Feels like I am faking physics. Why wouldn't varying dt, work well ? I mean,
the velocity magnitude of the velocity should decrease constant relative to
the change in time ? So I would think it would move at constant speed. Or maybe I
am wrong? Thanks. So what does dt, mean if I just set it to 1, or 5, or 0.5 ?

Share this post


Link to post
Share on other sites
1. What is the resolution/accuracy of your timer.
2. What framerate is your simulation running at.

You may be using a timer that does not provide enough resolution to run at the speeds your simulation is running at, especially if it's currently a fairly simple simulation running at hundreds of frames a second.

Also check out Gaffer's article on how to properly fix your timestep in a physics simulation (with reasons why it's beneficial to do so): Fix Your Timestep

All his other articles are great reads as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by Raskell
1. What is the resolution/accuracy of your timer.
2. What framerate is your simulation running at.

You may be using a timer that does not provide enough resolution to run at the speeds your simulation is running at, especially if it's currently a fairly simple simulation running at hundreds of frames a second.

Also check out Gaffer's article on how to properly fix your timestep in a physics simulation (with reasons why it's beneficial to do so): Fix Your Timestep

All his other articles are great reads as well.


Thanks for the link. I use the clock() function in the ctime header. Don't know
if there are better methods? Right now my frame rate is not constants. I did
not stabilize the frame rate. Using the help of the article inside the link,
it helps and now looks better. Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by Concentrate
[...] Right now my frame rate is not constants. I did
not stabilize the frame rate.

The point is not to fix your frame rate, but to decouple your physics updates from your frame rendering. Working with a variable dt can be a lot of trouble, so I strongly recommend that approach.

Share this post


Link to post
Share on other sites
>>The point is not to fix your frame rate, but to decouple your physics updates from your frame rendering. Working with a variable dt can be a lot of trouble, so I strongly recommend that approach.

Ok, But that might be troublesome sometimes.

For right now this is how I update it, using the graffe's article.

GLvoid disp()
{
update.start();

static float accumlator = 0.0f;
static const float deltaTime = 1/100.0f; //10 millisecond

if(update.getDiffSec() >= deltaTime)
{
accumlator += deltaTime;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,0,-30);

while(accumlator >= deltaTime){
spring.drawSpring(deltaTime);
accumlator -= deltaTime;
}


glBegin(GL_LINES);
glColor3f(1,0,0);
glLineWidth(10);
glVertex3f( spring.getRestLength().getX(), -5.0f,0.0f);
glVertex3f( spring.getRestLength().getX(), +5.0f,0.0f);
glEnd();

glutPostRedisplay();
glutSwapBuffers();

update.reset();
}
}





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