diff --git a/data/r2d2.urdf b/data/r2d2.urdf
index 091369db8..1d28b9a47 100644
--- a/data/r2d2.urdf
+++ b/data/r2d2.urdf
@@ -388,6 +388,7 @@
+
diff --git a/examples/Importers/ImportURDFDemo/URDF2Bullet.cpp b/examples/Importers/ImportURDFDemo/URDF2Bullet.cpp
index f5226f125..8833dd15b 100644
--- a/examples/Importers/ImportURDFDemo/URDF2Bullet.cpp
+++ b/examples/Importers/ImportURDFDemo/URDF2Bullet.cpp
@@ -410,6 +410,10 @@ void ConvertURDF2BulletInternal(
{
col->setRollingFriction(contactInfo.m_rollingFriction);
}
+ if ((contactInfo.m_flags & URDF_CONTACT_HAS_SPINNING_FRICTION)!=0)
+ {
+ col->setSpinningFriction(contactInfo.m_spinningFriction);
+ }
if ((contactInfo.m_flags & URDF_CONTACT_HAS_STIFFNESS_DAMPING)!=0)
{
col->setContactStiffnessAndDamping(contactInfo.m_contactStiffness,contactInfo.m_contactDamping);
diff --git a/examples/Importers/ImportURDFDemo/URDFJointTypes.h b/examples/Importers/ImportURDFDemo/URDFJointTypes.h
index 08c984268..88912cb1a 100644
--- a/examples/Importers/ImportURDFDemo/URDFJointTypes.h
+++ b/examples/Importers/ImportURDFDemo/URDFJointTypes.h
@@ -16,17 +16,20 @@ enum UrdfJointTypes
enum URDF_LinkContactFlags
{
URDF_CONTACT_HAS_LATERAL_FRICTION=1,
- URDF_CONTACT_HAS_ROLLING_FRICTION=2,
URDF_CONTACT_HAS_INERTIA_SCALING=2,
URDF_CONTACT_HAS_CONTACT_CFM=4,
URDF_CONTACT_HAS_CONTACT_ERP=8,
URDF_CONTACT_HAS_STIFFNESS_DAMPING=16,
+ URDF_CONTACT_HAS_ROLLING_FRICTION=32,
+ URDF_CONTACT_HAS_SPINNING_FRICTION=64,
+
};
struct URDFLinkContactInfo
{
btScalar m_lateralFriction;
btScalar m_rollingFriction;
+ btScalar m_spinningFriction;
btScalar m_inertiaScaling;
btScalar m_contactCfm;
btScalar m_contactErp;
@@ -38,6 +41,7 @@ struct URDFLinkContactInfo
URDFLinkContactInfo()
:m_lateralFriction(0.5),
m_rollingFriction(0),
+ m_spinningFriction(0),
m_inertiaScaling(1),
m_contactCfm(0),
m_contactErp(0),
diff --git a/examples/Importers/ImportURDFDemo/UrdfParser.cpp b/examples/Importers/ImportURDFDemo/UrdfParser.cpp
index 20e6a920f..e1d9629a0 100644
--- a/examples/Importers/ImportURDFDemo/UrdfParser.cpp
+++ b/examples/Importers/ImportURDFDemo/UrdfParser.cpp
@@ -672,7 +672,28 @@ bool UrdfParser::parseLink(UrdfModel& model, UrdfLink& link, TiXmlElement *confi
}
}
}
-
+ {
+ TiXmlElement *spinning_xml = ci->FirstChildElement("spinning_friction");
+ if (spinning_xml)
+ {
+ if (m_parseSDF)
+ {
+ link.m_contactInfo.m_spinningFriction = urdfLexicalCast(spinning_xml->GetText());
+ link.m_contactInfo.m_flags |= URDF_CONTACT_HAS_SPINNING_FRICTION;
+ } else
+ {
+ if (!spinning_xml->Attribute("value"))
+ {
+ logger->reportError("Link/contact: spinning friction element must have value attribute");
+ return false;
+ }
+
+ link.m_contactInfo.m_spinningFriction = urdfLexicalCast(spinning_xml->Attribute("value"));
+ link.m_contactInfo.m_flags |= URDF_CONTACT_HAS_SPINNING_FRICTION;
+
+ }
+ }
+ }
{
TiXmlElement *stiffness_xml = ci->FirstChildElement("stiffness");
diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
index e9c889b2c..25cefb11f 100644
--- a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
+++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
@@ -33,6 +33,7 @@ btCollisionObject::btCollisionObject()
m_friction(btScalar(0.5)),
m_restitution(btScalar(0.)),
m_rollingFriction(0.0f),
+ m_spinningFriction(0.f),
m_contactDamping(.1),
m_contactStiffness(1e4),
m_internalType(CO_COLLISION_OBJECT),
diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/src/BulletCollision/CollisionDispatch/btCollisionObject.h
index 5e08609e3..d042115e6 100644
--- a/src/BulletCollision/CollisionDispatch/btCollisionObject.h
+++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.h
@@ -85,7 +85,8 @@ protected:
btScalar m_friction;
btScalar m_restitution;
- btScalar m_rollingFriction;
+ btScalar m_rollingFriction;//torsional friction orthogonal to contact normal (useful to stop spheres rolling forever)
+ btScalar m_spinningFriction; // torsional friction around the contact normal (useful for grasping)
btScalar m_contactDamping;
btScalar m_contactStiffness;
@@ -323,7 +324,15 @@ public:
{
return m_rollingFriction;
}
-
+ void setSpinningFriction(btScalar frict)
+ {
+ m_updateRevision++;
+ m_spinningFriction = frict;
+ }
+ btScalar getSpinningFriction() const
+ {
+ return m_spinningFriction;
+ }
void setContactStiffnessAndDamping(btScalar stiffness, btScalar damping)
{
m_updateRevision++;
diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
index 48815d24f..a863a9492 100644
--- a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
+++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
@@ -24,7 +24,6 @@ ContactAddedCallback gContactAddedCallback=0;
-///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
btScalar btManifoldResult::calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar friction = body0->getRollingFriction() * body1->getFriction() + body1->getRollingFriction() * body0->getFriction();
@@ -38,6 +37,17 @@ btScalar btManifoldResult::calculateCombinedRollingFriction(const btCollisionObj
}
+btScalar btManifoldResult::calculateCombinedSpinningFriction(const btCollisionObject* body0,const btCollisionObject* body1)
+{
+ btScalar friction = body0->getSpinningFriction() * body1->getFriction() + body1->getSpinningFriction() * body0->getFriction();
+
+ const btScalar MAX_FRICTION = btScalar(10.);
+ if (friction < -MAX_FRICTION)
+ friction = -MAX_FRICTION;
+ if (friction > MAX_FRICTION)
+ friction = MAX_FRICTION;
+ return friction;
+}
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/src/BulletCollision/CollisionDispatch/btManifoldResult.h
index 66d11417d..55b6380a5 100644
--- a/src/BulletCollision/CollisionDispatch/btManifoldResult.h
+++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.h
@@ -146,7 +146,8 @@ public:
static btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1);
- static btScalar calculateCombinedContactDamping(const btCollisionObject* body0,const btCollisionObject* body1);
+ static btScalar calculateCombinedSpinningFriction(const btCollisionObject* body0,const btCollisionObject* body1);
+ static btScalar calculateCombinedContactDamping(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedContactStiffness(const btCollisionObject* body0,const btCollisionObject* body1);
};
diff --git a/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
index 5ae072ea0..04ab54ed9 100644
--- a/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
+++ b/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
@@ -72,7 +72,8 @@ class btManifoldPoint
m_distance1( distance ),
m_combinedFriction(btScalar(0.)),
m_combinedRollingFriction(btScalar(0.)),
- m_combinedRestitution(btScalar(0.)),
+ m_combinedSpinningFriction(btScalar(0.)),
+ m_combinedRestitution(btScalar(0.)),
m_userPersistentData(0),
m_contactPointFlags(0),
m_appliedImpulse(0.f),
@@ -99,8 +100,9 @@ class btManifoldPoint
btScalar m_distance1;
btScalar m_combinedFriction;
- btScalar m_combinedRollingFriction;
- btScalar m_combinedRestitution;
+ btScalar m_combinedRollingFriction;//torsional friction orthogonal to contact normal, useful to make spheres stop rolling forever
+ btScalar m_combinedSpinningFriction;//torsional friction around contact normal, useful for grasping objects
+ btScalar m_combinedRestitution;
//BP mod, store contact triangles.
int m_partId0;
diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp
index e0e8bc70f..9402a658c 100644
--- a/src/BulletDynamics/Dynamics/btRigidBody.cpp
+++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp
@@ -79,6 +79,8 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo&
//moved to btCollisionObject
m_friction = constructionInfo.m_friction;
m_rollingFriction = constructionInfo.m_rollingFriction;
+ m_spinningFriction = constructionInfo.m_spinningFriction;
+
m_restitution = constructionInfo.m_restitution;
setCollisionShape( constructionInfo.m_collisionShape );
diff --git a/src/BulletDynamics/Dynamics/btRigidBody.h b/src/BulletDynamics/Dynamics/btRigidBody.h
index 1d177db80..372245031 100644
--- a/src/BulletDynamics/Dynamics/btRigidBody.h
+++ b/src/BulletDynamics/Dynamics/btRigidBody.h
@@ -135,6 +135,8 @@ public:
///the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling forever.
///See Bullet/Demos/RollingFrictionDemo for usage
btScalar m_rollingFriction;
+ btScalar m_spinningFriction;//torsional friction around contact normal
+
///best simulation results using zero restitution.
btScalar m_restitution;
@@ -158,6 +160,7 @@ public:
m_angularDamping(btScalar(0.)),
m_friction(btScalar(0.5)),
m_rollingFriction(btScalar(0)),
+ m_spinningFriction(btScalar(0)),
m_restitution(btScalar(0.)),
m_linearSleepingThreshold(btScalar(0.8)),
m_angularSleepingThreshold(btScalar(1.f)),