I am trying to implement PD control for physics-based animation. While playing around with the btGeneric6DofConstraint I came across a weird limit in motor 1. There is clearly no limit set by default, isLimited() returns false, but the rotation stops after a quarter revolution. If I set a limit I can only make it more narrow. After setting a higher limit than half PI the rotation will still stop after a quarter revolution. It might be interesting to note that the weight node connected to the joint is vibrating when reaching the weird limit, but stands still when at a limit set by me.
Using motor 0 or 2 for pitch and roll I can turn full revolutions. I would expect that behaviour for motor 1 too. Am I confronted with a bug here or is there something I am missing? Tested it with bullet-2.80-rev2531.zip and the recent svn snapshot (2546).
Here is the code I was using. I modified the ConstraintDemo for that:
Code: Select all
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(0), btScalar(0), btScalar(0)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(0), btScalar(5), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyB = localCreateRigidBody(mass, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInA.setOrigin(btVector3(btScalar(0), btScalar(0), btScalar(0)));
frameInB = btTransform::getIdentity();
frameInB.setOrigin(btVector3(btScalar(0), btScalar(-5), btScalar(0)));
btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true);
m_dynamicsWorld->addConstraint(pGen6DOF, true);
pGen6DOF->setDbgDrawSize(btScalar(5.f));
// motor control
btRotationalLimitMotor* motor = pGen6DOF->getRotationalLimitMotor(1);
//pGen6DOF->getRotationalLimitMotor(1)->m_loLimit = -SIMD_PI * 0.25;
//pGen6DOF->getRotationalLimitMotor(1)->m_hiLimit = SIMD_PI * 0.25;
motor->m_enableMotor = true;
motor->m_maxMotorForce = 1;
motor->m_targetVelocity = 1;
printf("\nmotor is limited: %s",(motor->isLimited())?"true":"false");