Friction between body and groundplane
Posted: Fri Aug 04, 2017 6:03 am
Hi all,
I set up an ant on ground plane environment inspired by the evo neural network 3D walker example.
My problem now is, that I have no or minimal friction between the ant and the groundplane and I can not figure out how to increase it.
This results in my ML code learning to slide the ant, but not to walk.
The interesting part of init physics looks like
(I tried to set friction for the ground plane ground->setFriction(5); with no effect):
the spawnAnt follows the example; i call the ant initializer (appended below), which adds the rigid bodies for the main body and 12 leg parts connected via hinge constraints.
In there, I use body->setDamping(0.05, 0.85) but no setFriction.
How can I achieve h higher friction between the groundplane and the ant's body parts, but not between the ant body parts themselves (or at least no higher friction for the hinge motion)?
I set up an ant on ground plane environment inspired by the evo neural network 3D walker example.
My problem now is, that I have no or minimal friction between the ant and the groundplane and I can not figure out how to increase it.
This results in my ML code learning to slide the ant, but not to walk.
The interesting part of init physics looks like
(I tried to set friction for the ground plane ground->setFriction(5); with no effect):
Code: Select all
createEmptyDynamicsWorld();
m_dynamicsWorld->setInternalTickCallback(evaluationUpdatePreTickCallback, this, true); //true is preTick; this is necessary to have the torques appiled!
m_dynamicsWorld->setInternalTickCallback(evaluationUpdatePostTickCallback, this, false); //false is postTick; this is necessary to have the torques appiled!
// Setup a big ground box
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-10,0));
btRigidBody* ground = createRigidBody(btScalar(0.),groundTransform,groundShape);
ground->setFriction(5);
ground->setUserPointer(GROUND_ID);
}
// Spawn one ant
btVector3 offset(0,0,0);
int i = 0;
spawnAnt(i, offset, false);
the spawnAnt follows the example; i call the ant initializer (appended below), which adds the rigid bodies for the main body and 12 leg parts connected via hinge constraints.
In there, I use body->setDamping(0.05, 0.85) but no setFriction.
How can I achieve h higher friction between the groundplane and the ant's body parts, but not between the ant body parts themselves (or at least no higher friction for the hinge motion)?
Code: Select all
Ant(int index, btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed, BasicExample* pBasicExample )
: pContainingBasicExample (pBasicExample),
m_ownerWorld (ownerWorld)
{
m_index = index;
btVector3 vUp(0, 1, 0); // up in local reference frame
//randomizeSensoryMotorWeights();
//
// Setup geometry
m_shapes[0] = new btCapsuleShape(gRootBodyRadius, gRootBodyHeight); // root body capsule
int i;
for ( i=0; i<NUM_LEGS; i++)
{
m_shapes[1 + 2*i] = new btCapsuleShape(gLegRadius, gLegLength); // leg capsule
m_shapes[2 + 2*i] = new btCapsuleShape(gForeLegRadius, gForeLegLength); // fore leg capsule
}
//initialize jointTorqueValues
initJointTorque();
//
// Setup rigid bodies
btScalar rootAboveGroundHeight = gForeLegLength;
btTransform bodyOffset; bodyOffset.setIdentity();
bodyOffset.setOrigin(positionOffset);
// root body
btVector3 localRootBodyPosition = btVector3(btScalar(0.), rootAboveGroundHeight, btScalar(0.)); // root body position in local reference frame
btTransform transform;
transform.setIdentity();
transform.setOrigin(localRootBodyPosition);
m_bodies[0] = localCreateRigidBody(btScalar(bFixed?0.:1.), bodyOffset*transform, m_shapes[0]);
m_ownerWorld->addRigidBody(m_bodies[0]);
m_bodyRelativeTransforms[0] = btTransform::getIdentity();
m_bodies[0]->setUserPointer(this);
m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[0]), 0);
btHingeConstraint* hingeC;
//btConeTwistConstraint* coneC;
btTransform localA, localB, localC;
// legs
for (i = 0; i < NUM_LEGS; i++)
{
float footAngle = 2 * SIMD_PI * i / NUM_LEGS; // legs are uniformly distributed around the root body
float footYUnitPosition = sin(footAngle); // y position of the leg on the unit circle
float footXUnitPosition = cos(footAngle); // x position of the leg on the unit circle
transform.setIdentity();
btVector3 legCOM = btVector3(btScalar(footXUnitPosition*(gRootBodyRadius+0.5*gLegLength)), btScalar(rootAboveGroundHeight), btScalar(footYUnitPosition*(gRootBodyRadius+0.5*gLegLength)));
transform.setOrigin(legCOM);
// thigh
btVector3 legDirection = (legCOM - localRootBodyPosition).normalize();
btVector3 kneeAxis = legDirection.cross(vUp);
transform.setRotation(btQuaternion(kneeAxis, SIMD_HALF_PI));
m_bodies[1+2*i] = localCreateRigidBody(btScalar(1.), bodyOffset*transform, m_shapes[1+2*i]);
m_bodyRelativeTransforms[1+2*i] = transform;
m_bodies[1+2*i]->setUserPointer(this);
m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[1+2*i]),1+2*i);
// shin
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(footXUnitPosition*(gRootBodyRadius+gLegLength)), btScalar(rootAboveGroundHeight-0.5*gForeLegLength), btScalar(footYUnitPosition*(gRootBodyRadius+gLegLength))));
m_bodies[2+2*i] = localCreateRigidBody(btScalar(1.), bodyOffset*transform, m_shapes[2+2*i]);
m_bodyRelativeTransforms[2+2*i] = transform;
m_bodies[2+2*i]->setUserPointer(this);
m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[2+2*i]),2+2*i);
// hip joints
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,-footAngle,0); localA.setOrigin(btVector3(btScalar(footXUnitPosition*gRootBodyRadius), btScalar(0.), btScalar(footYUnitPosition*gRootBodyRadius)));
localB = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[1+2*i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(),localA));
hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1+2*i], localA, localB);
//hingeC->setLimit(btScalar(-0.75 * SIMD_PI_4), btScalar(SIMD_PI_8));
hingeC->setLimit(btScalar(-0.75 * SIMD_PI_4), btScalar(SIMD_PI_8), 1.0f, 1.0f, 0.0f );
//softness: ~inverse friction;bias: bias of relaxed rotation (1.0 is neutral), relaxationFactor
//hingeC->setLimit(btScalar(-0.1), btScalar(0.1));
m_joints[2*i] = hingeC;
{
btJointFeedback* fb = new btJointFeedback();
m_jointFeedback.push_back(fb);
hingeC->setJointFeedback(fb);
}
// knee joints
localA.setIdentity(); localB.setIdentity(); localC.setIdentity();
localA.getBasis().setEulerZYX(0,-footAngle,0); localA.setOrigin(btVector3(btScalar(footXUnitPosition*(gRootBodyRadius+gLegLength)), btScalar(0.), btScalar(footYUnitPosition*(gRootBodyRadius+gLegLength))));
localB = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[1+2*i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(),localA));
localC = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[2+2*i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(),localA));
hingeC = new btHingeConstraint(*m_bodies[1+2*i], *m_bodies[2+2*i], localB, localC);
//hingeC->setLimit(btScalar(-0.01), btScalar(0.01));
hingeC->setLimit(btScalar(-SIMD_PI_8), btScalar(0.2), 1.0f, 1.0f, 0.0f );
//softness: ~inverse friction;bias: bias of relaxed rotation (1.0 is neutral), relaxationFactor 0 means no force
m_joints[1+2*i] = hingeC;
m_ownerWorld->addRigidBody(m_bodies[1+2*i]); // add thigh bone
m_ownerWorld->addConstraint(m_joints[2*i], true); // connect thigh bone with root
if(pContainingBasicExample->detectCollisions()){ // if thigh bone causes collision, remove it again
m_ownerWorld->removeRigidBody(m_bodies[1+2*i]);
m_ownerWorld->removeConstraint(m_joints[2*i]); // disconnect thigh bone from root
}
else{
m_ownerWorld->addRigidBody(m_bodies[2+2*i]); // add shin bone
m_ownerWorld->addConstraint(m_joints[1+2*i], true); // connect shin bone with thigh
if(pContainingBasicExample->detectCollisions()){ // if shin bone causes collision, remove it again
m_ownerWorld->removeRigidBody(m_bodies[2+2*i]);
m_ownerWorld->removeConstraint(m_joints[1+2*i]); // disconnect shin bone from thigh
}
}
}
// Setup some damping on the m_bodies
for (i = 0; i < BODYPART_COUNT; ++i)
{
m_bodies[i]->setDamping(0.05, 0.85);
m_bodies[i]->setActivationState(DISABLE_DEACTIVATION); //we have only active objects in here
/*m_bodies[i]->setDeactivationTime(0.8);
//m_bodies[i]->setSleepingThresholds(1.6, 2.5);
m_bodies[i]->setSleepingThresholds(0.5f, 0.5f);
*/
}
//=== init some datafields
m_startPosition = getMainBodyPosition();
m_workTot=0.0; //init work done
// removeFromWorld(); // it should not yet be in the world
}