collision_common.cpp
Go to the documentation of this file.
00001 
00026 #include <industrial_collision_detection/collision_detection/collision_common.h>
00027 #include <moveit/collision_detection_fcl/collision_common.h>
00028 #include <ros/ros.h>
00029 
00030 namespace collision_detection
00031 {
00032   bool getDistanceInfo(const DistanceMap &distance_detailed, DistanceInfoMap &distance_info_map)
00033   {
00034     Eigen::Affine3d tf;
00035     tf.setIdentity();
00036     return getDistanceInfo(distance_detailed, distance_info_map, tf);
00037   }
00038 
00039   bool getDistanceInfo(const DistanceMap &distance_detailed, DistanceInfoMap &distance_info_map, const Eigen::Affine3d &tf)
00040   {
00041     bool status = true;
00042     for (DistanceMap::const_iterator it = distance_detailed.begin(); it != distance_detailed.end(); ++it)
00043     {
00044       DistanceInfo dist_info;
00045       DistanceResultsData dist = static_cast<const DistanceResultsData>(it->second);
00046       if (dist.link_name[0] == it->first)
00047       {
00048         dist_info.nearest_obsticle = dist.link_name[1];
00049         dist_info.link_point = tf * dist.nearest_points[0];
00050         dist_info.obsticle_point = tf * dist.nearest_points[1];
00051         dist_info.avoidance_vector = dist_info.link_point - dist_info.obsticle_point;
00052         dist_info.avoidance_vector.normalize();
00053         dist_info.distance = dist.min_distance;
00054       }
00055       else if (dist.link_name[1] == it->first)
00056       {
00057         dist_info.nearest_obsticle = dist.link_name[0];
00058         dist_info.link_point = tf * dist.nearest_points[1];
00059         dist_info.obsticle_point = tf * dist.nearest_points[0];
00060         dist_info.avoidance_vector = dist_info.link_point - dist_info.obsticle_point;
00061         dist_info.avoidance_vector.normalize();
00062         dist_info.distance = dist.min_distance;
00063       }
00064       else
00065       {
00066         ROS_ERROR("getDistanceInfo was unable to find link after match!");
00067         status &= false;
00068       }
00069 
00070       distance_info_map.insert(std::make_pair(it->first, dist_info));
00071     }
00072 
00073     return status;
00074   }
00075 
00076   void DistanceRequest::enableGroup(const robot_model::RobotModelConstPtr &kmodel)
00077   {
00078     if (kmodel->hasJointModelGroup(group_name))
00079       active_components_only = &kmodel->getJointModelGroup(group_name)->getUpdatedLinkModelsWithGeometrySet();
00080     else
00081       active_components_only = NULL;
00082   }
00083 
00084   bool distanceDetailedCallback(fcl::CollisionObject* o1, fcl::CollisionObject* o2, void* data, double& min_dist)
00085   {
00086     DistanceData* cdata = reinterpret_cast<DistanceData*>(data);
00087 
00088     const CollisionGeometryData* cd1 = static_cast<const CollisionGeometryData*>(o1->collisionGeometry()->getUserData());
00089     const CollisionGeometryData* cd2 = static_cast<const CollisionGeometryData*>(o2->collisionGeometry()->getUserData());
00090     bool active1 = true, active2 = true;
00091 
00092     // do not distance check geoms part of the same object / link / attached body
00093     if (cd1->sameObject(*cd2))
00094       return false;
00095 
00096     // If active components are specified
00097     if (cdata->req->active_components_only)
00098     {
00099       const robot_model::LinkModel *l1 = cd1->type == BodyTypes::ROBOT_LINK ? cd1->ptr.link : (cd1->type == BodyTypes::ROBOT_ATTACHED ? cd1->ptr.ab->getAttachedLink() : NULL);
00100       const robot_model::LinkModel *l2 = cd2->type == BodyTypes::ROBOT_LINK ? cd2->ptr.link : (cd2->type == BodyTypes::ROBOT_ATTACHED ? cd2->ptr.ab->getAttachedLink() : NULL);
00101 
00102       // If neither of the involved components is active
00103       if ((!l1 || cdata->req->active_components_only->find(l1) == cdata->req->active_components_only->end()) &&
00104           (!l2 || cdata->req->active_components_only->find(l2) == cdata->req->active_components_only->end()))
00105       {
00106         return false;
00107       }
00108       else
00109       {
00110         if (!l1 || cdata->req->active_components_only->find(l1) == cdata->req->active_components_only->end())
00111           active1 = false;
00112 
00113         if (!l2 || cdata->req->active_components_only->find(l2) == cdata->req->active_components_only->end())
00114           active2 = false;
00115       }
00116     }
00117 
00118     // use the collision matrix (if any) to avoid certain distance checks
00119     bool always_allow_collision = false;
00120     if (cdata->req->acm)
00121     {
00122       AllowedCollision::Type type;
00123 
00124       bool found = cdata->req->acm->getAllowedCollision(cd1->getID(), cd2->getID(), type);
00125       if (found)
00126       {
00127         // if we have an entry in the collision matrix, we read it
00128         if (type == AllowedCollision::ALWAYS)
00129         {
00130           always_allow_collision = true;
00131           if (!cdata->req->verbose)
00132             logDebug("Collision between '%s' and '%s' is always allowed. No contacts are computed.",
00133                      cd1->getID().c_str(), cd2->getID().c_str());
00134         }
00135       }
00136     }
00137 
00138     // check if a link is touching an attached object
00139     if (cd1->type == BodyTypes::ROBOT_LINK && cd2->type == BodyTypes::ROBOT_ATTACHED)
00140     {
00141       const std::set<std::string> &tl = cd2->ptr.ab->getTouchLinks();
00142       if (tl.find(cd1->getID()) != tl.end())
00143       {
00144         always_allow_collision = true;
00145         if (!cdata->req->verbose)
00146           logDebug("Robot link '%s' is allowed to touch attached object '%s'. No contacts are computed.",
00147                    cd1->getID().c_str(), cd2->getID().c_str());
00148       }
00149     }
00150     else
00151     {
00152       if (cd2->type == BodyTypes::ROBOT_LINK && cd1->type == BodyTypes::ROBOT_ATTACHED)
00153       {
00154         const std::set<std::string> &tl = cd1->ptr.ab->getTouchLinks();
00155         if (tl.find(cd2->getID()) != tl.end())
00156         {
00157           always_allow_collision = true;
00158           if (!cdata->req->verbose)
00159             logDebug("Robot link '%s' is allowed to touch attached object '%s'. No contacts are computed.",
00160                      cd2->getID().c_str(), cd1->getID().c_str());
00161         }
00162       }
00163     }
00164 
00165     if(always_allow_collision)
00166     {
00167       return false;
00168     }
00169 
00170     if (!cdata->req->verbose)
00171       logDebug("Actually checking collisions between %s and %s", cd1->getID().c_str(), cd2->getID().c_str());
00172 
00173 
00174     fcl::DistanceResult fcl_result;
00175     DistanceResultsData dist_result;
00176     double dist_threshold = cdata->req->distance_threshold;
00177     std::map<std::string, DistanceResultsData>::iterator it1, it2;
00178 
00179     if (!cdata->req->global)
00180     {
00181       it1 = cdata->res->distance.find(cd1->ptr.obj->id_);
00182       it2 = cdata->res->distance.find(cd2->ptr.obj->id_);
00183 
00184       if (cdata->req->active_components_only)
00185       {
00186         if (active1 && active2)
00187         {
00188           if (it1 != cdata->res->distance.end() && it2 != cdata->res->distance.end())
00189             dist_threshold = std::max(it1->second.min_distance, it2->second.min_distance);
00190         }
00191         else if (active1 && !active2)
00192         {
00193           if (it1 != cdata->res->distance.end())
00194             dist_threshold = it1->second.min_distance;
00195         }
00196         else if (!active1 && active2)
00197         {
00198           if (it2 != cdata->res->distance.end())
00199             dist_threshold = it2->second.min_distance;
00200         }
00201       }
00202       else
00203       {
00204         if (it1 != cdata->res->distance.end() && it2 != cdata->res->distance.end())
00205           dist_threshold = std::max(it1->second.min_distance, it2->second.min_distance);
00206       }
00207     }
00208     else
00209     {
00210         dist_threshold = cdata->res->minimum_distance.min_distance;
00211     }
00212 
00213     fcl_result.min_distance = dist_threshold;
00214     double d = fcl::distance(o1, o2, fcl::DistanceRequest(cdata->req->detailed), fcl_result);
00215 
00216     // Check if either object is already in the map. If not add it or if present
00217     // check to see if the new distance is closer. If closer remove the existing
00218     // one and add the new distance information.
00219     if (d < dist_threshold)
00220     {
00221       dist_result.min_distance = fcl_result.min_distance;
00222       dist_result.nearest_points[0] = Eigen::Vector3d(fcl_result.nearest_points[0].data.vs);
00223       dist_result.nearest_points[1] = Eigen::Vector3d(fcl_result.nearest_points[1].data.vs);
00224       dist_result.link_name[0] = cd1->ptr.obj->id_;
00225       dist_result.link_name[1] = cd2->ptr.obj->id_;
00226 
00227       cdata->res->minimum_distance.update(dist_result);
00228 
00229       if (!cdata->req->global)
00230       {
00231         if (d <= 0 && !cdata->res->collision)
00232         {
00233           cdata->res->collision = true;
00234         }
00235 
00236         if (active1)
00237         {
00238           if (it1 == cdata->res->distance.end())
00239           {
00240             cdata->res->distance.insert(std::make_pair(cd1->ptr.obj->id_, dist_result));
00241           }
00242           else
00243           {
00244             it1->second.update(dist_result);
00245           }
00246         }
00247 
00248         if (active2)
00249         {
00250           if (it2 == cdata->res->distance.end())
00251           {
00252             cdata->res->distance.insert(std::make_pair(cd2->ptr.obj->id_, dist_result));
00253           }
00254           else
00255           {
00256             it2->second.update(dist_result);
00257           }
00258         }
00259       }
00260       else
00261       {
00262         if (d <= 0)
00263         {
00264           cdata->res->collision = true;
00265           cdata->done = true;
00266         }
00267       }
00268     }
00269 
00270     return cdata->done;
00271   }
00272 }


industrial_collision_detection
Author(s): Levi Armstrong
autogenerated on Sat Jun 8 2019 19:23:38