[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;
}