[ODE] Old question : Trying to do "adaptive timestep"
Nguyen Binh
Nguyen Binh <ngbinh at glassegg.com>
Wed Jul 2 20:37:02 2003
Hi,
I'm trying to integrate adaptive timestep in ODE.
What did I do is :
(1) Save all bodies information (pos, rot,facc,...etc)
(4) take time step h
(3) Recover bodies info saved in 1.
(2) Take 2 time step h/2
(5) compare current infos of bodies with info saved in
1. then find "max error"
Code :
-------------------------------------------------------------
dReal stepsize_2 = stepsize * 0.5;
// 1.0 Save first states
dxBody* pBodyContainer = (dxBody*) ALLOCA ( nb * sizeof (dxBody));
int i = 0;
for (i = 0; i < nb ; i ++)
{
memcpy (&pBodyContainer[i] , body[i] , sizeof(dxBody));
}
// 2.0 Take two small step
dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize_2);
dInternalStepIsland_x2 (world,body,nb,0,0,stepsize_2);
//SEE THIS // Or this??? dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize_2);
// 2.1 Save states after first computing
dxBody* pBodyContainer2 = (dxBody*) ALLOCA ( nb * sizeof (dxBody));
for (i = 0; i < nb ; i ++)
{
memcpy (&pBodyContainer2[i] , body[i] , sizeof(dxBody));
}
// 3. restore first values
for (i = 0; i < nb ; i ++)
{
memcpy (body[i],&pBodyContainer[i] ,sizeof(dxBody));
}
// 4. Take h stepsize
dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize);
// 5. Now calculate the max error
double fMaxError = 0.0;
double fErr = 0.0f;
for (i = 0; i < nb ; i ++)
{
// Error in X coord
fErr = dFabs(pBodyContainer2[i].pos[0] - body[i]->pos[0]);
fMaxError = ( fErr > fMaxError )? fErr : fMaxError ;
// Error in Y coord
fErr = dFabs(pBodyContainer2[i].pos[1] - body[i]->pos[1]);
fMaxError = ( fErr > fMaxError )? fErr : fMaxError ;
// Error in Z coord
fErr = dFabs(pBodyContainer2[i].pos[2] - body[i]->pos[2]);
fMaxError = ( fErr > fMaxError )? fErr : fMaxError ;
}
// Now fMaxError contains the maximum error based on
// the position
if (fMaxError > dEpsilon)
{
world->auto_step = dSqrt(world->max_error / fMaxError)*stepsize;
}
else
{
world->auto_step = stepsize;
}
if (world->auto_step > world->max_step_size)
{
world->auto_step = world->max_step_size;
}
else
if (world->auto_step < world->min_step_size)
{
world->auto_step = world->min_step_size;
}
printf("Step %.4e\n",world->auto_step);
-------------------------------------------------------------
I have test this technique with test_boxstack sample in ODE
and it works fine,
But I have found 2 problems :
1. What info of Joints to pass when I need to take 2 time
step h/2?
Full joints info on both or one with full joints info
and one with no joints?
2. How can I calculate max error beetween two bunch of
body infos?
Have anyone tried this?
Any ideas?
--
Best regards,
---------------------------------------------------------------------
Nguyen Binh
Software Engineer
Glass Egg Digital Media
E.Town Building
7th Floor, 364 CongHoa Street
Tan Binh District,
HoChiMinh City,
VietNam,
Phone : +84 8 8109018
Fax : +84 8 8109013
www.glassegg.com
---------------------------------------------------------------------