00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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;
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
00109 PtrIMarkerShape_t ptr_obstacle;
00110 this->getMarkerShapeFromUrdf(Eigen::Vector3d(), Eigen::Quaterniond(), it->first, ptr_obstacle);
00111 ptr_obstacle->setDrawable(false);
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
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
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