5 #include <boost/bind.hpp> 6 #include <gazebo/gazebo.hh> 7 #include <gazebo/physics/physics.hh> 8 #include <gazebo/physics/ContactManager.hh> 9 #include <gazebo/physics/Contact.hh> 10 #include <gazebo/common/common.hh> 18 #define DEFAULT_FORCES_ANGLE_TOLERANCE 120 19 #define DEFAULT_UPDATE_RATE 5 20 #define DEFAULT_MAX_GRIP_COUNT 10 21 #define DEFAULT_RELEASE_TOLERANCE 0.005 22 #define DEFAULT_DISABLE_COLLISIONS_ON_ATTACH false 32 GazeboGraspFix::GazeboGraspFix(physics::ModelPtr _model)
51 #if GAZEBO_MAJOR_VERSION > 2 52 gazebo::common::Console::SetQuiet(
false);
62 this->
node = transport::NodePtr(
new transport::Node());
68 std::cout<<
"Loading grasp-fix plugin"<<std::endl;
72 physics::ModelPtr model = _parent;
73 this->
world = model->GetWorld();
75 sdf::ElementPtr disableCollisionsOnAttachElem = _sdf->GetElement(
"disable_collisions_on_attach");
76 if (!disableCollisionsOnAttachElem){
80 std::string str = disableCollisionsOnAttachElem->Get<std::string>();
82 if ((str==
"true") || (str==
"1")) bVal =
true;
87 sdf::ElementPtr forcesAngleToleranceElem = _sdf->GetElement(
"forces_angle_tolerance");
88 if (!forcesAngleToleranceElem){
89 std::cout<<
"GazeboGraspFix: Using default tolerance of "<<
DEFAULT_FORCES_ANGLE_TOLERANCE<<
" because no <forces_angle_tolerance> element specified."<<std::endl;
95 sdf::ElementPtr updateRateElem = _sdf->GetElement(
"update_rate");
98 std::cout<<
"GazeboGraspFix: Using "<<
DEFAULT_UPDATE_RATE<<
" because no <updateRate_tag> element specified."<<std::endl;
101 int _rate = updateRateElem->Get<
int>();
102 double _updateRate = _rate;
103 _updateSecs = 1.0/_updateRate;
104 std::cout<<
"GazeboGraspFix: Using update rate "<<_rate<<std::endl;
106 this->
updateRate = common::Time(0, common::Time::SecToNano(_updateSecs));
108 sdf::ElementPtr maxGripCountElem = _sdf->GetElement(
"max_grip_count");
109 if (!maxGripCountElem){
110 std::cout<<
"GazeboGraspFix: Using "<<
DEFAULT_MAX_GRIP_COUNT<<
" because no <max_grip_count> element specified."<<std::endl;
114 std::cout<<
"GazeboGraspFix: Using max_grip_count "<<this->
maxGripCount<<std::endl;
117 sdf::ElementPtr gripCountThresholdElem = _sdf->GetElement(
"grip_count_threshold");
118 if (!gripCountThresholdElem){
120 std::cout<<
"GazeboGraspFix: Using "<<this->
gripCountThreshold<<
" because no <grip_count_threshold> element specified."<<std::endl;
123 std::cout<<
"GazeboGraspFix: Using grip_count_threshold "<<this->
gripCountThreshold<<std::endl;
126 sdf::ElementPtr releaseToleranceElem = _sdf->GetElement(
"release_tolerance");
127 if (!releaseToleranceElem){
128 std::cout<<
"GazeboGraspFix: Using "<<
DEFAULT_RELEASE_TOLERANCE<<
" because no <release_tolerance> element specified."<<std::endl;
132 std::cout<<
"GazeboGraspFix: Using release_tolerance "<<this->
releaseTolerance<<std::endl;
136 std::vector<std::string> collisionNames;
138 sdf::ElementPtr armElem=_sdf->GetElement(
"arm");
141 gzerr <<
"GazeboGraspFix: Cannot load the GazeboGraspFix without any <arm> declarations"<<std::endl;
145 for (; armElem != NULL; armElem = armElem->GetNextElement(
"arm"))
147 sdf::ElementPtr armNameElem = armElem->GetElement(
"arm_name");
148 sdf::ElementPtr handLinkElem = armElem->GetElement(
"palm_link");
149 sdf::ElementPtr fingerLinkElem = armElem->GetElement(
"gripper_link");
151 if (!handLinkElem || !fingerLinkElem || !armNameElem) {
152 gzerr <<
"ERROR: GazeboGraspFix: Cannot use a GazeboGraspFix arm because " 153 <<
"not all of <arm_name>, <palm_link> and <gripper_link> elements specified in URDF/SDF. Skipping."<<std::endl;
157 std::string armName = armNameElem->Get<std::string>();
158 std::string palmName = handLinkElem->Get<std::string>();
161 std::vector<std::string> fingerLinkNames;
162 for (; fingerLinkElem != NULL; fingerLinkElem = fingerLinkElem->GetNextElement(
"gripper_link"))
164 std::string linkName = fingerLinkElem->Get<std::string>();
165 fingerLinkNames.push_back(linkName);
171 gzerr<<
"GazeboGraspFix: Arm named "<<armName<<
" was already added, cannot add it twice."<<std::endl;
174 std::map<std::string, physics::CollisionPtr> _collisions;
177 gzerr<<
"GazeboGraspFix: Could not initialize arm "<<armName<<
". Skipping."<<std::endl;
182 for (std::map<std::string, physics::CollisionPtr>::iterator collIt = _collisions.begin();
183 collIt != _collisions.end(); ++collIt)
185 const std::string& collName=collIt->first;
187 std::map<std::string, std::string>::iterator collIter = this->
collisions.find(collName);
189 gzwarn <<
"GazeboGraspFix: Adding Gazebo collision link element "<<collName<<
" multiple times, the grasp plugin may not work properly"<<std::endl;
192 std::cout<<
"GazeboGraspFix: Adding collision scoped name "<<collName<<std::endl;
194 collisionNames.push_back(collName);
200 gzerr <<
"ERROR: GazeboGraspFix: Cannot use a GazeboGraspFix because " 201 <<
"no arms were configured successfully. Plugin will not work."<<std::endl;
207 physics::PhysicsEnginePtr physics = this->
world->GetPhysicsEngine();
208 this->
node->Init(this->
world->GetName());
209 physics::ContactManager * contactManager = physics->GetContactManager();
210 contactManager->PublishContacts();
212 std::string topic = contactManager->CreateFilter(model->GetScopedName(), collisionNames);
214 std::cout<<
"Subscribing contact manager to topic "<<topic<<std::endl;
247 for (std::map<std::string, GazeboGraspGripper>::const_iterator it=
grippers.begin(); it!=
grippers.end(); ++it)
249 if (it->second.hasLink(linkName))
251 gripperName=it->first;
260 std::map<std::string, std::string> ret;
261 for (std::map<std::string, GazeboGraspGripper>::const_iterator it=
grippers.begin(); it!=
grippers.end(); ++it)
263 const std::string& gripperName = it->first;
279 for (std::map<std::string, int>::const_iterator gripInvIt=objContInfo.
grippersInvolved.begin();
282 const std::string& gripperName=gripInvIt->first;
293 std::map<std::string, GazeboGraspGripper>::const_iterator gIt=
grippers.find(gripperName);
296 gzerr <<
"GazeboGraspFix: Inconsistency, gripper "<<gripperName<<
" not found in GazeboGraspFix grippers"<<std::endl;
303 attachedToGripper = gripperName;
327 gripperName(o.gripperName),
328 collLink(o.collLink),
348 gazebo::math::Vector3
pos;
369 std::map<std::string, std::map<std::string, CollidingPoint> > contPoints(this->
contacts);
378 std::map<std::string, std::map<std::string, CollidingPoint> >::iterator objIt;
379 std::map<std::string, ObjectContactInfo> objectContactInfo;
381 for (objIt=contPoints.begin(); objIt!=contPoints.end(); ++objIt)
383 std::string objName=objIt->first;
390 std::map<std::string, CollidingPoint>::iterator lIt;
391 for (lIt=objIt->second.begin(); lIt!=objIt->second.end(); ++lIt){
392 std::string linkName=lIt->first;
394 gazebo::math::Vector3 avgForce=collP.
force/collP.
sum;
401 if (gContactCnt > _maxGripperContactCnt)
403 _maxGripperContactCnt = gContactCnt;
415 std::set<std::string> grippedObjects;
416 for (std::map<std::string, ObjectContactInfo>::iterator ocIt=objectContactInfo.begin();
417 ocIt!=objectContactInfo.end(); ++ocIt)
419 const std::string& objName=ocIt->first;
429 grippedObjects.insert(objName);
444 std::string attachedToGripper;
446 if (isAttachedToGripper)
455 std::map<std::string, GazeboGraspGripper>::iterator gIt=
grippers.find(graspingGripperName);
458 gzerr <<
"GazeboGraspFix: Inconsistency, gripper '"<<graspingGripperName
459 <<
"' not found in GazeboGraspFix grippers, so cannot do attachment of object " << objName << std::endl;
466 gzerr<<
"GazeboGraspFix has found that object "<<
467 graspingGripper.
attachedObject()<<
" is already attached to gripper "<<
468 graspingGripperName<<
", so can't grasp '"<<objName<<
"'!"<<std::endl;
472 std::cout<<
"GazeboGraspFix: Attaching "<<objName<<
" to gripper "<<graspingGripperName<<
"!!!!!!!"<<std::endl;
480 const std::map<std::string, CollidingPoint>& contPointsTmp = contPoints[objName];
481 std::map<std::string, CollidingPoint>& attGripConts = this->
attachGripContacts[objName];
482 attGripConts.clear();
483 std::map<std::string, CollidingPoint>::const_iterator contPointsIt;
484 for (contPointsIt=contPointsTmp.begin(); contPointsIt!=contPointsTmp.end(); ++contPointsIt)
486 const std::string& collidingLink = contPointsIt->first;
492 attGripConts[collidingLink] = collidingPoint;
497 gzerr<<
"GazeboGraspFix: Could not attach object "<<objName<<
" to gripper "<<graspingGripperName<<std::endl;
499 this->
OnAttach(objName, graspingGripperName);
509 std::map<std::string, int>::iterator gripCntIt;
512 const std::string& objName=gripCntIt->first;
514 if (grippedObjects.find(objName) != grippedObjects.end())
524 if (gripCntIt->second > 0) --(gripCntIt->second);
526 std::map<std::string, std::string>::iterator attIt = attachedObjects.find(objName);
527 bool isAttached = (attIt != attachedObjects.end());
531 if (!isAttached || (gripCntIt->second > this->gripCountThreshold))
continue;
533 const std::string& graspingGripperName=attIt->second;
551 std::map<std::string, std::map<std::string, CollidingPoint> >::iterator initCollIt=this->
attachGripContacts.find(objName);
553 std::cerr<<
"ERROR: Consistency: Could not find attachGripContacts for "<<objName<<std::endl;
557 std::map<std::string, CollidingPoint>& initColls=initCollIt->second;
561 std::map<std::string, CollidingPoint>::iterator pointIt;
562 for (pointIt=initColls.begin(); pointIt!=initColls.end(); ++pointIt)
566 gazebo::math::Vector3 relContactPos=cpInfo.
pos/cpInfo.
sum;
568 gazebo::math::Vector3 relObjPos=cpInfo.
objPos/cpInfo.
sum;
571 gazebo::math::Pose currObjWorldPose=cpInfo.
collObj->GetLink()->GetWorldPose();
574 gazebo::math::Pose currLinkWorldPose=cpInfo.
collLink->GetLink()->GetWorldPose();
577 gazebo::math::Matrix4 worldToLink=currLinkWorldPose.rot.GetAsMatrix4();
578 worldToLink.SetTranslate(currLinkWorldPose.pos);
581 gazebo::math::Matrix4 linkToContact=gazebo::math::Matrix4::IDENTITY;
582 linkToContact.SetTranslate(relContactPos);
585 gazebo::math::Matrix4 _currContactWorldPose=worldToLink*linkToContact;
586 gazebo::math::Vector3 currContactWorldPose=_currContactWorldPose.GetTranslation();
593 gazebo::math::Vector3 oldObjDist= relContactPos - relObjPos;
596 gazebo::math::Vector3 newObjDist= currContactWorldPose - currObjWorldPose.pos;
602 float diff=fabs(oldObjDist.GetLength() - newObjDist.GetLength());
613 std::map<std::string, GazeboGraspGripper>::iterator gggIt =
grippers.find(graspingGripperName);
616 gzerr <<
"GazeboGraspFix: Inconsistency: Gazebo gripper '"<<graspingGripperName<<
"' not found when checking for detachment" << std::endl;
621 std::cout<<
"GazeboGraspFix: Detaching "<<objName<<
" from gripper "<<graspingGripperName<<
"!!!!!!!"<<std::endl;
623 this->
OnDetach(objName,graspingGripperName);
632 double angularDistance(
const gazebo::math::Vector3& _v1,
const gazebo::math::Vector3& _v2) {
633 gazebo::math::Vector3 v1=_v1;
634 gazebo::math::Vector3 v2=_v2;
637 return acos(v1.Dot(v2));
641 if (((lengthRatio > 1) || (lengthRatio < 0)) && (lengthRatio > 1e-04 && (fabs(lengthRatio-1) > 1e-04))) {
642 std::cerr<<
"ERROR: checkGrip: always specify a lengthRatio of [0..1]"<<std::endl;
645 if (minAngleDiff <
M_PI_2){
646 std::cerr<<
"ERROR: checkGrip: min angle must be at least 90 degrees (PI/2)"<<std::endl;
649 std::vector<gazebo::math::Vector3>::const_iterator it1, it2;
650 for (it1=forces.begin(); it1!=forces.end(); ++it1){
651 gazebo::math::Vector3 v1=*it1;
652 for (it2=it1+1; it2!=forces.end(); ++it2){
653 gazebo::math::Vector3 v2=*it2;
654 float l1=v1.GetLength();
655 float l2=v2.GetLength();
656 if ((l1<1e-04) || (l2<1e-04))
continue;
664 if (angle > minAngleDiff) {
666 if (l1>l2) ratio=l2/l1;
669 if (ratio >= lengthRatio)
684 for (
int i = 0; i < _msg->contact_size(); ++i) {
685 physics::CollisionPtr collision1 = boost::dynamic_pointer_cast<physics::Collision>(
686 this->
world->GetEntity(_msg->contact(i).collision1()));
687 physics::CollisionPtr collision2 = boost::dynamic_pointer_cast<physics::Collision>(
688 this->
world->GetEntity(_msg->contact(i).collision2()));
690 if ((collision1 && !collision1->IsStatic()) && (collision2 && !collision2->IsStatic()))
692 std::string name1 = collision1->GetScopedName();
693 std::string name2 = collision2->GetScopedName();
696 int count = _msg->contact(i).position_size();
699 if ((count != _msg->contact(i).normal_size()) ||
700 (count != _msg->contact(i).wrench_size()) ||
701 (count != _msg->contact(i).depth_size()))
703 gzerr <<
"GazeboGraspFix: Contact message has invalid array sizes\n"<<std::endl;
707 std::string collidingObjName, collidingLink, gripperOfCollidingLink;
708 physics::CollisionPtr linkCollision;
709 physics::CollisionPtr objCollision;
711 physics::Contact contact;
712 contact = _msg->contact(i);
716 std::cerr<<
"ERROR: GazeboGraspFix: Not enough forces given for contact of ."<<name1<<
" / "<<name2<<std::endl;
721 std::vector<gazebo::math::Vector3> force;
725 std::map<std::string,std::string>::const_iterator gripperCollIt = this->
collisions.find(name2);
728 collidingObjName=name1;
730 linkCollision=collision2;
731 objCollision=collision1;
732 gripperOfCollidingLink=gripperCollIt->second;
733 for (
int k=0; k<contact.count; ++k)
734 force.push_back(contact.wrench[k].body1Force);
738 collidingObjName=name2;
740 linkCollision=collision1;
741 objCollision=collision2;
742 gripperOfCollidingLink=gripperCollIt->second;
743 for (
int k=0; k<contact.count; ++k)
744 force.push_back(contact.wrench[k].body2Force);
747 gazebo::math::Vector3 avgForce;
749 for (
int k=0; k<force.size(); ++k){
752 avgForce/=force.size();
754 gazebo::math::Vector3 avgPos;
756 for (
int k=0; k<contact.count; ++k) avgPos+=contact.positions[k];
757 avgPos/=contact.count;
760 gazebo::math::Pose linkWorldPose=linkCollision->GetLink()->GetWorldPose();
763 gazebo::math::Matrix4 worldToLink=linkWorldPose.rot.GetAsMatrix4();
764 worldToLink.SetTranslate(linkWorldPose.pos);
766 gazebo::math::Matrix4 worldToContact=gazebo::math::Matrix4::IDENTITY;
769 worldToContact.SetTranslate(avgPos);
773 gazebo::math::Matrix4 worldToLinkInv = worldToLink.Inverse();
774 gazebo::math::Matrix4 contactInLocal = worldToLinkInv * worldToContact;
775 gazebo::math::Vector3 contactPosInLocal = contactInLocal.GetTranslation();
795 gazebo::math::Pose objWorldPose = objCollision->GetLink()->GetWorldPose();
796 gazebo::math::Matrix4 worldToObj = objWorldPose.rot.GetAsMatrix4();
797 worldToObj.SetTranslate(objWorldPose.pos);
799 gazebo::math::Matrix4 objInLocal = worldToLinkInv * worldToObj;
800 gazebo::math::Vector3 objPosInLocal = objInLocal.GetTranslation();
809 p.
pos+=contactPosInLocal;
#define DEFAULT_RELEASE_TOLERANCE
double angularDistance(const gazebo::math::Vector3 &_v1, const gazebo::math::Vector3 &_v2)
bool isGripperLink(const std::string &linkName, std::string &gripperName) const
bool isObjectAttached() const
std::map< std::string, std::string > collisions
void HandleDetach(const std::string &objName)
std::map< std::string, std::map< std::string, CollidingPoint > > attachGripContacts
#define DEFAULT_DISABLE_COLLISIONS_ON_ATTACH
common::Time prevUpdateTime
bool checkGrip(const std::vector< math::Vector3 > &forces, float minAngleDiff, float lengthRatio)
virtual void OnDetach(const std::string &objectName, const std::string &armName)
float forcesAngleTolerance
CollidingPoint(const CollidingPoint &o)
const std::string & attachedObject() const
#define DEFAULT_FORCES_ANGLE_TOLERANCE
#define DEFAULT_MAX_GRIP_COUNT
gazebo::math::Vector3 force
physics::CollisionPtr collLink
#define DEFAULT_UPDATE_RATE
virtual void OnAttach(const std::string &objectName, const std::string &armName)
std::map< std::string, int > gripCounts
void OnContact(const ConstContactsPtr &ptr)
std::map< std::string, GazeboGraspGripper > grippers
physics::CollisionPtr collObj
Helper class for GazeboGraspFix which holds information for one arm. Attaches /detaches objects to th...
bool HandleAttach(const std::string &objName)
std::map< std::string, std::map< std::string, CollidingPoint > > contacts
bool Init(physics::ModelPtr &_model, const std::string &_gripperName, const std::string &palmLinkName, const std::vector< std::string > &fingerLinkNames, bool _disableCollisionsOnAttach, std::map< std::string, physics::CollisionPtr > &_collisions)
gazebo::math::Vector3 objPos
bool disableCollisionsOnAttach
bool objectAttachedToGripper(const ObjectContactInfo &objContInfo, std::string &attachedToGripper) const
virtual ~GazeboGraspFix()
boost::mutex mutexContacts
event::ConnectionPtr update_connection
transport::SubscriberPtr contactSub
bool hasCollisionLink(const std::string &linkName) const
std::map< std::string, std::string > getAttachedObjects() const
virtual void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
gazebo::math::Vector3 pos
int ALVAR_EXPORT diff(const std::vector< C > &v, std::vector< C > &ret)
double ALVAR_EXPORT angle(CvPoint *A, CvPoint *B, CvPoint *C, CvPoint *D, int isDirectionDependent)