[ODE] Stability problems

Jeroen Schmitz Jeroen Schmitz" <ode at q12.org
Thu Feb 20 05:43:02 2003


Matthews, Steve USA wrote:
> Try making your world step time consistent and much smaller,
> regardless of visual FPS, by using code like:
>
> ***********
>    int i;
>
>    const static double WORLD_STEP_TIME = 0.0001;
>    int numWorldSteps =
> (int)(systemTimeSinceLastFrame/WORLD_STEP_TIME);
>
>
>    for (i=0; i < numWorldSteps; i++)
>    {
>       collide();
>       worldStep(WORLD_STEP_TIME);
>       emptyContactGroup();
>    }
>
>    double leftoverWorldStepTime =
>          systemTimeSinceLastFrame - numWorldSteps * WORLD_STEP_TIME;
>
>    collide();
>    worldStep(leftoverWorldStepTime);
>
>    emptyContactGroup();
> **********
>   (Sorry the code is not ODE syntax, but this is what I'm using, and
> it's pretty close)
>
> This will ensure that the step time in your world is consistent and
> SMALL.  There are numerous posts in the archives that cover these
> stability (of the physics world) issues.

Altough this method would indeed ensure a consistent step time, the
disadvantage of this would be that on slower computer you would get a
considerable extra amount of calculations. The problem I see with the
solution above is that the lower your fps gets, the bigger the
systemTimeSinceLastFrame value would be, which would result in an
increasing numWorldSteps, which would in turn result in even poorer
performance on such a slow system. I tried the solution above compared
to a more frame-rate dependant step time and the result on slower
computers wasn't good.
The method I use comes from one of the ODE examples and uses half the
frame time for the time steps (with a certain minimum value to prevent
the time step from becoming too large, if the framerate would become
really slow), taking two world steps per frame. This looks like this:

 dSpaceCollide (m_odeSpace,(void*)this,&nearCallback);
 dWorldStep(m_odeWorld, MIN(systemTimeSinceLastFrame/2.0, 1.0/15.0));
 dJointGroupEmpty(m_contactgroup);
 dSpaceCollide (m_odeSpace,(void*)this,&nearCallback);
 dWorldStep(m_odeWorld, MIN(systemTimeSinceLastFrame/2.0, 1.0/15.0));
 dJointGroupEmpty(m_contactgroup);

Although this indeed has the disadvantage that on slower computers your
step time increases, it gives you a lower performance impact if the
framerate goes down.

Jeroen