link_to_collision.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 #include <string>
00019 #include <vector>
00020 
00021 #include <cob_obstacle_distance/link_to_collision.hpp>
00022 #include <eigen_conversions/eigen_msg.h>
00023 #include <visualization_msgs/Marker.h>
00024 
00025 
00026 LinkToCollision::LinkToCollision() : success_(true)
00027 {
00028 }
00029 
00030 
00031 LinkToCollision::~LinkToCollision()
00032 {
00033 }
00034 
00035 
00036 void LinkToCollision::poseURDFToMsg(const urdf::Pose& urdf_pose, geometry_msgs::Pose& msg_pose)
00037 {
00038     msg_pose.position.x = urdf_pose.position.x;
00039     msg_pose.position.y = urdf_pose.position.y;
00040     msg_pose.position.z = urdf_pose.position.z;
00041 
00042     msg_pose.orientation.x = urdf_pose.rotation.x;
00043     msg_pose.orientation.y = urdf_pose.rotation.y;
00044     msg_pose.orientation.z = urdf_pose.rotation.z;
00045     msg_pose.orientation.w = urdf_pose.rotation.w;
00046 }
00047 
00048 
00049 bool LinkToCollision::ignoreSelfCollisionPart(const std::string& link_of_interest,
00050                                               const std::string& self_collision_obstacle_link)
00051 {
00052     if (this->self_collision_map_.count(self_collision_obstacle_link) <= 0)
00053     {
00054         return false;
00055     }
00056 
00057     std::vector<std::string>::iterator sca_begin = this->self_collision_map_[self_collision_obstacle_link].begin();
00058     std::vector<std::string>::iterator sca_end = this->self_collision_map_[self_collision_obstacle_link].end();
00059     return std::find(sca_begin, sca_end, link_of_interest) == sca_end;  // if not found return true
00060 }
00061 
00062 
00063 bool LinkToCollision::initFile(const std::string& root_frame_id, const std::string& urdf_file_name)
00064 {
00065     this->root_frame_id_ = root_frame_id;
00066     this->success_ = this->model_.initFile(urdf_file_name);
00067     return this->success_;
00068 }
00069 
00070 
00071 bool LinkToCollision::initParameter(const std::string& root_frame_id, const std::string& urdf_param)
00072 {
00073     this->root_frame_id_ = root_frame_id;
00074     this->success_ = this->model_.initParam(urdf_param);
00075     return this->success_;
00076 }
00077 
00078 
00079 bool LinkToCollision::initSelfCollision(XmlRpc::XmlRpcValue& self_collision_params, boost::scoped_ptr<ShapesManager>& sm)
00080 {
00081     bool success = true;
00082     ROS_ASSERT(self_collision_params.getType() == XmlRpc::XmlRpcValue::TypeStruct);
00083     try
00084     {
00085         for (XmlRpc::XmlRpcValue::iterator it = self_collision_params.begin(); it != self_collision_params.end(); ++it)
00086         {
00087             std::vector<std::string> empty_vec;
00088             this->self_collision_map_[it->first] = empty_vec;
00089             ROS_ASSERT(it->second.getType() == XmlRpc::XmlRpcValue::TypeArray);
00090             for (int j=0; j < it->second.size(); ++j)
00091             {
00092                 ROS_ASSERT(it->second[j].getType() == XmlRpc::XmlRpcValue::TypeString);
00093                 this->self_collision_map_[it->first].push_back(it->second[j]);
00094             }
00095         }
00096     }
00097     catch(...)
00098     {
00099         success = false;
00100     }
00101 
00102     if (success)
00103     {
00104         for (MapIter_t it = this->self_collision_map_.begin(); it != this->self_collision_map_.end(); it++)
00105         {
00106             ROS_INFO_STREAM("Create self-collision obstacle for: " << it->first);
00107 
00108             // Create real obstacles now.
00109             PtrIMarkerShape_t ptr_obstacle;
00110             this->getMarkerShapeFromUrdf(Eigen::Vector3d(), Eigen::Quaterniond(), it->first, ptr_obstacle);
00111             ptr_obstacle->setDrawable(false);  // do not draw the marker in rviz again (are available in robot model->collision enabled...
00112             sm->addShape(it->first, ptr_obstacle);
00113         }
00114     }
00115 
00116     return success;
00117 }
00118 
00119 
00120 bool LinkToCollision::getMarkerShapeFromUrdf(const Eigen::Vector3d& abs_pos,
00121                                              const Eigen::Quaterniond& quat_pos,
00122                                              const std::string& link_of_interest,
00123                                              PtrIMarkerShape_t& segment_of_interest_marker_shape)
00124 {
00125     if (!this->success_)
00126     {
00127         ROS_ERROR("FrameToCollision object has not been initialized correctly.");
00128         return false;
00129     }
00130 
00131     bool local_success = true;
00132     PtrConstLink_t link = this->model_.getLink(link_of_interest);
00133     if (NULL != link)
00134     {
00135         geometry_msgs::Pose pose;
00136         tf::pointEigenToMsg(abs_pos, pose.position);
00137         tf::quaternionEigenToMsg(quat_pos, pose.orientation);
00138         if (NULL != link->collision && NULL != link->collision->geometry)
00139         {
00140             this->poseURDFToMsg(link->collision->origin, pose);
00141             this->createSpecificMarkerShape(link_of_interest,
00142                                             pose,
00143                                             g_shapeMsgTypeToVisMarkerType.obstacle_color_,
00144                                             link->collision->geometry,
00145                                             segment_of_interest_marker_shape);
00146         }
00147         else if (NULL != link->visual && NULL != link->visual->geometry)
00148         {
00149             ROS_WARN_STREAM("Could not find a collision or collision geometry for " << link_of_interest <<
00150                             ". Trying to create the shape from visual.");
00151             this->poseURDFToMsg(link->visual->origin, pose);
00152             this->createSpecificMarkerShape(link_of_interest,
00153                                             pose,
00154                                             g_shapeMsgTypeToVisMarkerType.obstacle_color_,
00155                                             link->visual->geometry,
00156                                             segment_of_interest_marker_shape);
00157         }
00158         else
00159         {
00160             ROS_ERROR_STREAM("There is either no collision object or no collision geometry available: " << link_of_interest <<
00161                              ". Trying fallback solution: getMarker from a default SPHERE.");
00162             const Eigen::Vector3d dim(0.05, 0.1, 0.1);
00163             this->getMarkerShapeFromType(visualization_msgs::Marker::SPHERE,
00164                                          pose,
00165                                          link_of_interest,
00166                                          dim,
00167                                          segment_of_interest_marker_shape);
00168             local_success = segment_of_interest_marker_shape != NULL;
00169         }
00170     }
00171     else
00172     {
00173         ROS_ERROR_STREAM("Could not find link in URDF model description: " << link_of_interest);
00174         local_success = false;
00175     }
00176 
00177     return local_success;
00178 }
00179 
00180 
00181 void LinkToCollision::createSpecificMarkerShape(const std::string& link_of_interest,
00182                                                 const geometry_msgs::Pose& pose,
00183                                                 const std_msgs::ColorRGBA& col,
00184                                                 const PtrGeometry_t& geometry,
00185                                                 PtrIMarkerShape_t& segment_of_interest_marker_shape)
00186 {
00187     if (urdf::Geometry::MESH == geometry->type)
00188     {
00189         std_msgs::ColorRGBA test_col;
00190         test_col.a = 0.0;
00191         test_col.r = 0.0;
00192 
00193         PtrMesh_t mesh = boost::static_pointer_cast<urdf::Mesh>(geometry);
00194         segment_of_interest_marker_shape.reset(new MarkerShape<BVH_RSS_t>(this->root_frame_id_,
00195                                                                           mesh->filename,
00196                                                                           pose,
00197                                                                           col));
00198     }
00199     else if (urdf::Geometry::BOX == geometry->type)
00200     {
00201         PtrBox_t urdf_box = boost::static_pointer_cast<urdf::Box>(geometry);
00202         fcl::Box b(urdf_box->dim.x,
00203                    urdf_box->dim.y,
00204                    urdf_box->dim.z);
00205 
00206         std_msgs::ColorRGBA test_col;
00207         test_col.a = 1.0;
00208         test_col.r = 1.0;
00209 
00210         // segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Box>(this->root_frame_id_, b, pose, col));
00211         segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Box>(this->root_frame_id_, b, pose, test_col));
00212     }
00213     else if (urdf::Geometry::SPHERE == geometry->type)
00214     {
00215         std_msgs::ColorRGBA test_col;
00216         test_col.a = 1.0;
00217         test_col.b = 1.0;
00218 
00219         PtrSphere_t urdf_sphere = boost::static_pointer_cast<urdf::Sphere>(geometry);
00220         fcl::Sphere s(urdf_sphere->radius);
00221         segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Sphere>(this->root_frame_id_, s, pose, test_col));
00222     }
00223     else if (urdf::Geometry::CYLINDER == geometry->type)
00224     {
00225         std_msgs::ColorRGBA test_col;
00226         test_col.a = 1.0;
00227         test_col.g = 1.0;
00228 
00229         PtrCylinder_t urdf_cyl = boost::static_pointer_cast<urdf::Cylinder>(geometry);
00230         fcl::Cylinder c(urdf_cyl->radius, urdf_cyl->length);
00231         segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Cylinder>(this->root_frame_id_, c, pose, test_col));
00232     }
00233     else
00234     {
00235         ROS_ERROR_STREAM("Geometry type unknown: " << geometry->type);
00236     }
00237 }
00238 
00239 
00240 bool LinkToCollision::getMarkerShapeFromType(const uint32_t& shape_type,
00241                                              const Eigen::Vector3d& abs_pos,
00242                                              const Eigen::Quaterniond& quat_pos,
00243                                              const std::string& link_of_interest,
00244                                              const Eigen::Vector3d& dimension,
00245                                              PtrIMarkerShape_t& segment_of_interest_marker_shape)
00246 {
00247     geometry_msgs::Pose pose;
00248     tf::pointEigenToMsg(abs_pos, pose.position);
00249     tf::quaternionEigenToMsg(quat_pos, pose.orientation);
00250     return this->getMarkerShapeFromType(shape_type,
00251                                         pose,
00252                                         link_of_interest,
00253                                         dimension,
00254                                         segment_of_interest_marker_shape);
00255 }
00256 
00257 
00258 bool LinkToCollision::getMarkerShapeFromType(const uint32_t& shape_type,
00259                                              const geometry_msgs::Pose& pose,
00260                                              const std::string& link_of_interest,
00261                                              const Eigen::Vector3d& dimension,
00262                                              PtrIMarkerShape_t& segment_of_interest_marker_shape)
00263 {
00264     // Representation of segment_of_interest as specific fcl::Shape
00265     fcl::Box b(dimension(FCL_BOX_X), dimension(FCL_BOX_Y), dimension(FCL_BOX_Z));
00266     fcl::Sphere s(dimension(FCL_RADIUS));
00267     fcl::Cylinder c(dimension(FCL_RADIUS), dimension(FCL_CYL_LENGTH));
00268     uint32_t loc_shape_type = shape_type;
00269     std::string mesh_resource;
00270     if (visualization_msgs::Marker::MESH_RESOURCE == loc_shape_type)
00271     {
00272         PtrConstLink_t link = this->model_.getLink(link_of_interest);
00273         if (this->success_ &&
00274                 NULL != link &&
00275                 NULL != link->collision &&
00276                 NULL != link->collision->geometry &&
00277                 link->collision->geometry->type == urdf::Geometry::MESH)
00278         {
00279             PtrMesh_t mesh = boost::static_pointer_cast<urdf::Mesh>(link->collision->geometry);
00280             mesh_resource = mesh->filename;
00281         }
00282         else
00283         {
00284             ROS_WARN_STREAM("Either link is not available in URDF or there is no MESH collision representation for " <<
00285                             link_of_interest << ". Rather using SPHERE.");
00286             loc_shape_type = visualization_msgs::Marker::SPHERE;
00287         }
00288     }
00289 
00290     std_msgs::ColorRGBA test_col;
00291 
00292     switch (loc_shape_type)
00293     {
00294         case visualization_msgs::Marker::CUBE:
00295             test_col.a = 1.0;
00296             test_col.r = 1.0;
00297             segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Box>(this->root_frame_id_, b, pose, test_col));
00298             break;
00299         case visualization_msgs::Marker::SPHERE:
00300             test_col.a = 1.0;
00301             test_col.b = 1.0;
00302             segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Sphere>(this->root_frame_id_, s, pose, test_col));
00303             break;
00304         case visualization_msgs::Marker::CYLINDER:
00305             test_col.a = 1.0;
00306             test_col.g = 1.0;
00307             segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Cylinder>(this->root_frame_id_, c, pose, test_col));
00308             break;
00309         case visualization_msgs::Marker::MESH_RESOURCE:
00310             segment_of_interest_marker_shape.reset(new MarkerShape<BVH_RSS_t>(this->root_frame_id_,
00311                                                                               mesh_resource,
00312                                                                               pose,
00313                                                                               test_col));
00314             break;
00315         default:
00316            ROS_ERROR("Failed to process request due to unknown shape type: %d", loc_shape_type);
00317            return false;
00318     }
00319 
00320     return true;
00321 }
00322 


cob_obstacle_distance
Author(s): Marco Bezzon
autogenerated on Thu Jun 6 2019 21:19:14