path_display.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Willow Garage, Inc.
3  * 2020, Locus Robotics
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the Willow Garage, Inc. or Locus Robotics nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
34 #include <boost/bind.hpp>
35 
36 #include <OgreSceneNode.h>
37 #include <OgreSceneManager.h>
38 #include <OgreMatrix4.h>
39 
40 #include <algorithm>
41 #include <vector>
42 
43 namespace robot_nav_rviz_plugins
44 {
46 {
47  style_property_ = new rviz::EnumProperty("Line Style", "Lines",
48  "The rendering operation to use to draw the grid lines.", this, SLOT(updateStyle()));
49  style_property_->addOption("Lines", static_cast<int>(LineStyle::LINES));
50  style_property_->addOption("Billboards", static_cast<int>(LineStyle::BILLBOARDS));
51 
52  line_width_property_ = new rviz::FloatProperty("Line Width", 0.03, "The width, in meters, of each path line. "
53  "Only works with the 'Billboards' style.", this, SLOT(updateLineWidth()), this);
56 
57  color_property_ = new rviz::ColorProperty("Color", QColor(41, 170, 226), "Color to draw the path.", this);
58  alpha_property_ = new rviz::FloatProperty("Alpha", 1.0, "Amount of transparency to apply to the path.", this);
59 
60  buffer_length_property_ = new rviz::IntProperty("Buffer Length", 1, "Number of paths to display.", this,
61  SLOT(updateBufferLength()));
63 
64  offset_property_ = new rviz::VectorProperty("Offset", Ogre::Vector3::ZERO,
65  "Allows you to offset the path from the origin of the reference frame. In meters.", this, SLOT(updateOffset()));
66 
67  pose_style_property_ = new rviz::EnumProperty("Pose Style", "None", "Shape to display the pose as.", this,
68  SLOT(updatePoseStyle()));
69  pose_style_property_->addOption("None", static_cast<int>(PoseStyle::NONE));
70  pose_style_property_->addOption("Axes", static_cast<int>(PoseStyle::AXES));
71  pose_style_property_->addOption("Arrows", static_cast<int>(PoseStyle::ARROWS));
72 
73  pose_axes_length_property_ = new rviz::FloatProperty("Length", 0.3, "Length of the axes.", this,
74  SLOT(updatePoseAxisGeometry()));
75  pose_axes_radius_property_ = new rviz::FloatProperty("Radius", 0.03, "Radius of the axes.", this,
76  SLOT(updatePoseAxisGeometry()));
77  pose_arrow_color_property_ = new rviz::ColorProperty("Pose Color", QColor(41, 170, 226), "Color to draw the poses.",
78  this, SLOT(updatePoseArrowColor()));
79  pose_arrow_shaft_length_property_ = new rviz::FloatProperty("Shaft Length", 0.1, "Length of the arrow shaft.",
80  this, SLOT(updatePoseArrowGeometry()));
81  pose_arrow_head_length_property_ = new rviz::FloatProperty("Head Length", 0.2, "Length of the arrow head.",
82  this, SLOT(updatePoseArrowGeometry()));
83  pose_arrow_shaft_diameter_property_ = new rviz::FloatProperty("Shaft Diameter", 0.1, "Diameter of the arrow shaft.",
84  this, SLOT(updatePoseArrowGeometry()));
85  pose_arrow_head_diameter_property_ = new rviz::FloatProperty("Head Diameter", 0.3, "Diameter of the arrow head.",
86  this, SLOT(updatePoseArrowGeometry()));
94 }
95 
97 {
99 }
100 
102 {
105 }
106 
108 {
109  MFDClass::reset();
111 }
112 
113 void PathDisplay::allocateAxesVector(std::vector<rviz::Axes*>& axes_vect, int num)
114 {
115  unsigned int num_u = static_cast<unsigned int>(num);
116  if (num_u > axes_vect.size())
117  {
118  for (size_t i = axes_vect.size(); i < num_u; i++)
119  {
123  axes_vect.push_back(axes);
124  }
125  }
126  else if (num_u < axes_vect.size())
127  {
128  for (int i = axes_vect.size() - 1; num <= i; i--)
129  {
130  delete axes_vect[i];
131  }
132  axes_vect.resize(num);
133  }
134 }
135 
136 void PathDisplay::allocateArrowVector(std::vector<rviz::Arrow*>& arrow_vect, int num)
137 {
138  unsigned int num_u = static_cast<unsigned int>(num);
139  if (num_u > arrow_vect.size())
140  {
141  for (size_t i = arrow_vect.size(); i < num_u; i++)
142  {
144  arrow_vect.push_back(arrow);
145  }
146  }
147  else if (num_u < arrow_vect.size())
148  {
149  for (int i = arrow_vect.size() - 1; num <= i; i--)
150  {
151  delete arrow_vect[i];
152  }
153  arrow_vect.resize(num);
154  }
155 }
156 
158 {
159  switch (getLineStyle())
160  {
161  case LineStyle::LINES:
162  default:
164  break;
165 
168  break;
169  }
170 
172 }
173 
175 {
176  float line_width = line_width_property_->getFloat();
177 
179  {
180  for (rviz::BillboardLine* billboard_line : billboard_lines_)
181  {
182  if (billboard_line) billboard_line->setLineWidth(line_width);
183  }
184  }
186 }
187 
189 {
190  scene_node_->setPosition(offset_property_->getVector());
192 }
193 
195 {
196  switch (getPoseStyle())
197  {
198  case PoseStyle::AXES:
206  break;
207  case PoseStyle::ARROWS:
215  break;
216  default:
224  }
226 }
227 
229 {
230  for (auto& axes_vect : axes_chain_)
231  {
232  for (auto& axes : axes_vect)
233  {
236  }
237  }
239 }
240 
242 {
243  Ogre::ColourValue color = pose_arrow_color_property_->getOgreColor();
244 
245  for (auto& arrow_vect : arrow_chain_)
246  {
247  for (auto& arrow : arrow_vect)
248  {
249  arrow->setColor(color);
250  }
251  }
253 }
254 
256 {
257  for (auto& arrow_vect : arrow_chain_)
258  {
259  for (auto& arrow : arrow_vect)
260  {
265  }
266  }
268 }
269 
271 {
272  // Destroy all simple lines, if any
273  for (auto& manual_object : manual_objects_)
274  {
275  if (manual_object)
276  {
277  manual_object->clear();
278  scene_manager_->destroyManualObject(manual_object);
279  manual_object = NULL; // ensure it doesn't get destroyed again
280  }
281  }
282 
283  // Destroy all billboards, if any
284  for (auto& billboard_line : billboard_lines_)
285  {
286  if (billboard_line)
287  {
288  delete billboard_line; // also destroys the corresponding scene node
289  billboard_line = NULL; // ensure it doesn't get destroyed again
290  }
291  }
292 
293  // Destroy Pose Vectors
294  for (auto& axes_vect : axes_chain_)
295  {
296  allocateAxesVector(axes_vect, 0);
297  }
298  axes_chain_.resize(0);
299 
300  for (auto& arrow_vect : arrow_chain_)
301  {
302  allocateArrowVector(arrow_vect, 0);
303  }
304  arrow_chain_.resize(0);
305 }
306 
308 {
309  // Delete old path objects
310  destroyObjects();
311 
312  // Read options
313  int buffer_length = buffer_length_property_->getInt();
314 
315  // Create new path objects
316  switch (getLineStyle())
317  {
318  case LineStyle::LINES: // simple lines with fixed width of 1px
319  manual_objects_.resize(buffer_length);
320  for (size_t i = 0; i < manual_objects_.size(); i++)
321  {
322  manual_objects_[i] = scene_manager_->createManualObject();
323  manual_objects_[i]->setDynamic(true);
324  scene_node_->attachObject(manual_objects_[i]);
325  }
326  break;
327 
328  case LineStyle::BILLBOARDS: // billboards with configurable width
329  billboard_lines_.resize(buffer_length);
330  for (size_t i = 0; i < billboard_lines_.size(); i++)
331  {
333  }
334  break;
335  }
336  axes_chain_.resize(buffer_length);
337  arrow_chain_.resize(buffer_length);
338 }
339 
340 void PathDisplay::processMessage(const nav_2d_msgs::Path2D::ConstPtr& msg)
341 {
342  // Calculate index of oldest element in cyclic buffer
343  size_t bufferIndex = messages_received_ % buffer_length_property_->getInt();
344 
345  LineStyle style = getLineStyle();
346  PoseStyle pose_style = getPoseStyle();
347  Ogre::ManualObject* manual_object = NULL;
348  rviz::BillboardLine* billboard_line = NULL;
349 
350  // Delete oldest element
351  switch (style)
352  {
353  case LineStyle::LINES:
354  manual_object = manual_objects_[bufferIndex];
355  manual_object->clear();
356  break;
357 
359  billboard_line = billboard_lines_[bufferIndex];
360  billboard_line->clear();
361  break;
362  }
363 
364  std::vector<rviz::Arrow*>& arrow_vect = arrow_chain_[bufferIndex];
365  std::vector<rviz::Axes*>& axes_vect = axes_chain_[bufferIndex];
366 
367  // Check if path contains invalid coordinate values
368  if (!validateFloats(*msg))
369  {
370  setStatus(rviz::StatusProperty::Error, "Topic", "Message contained invalid floating point values (nans or infs)");
371  return;
372  }
373 
374  // Lookup transform into fixed frame
375  Ogre::Vector3 position;
376  Ogre::Quaternion orientation;
377  if (!context_->getFrameManager()->getTransform(msg->header, position, orientation))
378  {
379  ROS_DEBUG("Error transforming from frame '%s' to frame '%s'",
380  msg->header.frame_id.c_str(), qPrintable(fixed_frame_));
381  }
382 
383  Ogre::Matrix4 transform(orientation);
384  transform.setTrans(position);
385 
386  // scene_node_->setPosition(position);
387  // scene_node_->setOrientation(orientation);
388 
389  Ogre::ColourValue color = color_property_->getOgreColor();
390  color.a = alpha_property_->getFloat();
391  Ogre::ColourValue arrow_color = pose_arrow_color_property_->getOgreColor();
392 
393  uint32_t num_points = msg->poses.size();
394  switch (style)
395  {
396  case LineStyle::LINES:
397  manual_object->estimateVertexCount(num_points);
398  manual_object->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
399  break;
400 
402  billboard_line->setNumLines(1);
403  billboard_line->setMaxPointsPerLine(num_points);
404  billboard_line->setLineWidth(line_width_property_->getFloat());
405  break;
406  }
407  switch (pose_style)
408  {
409  case PoseStyle::NONE:
410  break;
411  case PoseStyle::AXES:
412  allocateAxesVector(axes_vect, num_points);
413  break;
414  case PoseStyle::ARROWS:
415  allocateArrowVector(arrow_vect, num_points);
416  break;
417  }
418 
419  for (uint32_t i = 0; i < num_points; ++i)
420  {
421  geometry_msgs::Pose pose = nav_2d_utils::pose2DToPose(msg->poses[i]);
422 
423  Ogre::Vector3 xpos = transform * Ogre::Vector3(pose.position.x,
424  pose.position.y,
425  pose.position.z);
426  const geometry_msgs::Quaternion& quat = pose.orientation;
427  Ogre::Quaternion xquat = orientation * Ogre::Quaternion(quat.w, quat.x, quat.y, quat.z);
428 
429  switch (style)
430  {
431  case LineStyle::LINES:
432  manual_object->position(xpos.x, xpos.y, xpos.z);
433  manual_object->colour(color);
434  break;
436  billboard_line->addPoint(xpos, color);
437  break;
438  }
439  switch (pose_style)
440  {
441  case PoseStyle::NONE:
442  break;
443 
444  case PoseStyle::AXES:
445  axes_vect[i]->setPosition(xpos);
446  axes_vect[i]->setOrientation(xquat);
447  break;
448 
449  case PoseStyle::ARROWS:
450  arrow_vect[i]->setColor(arrow_color);
451  arrow_vect[i]->set(pose_arrow_shaft_length_property_->getFloat(),
455  arrow_vect[i]->setPosition(xpos);
456  arrow_vect[i]->setDirection(xquat * Ogre::Vector3(1, 0, 0));
457  break;
458  }
459  }
460 
461  if (style == LineStyle::LINES)
462  manual_object->end();
463 
465 }
466 
467 } // namespace robot_nav_rviz_plugins
468 
rviz::EnumProperty * style_property_
Definition: path_display.h:92
#define NULL
void setMin(float min)
rviz::VectorProperty * offset_property_
Definition: path_display.h:97
rviz::ColorProperty * color_property_
Definition: path_display.h:93
std::vector< Ogre::ManualObject * > manual_objects_
Definition: path_display.h:87
Ogre::ColourValue getOgreColor() const
geometry_msgs::Pose pose2DToPose(const geometry_msgs::Pose2D &pose2d)
void addPoint(const Ogre::Vector3 &point)
rviz::ColorProperty * pose_arrow_color_property_
Definition: path_display.h:103
DisplayContext * context_
virtual int getInt() const
rviz::IntProperty * buffer_length_property_
Definition: path_display.h:96
virtual float getFloat() const
std::vector< std::vector< rviz::Axes * > > axes_chain_
Definition: path_display.h:89
void allocateAxesVector(std::vector< rviz::Axes * > &axes_vect, int num)
Displays a nav_2d_msgs::Path2D message in Rviz.
Definition: path_display.h:54
void setMin(int min)
Ogre::SceneNode * scene_node_
rviz::FloatProperty * pose_axes_radius_property_
Definition: path_display.h:102
QString fixed_frame_
std::vector< std::vector< rviz::Arrow * > > arrow_chain_
Definition: path_display.h:90
virtual void addOption(const QString &option, int value=0)
rviz::FloatProperty * pose_axes_length_property_
Definition: path_display.h:101
rviz::FloatProperty * pose_arrow_head_diameter_property_
Definition: path_display.h:107
rviz::FloatProperty * line_width_property_
Definition: path_display.h:95
Several reusable pieces for displaying polygons.
virtual FrameManager * getFrameManager() const =0
rviz::FloatProperty * pose_arrow_shaft_length_property_
Definition: path_display.h:104
std::vector< rviz::BillboardLine * > billboard_lines_
Definition: path_display.h:88
rviz::FloatProperty * pose_arrow_head_length_property_
Definition: path_display.h:105
void setNumLines(uint32_t num)
void setMaxPointsPerLine(uint32_t max)
Ogre::SceneManager * scene_manager_
rviz::FloatProperty * alpha_property_
Definition: path_display.h:94
rviz::FloatProperty * pose_arrow_shaft_diameter_property_
Definition: path_display.h:106
virtual void queueRender()=0
virtual Ogre::Vector3 getVector() const
rviz::EnumProperty * pose_style_property_
Definition: path_display.h:100
bool getTransform(const Header &header, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
bool validateFloats(const nav_grid::NavGridInfo &info)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
void allocateArrowVector(std::vector< rviz::Arrow * > &arrow_vect, int num)
void processMessage(const nav_2d_msgs::Path2D::ConstPtr &msg) override
virtual void setStatus(StatusProperty::Level level, const QString &name, const QString &text)
void setLineWidth(float width)
#define ROS_DEBUG(...)


robot_nav_rviz_plugins
Author(s):
autogenerated on Sun Jan 10 2021 04:08:58