applyForce stops working when btRigidBody does not move for some time

Post Reply
tmohr
Posts: 8
Joined: Sat Mar 31, 2018 6:30 pm

applyForce stops working when btRigidBody does not move for some time

Post by tmohr » Tue Apr 03, 2018 7:41 pm

Hello,

I have a ground plane and one cube that I let fall down.

When the key "a" is pressed I apply a force thats direction is against gravity.
This works fine, as long as I press "a" the cube flies upwards, if I release "a" it falls down again.

But after a certain time applyForce() does not have any effect any more.

What I found during debugging is: In btRigidBody.c in applyDamping() I print out m_linearVelocity.
The values make sense. If the cube rests without movement then the values in m_linearVelocity go lower.
At a certain point they become 0.0 and at exact that time applyForce() does not have an effect any more.

If I then press "a" and by that do applyForce() then the values in m_linearVelocity go to a certain value,
but the cube does not move any more.

i have these global variables:

Code: Select all

btBroadphaseInterface* broadphase;
btDefaultCollisionConfiguration* collisionConfiguration;
btCollisionDispatcher* dispatcher;
btSequentialImpulseConstraintSolver* solver;
btDiscreteDynamicsWorld* dynamicsWorld;

btCollisionShape* groundShape;

btDefaultMotionState* groundMotionState;
btRigidBody::btRigidBodyConstructionInfo* groundRigidBodyCI;
btRigidBody* groundRigidBody;

btCollisionShape* fallShape;
btDefaultMotionState* fallMotionState;
btRigidBody::btRigidBodyConstructionInfo* fallRigidBodyCI;
btRigidBody* fallRigidBody;
btVector3* fallInertia;

The initialization is done like this (gravity goes in direction Z):

Code: Select all

  broadphase = new btDbvtBroadphase();
  collisionConfiguration = new btDefaultCollisionConfiguration();
  dispatcher = new btCollisionDispatcher(collisionConfiguration);
  solver = new btSequentialImpulseConstraintSolver;
  dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
  dynamicsWorld->setGravity(btVector3(0, 0, -10));

  groundShape = new btStaticPlaneShape(btVector3(0, 0, 1), 1);
  groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, -1)));
  groundRigidBodyCI = new btRigidBody::btRigidBodyConstructionInfo(0, groundMotionState, groundShape, btVector3(0, 0, 0));
  groundRigidBody = new btRigidBody(*groundRigidBodyCI);

  dynamicsWorld->addRigidBody(groundRigidBody);


  btScalar mass = 1;

  fallShape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
  fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 15)));
  fallInertia = new btVector3(0, 0, 0);
  fallShape->calculateLocalInertia(mass, *fallInertia);
  fallRigidBodyCI = new btRigidBody::btRigidBodyConstructionInfo(mass, fallMotionState, fallShape, *fallInertia);
  fallRigidBody = new btRigidBody(*fallRigidBodyCI);

  dynamicsWorld->addRigidBody(fallRigidBody);
To apply a force (each cycle this code is executed if "a" is pressed:

Code: Select all

#define IMP  50
      fallRigidBody->applyForce(btVector3(0, 0, IMP), btVector3(0, 0, 0));
It would be great if anybody had a hint on this.

It looks to me that after some dampening it is detected that the velocity is near 0 and then it is set to 0.
Not sure if I need to do anything else.


Thanks for any hints,
Torsten

tmohr
Posts: 8
Joined: Sat Mar 31, 2018 6:30 pm

Re: applyForce stops working when btRigidBody does not move for some time

Post by tmohr » Tue Apr 03, 2018 8:33 pm

Hi,

I created an example that I compile with the sources of Bullet-2.87 and that shows the effect.
The example is attached. I wonder if somebody can reproduce the weird behavior or can tell that it is working as expected?

Here is the main part:

Code: Select all

// Gravity is in Z axis
int main(int argc, char** argv) {
  init_bullet();

  for(int i = 0; i < 300; i++) {
    printf("loop %i\n");

    // This has an effect, you can see Z position goes up
    if(100 < i && i < 110) {
      fallRigidBody->applyForce(btVector3(0, 0, 50), btVector3(0, 0, 0));
    }

    // This does NOT have an effect, the cube was on the floor too long
    if(280 < i && i < 290) {
      fallRigidBody->applyForce(btVector3(0, 0, 50), btVector3(0, 0, 0));
    }

    bullet_cyclic();

    btTransform trans;
    fallRigidBody->getMotionState()->getWorldTransform(trans);
    btVector3 pos = trans.getOrigin();

    printf("pos %f %f %f\n", pos.getX(), pos.getY(), pos.getZ());
  }
}
Thanks for any hints,
Torsten
Attachments
main.cpp
bullet example
(2.64 KiB) Downloaded 36 times

Mako_energy02
Posts: 171
Joined: Sun Jan 17, 2010 4:47 am

Re: applyForce stops working when btRigidBody does not move for some time

Post by Mako_energy02 » Tue Apr 03, 2018 10:49 pm

The immediate thing that came to mind is object activation. This is intended to be an optimization that allows Bullet to skip objects that don't need processing. It sounds like it's being deactivated, and simply not waking up when you apply the force. You can test this by forcing the activation when you apply the force.

The method you want is on the CollisionObject class:
http://bulletphysics.org/Bullet/BulletF ... 667e02c816

Lines 22 through 26 in the CollisionObject header have the values that are expected to go into it:
http://bulletphysics.org/Bullet/BulletF ... ource.html

ACTIVE_TAG means it should be processed. DISABLE_SIMULATION means it should be skipped. DISABLE_DEACTIVATION means you never want it to sleep under any circumstance.

tmohr
Posts: 8
Joined: Sat Mar 31, 2018 6:30 pm

Re: applyForce stops working when btRigidBody does not move for some time

Post by tmohr » Wed Apr 04, 2018 2:59 am

Great, that solved it. Thanks for that hint.

I haven't seen that one in any of the examples. Not sure, can I read somewhere about any other methods / attributes that could be pitfalls?

Best regards
Torsten

Post Reply