NewtonSetSleepState does not wake bodies properly

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

NewtonSetSleepState does not wake bodies properly

Postby jamesm6162 » Tue Jul 26, 2016 8:19 am

Hi

I have a situation where I apply external forces to a body that is connected via a constraint to another body.

When I apply the force to the body I call NewtonSetSleepState(body, 0) to wake it up. However the force as very little to no effect.

When I disable autosleep on all bodies, then the force moves both bodies, exactly as it should.

Then with autosleep enabled again, I call NewtonSetSleepState(...,0) on BOTH bodies before I apply the force, yet still they do not move, or need a much larger force before they start moving.

I have created a sandbox demo to test. Each body is 1000kg and I set friction to the minimum 0.01 in the callback.

With autosleep off it requires around 300Nm force to move, but with autosleep on it does not move at all, untill you increase the force (Hold 'F' to increase, and 'R' to decrease)

Code: Select all


class ActivationTestController: public CustomControllerBase
{
   class ActivationTestEntity: public DemoEntity
   {
      NewtonBody* m_body;
      dVector m_force;
      dFloat m_friction;
   public:   
      ActivationTestEntity(DemoEntityManager* const scene, dMatrix& matrix, dFloat mass)
         :DemoEntity (matrix, NULL)
         , m_force(0.0)
         , m_friction(0.0)
      {
         NewtonWorld* const world = scene->GetNewton();

         dVector size(1.0f, 1.0f, 1.0f, 0.0f);

         int materialID =  NewtonMaterialGetDefaultGroupID (world);         
         NewtonCollision* boxShape = CreateConvexCollision (world, dGetIdentityMatrix(), size, _BOX_PRIMITIVE, 0);

         m_body = CreateSimpleBody(world, this, mass, matrix, boxShape, materialID);
         NewtonBodySetForceAndTorqueCallback(m_body, ApplyForces);
         NewtonMaterialSetCollisionCallback (world, materialID, materialID, OnAABBOverlap, ContactFriction);
         
         DemoMesh* const geometry = new DemoMesh("convexShape", boxShape, "smilli.tga", "smilli.tga", "smilli.tga");
         SetMesh(geometry, dGetIdentityMatrix());
         geometry->Release();

         scene->Append(this);

         NewtonDestroyCollision (boxShape);
      }

      ~ActivationTestEntity()
      {
         
      }

      NewtonBody* GetBody() const { return m_body; }

      virtual void Render(dFloat timeStep, DemoEntityManager* const scene) const
      {
         DemoEntity::Render(timeStep, scene);
      }

      static void  ApplyForces(const NewtonBody* body, dFloat timestep, int threadIndex)
      {
         dFloat Ixx;
         dFloat Iyy;
         dFloat Izz;
         dFloat mass;

         NewtonBodyGetMass (body, &mass, &Ixx, &Iyy, &Izz);

         dVector force (dVector (0.0f, 1.0f, 0.0f).Scale (mass * DEMO_GRAVITY));
         ActivationTestEntity* entity = (ActivationTestEntity*)NewtonBodyGetUserData(body);
         NewtonBodySetSleepState(body, 0);
         //NewtonBodySetFreezeState(body, 0);
         force += entity->m_force;            
         
         
         NewtonBodySetForce (body, &force.m_x);
      }

      // optionally uncomment this for hard joint simulations
      static int OnAABBOverlap (const NewtonMaterial* const material, const NewtonBody* const body0, const NewtonBody* const body1, int threadIndex)
      {
         return 1;
      }

      static void ContactFriction (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex)
      {
         dFloat Ixx;
         dFloat Iyy;
         dFloat Izz;
         dFloat mass;

         // call  the basic call back
         GenericContactProcess (contactJoint, timestep, threadIndex);

         const NewtonBody* const body0 = NewtonJointGetBody0(contactJoint);
         const NewtonBody* const body1 = NewtonJointGetBody1(contactJoint);
         const NewtonBody* body = body0;
         NewtonBodyGetMass (body, &mass, &Ixx, &Iyy, &Izz);
         if (mass == 0.0f) {
            body = body1;
         }

         ActivationTestEntity* entity = (ActivationTestEntity*) NewtonBodyGetUserData(body);
         dFloat friction = entity->GetFriction();
         for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) {
            NewtonMaterial* const material = NewtonContactGetMaterial (contact);
            NewtonMaterialSetContactFrictionCoef (material, friction, friction*0.8, 0);
            NewtonMaterialSetContactFrictionCoef (material, friction, friction*0.8, 1);
         }
      }

      void AddForce(const dVector& f)
      {
         m_force += f;
      }

      const dVector& GetForce() const
      {
         return m_force;
      }

      dFloat GetFriction() const
      {
         return m_friction;
      }
   };

   DemoEntityManager* m_scene;
   
public:
   void PreUpdate(dFloat timestep, int threadIndex)
   {      
      if (m_scene->GetRootWindow()->GetKeyState('F'))
      {
         m_parent->AddForce(dVector(0,0,1000.0*timestep));
      }

      if (m_scene->GetRootWindow()->GetKeyState('R'))
      {
         m_parent->AddForce(dVector(0,0,-1000.0*timestep));
      }

      if (m_scene->GetRootWindow()->GetKeyState('T'))
      {
         m_parent->AddForce(dVector(-1000.0*timestep, 0,0));
      }

      if (m_scene->GetRootWindow()->GetKeyState('G'))
      {
         m_parent->AddForce(dVector(1000.0*timestep,0,0));
      }
   }

   void PostUpdate(dFloat timestep, int threadIndex)
   {
      
   }

   void Init()
   {
      NewtonWorld* const world = ((CustomControllerManager<ActivationTestController>*)GetManager())->GetWorld();
      DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world);
      m_scene = scene;
      dMatrix m(dGetIdentityMatrix());

      m.m_posit = dVector(0,2, 2);
      m_parent = new ActivationTestEntity(scene, m, 1000);
      m_parent->AddForce(dVector(0,0,300));

      m.m_posit = dVector(0,2,-2);
      m_child = new ActivationTestEntity(scene, m, 1000);
      // Halfway
      dMatrix pivot(dRollMatrix(90.0f * 3.141592f / 180.0f));
      pivot.m_posit = dVector(0,2,0);
      CustomHinge* hinge = new CustomHinge(pivot, m_child->GetBody(), m_parent->GetBody());
   }

   void RenderDebug(DemoEntityManager* const scene, int lineNumber)
   {
      dVector color(1.0f, 1.0f, 0.0f, 0.0f);
      const dVector& force = m_parent->GetForce();
      scene->Print(color, 10, lineNumber + 20, "Force: %0.3f,%0.3f,%0.3f", force.m_x, force.m_y, force.m_z);
   }

private:
   ActivationTestEntity* m_parent;
   ActivationTestEntity* m_child;
};


class ActivationTestManager : public CustomControllerManager<ActivationTestController>
{
public:
   ActivationTestManager(DemoEntityManager* const scene)
      :CustomControllerManager<ActivationTestController>(scene->GetNewton(), "ActivationTestManager")
   {
      ActivationTestController* controller = CreateController();
      controller->Init();

      scene->Set2DDisplayRenderFunction(RenderDebug, controller);
   }

   static void RenderDebug(DemoEntityManager* const manager, void* const context, int lineNumber)
   {
      ActivationTestController* controller = (ActivationTestController*) context;
      controller->RenderDebug(manager, lineNumber);
   }

   virtual void Debug () const {};
};

void CustomTest (DemoEntityManager* const scene)
{
    scene->CreateSkyBox();

   CreateLevelMesh (scene, "flatPlane.ngd", 1);
    ActivationTestManager* manager = new ActivationTestManager(scene);
   
   scene->GetRootWindow()->m_debugDisplayMode = 2;
   // place camera into position
    dMatrix camMatrix (dGetIdentityMatrix());
   
   dVector origin(-10,5,0);
    dQuaternion rot (camMatrix);
   
    scene->SetCameraMatrix(rot, origin.Scale(1.01));
}


Can you tell me why this is happening?

Thanks
James
jamesm6162
 
Posts: 49
Joined: Wed Aug 12, 2015 8:50 am

Re: NewtonSetSleepState does not wake bodies properly

Postby Julio Jerez » Tue Jul 26, 2016 1:44 pm

you should have to do any set auto sleep manipulation at all, if the force is different that the previous the body will automatically wake up. where are you applying the force?

is that code fragment a working script?
Julio Jerez
Moderator
Moderator
 
Posts: 11043
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonSetSleepState does not wake bodies properly

Postby jamesm6162 » Wed Jul 27, 2016 2:04 am

Yes the code is a complete demo that you can copy paste, just rename the demo function from "CustomTest" to whatever demo you are replacing.

I apply the force in the ApplyForces callback set using NewtonBodySetForceAndTorqueCallback. Inside I use NewtonBodySetForce
jamesm6162
 
Posts: 49
Joined: Wed Aug 12, 2015 8:50 am


Return to Bugs and Fixes

Who is online

Users browsing this forum: Julio Jerez and 1 guest