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
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
00058
00059
00060 this->prevUpdateTime = common::Time::GetWallTime();
00061
00062
00063
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
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
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
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
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
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
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
00234 std::map<std::string, std::string>::iterator collIter = this->collisions.find(
00235 collName);
00236 if (collIter !=
00237 this->collisions.end())
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
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();
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
00284 std::vector<GzVector3> appliedForces;
00285
00286
00287
00288
00289 std::map<std::string, int> grippersInvolved;
00290
00291
00292
00293 int maxGripperContactCnt;
00294
00295
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
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
00400
00401
00402 std::string gripperName;
00403
00404
00405 physics::CollisionPtr collLink, collObj;
00406
00407
00408 GzVector3 force;
00409
00410
00411
00412 GzVector3 pos;
00413
00414
00415
00416 GzVector3 objPos;
00417
00418
00419
00420
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
00437
00438
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
00466
00467
00468
00469
00470 float angle = AngularDistance(v1, v2);
00471
00472 if (angle > minAngleDiff)
00473 {
00474 float ratio;
00475 if (l1 > l2) ratio = l2 / l1;
00476 else ratio = l1 / l2;
00477
00478 if (ratio >= lengthRatio)
00479 {
00480
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
00496
00497 this->mutexContacts.lock();
00498 std::map<std::string, std::map<std::string, CollidingPoint> > contPoints(
00499 this->contacts);
00500 this->contacts.clear();
00501 this->mutexContacts.unlock();
00502
00503
00504
00505
00506
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
00514
00515
00516 ObjectContactInfo &objContInfo = objectContactInfo[objName];
00517
00518
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
00526 objContInfo.appliedForces.push_back(avgForce);
00527
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
00540
00541
00542
00543
00544
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
00554
00555
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;
00570 if (!CheckGrip(objContInfo.appliedForces, minAngleDiff, 0.3))
00571 continue;
00572
00573
00574 grippedObjects.insert(objName);
00575
00576
00577
00578 int &counts = this->gripCounts[objName];
00579 if (counts < this->maxGripCount) ++counts;
00580
00581
00582 if (counts <= this->gripCountThreshold)
00583 continue;
00584
00585
00586
00587
00588
00589 std::string attachedToGripper;
00590 bool isAttachedToGripper = ObjectAttachedToGripper(objContInfo,
00591 attachedToGripper);
00592 if (isAttachedToGripper)
00593 {
00594
00595
00596
00597 continue;
00598 }
00599
00600
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
00625
00626
00627
00628
00629
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
00642 if (graspingGripper.hasCollisionLink(collidingLink))
00643 {
00644
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 }
00656
00657
00658
00659
00660 std::map<std::string, std::string> attachedObjects = GetAttachedObjects();
00661
00662
00663
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
00674
00675 continue;
00676 }
00677
00678
00679
00680
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
00689
00690 if (!isAttached || (gripCntIt->second > this->gripCountThreshold)) continue;
00691
00692 const std::string &graspingGripperName = attIt->second;
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
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
00723 std::map<std::string, CollidingPoint>::iterator pointIt;
00724 for (pointIt = initColls.begin(); pointIt != initColls.end(); ++pointIt)
00725 {
00726 CollidingPoint &cpInfo = pointIt->second;
00727
00728 GzVector3 relContactPos = cpInfo.pos / cpInfo.sum;
00729
00730 GzVector3 relObjPos = cpInfo.objPos / cpInfo.sum;
00731
00732
00733 GzPose3 currObjWorldPose =
00734 gazebo::GetWorldPose(cpInfo.collObj->GetLink());
00735
00736
00737 GzPose3 currLinkWorldPose =
00738 gazebo::GetWorldPose(cpInfo.collLink->GetLink());
00739
00740
00741 GzMatrix4 worldToLink = gazebo::GetMatrix(currLinkWorldPose);
00742
00743
00744 GzMatrix4 linkToContact = gazebo::GetMatrix(relContactPos);
00745
00746
00747 GzMatrix4 _currContactWorldPose = worldToLink * linkToContact;
00748 GzVector3 currContactWorldPose = gazebo::GetPos(_currContactWorldPose);
00749
00750
00751
00752
00753
00754
00755 GzVector3 oldObjDist = relContactPos - relObjPos;
00756
00757
00758
00759 GzVector3 newObjDist = currContactWorldPose - gazebo::GetPos(currObjWorldPose);
00760
00761
00762
00763
00764
00765 float diff =
00766 fabs(gazebo::GetLength(oldObjDist) - gazebo::GetLength(newObjDist));
00767
00768
00769 if (diff > releaseTolerance)
00770 {
00771 ++cntRelease;
00772 }
00773 }
00774
00775 if (cntRelease > 0)
00776 {
00777
00778
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
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
00805
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
00822 int count = _msg->contact(i).position_size();
00823
00824
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
00849 std::vector<GzVector3> force;
00850
00851
00852
00853 std::map<std::string, std::string>::const_iterator gripperCollIt =
00854 this->collisions.find(name2);
00855 if (gripperCollIt != this->collisions.end())
00856 {
00857
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
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
00881 for (int k = 0; k < force.size(); ++k)
00882 {
00883 avgForce += force[k];
00884 }
00885 avgForce /= force.size();
00886
00887 GzVector3 avgPos;
00888
00889 for (int k = 0; k < contact.count; ++k) avgPos += contact.positions[k];
00890 avgPos /= contact.count;
00891
00892
00893 GzPose3 linkWorldPose = gazebo::GetWorldPose(linkCollision->GetLink());
00894
00895
00896 GzMatrix4 worldToLink = gazebo::GetMatrix(linkWorldPose);
00897
00898
00899
00900 GzMatrix4 worldToContact = gazebo::GetMatrix(avgPos);
00901
00902
00903
00904 GzMatrix4 worldToLinkInv = worldToLink.Inverse();
00905 GzMatrix4 contactInLocal = worldToLinkInv * worldToContact;
00906 GzVector3 contactPosInLocal = gazebo::GetPos(contactInLocal);
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
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];
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
00946 }
00947 }
00948 }