eband_visualization.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2010, Willow Garage, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Willow Garage, Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Author: Christian Connette
36  *********************************************************************/
37 
38 
40 
41 
42 namespace eband_local_planner{
43 
44 
45  EBandVisualization::EBandVisualization() : initialized_(false) {}
46 
47 
49  {
50  initialize(pn, costmap_ros);
51  }
52 
53 
55 
56 
58  {
59  // check if visualization already initialized
60  if(!initialized_)
61  {
62  // read parameters from parameter server
63  pn.param("marker_lifetime", marker_lifetime_, 0.5);
64 
65  // advertise topics
66  one_bubble_pub_ = pn.advertise<visualization_msgs::Marker>("eband_visualization", 1);
67  // although we want to publish MarkerArrays we have to advertise Marker topic first -> rviz searchs relative to this
68  bubble_pub_ = pn.advertise<visualization_msgs::MarkerArray>("eband_visualization_array", 1);
69 
70  // copy adress of costmap and Transform Listener (handed over from move_base) -> to get robot shape
71  costmap_ros_ = costmap_ros;
72 
73  initialized_ = true;
74  }
75  else
76  {
77  ROS_WARN("Trying to initialize already initialized visualization, doing nothing.");
78  }
79  }
80 
81 
83  eband_local_planner::EBandPlannerConfig& config)
84  {
85  marker_lifetime_ = config.marker_lifetime;
86  }
87 
88 
89  void EBandVisualization::publishBand(std::string marker_name_space, std::vector<Bubble> band)
90  {
91  // check if visualization was initialized
92  if(!initialized_)
93  {
94  ROS_ERROR("Visualization not yet initialized, please call initialize() before using visualization");
95  return;
96  }
97 
98  visualization_msgs::MarkerArray eband_msg;
99  eband_msg.markers.resize(band.size());
100 
101  visualization_msgs::MarkerArray eband_heading_msg;
102  eband_heading_msg.markers.resize(band.size());
103  std::string marker_heading_name_space = marker_name_space;
104  marker_heading_name_space.append("_heading");
105 
106  // convert elastic band to msg
107  for(int i = 0; i < ((int) band.size()); i++)
108  {
109  // convert bubbles in eband to marker msg
110  bubbleToMarker(band[i], eband_msg.markers[i], marker_name_space, i, green);
111 
112  // convert bubbles in eband to marker msg
113  // bubbleHeadingToMarker(band[i], eband_heading_msg.markers[i], marker_heading_name_space, i, green);
114  }
115 
116  // publish
117  bubble_pub_.publish(eband_msg);
118  //bubble_pub_.publish(eband_heading_msg);
119  }
120 
121 
122  void EBandVisualization::publishBubble(std::string marker_name_space, int marker_id, Bubble bubble)
123  {
124  // check if visualization was initialized
125  if(!initialized_)
126  {
127  ROS_ERROR("Visualization not yet initialized, please call initialize() before using visualization");
128  return;
129  }
130 
131  visualization_msgs::Marker bubble_msg;
132 
133  // convert bubble to marker msg
134  bubbleToMarker(bubble, bubble_msg, marker_name_space, marker_id, green);
135 
136  // publish
137  one_bubble_pub_.publish(bubble_msg);
138  }
139 
140 
141  void EBandVisualization::publishBubble(std::string marker_name_space, int marker_id, Color marker_color, Bubble bubble)
142  {
143  // check if visualization was initialized
144  if(!initialized_)
145  {
146  ROS_ERROR("Visualization not yet initialized, please call initialize() before using visualization");
147  return;
148  }
149 
150  visualization_msgs::Marker bubble_msg;
151 
152  // convert bubble to marker msg
153  bubbleToMarker(bubble, bubble_msg, marker_name_space, marker_id, marker_color);
154 
155  // publish
156  one_bubble_pub_.publish(bubble_msg);
157  }
158 
159 
160  void EBandVisualization::publishForceList(std::string marker_name_space, std::vector<geometry_msgs::WrenchStamped> forces, std::vector<Bubble> band)
161  {
162  // check if visualization was initialized
163  if(!initialized_)
164  {
165  ROS_ERROR("Visualization not yet initialized, please call initialize() before using visualization");
166  return;
167  }
168 
169  visualization_msgs::MarkerArray forces_msg;
170  forces_msg.markers.resize(forces.size());
171 
172  //before converting to msg - check whether internal, external or resulting forces - switch color
173  Color marker_color = green;
174  if(marker_name_space.compare("internal_forces") == 0)
175  marker_color = blue;
176 
177  if(marker_name_space.compare("external_forces") == 0)
178  marker_color = red;
179 
180  if(marker_name_space.compare("resulting_forces") == 0)
181  marker_color = green;
182 
183  for(int i = 0; i < ((int) forces.size()); i++)
184  {
185  // convert wrenches in force list into marker msg
186  forceToMarker(forces[i], band[i].center.pose, forces_msg.markers[i], marker_name_space, i, marker_color);
187  }
188 
189  // publish
190  bubble_pub_.publish(forces_msg);
191  }
192 
193  void EBandVisualization::publishForce(std::string marker_name_space, int id, Color marker_color, geometry_msgs::WrenchStamped force, Bubble bubble)
194  {
195  // check if visualization was initialized
196  if(!initialized_)
197  {
198  ROS_ERROR("Visualization not yet initialized, please call initialize() before using visualization");
199  return;
200  }
201 
202  visualization_msgs::Marker force_msg;
203 
204  // convert wrenches in force list into marker msg
205  forceToMarker(force, bubble.center.pose, force_msg, marker_name_space, id, marker_color);
206 
207  // publish
208  one_bubble_pub_.publish(force_msg);
209  }
210 
211 
212  void EBandVisualization::bubbleToMarker(Bubble bubble, visualization_msgs::Marker& marker, std::string marker_name_space, int marker_id, Color marker_color)
213  {
214  geometry_msgs::Pose2D tmp_pose2d;
215 
216  // header
217  marker.header.stamp = ros::Time::now();
218  marker.header.frame_id = bubble.center.header.frame_id;
219 
220  // identifier and cmds
221  marker.ns = marker_name_space;
222  marker.id = marker_id;
223  marker.type = visualization_msgs::Marker::SPHERE;
224  marker.action = visualization_msgs::Marker::ADD;
225 
226  // body
227  marker.pose = bubble.center.pose;
228  // get theta-angle to display as elevation
229  PoseToPose2D(bubble.center.pose, tmp_pose2d);
230  marker.pose.position.z = 0;//tmp_pose2d.theta * getCircumscribedRadius(*costmap_ros_);
231  // scale ~ diameter --> is 2x expansion ~ radius
232  marker.scale.x = 2.0*bubble.expansion;
233  marker.scale.y = 2.0*bubble.expansion;
234  marker.scale.z = 2.0*bubble.expansion;
235 
236  // color (rgb)
237  marker.color.r = 0.0f;
238  marker.color.g = 0.0f;
239  marker.color.b = 0.0f;
240  switch(marker_color)
241  {
242  case red: { marker.color.r = 1.0f; break; }
243  case green: { marker.color.g = 1.0f; break; }
244  case blue: { marker.color.b = 1.0f; break; }
245  }
246  // transparency (alpha value < 1 : displays marker transparent)
247  marker.color.a = 0.75;
248 
249  // lifetime of this marker
250  marker.lifetime = ros::Duration(marker_lifetime_);
251  }
252 
253 
254  void EBandVisualization::bubbleHeadingToMarker(Bubble bubble, visualization_msgs::Marker& marker, std::string marker_name_space, int marker_id, Color marker_color)
255  {
256  geometry_msgs::Pose2D tmp_pose2d;
257 
258  // header
259  marker.header.stamp = ros::Time::now();
260  marker.header.frame_id = bubble.center.header.frame_id;
261 
262  // identifier and cmds
263  marker.ns = marker_name_space;
264  marker.id = marker_id;
265  marker.type = visualization_msgs::Marker::ARROW;
266  marker.action = visualization_msgs::Marker::ADD;
267 
268  // body
269  marker.pose = bubble.center.pose;
270  // get theta-angle to display as elevation
271  PoseToPose2D(bubble.center.pose, tmp_pose2d);
272  marker.pose.position.z = tmp_pose2d.theta * getCircumscribedRadius(*costmap_ros_);
273  // scale ~ diameter --> is 2x expansion ~ radius
274  marker.scale.x = 0.9;
275  marker.scale.y = 0.45;
276  marker.scale.z = 0.45;
277 
278  // color (rgb)
279  marker.color.r = 0.0f;
280  marker.color.g = 0.0f;
281  marker.color.b = 0.0f;
282  switch(marker_color)
283  {
284  case red: { marker.color.r = 1.0f; break; }
285  case green: { marker.color.g = 1.0f; break; }
286  case blue: { marker.color.b = 1.0f; break; }
287  }
288  // transparency (alpha value < 1 : displays marker transparent)
289  marker.color.a = 1.0;
290 
291  // lifetime of this marker
292  marker.lifetime = ros::Duration(marker_lifetime_);
293  }
294 
295 
296  void EBandVisualization::forceToMarker(geometry_msgs::WrenchStamped wrench, geometry_msgs::Pose wrench_origin, visualization_msgs::Marker& marker, std::string marker_name_space, int marker_id, Color marker_color)
297  {
298  geometry_msgs::Pose2D tmp_pose2d;
299 
300  // header
301  marker.header.stamp = ros::Time::now();
302  marker.header.frame_id = wrench.header.frame_id;
303 
304  // identifier and cmds
305  marker.ns = marker_name_space;
306  marker.id = marker_id;
307  marker.type = visualization_msgs::Marker::ARROW;
308  marker.action = visualization_msgs::Marker::ADD;
309 
310  // body - origin
311  marker.pose.position = wrench_origin.position;
312  // get theta-angle to display as elevation
313  PoseToPose2D(wrench_origin, tmp_pose2d);
314  marker.pose.position.z = tmp_pose2d.theta * getCircumscribedRadius(*costmap_ros_);
315 
316  // body - orientation of vector (calc. quaternion that transform xAxis into force-vector)
317  // check if force different from zero
318  if( (wrench.wrench.force.x != 0) || (wrench.wrench.force.y != 0) || (wrench.wrench.torque.z != 0) )
319  {
320  // find AxisAngle Representation then convert to Quaternion
321  // (Axis = normalize(vec1) cross normalize(vec2) // cos(Angle) = normalize(vec1) dot normalize(vec2))
322  Eigen::Vector3d x_axis(1.0, 0.0, 0.0);
323  Eigen::Vector3d target_vec( wrench.wrench.force.x, wrench.wrench.force.y, wrench.wrench.torque.z / getCircumscribedRadius(*costmap_ros_) );
324  Eigen::Vector3d rotation_axis(1.0, 0.0, 0.0);
325  double rotation_angle = 0.0;
326  // get Axis orthogonal to both vectors ()
327  x_axis.normalize(); // unneccessary but just in case
328  target_vec.normalize();
329  if(!(x_axis == target_vec))
330  {
331  // vector not identical - cross-product defined
332  rotation_axis = x_axis.cross(target_vec);
333  rotation_angle = x_axis.dot(target_vec);
334  rotation_angle = acos(rotation_angle);
335  }
336  // create AngleAxis representation
337  rotation_axis.normalize(); // normalize vector -> otherwise AngleAxis will be invalid!
338  const double s = sin(rotation_angle/2);
339  const double c = cos(rotation_angle/2);
340  Eigen::Quaterniond rotate_quat(c, s*rotation_axis.x(), s*rotation_axis.y(), s*rotation_axis.z());
341 
342  // transform quaternion back from Eigen to ROS
343  tf::Quaternion orientation_tf;
344  geometry_msgs::Quaternion orientation_msg;
345  tf::quaternionEigenToTF(rotate_quat, orientation_tf);
346  tf::quaternionTFToMsg(orientation_tf, orientation_msg);
347 
348  // finally set orientation of marker
349  marker.pose.orientation = orientation_msg;
350 
351  // scale ~ diameter --> is 2x expansion ~ radius
352  double scale = sqrt( (wrench.wrench.force.x * wrench.wrench.force.x) + (wrench.wrench.force.y * wrench.wrench.force.y) +
353  ( (wrench.wrench.torque.z/getCircumscribedRadius(*costmap_ros_))*(wrench.wrench.torque.z/getCircumscribedRadius(*costmap_ros_)) ) );
354  marker.scale.x = scale; //1.0;
355  marker.scale.y = scale; //1.0;
356  marker.scale.z = scale; //1.0;
357 
358  // color (rgb)
359  marker.color.r = 0.0f;
360  marker.color.g = 0.0f;
361  marker.color.b = 0.0f;
362  switch(marker_color)
363  {
364  case red: { marker.color.r = 1.0f; break; }
365  case green: { marker.color.g = 1.0f; break; }
366  case blue: { marker.color.b = 1.0f; break; }
367  }
368  // transparency (alpha value < 1 : displays marker transparent)
369  marker.color.a = 1.25;
370  }
371  else
372  {
373  // force on this bubble is zero -> make marker invisible
374  marker.pose.orientation = wrench_origin.orientation; // just take orientation of bubble as dummy-value
375 
376  // scale
377  marker.scale.x = 0.0;
378  marker.scale.y = 0.0;
379  marker.scale.z = 0.0;
380 
381  // color (rgb)
382  marker.color.r = 0.0f;
383  marker.color.g = 0.0f;
384  marker.color.b = 0.0f;
385 
386  // transparency (alpha value < 1 : displays marker transparent)
387  marker.color.a = 0.0;
388  }
389 
390  // lifetime of this marker
391  marker.lifetime = ros::Duration(marker_lifetime_);
392  }
393 
394 };
395 
void publish(const boost::shared_ptr< M > &message) const
void reconfigure(EBandPlannerConfig &config)
Reconfigures the parameters of the planner.
XmlRpcServer s
void bubbleHeadingToMarker(Bubble bubble, visualization_msgs::Marker &marker, std::string marker_name_space, int marker_id, Color marker_color)
converts the haeding of a bubble into a Arrow-Marker msg - this is visualization-specific ...
void publishBubble(std::string marker_name_space, int marker_id, Bubble bubble)
publishes a single bubble as a Marker
#define ROS_WARN(...)
void bubbleToMarker(Bubble bubble, visualization_msgs::Marker &marker, std::string marker_name_space, int marker_id, Color marker_color)
converts a bubble into a Marker msg - this is visualization-specific
void publishBand(std::string marker_name_space, std::vector< Bubble > band)
publishes the bubbles (Position and Expansion) in a band as Marker-Array
double getCircumscribedRadius(costmap_2d::Costmap2DROS &costmap)
Gets the footprint of the robot and computes the circumscribed radius for the eband approach...
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::Publisher one_bubble_pub_
publishes markers to visualize bubbles of elastic band ("modified global plan")
static void quaternionTFToMsg(const Quaternion &bt, geometry_msgs::Quaternion &msg)
costmap_2d::Costmap2DROS * costmap_ros_
pointer to costmap - needed to retrieve information about robot geometry
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
void publishForceList(std::string marker_name_space, std::vector< geometry_msgs::WrenchStamped > forces, std::vector< Bubble > band)
publishes the list of forces along the band as Marker-Array
void initialize(ros::NodeHandle &pn, costmap_2d::Costmap2DROS *costmap_ros)
Initializes the visualization class.
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
void quaternionEigenToTF(const Eigen::Quaterniond &e, tf::Quaternion &t)
void forceToMarker(geometry_msgs::WrenchStamped wrench, geometry_msgs::Pose wrench_origin, visualization_msgs::Marker &marker, std::string marker_name_space, int marker_id, Color marker_color)
converts a wrench into a Marker msg - this is visualization-specific
ros::Publisher bubble_pub_
publishes markers to visualize bubbles of elastic band ("modified global plan")
static Time now()
geometry_msgs::PoseStamped center
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
#define ROS_ERROR(...)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
void publishForce(std::string marker_name_space, int id, Color marker_color, geometry_msgs::WrenchStamped force, Bubble bubble)
publishes a single force as a Marker
void PoseToPose2D(const geometry_msgs::Pose pose, geometry_msgs::Pose2D &pose2D)
Converts a frame of type Pose to type Pose2D (mainly -> conversion of orientation from quaternions to...


eband_local_planner
Author(s): Christian Connette, Bhaskara Marthi, Piyush Khandelwal
autogenerated on Sat Feb 22 2020 04:03:28