link_to_collision.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <string>
19 #include <vector>
20 
23 #include <visualization_msgs/Marker.h>
24 
25 
27 {
28 }
29 
30 
32 {
33 }
34 
35 
36 void LinkToCollision::poseURDFToMsg(const urdf::Pose& urdf_pose, geometry_msgs::Pose& msg_pose)
37 {
38  msg_pose.position.x = urdf_pose.position.x;
39  msg_pose.position.y = urdf_pose.position.y;
40  msg_pose.position.z = urdf_pose.position.z;
41 
42  msg_pose.orientation.x = urdf_pose.rotation.x;
43  msg_pose.orientation.y = urdf_pose.rotation.y;
44  msg_pose.orientation.z = urdf_pose.rotation.z;
45  msg_pose.orientation.w = urdf_pose.rotation.w;
46 }
47 
48 
49 bool LinkToCollision::ignoreSelfCollisionPart(const std::string& link_of_interest,
50  const std::string& self_collision_obstacle_link)
51 {
52  if (this->self_collision_map_.count(self_collision_obstacle_link) <= 0)
53  {
54  return false;
55  }
56 
57  std::vector<std::string>::iterator sca_begin = this->self_collision_map_[self_collision_obstacle_link].begin();
58  std::vector<std::string>::iterator sca_end = this->self_collision_map_[self_collision_obstacle_link].end();
59  return std::find(sca_begin, sca_end, link_of_interest) == sca_end; // if not found return true
60 }
61 
62 
63 bool LinkToCollision::initFile(const std::string& root_frame_id, const std::string& urdf_file_name)
64 {
65  this->root_frame_id_ = root_frame_id;
66  this->success_ = this->model_.initFile(urdf_file_name);
67  return this->success_;
68 }
69 
70 
71 bool LinkToCollision::initParameter(const std::string& root_frame_id, const std::string& urdf_param)
72 {
73  this->root_frame_id_ = root_frame_id;
74  this->success_ = this->model_.initParam(urdf_param);
75  return this->success_;
76 }
77 
78 
79 bool LinkToCollision::initSelfCollision(XmlRpc::XmlRpcValue& self_collision_params, boost::scoped_ptr<ShapesManager>& sm)
80 {
81  bool success = true;
82  ROS_ASSERT(self_collision_params.getType() == XmlRpc::XmlRpcValue::TypeStruct);
83  try
84  {
85  for (XmlRpc::XmlRpcValue::iterator it = self_collision_params.begin(); it != self_collision_params.end(); ++it)
86  {
87  std::vector<std::string> empty_vec;
88  this->self_collision_map_[it->first] = empty_vec;
89  ROS_ASSERT(it->second.getType() == XmlRpc::XmlRpcValue::TypeArray);
90  for (int j=0; j < it->second.size(); ++j)
91  {
92  ROS_ASSERT(it->second[j].getType() == XmlRpc::XmlRpcValue::TypeString);
93  this->self_collision_map_[it->first].push_back(it->second[j]);
94  }
95  }
96  }
97  catch(...)
98  {
99  success = false;
100  }
101 
102  if (success)
103  {
104  for (MapIter_t it = this->self_collision_map_.begin(); it != this->self_collision_map_.end(); it++)
105  {
106  ROS_INFO_STREAM("Create self-collision obstacle for: " << it->first);
107 
108  // Create real obstacles now.
109  PtrIMarkerShape_t ptr_obstacle;
110  this->getMarkerShapeFromUrdf(Eigen::Vector3d(), Eigen::Quaterniond(), it->first, ptr_obstacle);
111  ptr_obstacle->setDrawable(false); // do not draw the marker in rviz again (are available in robot model->collision enabled...
112  sm->addShape(it->first, ptr_obstacle);
113  }
114  }
115 
116  return success;
117 }
118 
119 
120 bool LinkToCollision::getMarkerShapeFromUrdf(const Eigen::Vector3d& abs_pos,
121  const Eigen::Quaterniond& quat_pos,
122  const std::string& link_of_interest,
123  PtrIMarkerShape_t& segment_of_interest_marker_shape)
124 {
125  if (!this->success_)
126  {
127  ROS_ERROR("FrameToCollision object has not been initialized correctly.");
128  return false;
129  }
130 
131  bool local_success = true;
132  PtrConstLink_t link = this->model_.getLink(link_of_interest);
133  if (NULL != link)
134  {
135  geometry_msgs::Pose pose;
136  tf::pointEigenToMsg(abs_pos, pose.position);
137  tf::quaternionEigenToMsg(quat_pos, pose.orientation);
138  if (NULL != link->collision && NULL != link->collision->geometry)
139  {
140  this->poseURDFToMsg(link->collision->origin, pose);
141  this->createSpecificMarkerShape(link_of_interest,
142  pose,
144  link->collision->geometry,
145  segment_of_interest_marker_shape);
146  }
147  else if (NULL != link->visual && NULL != link->visual->geometry)
148  {
149  ROS_WARN_STREAM("Could not find a collision or collision geometry for " << link_of_interest <<
150  ". Trying to create the shape from visual.");
151  this->poseURDFToMsg(link->visual->origin, pose);
152  this->createSpecificMarkerShape(link_of_interest,
153  pose,
155  link->visual->geometry,
156  segment_of_interest_marker_shape);
157  }
158  else
159  {
160  ROS_ERROR_STREAM("There is either no collision object or no collision geometry available: " << link_of_interest <<
161  ". Trying fallback solution: getMarker from a default SPHERE.");
162  const Eigen::Vector3d dim(0.05, 0.1, 0.1);
163  this->getMarkerShapeFromType(visualization_msgs::Marker::SPHERE,
164  pose,
165  link_of_interest,
166  dim,
167  segment_of_interest_marker_shape);
168  local_success = segment_of_interest_marker_shape != NULL;
169  }
170  }
171  else
172  {
173  ROS_ERROR_STREAM("Could not find link in URDF model description: " << link_of_interest);
174  local_success = false;
175  }
176 
177  return local_success;
178 }
179 
180 
181 void LinkToCollision::createSpecificMarkerShape(const std::string& link_of_interest,
182  const geometry_msgs::Pose& pose,
183  const std_msgs::ColorRGBA& col,
184  const PtrGeometry_t& geometry,
185  PtrIMarkerShape_t& segment_of_interest_marker_shape)
186 {
187  if (urdf::Geometry::MESH == geometry->type)
188  {
189  std_msgs::ColorRGBA test_col;
190  test_col.a = 0.0;
191  test_col.r = 0.0;
192 
193  PtrMesh_t mesh = boost::static_pointer_cast<urdf::Mesh>(geometry);
194  segment_of_interest_marker_shape.reset(new MarkerShape<BVH_RSS_t>(this->root_frame_id_,
195  mesh->filename,
196  pose,
197  col));
198  }
199  else if (urdf::Geometry::BOX == geometry->type)
200  {
201  PtrBox_t urdf_box = boost::static_pointer_cast<urdf::Box>(geometry);
202  fcl::Box b(urdf_box->dim.x,
203  urdf_box->dim.y,
204  urdf_box->dim.z);
205 
206  std_msgs::ColorRGBA test_col;
207  test_col.a = 1.0;
208  test_col.r = 1.0;
209 
210  // segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Box>(this->root_frame_id_, b, pose, col));
211  segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Box>(this->root_frame_id_, b, pose, test_col));
212  }
213  else if (urdf::Geometry::SPHERE == geometry->type)
214  {
215  std_msgs::ColorRGBA test_col;
216  test_col.a = 1.0;
217  test_col.b = 1.0;
218 
219  PtrSphere_t urdf_sphere = boost::static_pointer_cast<urdf::Sphere>(geometry);
220  fcl::Sphere s(urdf_sphere->radius);
221  segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Sphere>(this->root_frame_id_, s, pose, test_col));
222  }
223  else if (urdf::Geometry::CYLINDER == geometry->type)
224  {
225  std_msgs::ColorRGBA test_col;
226  test_col.a = 1.0;
227  test_col.g = 1.0;
228 
229  PtrCylinder_t urdf_cyl = boost::static_pointer_cast<urdf::Cylinder>(geometry);
230  fcl::Cylinder c(urdf_cyl->radius, urdf_cyl->length);
231  segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Cylinder>(this->root_frame_id_, c, pose, test_col));
232  }
233  else
234  {
235  ROS_ERROR_STREAM("Geometry type unknown: " << geometry->type);
236  }
237 }
238 
239 
240 bool LinkToCollision::getMarkerShapeFromType(const uint32_t& shape_type,
241  const Eigen::Vector3d& abs_pos,
242  const Eigen::Quaterniond& quat_pos,
243  const std::string& link_of_interest,
244  const Eigen::Vector3d& dimension,
245  PtrIMarkerShape_t& segment_of_interest_marker_shape)
246 {
247  geometry_msgs::Pose pose;
248  tf::pointEigenToMsg(abs_pos, pose.position);
249  tf::quaternionEigenToMsg(quat_pos, pose.orientation);
250  return this->getMarkerShapeFromType(shape_type,
251  pose,
252  link_of_interest,
253  dimension,
254  segment_of_interest_marker_shape);
255 }
256 
257 
258 bool LinkToCollision::getMarkerShapeFromType(const uint32_t& shape_type,
259  const geometry_msgs::Pose& pose,
260  const std::string& link_of_interest,
261  const Eigen::Vector3d& dimension,
262  PtrIMarkerShape_t& segment_of_interest_marker_shape)
263 {
264  // Representation of segment_of_interest as specific fcl::Shape
265  fcl::Box b(dimension(FCL_BOX_X), dimension(FCL_BOX_Y), dimension(FCL_BOX_Z));
266  fcl::Sphere s(dimension(FCL_RADIUS));
267  fcl::Cylinder c(dimension(FCL_RADIUS), dimension(FCL_CYL_LENGTH));
268  uint32_t loc_shape_type = shape_type;
269  std::string mesh_resource;
270  if (visualization_msgs::Marker::MESH_RESOURCE == loc_shape_type)
271  {
272  PtrConstLink_t link = this->model_.getLink(link_of_interest);
273  if (this->success_ &&
274  NULL != link &&
275  NULL != link->collision &&
276  NULL != link->collision->geometry &&
277  link->collision->geometry->type == urdf::Geometry::MESH)
278  {
279  PtrMesh_t mesh = boost::static_pointer_cast<urdf::Mesh>(link->collision->geometry);
280  mesh_resource = mesh->filename;
281  }
282  else
283  {
284  ROS_WARN_STREAM("Either link is not available in URDF or there is no MESH collision representation for " <<
285  link_of_interest << ". Rather using SPHERE.");
286  loc_shape_type = visualization_msgs::Marker::SPHERE;
287  }
288  }
289 
290  std_msgs::ColorRGBA test_col;
291 
292  switch (loc_shape_type)
293  {
294  case visualization_msgs::Marker::CUBE:
295  test_col.a = 1.0;
296  test_col.r = 1.0;
297  segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Box>(this->root_frame_id_, b, pose, test_col));
298  break;
299  case visualization_msgs::Marker::SPHERE:
300  test_col.a = 1.0;
301  test_col.b = 1.0;
302  segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Sphere>(this->root_frame_id_, s, pose, test_col));
303  break;
304  case visualization_msgs::Marker::CYLINDER:
305  test_col.a = 1.0;
306  test_col.g = 1.0;
307  segment_of_interest_marker_shape.reset(new MarkerShape<fcl::Cylinder>(this->root_frame_id_, c, pose, test_col));
308  break;
309  case visualization_msgs::Marker::MESH_RESOURCE:
310  segment_of_interest_marker_shape.reset(new MarkerShape<BVH_RSS_t>(this->root_frame_id_,
311  mesh_resource,
312  pose,
313  test_col));
314  break;
315  default:
316  ROS_ERROR("Failed to process request due to unknown shape type: %d", loc_shape_type);
317  return false;
318  }
319 
320  return true;
321 }
322 
URDF_EXPORT bool initFile(const std::string &filename)
#define NULL
#define FCL_RADIUS
std::shared_ptr< IMarkerShape > PtrIMarkerShape_t
ValueStruct::iterator iterator
urdf::MeshSharedPtr PtrMesh_t
std::unordered_map< std::string, std::vector< std::string > > self_collision_map_
void quaternionEigenToMsg(const Eigen::Quaterniond &e, geometry_msgs::Quaternion &m)
XmlRpcServer s
#define FCL_CYL_LENGTH
std::unordered_map< std::string, std::vector< std::string > >::iterator MapIter_t
Template class implementation for box, sphere and cylinder fcl::shapes. Creates visualization marker...
Type const & getType() const
void poseURDFToMsg(const urdf::Pose &urdf_pose, geometry_msgs::Pose &msg_pose)
bool ignoreSelfCollisionPart(const std::string &link_of_interest, const std::string &self_collision_obstacle_link)
bool getMarkerShapeFromUrdf(const Eigen::Vector3d &abs_pos, const Eigen::Quaterniond &quat_pos, const std::string &link_of_interest, PtrIMarkerShape_t &segment_of_interest_marker_shape)
urdf::CylinderSharedPtr PtrCylinder_t
URDF_EXPORT bool initParam(const std::string &param)
#define ROS_WARN_STREAM(args)
void pointEigenToMsg(const Eigen::Vector3d &e, geometry_msgs::Point &m)
static ShapeMsgTypeToVisMarkerType g_shapeMsgTypeToVisMarkerType
std::string root_frame_id_
#define ROS_INFO_STREAM(args)
bool initFile(const std::string &root_frame_id, const std::string &urdf_file_name)
#define ROS_ERROR_STREAM(args)
urdf::LinkConstSharedPtr PtrConstLink_t
#define ROS_ASSERT(cond)
#define ROS_ERROR(...)
bool initSelfCollision(XmlRpc::XmlRpcValue &self_collision_params, boost::scoped_ptr< ShapesManager > &sm)
bool getMarkerShapeFromType(const uint32_t &shape_type, const Eigen::Vector3d &abs_pos, const Eigen::Quaterniond &quat_pos, const std::string &link_of_interest, const Eigen::Vector3d &dimension, PtrIMarkerShape_t &segment_of_interest_marker_shape)
void createSpecificMarkerShape(const std::string &link_of_interest, const geometry_msgs::Pose &pose, const std_msgs::ColorRGBA &col, const PtrGeometry_t &geometry, PtrIMarkerShape_t &segment_of_interest_marker_shape)
first: link to be considered &#39;obstacle&#39;, second: links of component to be considered for self-collisi...
urdf::SphereSharedPtr PtrSphere_t
bool initParameter(const std::string &root_frame_id, const std::string &urdf_param)
urdf::BoxSharedPtr PtrBox_t
urdf::GeometrySharedPtr PtrGeometry_t


cob_obstacle_distance
Author(s): Marco Bezzon
autogenerated on Thu Apr 8 2021 02:39:47