I'm using Bullet 2.82 on an Ubunutu 14.04 system.
When running my simulation with valgrind, I received a lot of uninitialized value errors, and I've tracked the major one down to certain elements in the currentConstaintRow[] array in solveGroupCacheFriendlySetup() in btSequentialImpulseConstraintSolver.cpp. Using gdb, it seems like the last element of the array goes through the for loop posted below, and some of it's members get set (m_solverBodyIdA and m_solverBodyIdB) but others don't (m_loweLimit and m_upperLimit).
The error first rears its head on this line, also in the larger code-section below (on the getBreakingImpulseThreshold call):
Code: Select all
if (solverConstraint.m_upperLimit>=constraints[i]->getBreakingImpulseThreshold())
Code: Select all
int j;
for ( j=0;j<info1.m_numConstraintRows;j++)
{
memset(¤tConstraintRow[j],0,sizeof(btSolverConstraint));
currentConstraintRow[j].m_lowerLimit = -SIMD_INFINITY;
currentConstraintRow[j].m_upperLimit = SIMD_INFINITY;
currentConstraintRow[j].m_appliedImpulse = 0.f;
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
currentConstraintRow[j].m_overrideNumSolverIterations = overrideNumSolverIterations;
}
bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
btTypedConstraint::btConstraintInfo2 info2;
info2.fps = 1.f/infoGlobal.m_timeStep;
info2.erp = infoGlobal.m_erp;
info2.m_J1linearAxis = currentConstraintRow->m_contactNormal1;
info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2;
info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
///the size of btSolverConstraint needs be a multiple of btScalar
btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
info2.m_constraintError = ¤tConstraintRow->m_rhs;
currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
info2.m_damping = infoGlobal.m_damping;
info2.cfm = ¤tConstraintRow->m_cfm;
info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit;
info2.m_upperLimit = ¤tConstraintRow->m_upperLimit;
info2.m_numIterations = infoGlobal.m_numIterations;
constraints[i]->getInfo2(&info2);
///finalize the constraint setup
for ( j=0;j<info1.m_numConstraintRows;j++)
{
btSolverConstraint& solverConstraint = currentConstraintRow[j];
if (solverConstraint.m_upperLimit>=constraints[i]->getBreakingImpulseThreshold())
{
solverConstraint.m_upperLimit = constraints[i]->getBreakingImpulseThreshold();
}
if (solverConstraint.m_lowerLimit<=-constraints[i]->getBreakingImpulseThreshold())
{
solverConstraint.m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold();
}
solverConstraint.m_originalContactPoint = constraint;
{
const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
}
{
const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
}
{
btVector3 iMJlA = solverConstraint.m_contactNormal1*rbA.getInvMass();
btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
btVector3 iMJlB = solverConstraint.m_contactNormal2*rbB.getInvMass();//sign of normal?
btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal1);
sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
sum += iMJlB.dot(solverConstraint.m_contactNormal2);
sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
btScalar fsum = btFabs(sum);
btAssert(fsum > SIMD_EPSILON);
solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?btScalar(1.)/sum : 0.f;
}
Code: Select all
==5013== Conditional jump or move depends on uninitialised value(s)
==5013== at 0x55B18F0: btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject**, int, btPersistentManifold**, int, btTypedConstraint**, int, btContactSolverInfo const&, btIDebugDraw*) (btSequentialImpulseConstraintSolver.cpp:1226)
==5013== by 0x55B4528: btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject**, int, btPersistentManifold**, int, btTypedConstraint**, int, btContactSolverInfo const&, btIDebugDraw*, btDispatcher*) (btSequentialImpulseConstraintSolver.cpp:1725)
==5013== by 0x55C3C49: InplaceSolverIslandCallback::processConstraints() (btDiscreteDynamicsWorld.cpp:191)
==5013== by 0x55BEE77: btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo&) (btDiscreteDynamicsWorld.cpp:729)
==5013== by 0x55BE303: btDiscreteDynamicsWorld::internalSingleStepSimulation(float) (btDiscreteDynamicsWorld.cpp:502)
==5013== by 0x55BE12F: btDiscreteDynamicsWorld::stepSimulation(float, int, float) (btDiscreteDynamicsWorld.cpp:452)
==5013== by 0x40BA94: NoiseWorld::clientMoveAndDisplay() (NoiseWorld.cpp:288)
==5013== by 0x40CBC8: main (main.cpp:48)
==5013== Uninitialised value was created by a heap allocation
==5013== at 0x4C2ABBD: malloc (vg_replace_malloc.c:296)
==5013== by 0x5B714FC: btAllocDefault(unsigned long) (btAlignedAllocator.cpp:24)
==5013== by 0x5B71547: btAlignedAllocDefault(unsigned long, int) (btAlignedAllocator.cpp:70)
==5013== by 0x5B7167F: btAlignedAllocInternal(unsigned long, int) (btAlignedAllocator.cpp:163)
==5013== by 0x40EDA9: btHingeConstraint::operator new(unsigned long) (btHingeConstraint.h:103)
==5013== by 0x410113: NoiseWorld::CreateHinge(int, int, int, float, float, float, float, float, float, float, float, bool) (NoiseWorld.h:332)
==5013== by 0x40B21C: NoiseWorld::initPhysics() (NoiseWorld.cpp:193)
==5013== by 0x40CB94: main (main.cpp:43)
All the best,
Josh