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