GazeboGraspFix.cpp
Go to the documentation of this file.
00001 #include <boost/bind.hpp>
00002 #include <gazebo/gazebo.hh>
00003 #include <gazebo/physics/physics.hh>
00004 #include <gazebo/physics/ContactManager.hh>
00005 #include <gazebo/physics/Contact.hh>
00006 #include <gazebo/common/common.hh>
00007 #include <stdio.h>
00008 
00009 #include <gazebo_grasp_plugin/GazeboGraspFix.h>
00010 #include <gazebo_version_helpers/GazeboVersionHelpers.h>
00011 
00012 using gazebo::GazeboGraspFix;
00013 using gazebo::GzVector3;
00014 
00015 #define DEFAULT_FORCES_ANGLE_TOLERANCE 120
00016 #define DEFAULT_UPDATE_RATE 5
00017 #define DEFAULT_MAX_GRIP_COUNT 10
00018 #define DEFAULT_RELEASE_TOLERANCE 0.005
00019 #define DEFAULT_DISABLE_COLLISIONS_ON_ATTACH false
00020 
00021 // Register this plugin with the simulator
00022 GZ_REGISTER_MODEL_PLUGIN(GazeboGraspFix)
00023 
00024 
00025 GazeboGraspFix::GazeboGraspFix()
00026 {
00027   InitValues();
00028 }
00029 
00031 GazeboGraspFix::GazeboGraspFix(physics::ModelPtr _model)
00032 {
00033   InitValues();
00034 }
00035 
00037 GazeboGraspFix::~GazeboGraspFix()
00038 {
00039   this->update_connection.reset();
00040   if (this->node) this->node->Fini();
00041   this->node.reset();
00042 }
00043 
00045 void GazeboGraspFix::Init()
00046 {
00047   this->prevUpdateTime = common::Time::GetWallTime();
00048 }
00049 
00051 void GazeboGraspFix::InitValues()
00052 {
00053 #if GAZEBO_MAJOR_VERSION > 2
00054   gazebo::common::Console::SetQuiet(false);
00055 #endif
00056 
00057   // float timeDiff=0.25;
00058   // this->releaseTolerance=0.005;
00059   // this->updateRate = common::Time(0, common::Time::SecToNano(timeDiff));
00060   this->prevUpdateTime = common::Time::GetWallTime();
00061   //float graspedSecs=2;
00062   //this->maxGripCount=floor(graspedSecs/timeDiff);
00063   //this->gripCountThreshold=floor(this->maxGripCount/2);
00064   this->node = transport::NodePtr(new transport::Node());
00065 }
00066 
00068 void GazeboGraspFix::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
00069 {
00070   gzmsg << "Loading grasp-fix plugin" << std::endl;
00071 
00072   // ++++++++++++ Read parameters and initialize fields  +++++++++++++++
00073 
00074   physics::ModelPtr model = _parent;
00075   this->world = model->GetWorld();
00076 
00077   sdf::ElementPtr disableCollisionsOnAttachElem =
00078     _sdf->GetElement("disable_collisions_on_attach");
00079   if (!disableCollisionsOnAttachElem)
00080   {
00081     gzmsg << "GazeboGraspFix: Using default " <<
00082           DEFAULT_DISABLE_COLLISIONS_ON_ATTACH <<
00083           " because no <disable_collisions_on_attach> element specified." <<
00084           std::endl;
00085     this->disableCollisionsOnAttach = DEFAULT_DISABLE_COLLISIONS_ON_ATTACH;
00086   }
00087   else
00088   {
00089     std::string str = disableCollisionsOnAttachElem->Get<std::string>();
00090     bool bVal = false;
00091     if ((str == "true") || (str == "1"))  bVal = true;
00092     this->disableCollisionsOnAttach = bVal;
00093     gzmsg << "GazeboGraspFix: Using disable_collisions_on_attach " <<
00094           this->disableCollisionsOnAttach << std::endl;
00095   }
00096 
00097   sdf::ElementPtr forcesAngleToleranceElem =
00098     _sdf->GetElement("forces_angle_tolerance");
00099   if (!forcesAngleToleranceElem)
00100   {
00101     gzmsg << "GazeboGraspFix: Using default tolerance of " <<
00102           DEFAULT_FORCES_ANGLE_TOLERANCE <<
00103           " because no <forces_angle_tolerance> element specified." <<
00104           std::endl;
00105     this->forcesAngleTolerance = DEFAULT_FORCES_ANGLE_TOLERANCE * M_PI / 180;
00106   }
00107   else
00108   {
00109     this->forcesAngleTolerance =
00110       forcesAngleToleranceElem->Get<float>() * M_PI / 180;
00111   }
00112 
00113   sdf::ElementPtr updateRateElem = _sdf->GetElement("update_rate");
00114   double _updateSecs;
00115   if (!updateRateElem)
00116   {
00117     gzmsg << "GazeboGraspFix: Using  " << DEFAULT_UPDATE_RATE <<
00118           " because no <updateRate_tag> element specified." << std::endl;
00119     _updateSecs = 1.0 / DEFAULT_UPDATE_RATE;
00120   }
00121   else
00122   {
00123     int _rate = updateRateElem->Get<int>();
00124     double _updateRate = _rate;
00125     _updateSecs = 1.0 / _updateRate;
00126     gzmsg << "GazeboGraspFix: Using update rate " << _rate << std::endl;
00127   }
00128   this->updateRate = common::Time(0, common::Time::SecToNano(_updateSecs));
00129 
00130   sdf::ElementPtr maxGripCountElem = _sdf->GetElement("max_grip_count");
00131   if (!maxGripCountElem)
00132   {
00133     gzmsg << "GazeboGraspFix: Using  " << DEFAULT_MAX_GRIP_COUNT <<
00134           " because no <max_grip_count> element specified." << std::endl;
00135     this->maxGripCount = DEFAULT_MAX_GRIP_COUNT;
00136   }
00137   else
00138   {
00139     this->maxGripCount = maxGripCountElem->Get<int>();
00140     gzmsg << "GazeboGraspFix: Using max_grip_count "
00141           << this->maxGripCount << std::endl;
00142   }
00143 
00144   sdf::ElementPtr gripCountThresholdElem =
00145     _sdf->GetElement("grip_count_threshold");
00146   if (!gripCountThresholdElem)
00147   {
00148     this->gripCountThreshold = floor(this->maxGripCount / 2.0);
00149     gzmsg << "GazeboGraspFix: Using  " << this->gripCountThreshold <<
00150           " because no <grip_count_threshold> element specified." <<
00151           std::endl;
00152   }
00153   else
00154   {
00155     this->gripCountThreshold = gripCountThresholdElem->Get<int>();
00156     gzmsg << "GazeboGraspFix: Using grip_count_threshold " <<
00157           this->gripCountThreshold << std::endl;
00158   }
00159 
00160   sdf::ElementPtr releaseToleranceElem = _sdf->GetElement("release_tolerance");
00161   if (!releaseToleranceElem)
00162   {
00163     gzmsg << "GazeboGraspFix: Using  " << DEFAULT_RELEASE_TOLERANCE <<
00164           " because no <release_tolerance> element specified." << std::endl;
00165     this->releaseTolerance = DEFAULT_RELEASE_TOLERANCE;
00166   }
00167   else
00168   {
00169     this->releaseTolerance = releaseToleranceElem->Get<float>();
00170     gzmsg << "GazeboGraspFix: Using release_tolerance " <<
00171           this->releaseTolerance << std::endl;
00172   }
00173 
00174   // will contain all names of collision entities involved from all arms
00175   std::vector<std::string> collisionNames;
00176 
00177   sdf::ElementPtr armElem = _sdf->GetElement("arm");
00178   if (!armElem)
00179   {
00180     gzerr << "GazeboGraspFix: Cannot load the GazeboGraspFix without any <arm> declarations"
00181           << std::endl;
00182     return;
00183   }
00184   // add all arms:
00185   for (; armElem != NULL; armElem = armElem->GetNextElement("arm"))
00186   {
00187     sdf::ElementPtr armNameElem = armElem->GetElement("arm_name");
00188     sdf::ElementPtr handLinkElem = armElem->GetElement("palm_link");
00189     sdf::ElementPtr fingerLinkElem = armElem->GetElement("gripper_link");
00190 
00191     if (!handLinkElem || !fingerLinkElem || !armNameElem)
00192     {
00193       gzerr << "ERROR: GazeboGraspFix: Cannot use a GazeboGraspFix arm because "
00194             << "not all of <arm_name>, <palm_link> and <gripper_link> elements specified in URDF/SDF. Skipping."
00195             << std::endl;
00196       continue;
00197     }
00198 
00199     std::string armName = armNameElem->Get<std::string>();
00200     std::string palmName = handLinkElem->Get<std::string>();
00201 
00202     // collect all finger names:
00203     std::vector<std::string> fingerLinkNames;
00204     for (; fingerLinkElem != NULL;
00205          fingerLinkElem = fingerLinkElem->GetNextElement("gripper_link"))
00206     {
00207       std::string linkName = fingerLinkElem->Get<std::string>();
00208       fingerLinkNames.push_back(linkName);
00209     }
00210 
00211     // add new gripper
00212     if (grippers.find(armName) != grippers.end())
00213     {
00214       gzerr << "GazeboGraspFix: Arm named " << armName <<
00215             " was already added, cannot add it twice." << std::endl;
00216     }
00217     GazeboGraspGripper &gripper = grippers[armName];
00218     std::map<std::string, physics::CollisionPtr> _collisions;
00219     if (!gripper.Init(_parent, armName, palmName, fingerLinkNames,
00220                       disableCollisionsOnAttach, _collisions))
00221     {
00222       gzerr << "GazeboGraspFix: Could not initialize arm " << armName << ". Skipping."
00223             << std::endl;
00224       grippers.erase(armName);
00225       continue;
00226     }
00227     // add all the grippers's collision elements
00228     for (std::map<std::string, physics::CollisionPtr>::iterator collIt =
00229            _collisions.begin();
00230          collIt != _collisions.end(); ++collIt)
00231     {
00232       const std::string &collName = collIt->first;
00233       //physics::CollisionPtr& coll=collIt->second;
00234       std::map<std::string, std::string>::iterator collIter = this->collisions.find(
00235             collName);
00236       if (collIter !=
00237           this->collisions.end())   //this collision was already added before
00238       {
00239         gzwarn << "GazeboGraspFix: Adding Gazebo collision link element " << collName <<
00240                " multiple times, the grasp plugin may not work properly" << std::endl;
00241         continue;
00242       }
00243       gzmsg << "GazeboGraspFix: Adding collision scoped name " << collName <<
00244             std::endl;
00245       this->collisions[collName] = armName;
00246       collisionNames.push_back(collName);
00247     }
00248   }
00249 
00250   if (grippers.empty())
00251   {
00252     gzerr << "ERROR: GazeboGraspFix: Cannot use a GazeboGraspFix because "
00253           << "no arms were configured successfully. Plugin will not work." << std::endl;
00254     return;
00255   }
00256 
00257   // ++++++++++++ start up things +++++++++++++++
00258 
00259   physics::PhysicsEnginePtr physics = GetPhysics(this->world);
00260   this->node->Init(gazebo::GetName(*(this->world)));
00261   physics::ContactManager *contactManager = physics->GetContactManager();
00262   contactManager->PublishContacts();  // TODO not sure this is required?
00263 
00264   std::string topic = contactManager->CreateFilter(model->GetScopedName(),
00265                       collisionNames);
00266   if (!this->contactSub)
00267   {
00268     gzmsg << "Subscribing contact manager to topic " << topic << std::endl;
00269     bool latching = false;
00270     this->contactSub = this->node->Subscribe(topic, &GazeboGraspFix::OnContact,
00271                        this, latching);
00272   }
00273 
00274   update_connection = event::Events::ConnectWorldUpdateEnd(boost::bind(
00275                         &GazeboGraspFix::OnUpdate, this));
00276 }
00277 
00279 class GazeboGraspFix::ObjectContactInfo
00280 {
00281   public:
00282 
00283     // all forces effecting on the object
00284     std::vector<GzVector3> appliedForces;
00285 
00286     // all grippers involved in the process, along with
00287     // a number counting the number of contact points with the
00288     // object per gripper
00289     std::map<std::string, int> grippersInvolved;
00290 
00291     // maximum number of contacts of *any one* gripper
00292     // (any in grippersInvolved)
00293     int maxGripperContactCnt;
00294 
00295     // the gripper for maxGripperContactCnt
00296     std::string maxContactGripper;
00297 };
00298 
00300 bool GazeboGraspFix::IsGripperLink(const std::string &linkName,
00301                                    std::string &gripperName) const
00302 {
00303   for (std::map<std::string, GazeboGraspGripper>::const_iterator it =
00304          grippers.begin(); it != grippers.end(); ++it)
00305   {
00306     if (it->second.hasLink(linkName))
00307     {
00308       gripperName = it->first;
00309       return true;
00310     }
00311   }
00312   return false;
00313 }
00314 
00316 std::map<std::string, std::string> GazeboGraspFix::GetAttachedObjects() const
00317 {
00318   std::map<std::string, std::string> ret;
00319   for (std::map<std::string, GazeboGraspGripper>::const_iterator it =
00320          grippers.begin(); it != grippers.end(); ++it)
00321   {
00322     const std::string &gripperName = it->first;
00323     const GazeboGraspGripper &gripper = it->second;
00324     if (gripper.isObjectAttached())
00325     {
00326       ret[gripper.attachedObject()] = gripperName;
00327     }
00328   }
00329   return ret;
00330 }
00331 
00333 bool GazeboGraspFix::ObjectAttachedToGripper(const ObjectContactInfo
00334     &objContInfo, std::string &attachedToGripper) const
00335 {
00336   for (std::map<std::string, int>::const_iterator gripInvIt =
00337          objContInfo.grippersInvolved.begin();
00338        gripInvIt != objContInfo.grippersInvolved.end(); ++gripInvIt)
00339   {
00340     const std::string &gripperName = gripInvIt->first;
00341     if (ObjectAttachedToGripper(gripperName, attachedToGripper))
00342     {
00343       return true;
00344     }
00345   }
00346   return false;
00347 }
00348 
00350 bool GazeboGraspFix::ObjectAttachedToGripper(const std::string &gripperName,
00351     std::string &attachedToGripper) const
00352 {
00353   std::map<std::string, GazeboGraspGripper>::const_iterator gIt = grippers.find(
00354         gripperName);
00355   if (gIt == grippers.end())
00356   {
00357     gzerr << "GazeboGraspFix: Inconsistency, gripper " << gripperName <<
00358           " not found in GazeboGraspFix grippers" << std::endl;
00359     return false;
00360   }
00361   const GazeboGraspGripper &gripper = gIt->second;
00362   // gzmsg<<"Gripper "<<gripperName<<" is involved in the grasp"<<std::endl;
00363   if (gripper.isObjectAttached())
00364   {
00365     attachedToGripper = gripperName;
00366     return true;
00367   }
00368   return false;
00369 }
00370 
00371 
00373 
00386 class GazeboGraspFix::CollidingPoint
00387 {
00388   public:
00389     CollidingPoint(): sum(0) {}
00390     CollidingPoint(const CollidingPoint &o):
00391       gripperName(o.gripperName),
00392       collLink(o.collLink),
00393       collObj(o.collObj),
00394       force(o.force),
00395       pos(o.pos),
00396       objPos(o.objPos),
00397       sum(o.sum) {}
00398 
00399     // Name of the gripper/arm involved in contact point
00400     // This is not the specific link, but the name of the
00401     // whole gripper
00402     std::string gripperName;
00403 
00404     // the collision
00405     physics::CollisionPtr collLink, collObj;
00406 
00407     // average force vector of the colliding point
00408     GzVector3 force;
00409 
00410     // position (relative to reference frame of gripper
00411     // collision surface) where the contact happens on collision surface
00412     GzVector3 pos;
00413 
00414     // position (relative to reference frame of *gripper* collision surface)
00415     // where the object center is located during collision.
00416     GzVector3 objPos;
00417 
00418     // sum of force and pose (they are actually summed
00419     // up from several contact points).
00420     // Divide both \e force and \e pos by this to obtain average
00421     int sum;
00422 };
00423 
00425 double AngularDistance(const GzVector3 &_v1,
00426                        const GzVector3 &_v2)
00427 {
00428   GzVector3 v1 = _v1;
00429   GzVector3 v2 = _v2;
00430   v1.Normalize();
00431   v2.Normalize();
00432   return acos(v1.Dot(v2));
00433 }
00434 
00436 // Checks whether any two vectors in the set have an angle greater
00437 // than minAngleDiff (in rad), and one is at least
00438 // lengthRatio (0..1) of the other in it's length.
00439 bool CheckGrip(const std::vector<GzVector3> &forces,
00440                float minAngleDiff, float lengthRatio)
00441 {
00442   if (((lengthRatio > 1) || (lengthRatio < 0)) && (lengthRatio > 1e-04
00443       && (fabs(lengthRatio - 1) > 1e-04)))
00444   {
00445     std::cerr << "ERROR: CheckGrip: always specify a lengthRatio of [0..1]" <<
00446               std::endl;
00447     return false;
00448   }
00449   if (minAngleDiff < M_PI_2)
00450   {
00451     std::cerr << "ERROR: CheckGrip: min angle must be at least 90 degrees (PI/2)" <<
00452               std::endl;
00453     return false;
00454   }
00455   std::vector<GzVector3>::const_iterator it1, it2;
00456   for (it1 = forces.begin(); it1 != forces.end(); ++it1)
00457   {
00458     GzVector3 v1 = *it1;
00459     for (it2 = it1 + 1; it2 != forces.end(); ++it2)
00460     {
00461       GzVector3 v2 = *it2;
00462       float l1 = gazebo::GetLength(v1);
00463       float l2 = gazebo::GetLength(v2);
00464       if ((l1 < 1e-04) || (l2 < 1e-04)) continue;
00465       /*GzVector3 _v1=v1;
00466       GzVector3 _v2=v2;
00467       _v1/=l1;
00468       _v2/=l2;
00469       float angle=acos(_v1.Dot(_v2));*/
00470       float angle = AngularDistance(v1, v2);
00471       // gzmsg<<"Angular distance between v1.len="<<v1.GetLength()<<" and v2.len="<<v2.GetLength()<<": "<<angle*180/M_PI<<std::endl;
00472       if (angle > minAngleDiff)
00473       {
00474         float ratio;
00475         if (l1 > l2) ratio = l2 / l1;
00476         else ratio = l1 / l2;
00477         // gzmsg<<"Got angle "<<angle<<", ratio "<<ratio<<std::endl;
00478         if (ratio >= lengthRatio)
00479         {
00480           // gzmsg<<"CheckGrip() is true"<<std::endl;
00481           return true;
00482         }
00483       }
00484     }
00485   }
00486   return false;
00487 }
00488 
00490 void GazeboGraspFix::OnUpdate()
00491 {
00492   if ((common::Time::GetWallTime() - this->prevUpdateTime) < this->updateRate)
00493     return;
00494 
00495   // first, copy all contact data into local struct. Don't do the complex grip check (CheckGrip)
00496   // within the mutex, because that slows down OnContact().
00497   this->mutexContacts.lock();
00498   std::map<std::string, std::map<std::string, CollidingPoint> > contPoints(
00499     this->contacts);
00500   this->contacts.clear(); // clear so it can be filled anew by OnContact().
00501   this->mutexContacts.unlock();
00502 
00503   // contPoints now contains CollidingPoint objects for each *object* and *link*.
00504 
00505   // Iterate through all contact points to gather all summed forces
00506   // (and other useful information) for all the objects (so we have all forces on one object).
00507   std::map<std::string, std::map<std::string, CollidingPoint> >::iterator objIt;
00508   std::map<std::string, ObjectContactInfo> objectContactInfo;
00509 
00510   for (objIt = contPoints.begin(); objIt != contPoints.end(); ++objIt)
00511   {
00512     std::string objName = objIt->first;
00513     //gzmsg<<"Examining object collisions with "<<objName<<std::endl;
00514 
00515     // create new entry in accumulated results map and get reference to fill in:
00516     ObjectContactInfo &objContInfo = objectContactInfo[objName];
00517 
00518     // for all links colliding with this object...
00519     std::map<std::string, CollidingPoint>::iterator lIt;
00520     for (lIt = objIt->second.begin(); lIt != objIt->second.end(); ++lIt)
00521     {
00522       std::string linkName = lIt->first;
00523       CollidingPoint &collP = lIt->second;
00524       GzVector3 avgForce = collP.force / collP.sum;
00525       // gzmsg << "Found collision with "<<linkName<<": "<<avgForce.x<<", "<<avgForce.y<<", "<<avgForce.z<<" (avg over "<<collP.sum<<")"<<std::endl;
00526       objContInfo.appliedForces.push_back(avgForce);
00527       // insert the gripper (if it doesn't exist yet) and increase contact counter
00528       int &gContactCnt = objContInfo.grippersInvolved[collP.gripperName];
00529       gContactCnt++;
00530       int &_maxGripperContactCnt = objContInfo.maxGripperContactCnt;
00531       if (gContactCnt > _maxGripperContactCnt)
00532       {
00533         _maxGripperContactCnt = gContactCnt;
00534         objContInfo.maxContactGripper = collP.gripperName;
00535       }
00536     }
00537   }
00538 
00539   // ++++++++++++++++++++ Handle Attachment  +++++++++++++++++++++++++++++++
00540 
00541   // collect of all objects which are found to be "gripped" at the current stage.
00542   // if they are gripped, increase the grip counter. If the grip count exceeds the
00543   // threshold, attach the object to the gripper which has most contact points with the
00544   // object.
00545   std::set<std::string> grippedObjects;
00546   for (std::map<std::string, ObjectContactInfo>::iterator ocIt =
00547          objectContactInfo.begin();
00548        ocIt != objectContactInfo.end(); ++ocIt)
00549   {
00550     const std::string &objName = ocIt->first;
00551     const ObjectContactInfo &objContInfo = ocIt->second;
00552 
00553     // gzmsg<<"Number applied forces on "<<objName<<": "<<objContInfo.appliedForces.size()<<std::endl;
00554   
00555     // TODO: remove this test print, for issue #26 ------------------- 
00556 #if 0
00557     physics::CollisionPtr objColl =
00558       boost::dynamic_pointer_cast<physics::Collision>(GetEntityByName(world, objName));
00559     if (objColl && objColl->GetLink())
00560     {
00561       auto linVel = GetWorldVelocity(objColl->GetLink());
00562       gzmsg << "Velocity for link " << objColl->GetLink()->GetName()
00563         << " (collision name " << objName << "): " << linVel
00564         << ", absolute val " << GetLength(linVel) << std::endl;
00565     }
00566 #endif
00567     // ------------------- 
00568 
00569     float minAngleDiff = this->forcesAngleTolerance; //120 * M_PI/180;
00570     if (!CheckGrip(objContInfo.appliedForces, minAngleDiff, 0.3))
00571       continue;
00572 
00573     // add to "gripped objects"
00574     grippedObjects.insert(objName);
00575 
00576     //gzmsg<<"Grasp Held: "<<objName<<" grip count: "<<this->gripCounts[objName]<<std::endl;
00577 
00578     int &counts = this->gripCounts[objName];
00579     if (counts < this->maxGripCount) ++counts;
00580 
00581     // only need to attach object if the grip count threshold is exceeded
00582     if (counts <= this->gripCountThreshold)
00583       continue;
00584 
00585     //gzmsg<<"GRIPPING "<<objName<<", grip count "<<counts<<" (threshold "<<this->gripCountThreshold<<")"<<std::endl;
00586 
00587     // find out if any of the grippers involved in the grasp is already grasping the object.
00588     // If there is no such gripper, attach it to the gripper which has most contact points.
00589     std::string attachedToGripper;
00590     bool isAttachedToGripper = ObjectAttachedToGripper(objContInfo,
00591                                attachedToGripper);
00592     if (isAttachedToGripper)
00593     {
00594       // the object is already attached to a gripper, so it does not need to be attached.
00595       // gzmsg << "GazeboGraspFix has found that object "<<
00596       //     gripper.attachedObject()<<" is already attached to gripper "<<gripperName;
00597       continue;
00598     }
00599 
00600     // attach the object to the gripper with most contact counts
00601     const std::string &graspingGripperName = objContInfo.maxContactGripper;
00602     std::map<std::string, GazeboGraspGripper>::iterator gIt = grippers.find(
00603           graspingGripperName);
00604     if (gIt == grippers.end())
00605     {
00606       gzerr << "GazeboGraspFix: Inconsistency, gripper '" << graspingGripperName
00607             << "' not found in GazeboGraspFix grippers, so cannot do attachment of object "
00608             << objName << std::endl;
00609       continue;
00610     }
00611     GazeboGraspGripper &graspingGripper = gIt->second;
00612 
00613     if (graspingGripper.isObjectAttached())
00614     {
00615       gzerr << "GazeboGraspFix has found that object " <<
00616             graspingGripper.attachedObject() << " is already attached to gripper " <<
00617             graspingGripperName << ", so can't grasp '" << objName << "'!" << std::endl;
00618       continue;
00619     }
00620 
00621     gzmsg << "GazeboGraspFix: Attaching " << objName << " to gripper " <<
00622           graspingGripperName << "." << std::endl;
00623 
00624     // Store the array of contact poses which played part in the grip, sorted by colliding link.
00625     // Filter out all link names of other grippers, otherwise if the other gripper moves
00626     // away, this is going to trigger the release condition.
00627     // XXX this does not consider full support for an object being gripped by two grippers (e.g.
00628     // one left, one right).
00629     // this->attachGripContacts[objName]=contPoints[objName];
00630     const std::map<std::string, CollidingPoint> &contPointsTmp =
00631       contPoints[objName];
00632     std::map<std::string, CollidingPoint> &attGripConts =
00633       this->attachGripContacts[objName];
00634     attGripConts.clear();
00635     std::map<std::string, CollidingPoint>::const_iterator contPointsIt;
00636     for (contPointsIt = contPointsTmp.begin(); contPointsIt != contPointsTmp.end();
00637          ++contPointsIt)
00638     {
00639       const std::string &collidingLink = contPointsIt->first;
00640       const CollidingPoint &collidingPoint = contPointsIt->second;
00641       // gzmsg<<"Checking initial contact with "<<collidingLink<<" and "<<graspingGripperName<<std::endl;
00642       if (graspingGripper.hasCollisionLink(collidingLink))
00643       {
00644         // gzmsg<<"Insert initial contact with "<<collidingLink<<std::endl;
00645         attGripConts[collidingLink] = collidingPoint;
00646       }
00647     }
00648 
00649     if (!graspingGripper.HandleAttach(objName))
00650     {
00651       gzerr << "GazeboGraspFix: Could not attach object " << objName << " to gripper "
00652             << graspingGripperName << std::endl;
00653     }
00654     this->OnAttach(objName, graspingGripperName);
00655   }  // for all objects
00656 
00657 
00658 
00659   // ++++++++++++++++++++ Handle Detachment  +++++++++++++++++++++++++++++++
00660   std::map<std::string, std::string> attachedObjects = GetAttachedObjects();
00661 
00662   // now, for all objects that are not currently gripped,
00663   // decrease grip counter, and possibly release object.
00664   std::map<std::string, int>::iterator gripCntIt;
00665   for (gripCntIt = this->gripCounts.begin(); gripCntIt != this->gripCounts.end();
00666        ++gripCntIt)
00667   {
00668 
00669     const std::string &objName = gripCntIt->first;
00670 
00671     if (grippedObjects.find(objName) != grippedObjects.end())
00672     {
00673       // this object is one we just detected as "gripped", so no need to check for releasing it...
00674       // gzmsg<<"NOT considering "<<objName<<" for detachment."<<std::endl;
00675       continue;
00676     }
00677 
00678     // the object does not satisfy "gripped" criteria, so potentially has to be released.
00679 
00680     // gzmsg<<"NOT-GRIPPING "<<objName<<", grip count "<<gripCntIt->second<<" (threshold "<<this->gripCountThreshold<<")"<<std::endl;
00681 
00682     if (gripCntIt->second > 0) --(gripCntIt->second);
00683 
00684     std::map<std::string, std::string>::iterator attIt = attachedObjects.find(
00685           objName);
00686     bool isAttached = (attIt != attachedObjects.end());
00687 
00688     // gzmsg<<"is attached: "<<isAttached<<std::endl;
00689 
00690     if (!isAttached || (gripCntIt->second > this->gripCountThreshold)) continue;
00691 
00692     const std::string &graspingGripperName = attIt->second;
00693 
00694     // gzmsg<<"Considering "<<objName<<" for detachment."<<std::endl;
00695 
00696     // Object should potentially be detached now.
00697     // However, this happens too easily when just considering the count, as the fingers
00698     // in gazebo start wobbling as the arm moves around, and although they are still
00699     // close to the object, the grip is not detected any more. So to be sure, we will
00700     // check that the collision point (the place on the link where the contact originally
00701     // was detected) has not moved too far from where it originally was, relative to the object.
00702 
00703     // get the initial set of CollidingPoints for this object
00704     // note that it is enough to use the initial contact points, because the object won't
00705     // have "slipped" after being attached, and the location of the original contact point
00706     // on the link itself is considered as a fixed point on the link, regardless whether this
00707     // point is currently still colliding with the object or not. We only want to know whether
00708     // this fixed point on the link has increased in distance from the corresponding fixed
00709     // point (where the contact originally happened) on the object.
00710     std::map<std::string, std::map<std::string, CollidingPoint> >::iterator
00711     initCollIt = this->attachGripContacts.find(objName);
00712     if (initCollIt == this->attachGripContacts.end())
00713     {
00714       std::cerr << "ERROR: Consistency: Could not find attachGripContacts for " <<
00715                 objName << std::endl;
00716       continue;
00717     }
00718 
00719     std::map<std::string, CollidingPoint> &initColls = initCollIt->second;
00720     int cntRelease = 0;
00721 
00722     // for all links which have initially been detected to collide:
00723     std::map<std::string, CollidingPoint>::iterator pointIt;
00724     for (pointIt = initColls.begin(); pointIt != initColls.end(); ++pointIt)
00725     {
00726       CollidingPoint &cpInfo = pointIt->second;
00727       // initial distance from link to contact point (relative to link)
00728       GzVector3 relContactPos = cpInfo.pos / cpInfo.sum;
00729       // Initial distance from link to object (relative to link)
00730       GzVector3 relObjPos = cpInfo.objPos / cpInfo.sum;
00731 
00732       // Get current world pose of object
00733       GzPose3 currObjWorldPose =
00734         gazebo::GetWorldPose(cpInfo.collObj->GetLink());
00735 
00736       // Get world pose of link
00737       GzPose3 currLinkWorldPose =
00738         gazebo::GetWorldPose(cpInfo.collLink->GetLink());
00739 
00740       // Get transform for currLinkWorldPose as matrix
00741       GzMatrix4 worldToLink = gazebo::GetMatrix(currLinkWorldPose);
00742 
00743       // Get the transform from collision link to contact point
00744       GzMatrix4 linkToContact = gazebo::GetMatrix(relContactPos);
00745 
00746       // The current world position of the contact point right now is:
00747       GzMatrix4 _currContactWorldPose = worldToLink * linkToContact;
00748       GzVector3 currContactWorldPose = gazebo::GetPos(_currContactWorldPose);
00749 
00750       // The initial contact point location on the link should still correspond
00751       // to the initial contact point location on the object.
00752 
00753       // Initial vector from object center to contact point (relative to link,
00754       // because relObjPos and relContactPos are from center of link)
00755       GzVector3 oldObjDist = relContactPos - relObjPos;
00756       // The same vector as \e oldObjDist, but calculated by the current world pose
00757       // of object and the current location of the initial contact location on the link.
00758       // This is the new distance from contact to object.
00759       GzVector3 newObjDist = currContactWorldPose - gazebo::GetPos(currObjWorldPose);
00760 
00761       //gzmsg<<"Obj Trans "<<cpInfo.collLink->GetName()<<": "<<relObjPos.x<<", "<<relObjPos.y<<", "<<relObjPos.z<<std::endl;
00762       //gzmsg<<"Cont Trans "<<cpInfo.collLink->GetName()<<": "<<relContactPos.x<<", "<<relContactPos.y<<", "<<relContactPos.z<<std::endl;
00763 
00764       // the difference between these vectors should not be too large...
00765       float diff =
00766         fabs(gazebo::GetLength(oldObjDist) - gazebo::GetLength(newObjDist));
00767       //gzmsg<<"Diff for link "<<cpInfo.collLink->GetName()<<": "<<diff<<std::endl;
00768 
00769       if (diff > releaseTolerance)
00770       {
00771         ++cntRelease;
00772       }
00773     }
00774 
00775     if (cntRelease > 0)
00776     {
00777       // sufficient links did not meet the criteria to be close enough to the object.
00778       // First, get the grasping gripper:
00779       std::map<std::string, GazeboGraspGripper>::iterator gggIt = grippers.find(
00780             graspingGripperName);
00781       if (gggIt == grippers.end())
00782       {
00783         gzerr << "GazeboGraspFix: Inconsistency: Gazebo gripper '" <<
00784               graspingGripperName << "' not found when checking for detachment" << std::endl;
00785         continue;
00786       }
00787       GazeboGraspGripper &graspingGripper = gggIt->second;
00788       // Now, detach the object:
00789       gzmsg << "GazeboGraspFix: Detaching " << objName << " from gripper " <<
00790             graspingGripperName << "." << std::endl;
00791       graspingGripper.HandleDetach(objName);
00792       this->OnDetach(objName, graspingGripperName);
00793       gripCntIt->second = 0;
00794       this->attachGripContacts.erase(initCollIt);
00795     }
00796   }
00797 
00798   this->prevUpdateTime = common::Time::GetWallTime();
00799 }
00800 
00802 void GazeboGraspFix::OnContact(const ConstContactsPtr &_msg)
00803 {
00804   //gzmsg<<"CONTACT! "<<std::endl;//<<_contact<<std::endl;
00805   // for all contacts...
00806   for (int i = 0; i < _msg->contact_size(); ++i)
00807   {
00808     physics::CollisionPtr collision1 =
00809       boost::dynamic_pointer_cast<physics::Collision>(
00810         gazebo::GetEntityByName(this->world, _msg->contact(i).collision1()));
00811     physics::CollisionPtr collision2 =
00812       boost::dynamic_pointer_cast<physics::Collision>(
00813         gazebo::GetEntityByName(this->world, _msg->contact(i).collision2()));
00814 
00815     if ((collision1 && !collision1->IsStatic()) && (collision2
00816         && !collision2->IsStatic()))
00817     {
00818       std::string name1 = collision1->GetScopedName();
00819       std::string name2 = collision2->GetScopedName();
00820 
00821       //gzmsg<<"OBJ CONTACT! "<<name1<<" / "<<name2<<std::endl;
00822       int count = _msg->contact(i).position_size();
00823 
00824       // Check to see if the contact arrays all have the same size.
00825       if ((count != _msg->contact(i).normal_size()) ||
00826           (count != _msg->contact(i).wrench_size()) ||
00827           (count != _msg->contact(i).depth_size()))
00828       {
00829         gzerr << "GazeboGraspFix: Contact message has invalid array sizes\n" <<
00830               std::endl;
00831         continue;
00832       }
00833 
00834       std::string collidingObjName, collidingLink, gripperOfCollidingLink;
00835       physics::CollisionPtr linkCollision;
00836       physics::CollisionPtr objCollision;
00837 
00838       physics::Contact contact;
00839       contact = _msg->contact(i);
00840 
00841       if (contact.count < 1)
00842       {
00843         std::cerr << "ERROR: GazeboGraspFix: Not enough forces given for contact of ."
00844                   << name1 << " / " << name2 << std::endl;
00845         continue;
00846       }
00847 
00848       // all force vectors which are part of this contact
00849       std::vector<GzVector3> force;
00850 
00851       // find out which part of the colliding entities is the object, *not* the gripper,
00852       // and copy all the forces applied to it into the vector 'force'.
00853       std::map<std::string, std::string>::const_iterator gripperCollIt =
00854         this->collisions.find(name2);
00855       if (gripperCollIt != this->collisions.end())
00856       {
00857         // collision 1 is the object
00858         collidingObjName = name1;
00859         collidingLink = name2;
00860         linkCollision = collision2;
00861         objCollision = collision1;
00862         gripperOfCollidingLink = gripperCollIt->second;
00863         for (int k = 0; k < contact.count; ++k)
00864           force.push_back(contact.wrench[k].body1Force);
00865       }
00866       else if ((gripperCollIt = this->collisions.find(name1)) !=
00867                this->collisions.end())
00868       {
00869         // collision 2 is the object
00870         collidingObjName = name2;
00871         collidingLink = name1;
00872         linkCollision = collision1;
00873         objCollision = collision2;
00874         gripperOfCollidingLink = gripperCollIt->second;
00875         for (int k = 0; k < contact.count; ++k)
00876           force.push_back(contact.wrench[k].body2Force);
00877       }
00878 
00879       GzVector3 avgForce;
00880       // compute average/sum of the forces applied on the object
00881       for (int k = 0; k < force.size(); ++k)
00882       {
00883         avgForce += force[k];
00884       }
00885       avgForce /= force.size();
00886 
00887       GzVector3 avgPos;
00888       // compute center point (average pose) of all the origin positions of the forces appied
00889       for (int k = 0; k < contact.count; ++k) avgPos += contact.positions[k];
00890       avgPos /= contact.count;
00891 
00892       // now, get average pose relative to the colliding link
00893       GzPose3 linkWorldPose = gazebo::GetWorldPose(linkCollision->GetLink());
00894 
00895       // To find out the collision point relative to the Link's local coordinate system, first get the Poses as 4x4 matrices
00896       GzMatrix4 worldToLink = gazebo::GetMatrix(linkWorldPose);
00897 
00898       // We can assume that the contact has identity rotation because we don't care about its orientation.
00899       // We could always set another rotation here too.
00900       GzMatrix4 worldToContact = gazebo::GetMatrix(avgPos);
00901 
00902       // now, worldToLink * contactInLocal = worldToContact
00903       // hence, contactInLocal = worldToLink.Inv * worldToContact
00904       GzMatrix4 worldToLinkInv = worldToLink.Inverse();
00905       GzMatrix4 contactInLocal = worldToLinkInv * worldToContact;
00906       GzVector3 contactPosInLocal = gazebo::GetPos(contactInLocal);
00907 
00908       //gzmsg<<"---------"<<std::endl;
00909       //gzmsg<<"CNT in loc: "<<contactPosInLocal.x<<","<<contactPosInLocal.y<<","<<contactPosInLocal.z<<std::endl;
00910 
00911       /*GzVector3 sDiff=avgPos-linkWorldPose.pos;
00912       gzmsg<<"SIMPLE trans: "<<sDiff.x<<","<<sDiff.y<<","<<sDiff.z<<std::endl;
00913       gzmsg<<"coll world pose: "<<linkWorldPose.pos.x<<", "<<linkWorldPose.pos.y<<", "<<linkWorldPose.pos.z<<std::endl;
00914       gzmsg<<"contact avg pose: "<<avgPos.x<<", "<<avgPos.y<<", "<<avgPos.z<<std::endl;
00915 
00916       GzVector3 lX=linkWorldPose.rot.GetXAxis();
00917       GzVector3 lY=linkWorldPose.rot.GetYAxis();
00918       GzVector3 lZ=linkWorldPose.rot.GetZAxis();
00919 
00920       gzmsg<<"World ori: "<<linkWorldPose.rot.x<<","<<linkWorldPose.rot.y<<","<<linkWorldPose.rot.z<<","<<linkWorldPose.rot.w<<std::endl;
00921       gzmsg<<"x axis: "<<lX.x<<","<<lX.y<<","<<lX.z<<std::endl;
00922       gzmsg<<"y axis: "<<lY.x<<","<<lY.y<<","<<lY.z<<std::endl;
00923       gzmsg<<"z axis: "<<lZ.x<<","<<lZ.y<<","<<lZ.z<<std::endl;*/
00924 
00925       // Get the pose of the object and compute it's relative position to
00926       // the collision surface.
00927       GzPose3 objWorldPose = gazebo::GetWorldPose(objCollision->GetLink());
00928       GzMatrix4 worldToObj = gazebo::GetMatrix(objWorldPose);
00929 
00930       GzMatrix4 objInLocal = worldToLinkInv * worldToObj;
00931       GzVector3 objPosInLocal = gazebo::GetPos(objInLocal);
00932 
00933       {
00934         boost::mutex::scoped_lock lock(this->mutexContacts);
00935         CollidingPoint &p =
00936           this->contacts[collidingObjName][collidingLink];  // inserts new entry if doesn't exist
00937         p.gripperName = gripperOfCollidingLink;
00938         p.collLink = linkCollision;
00939         p.collObj = objCollision;
00940         p.force += avgForce;
00941         p.pos += contactPosInLocal;
00942         p.objPos += objPosInLocal;
00943         p.sum++;
00944       }
00945       //gzmsg<<"Average force of contact= "<<avgForce.x<<", "<<avgForce.y<<", "<<avgForce.z<<" out of "<<force.size()<<" vectors."<<std::endl;
00946     }
00947   }
00948 }


gazebo_grasp_plugin
Author(s): Jennifer Buehler
autogenerated on Tue May 7 2019 03:29:31