[ODE] non static deltaTime in the step (worldStep(world,deltaTime) instead of worldStep(world,0.05)) => problem?

Frédéric Marmond fmarmond at soleri.com
Fri Jan 11 03:22:02 2002


Hi,

I posted a question yesterday, which was not very precise.

I'm trying to use ODE with an other graphic/collision system.
So, I don't use ODE geoms, nether collide, nether draw funcs.

As my frame rate may change (depending of  the amount of graphic to draw, and 
of other calculations), i introduce the notion of deltaTime as follow:

deltaTime = timeNow - timeLast 
then, i make a worldStep(world,deltaTime)
Isn't it good?????

As I got strange results, I'm trying now to use it without graphic at all, 
just to see where the problem is.



The problem is that when deltaTime is too small, the ODE is very instable.

So, I introduced a little loop to slow down the prog.
deltaTime is bigger, and the ODE is ok.


When i say that ODE is instable:
I use only one body, without force.
It start at Z>0.0 => it falls.
I only detect collision when it touch the Z=0 plane (ground)
After a bounce, it stabilize at this position (touch the plane Z=0)

But, after a while, it moves again, and make a great jump (unless its mass is 
800 and the gravitation is -9.81!!!)


With the loop to slow down my prog, it doesn't do this jump.


Is there any issue??????????

thanks for any help!

Fred

Here is the simplist code:
#include <ode/ode.h>
#include <sys/time.h>	//for gettimeofday => time at micro second resolution


// some constants
#define ORIG_Z 1.5
#define ORIG_MASS 8000000


static dWorldID world;
static dBodyID body;	//the body is assumed to be a sphere, with radius of 1.
static dJointGroupID contactgroup;


static const dReal* bpos;

static  timeval tdeb;
static	float tnow;
static	float tlast;
static 	float	deltaTime=0.0;


//compute the deltaTime between two frames
static void gDeltaTime()
{
	timeval tvnow;
	gettimeofday(&tvnow,0);
	tnow=(tvnow.tv_sec-tdeb.tv_sec)+(tvnow.tv_usec-tdeb.tv_usec)/1000000.0;
	deltaTime=(tnow-tlast);
	tlast=tnow;
}


//very simplist collide function:
//test if the body (sphere radius=1) touch the ground (z=0)
static void collide()
{

  if (bpos[2]<=1.0)
  {
      printf("\tTouch!");
      dContact contact;
      contact.surface.mode = dContactSoftERP | dContactSoftCFM;
      contact.surface.mu = dInfinity;
      contact.surface.soft_erp = 0.1;
      contact.surface.soft_cfm = 0.0;

      //depth of intrusion
      contact.geom.depth=-(bpos[2]-1.0);

      //contact is at body's position, z-=1, (body is a sphere radius=1)
      contact.geom.pos[0]=bpos[0];
      contact.geom.pos[1]=bpos[1];
      contact.geom.pos[2]=bpos[2]-1.0;

      //the ground is the plan z=0
      contact.geom.normal[0]=0.0;
      contact.geom.normal[1]=0.0;
      contact.geom.normal[2]=1.0;

      dJointID c = dJointCreateContact (world,contactgroup,&contact);
      //printf("\ndepth=%f",contact[i].geom.depth);
      //contact between body and the ground(static)
      dJointAttach (c,body,0);
 }
}


//basic motion
static void motion ()
{
    gDeltaTime();

    printf("\ndeltaTime=%.10f",deltaTime);
	printf("\ttimeNow=%.10f",tnow);
	printf("\tPos=%f\t%f\t%f",bpos[0],bpos[1],bpos[2]);

    collide ();

    dWorldStep (world,deltaTime);

    // remove all contact joints
    dJointGroupEmpty (contactgroup);
}


int main (int argc, char **argv)
{
  dMass m;


  // create world
  world = dWorldCreate();
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-9.81);

  // create body
  body = dBodyCreate (world);
  dBodySetPosition (body,0,0,ORIG_Z);
  dMassSetSphere (&m,1,1.0);
  dMassAdjust (&m,ORIG_MASS);
  dBodySetMass (body,&m);


  gettimeofday(&tdeb,0);
  gDeltaTime();
  gDeltaTime();
  while (true)
  {
	bpos=dBodyGetPosition(body);

  	motion();



	//loop to slow down the prog.
	//if you comment this loop, the system becomes instable!!!
	for (long i=0;i<100000;i++)
	{
		float a=cos((float)i);	//wait a moment
	}


  }

  dJointGroupDestroy (contactgroup);
  dWorldDestroy (world);

  return 0;
}