tf_display.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <boost/bind.hpp>
31 #include <regex>
32 
33 #include <OgreSceneNode.h>
34 #include <OgreSceneManager.h>
35 #include <QValidator>
36 #include <QLineEdit>
37 #include <QToolTip>
38 
39 #include <tf/transform_listener.h>
40 
41 #include "rviz/display_context.h"
42 #include "rviz/frame_manager.h"
44 #include "rviz/ogre_helpers/axes.h"
53 
55 
56 namespace rviz
57 {
59 {
60 public:
61  FrameSelectionHandler(FrameInfo* frame, TFDisplay* display, DisplayContext* context);
63  {
64  }
65 
66  void createProperties(const Picked& obj, Property* parent_property) override;
67  void destroyProperties(const Picked& obj, Property* parent_property) override;
68 
69  bool getEnabled();
70  void setEnabled(bool enabled);
71  void setParentName(std::string parent_name);
72  void setPosition(const Ogre::Vector3& position);
73  void setOrientation(const Ogre::Quaternion& orientation);
74 
75 private:
83 };
84 
86  TFDisplay* display,
87  DisplayContext* context)
88  : SelectionHandler(context)
89  , frame_(frame)
90  , display_(display)
91  , category_property_(nullptr)
92  , enabled_property_(nullptr)
93  , parent_property_(nullptr)
94  , position_property_(nullptr)
95  , orientation_property_(nullptr)
96 {
97 }
98 
99 void FrameSelectionHandler::createProperties(const Picked& /*obj*/, Property* parent_property)
100 {
102  new Property("Frame " + QString::fromStdString(frame_->name_), QVariant(), "", parent_property);
103 
104  enabled_property_ = new BoolProperty("Enabled", true, "", category_property_,
105  SLOT(updateVisibilityFromSelection()), frame_);
106 
107  parent_property_ = new StringProperty("Parent", "", "", category_property_);
109 
110  position_property_ = new VectorProperty("Position", Ogre::Vector3::ZERO, "", category_property_);
112 
114  new QuaternionProperty("Orientation", Ogre::Quaternion::IDENTITY, "", category_property_);
116 }
117 
118 void FrameSelectionHandler::destroyProperties(const Picked& /*obj*/, Property* /*parent_property*/)
119 {
120  delete category_property_; // This deletes its children as well.
121  category_property_ = nullptr;
122  enabled_property_ = nullptr;
123  parent_property_ = nullptr;
124  position_property_ = nullptr;
125  orientation_property_ = nullptr;
126 }
127 
129 {
130  if (enabled_property_)
131  {
132  return enabled_property_->getBool();
133  }
134  return false; // should never happen, but don't want to crash if it does.
135 }
136 
138 {
139  if (enabled_property_)
140  {
141  enabled_property_->setBool(enabled);
142  }
143 }
144 
145 void FrameSelectionHandler::setParentName(std::string parent_name)
146 {
147  if (parent_property_)
148  {
149  parent_property_->setStdString(parent_name);
150  }
151 }
152 
153 void FrameSelectionHandler::setPosition(const Ogre::Vector3& position)
154 {
155  if (position_property_)
156  {
157  position_property_->setVector(position);
158  }
159 }
160 
161 void FrameSelectionHandler::setOrientation(const Ogre::Quaternion& orientation)
162 {
164  {
165  orientation_property_->setQuaternion(orientation);
166  }
167 }
168 
169 class RegexValidator : public QValidator
170 {
171  QLineEdit* editor_;
172 
173 public:
174  RegexValidator(QLineEdit* editor) : QValidator(editor), editor_(editor)
175  {
176  }
177  QValidator::State validate(QString& input, int& /*pos*/) const override
178  {
179  try
180  {
181  std::regex(input.toLocal8Bit().constData());
182  editor_->setStyleSheet(QString());
183  QToolTip::hideText();
184  return QValidator::Acceptable;
185  }
186  catch (const std::regex_error& e)
187  {
188  editor_->setStyleSheet("background: #ffe4e4");
189  QToolTip::showText(editor_->mapToGlobal(QPoint(0, 5)), tr(e.what()), editor_, QRect(), 5000);
190  return QValidator::Intermediate;
191  }
192  }
193 };
194 
196 {
197  std::regex default_;
198  std::regex regex_;
199 
201  {
202  const auto& value = getString();
203  if (value.isEmpty())
204  regex_ = default_;
205  else
206  {
207  try
208  {
209  regex_.assign(value.toLocal8Bit().constData(), std::regex_constants::optimize);
210  }
211  catch (const std::regex_error& e)
212  {
213  regex_ = default_;
214  }
215  }
216  }
217 
218 public:
219  RegexFilterProperty(const QString& name, const std::regex& regex, Property* parent)
220  : StringProperty(name, "", "regular expression", parent), default_(regex), regex_(regex)
221  {
222  QObject::connect(this, &RegexFilterProperty::changed, this, [this]() { onValueChanged(); });
223  }
224  const std::regex& regex() const
225  {
226  return regex_;
227  }
228 
229  QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option) override
230  {
231  auto* editor = qobject_cast<QLineEdit*>(StringProperty::createEditor(parent, option));
232  if (editor)
233  editor->setValidator(new RegexValidator(editor));
234  return editor;
235  }
236 };
237 
238 typedef std::set<FrameInfo*> S_FrameInfo;
239 
240 TFDisplay::TFDisplay() : Display(), update_timer_(0.0f), changing_single_frame_enabled_state_(false)
241 {
243  new BoolProperty("Show Names", true, "Whether or not names should be shown next to the frames.",
244  this, SLOT(updateShowNames()));
245 
247  new BoolProperty("Show Axes", true, "Whether or not the axes of each frame should be shown.", this,
248  SLOT(updateShowAxes()));
249 
250  show_arrows_property_ = new BoolProperty("Show Arrows", true,
251  "Whether or not arrows from child to parent should be shown.",
252  this, SLOT(updateShowArrows()));
253 
255  new FloatProperty("Marker Scale", 1, "Scaling factor for all names, axes and arrows.", this);
256 
257  update_rate_property_ = new FloatProperty("Update Interval", 0,
258  "The interval, in seconds, at which to update the frame "
259  "transforms. 0 means to do so every update cycle.",
260  this);
262 
264  "Frame Timeout", 15,
265  "The length of time, in seconds, before a frame that has not been updated is considered \"dead\"."
266  " For 1/3 of this time the frame will appear correct, for the second 1/3rd it will fade to gray,"
267  " and then it will fade out completely.",
268  this);
270 
271  filter_whitelist_property_ = new RegexFilterProperty("Filter (whitelist)", std::regex(""), this);
272  filter_blacklist_property_ = new RegexFilterProperty("Filter (blacklist)", std::regex(), this);
273 
274  frames_category_ = new Property("Frames", QVariant(), "The list of all frames.", this);
275 
277  new BoolProperty("All Enabled", true, "Whether all the frames should be enabled or not.",
278  frames_category_, SLOT(allEnabledChanged()), this);
279 
280  tree_category_ = new Property(
281  "Tree", QVariant(), "A tree-view of the frames, showing the parent/child relationships.", this);
282 }
283 
285 {
286  clear();
287  if (initialized())
288  {
289  root_node_->removeAndDestroyAllChildren();
290  scene_manager_->destroySceneNode(root_node_);
291  }
292 }
293 
295 {
297 
298  root_node_ = scene_node_->createChildSceneNode();
299 
300  names_node_ = root_node_->createChildSceneNode();
301  arrows_node_ = root_node_->createChildSceneNode();
302  axes_node_ = root_node_->createChildSceneNode();
303 }
304 
305 void TFDisplay::load(const Config& config)
306 {
307  Display::load(config);
308 
309  // Load the enabled state for all frames specified in the config, and store
310  // the values in a map so that the enabled state can be properly set once
311  // the frame is created
312  Config c = config.mapGetChild("Frames");
313  for (Config::MapIterator iter = c.mapIterator(); iter.isValid(); iter.advance())
314  {
315  QString key = iter.currentKey();
316  if (key != "All Enabled")
317  {
318  const Config& child = iter.currentChild();
319  bool enabled = child.mapGetChild("Value").getValue().toBool();
320 
321  frame_config_enabled_state_[key.toStdString()] = enabled;
322  }
323  }
324 }
325 
327 {
328  // Clear the tree.
330 
331  // Clear the frames category, except for the "All enabled" property, which is first.
333 
334  // Clear all frames
335  while (!frames_.empty())
336  deleteFrame(frames_.begin(), false);
337 
338  update_timer_ = 0.0f;
339 
340  clearStatuses();
341 }
342 
344 {
345  root_node_->setVisible(true);
346 
347  names_node_->setVisible(show_names_property_->getBool());
349  axes_node_->setVisible(show_axes_property_->getBool());
350 }
351 
353 {
354  root_node_->setVisible(false);
355  clear();
356 }
357 
359 {
360  names_node_->setVisible(show_names_property_->getBool());
361 
362  M_FrameInfo::iterator it = frames_.begin();
363  M_FrameInfo::iterator end = frames_.end();
364  for (; it != end; ++it)
365  {
366  FrameInfo* frame = it->second;
367 
368  frame->updateVisibilityFromFrame();
369  }
370 }
371 
373 {
374  axes_node_->setVisible(show_axes_property_->getBool());
375 
376  M_FrameInfo::iterator it = frames_.begin();
377  M_FrameInfo::iterator end = frames_.end();
378  for (; it != end; ++it)
379  {
380  FrameInfo* frame = it->second;
381 
382  frame->updateVisibilityFromFrame();
383  }
384 }
385 
387 {
389 
390  M_FrameInfo::iterator it = frames_.begin();
391  M_FrameInfo::iterator end = frames_.end();
392  for (; it != end; ++it)
393  {
394  FrameInfo* frame = it->second;
395 
396  frame->updateVisibilityFromFrame();
397  }
398 }
399 
401 {
403  {
404  return;
405  }
406  bool enabled = all_enabled_property_->getBool();
407 
408  M_FrameInfo::iterator it = frames_.begin();
409  M_FrameInfo::iterator end = frames_.end();
410  for (; it != end; ++it)
411  {
412  FrameInfo* frame = it->second;
413 
414  frame->enabled_property_->setBool(enabled);
415  }
416 }
417 
418 void TFDisplay::update(float wall_dt, float /*ros_dt*/)
419 {
420  update_timer_ += wall_dt;
421  float update_rate = update_rate_property_->getFloat();
422  if (update_rate < 0.0001f || update_timer_ > update_rate)
423  {
424  updateFrames();
425 
426  update_timer_ = 0.0f;
427  }
428 }
429 
430 FrameInfo* TFDisplay::getFrameInfo(const std::string& frame)
431 {
432  M_FrameInfo::iterator it = frames_.find(frame);
433  if (it == frames_.end())
434  {
435  return nullptr;
436  }
437 
438  return it->second;
439 }
440 
442 {
443  typedef std::vector<std::string> V_string;
444  V_string frames;
445 // TODO(wjwwood): remove this and use tf2 interface instead
446 #ifndef _WIN32
447 #pragma GCC diagnostic push
448 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
449 #endif
450 
452 
453 #ifndef _WIN32
454 #pragma GCC diagnostic pop
455 #endif
456 
457  // filter frames according to white- and black-list regular expressions
458  auto it = frames.begin(), end = frames.end();
459  while (it != end)
460  {
461  if (it->empty() || !std::regex_search(*it, filter_whitelist_property_->regex()) ||
462  std::regex_search(*it, filter_blacklist_property_->regex()))
463  std::swap(*it, *--end); // swap current to-be-dropped name with last one
464  else
465  ++it;
466  }
467 
468  S_FrameInfo current_frames;
469  for (it = frames.begin(); it != end; ++it)
470  {
471  FrameInfo* info = getFrameInfo(*it);
472  if (!info)
473  {
474  info = createFrame(*it);
475  }
476  else
477  {
478  updateFrame(info);
479  }
480 
481  current_frames.insert(info);
482  }
483 
484  for (auto frame_it = frames_.begin(), frame_end = frames_.end(); frame_it != frame_end;)
485  {
486  if (current_frames.find(frame_it->second) == current_frames.end())
487  frame_it = deleteFrame(frame_it, true);
488  else
489  ++frame_it;
490  }
491 
493 }
494 
495 static const Ogre::ColourValue ARROW_HEAD_COLOR(1.0f, 0.1f, 0.6f, 1.0f);
496 static const Ogre::ColourValue ARROW_SHAFT_COLOR(0.8f, 0.8f, 0.3f, 1.0f);
497 
498 FrameInfo* TFDisplay::createFrame(const std::string& frame)
499 {
500  FrameInfo* info = new FrameInfo(this);
501  frames_.insert(std::make_pair(frame, info));
502 
503  info->name_ = frame;
504  info->last_update_ = ros::Time::now();
505  info->axes_ = new Axes(scene_manager_, axes_node_, 0.2, 0.02);
506  info->axes_->getSceneNode()->setVisible(show_axes_property_->getBool());
507  info->selection_handler_.reset(new FrameSelectionHandler(info, this, context_));
508  info->selection_handler_->addTrackedObjects(info->axes_->getSceneNode());
509 
510  info->name_text_ = new MovableText(frame, "Liberation Sans", 0.1);
512  info->name_node_ = names_node_->createChildSceneNode();
513  info->name_node_->attachObject(info->name_text_);
514  info->name_node_->setVisible(show_names_property_->getBool());
515 
516  info->parent_arrow_ = new Arrow(scene_manager_, arrows_node_, 1.0f, 0.01, 1.0f, 0.08);
517  info->parent_arrow_->getSceneNode()->setVisible(false);
518  info->parent_arrow_->setHeadColor(ARROW_HEAD_COLOR);
519  info->parent_arrow_->setShaftColor(ARROW_SHAFT_COLOR);
520 
521  info->enabled_property_ = new BoolProperty(QString::fromStdString(info->name_), true,
522  "Enable or disable this individual frame.", nullptr,
523  SLOT(updateVisibilityFromFrame()), info);
525 
526  info->parent_property_ =
527  new StringProperty("Parent", "", "Parent of this frame. (Not editable)", info->enabled_property_);
528  info->parent_property_->setReadOnly(true);
529 
530  info->position_property_ =
531  new VectorProperty("Position", Ogre::Vector3::ZERO,
532  "Position of this frame, in the current Fixed Frame. (Not editable)",
533  info->enabled_property_);
534  info->position_property_->setReadOnly(true);
535 
536  info->orientation_property_ =
537  new QuaternionProperty("Orientation", Ogre::Quaternion::IDENTITY,
538  "Orientation of this frame, in the current Fixed Frame. (Not editable)",
539  info->enabled_property_);
540  info->orientation_property_->setReadOnly(true);
541 
542  info->rel_position_property_ =
543  new VectorProperty("Relative Position", Ogre::Vector3::ZERO,
544  "Position of this frame, relative to it's parent frame. (Not editable)",
545  info->enabled_property_);
546  info->rel_position_property_->setReadOnly(true);
547 
549  new QuaternionProperty("Relative Orientation", Ogre::Quaternion::IDENTITY,
550  "Orientation of this frame, relative to it's parent frame. (Not editable)",
551  info->enabled_property_);
553 
554  // If the current frame was specified as disabled in the config file
555  // then its enabled state must be updated accordingly
556  if (frame_config_enabled_state_.count(frame) > 0 && !frame_config_enabled_state_[frame])
557  {
558  info->enabled_property_->setBool(false);
559  }
560 
561  updateFrame(info);
562 
563  return info;
564 }
565 
566 Ogre::ColourValue lerpColor(const Ogre::ColourValue& start, const Ogre::ColourValue& end, float t)
567 {
568  return start * t + end * (1 - t);
569 }
570 
572 {
573 // TODO(wjwwood): remove this and use tf2 interface instead
574 #ifndef _WIN32
575 #pragma GCC diagnostic push
576 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
577 #endif
578 
580 
581 #ifndef _WIN32
582 #pragma GCC diagnostic pop
583 #endif
584 
585  // Check last received time so we can grey out/fade out frames that have stopped being published
586  ros::Time latest_time;
587  tf->getLatestCommonTime(fixed_frame_.toStdString(), frame->name_, latest_time, nullptr);
588 
589  if ((latest_time != frame->last_time_to_fixed_) || (latest_time == ros::Time()))
590  {
591  frame->last_update_ = ros::Time::now();
592  frame->last_time_to_fixed_ = latest_time;
593  }
594 
595  // Fade from color -> grey, then grey -> fully transparent
596  ros::Duration age = ros::Time::now() - frame->last_update_;
597  float frame_timeout = frame_timeout_property_->getFloat();
598  float one_third_timeout = frame_timeout * 0.3333333f;
599  if (age > ros::Duration(frame_timeout))
600  {
601  frame->parent_arrow_->getSceneNode()->setVisible(false);
602  frame->axes_->getSceneNode()->setVisible(false);
603  frame->name_node_->setVisible(false);
604  return;
605  }
606  else if (age > ros::Duration(one_third_timeout))
607  {
608  Ogre::ColourValue grey(0.7, 0.7, 0.7, 1.0);
609 
610  if (age > ros::Duration(one_third_timeout * 2))
611  {
612  float a = std::max(0.0, (frame_timeout - age.toSec()) / one_third_timeout);
613  Ogre::ColourValue c = Ogre::ColourValue(grey.r, grey.g, grey.b, a);
614 
615  frame->axes_->setXColor(c);
616  frame->axes_->setYColor(c);
617  frame->axes_->setZColor(c);
618  frame->name_text_->setColor(c);
619  frame->parent_arrow_->setColor(c.r, c.g, c.b, c.a);
620  }
621  else
622  {
623  float t = std::max(0.0, (one_third_timeout * 2 - age.toSec()) / one_third_timeout);
624  frame->axes_->setXColor(lerpColor(frame->axes_->getDefaultXColor(), grey, t));
625  frame->axes_->setYColor(lerpColor(frame->axes_->getDefaultYColor(), grey, t));
626  frame->axes_->setZColor(lerpColor(frame->axes_->getDefaultZColor(), grey, t));
627  frame->name_text_->setColor(lerpColor(Ogre::ColourValue::White, grey, t));
628  frame->parent_arrow_->setShaftColor(lerpColor(ARROW_SHAFT_COLOR, grey, t));
629  frame->parent_arrow_->setHeadColor(lerpColor(ARROW_HEAD_COLOR, grey, t));
630  }
631  }
632  else
633  {
634  frame->axes_->setToDefaultColors();
635  frame->name_text_->setColor(Ogre::ColourValue::White);
636  frame->parent_arrow_->setHeadColor(ARROW_HEAD_COLOR);
637  frame->parent_arrow_->setShaftColor(ARROW_SHAFT_COLOR);
638  }
639 
640  setStatusStd(StatusProperty::Ok, frame->name_, "Transform OK");
641 
642  float scale = scale_property_->getFloat();
643  bool frame_enabled = frame->enabled_property_->getBool();
644 
645  Ogre::Vector3 position;
646  Ogre::Quaternion orientation;
647  if (!context_->getFrameManager()->getTransform(frame->name_, ros::Time(), position, orientation))
648  {
649  std::stringstream ss;
650  ss << "No transform from [" << frame->name_ << "] to frame [" << fixed_frame_.toStdString() << "]";
651  setStatusStd(StatusProperty::Warn, frame->name_, ss.str());
652  ROS_DEBUG("Error transforming frame '%s' to frame '%s'", frame->name_.c_str(),
653  qPrintable(fixed_frame_));
654  frame->name_node_->setVisible(false);
655  frame->axes_->getSceneNode()->setVisible(false);
656  frame->parent_arrow_->getSceneNode()->setVisible(false);
657  }
658  else
659  {
660  frame->selection_handler_->setPosition(position);
661  frame->selection_handler_->setOrientation(orientation);
662 
663  frame->axes_->setPosition(position);
664  frame->axes_->setOrientation(orientation);
665  frame->axes_->getSceneNode()->setVisible(show_axes_property_->getBool() && frame_enabled);
666  frame->axes_->setScale(Ogre::Vector3(scale, scale, scale));
667 
668  frame->name_node_->setPosition(position);
669  frame->name_node_->setVisible(show_names_property_->getBool() && frame_enabled);
670  frame->name_node_->setScale(scale, scale, scale);
671 
672  frame->position_property_->setVector(position);
673  frame->orientation_property_->setQuaternion(orientation);
674  }
675 
676  std::string old_parent = frame->parent_;
677  frame->parent_.clear();
678  bool has_parent = tf->getParent(frame->name_, ros::Time(), frame->parent_);
679  if (has_parent)
680  {
681  tf::StampedTransform transform;
682  try
683  {
684 // TODO(wjwwood): remove this and use tf2 interface instead
685 #ifndef _WIN32
686 #pragma GCC diagnostic push
687 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
688 #endif
689 
690  auto tf_client = context_->getFrameManager()->getTFClientPtr();
691 
692 #ifndef _WIN32
693 #pragma GCC diagnostic pop
694 #endif
695  tf_client->lookupTransform(frame->parent_, frame->name_, ros::Time(0), transform);
696  }
697  catch (tf::TransformException& e)
698  {
699  ROS_DEBUG("Error transforming frame '%s' (parent of '%s') to frame '%s'", frame->parent_.c_str(),
700  frame->name_.c_str(), qPrintable(fixed_frame_));
701  }
702 
703  // get the position/orientation relative to the parent frame
704  Ogre::Vector3 relative_position(transform.getOrigin().x(), transform.getOrigin().y(),
705  transform.getOrigin().z());
706  Ogre::Quaternion relative_orientation(transform.getRotation().w(), transform.getRotation().x(),
707  transform.getRotation().y(), transform.getRotation().z());
708  frame->rel_position_property_->setVector(relative_position);
709  frame->rel_orientation_property_->setQuaternion(relative_orientation);
710 
712  {
713  Ogre::Vector3 parent_position;
714  Ogre::Quaternion parent_orientation;
715  if (!context_->getFrameManager()->getTransform(frame->parent_, ros::Time(), parent_position,
716  parent_orientation))
717  {
718  ROS_DEBUG("Error transforming frame '%s' (parent of '%s') to frame '%s'", frame->parent_.c_str(),
719  frame->name_.c_str(), qPrintable(fixed_frame_));
720  }
721 
722  Ogre::Vector3 direction = parent_position - position;
723  float distance = direction.length();
724  direction.normalise();
725 
726  Ogre::Quaternion orient = Ogre::Vector3::NEGATIVE_UNIT_Z.getRotationTo(direction);
727 
728  frame->distance_to_parent_ = distance;
729  float head_length = (distance < 0.1 * scale) ? (0.1 * scale * distance) : 0.1 * scale;
730  float shaft_length = distance - head_length;
731  // aleeper: This was changed from 0.02 and 0.08 to 0.01 and 0.04 to match proper radius handling in
732  // arrow.cpp
733  frame->parent_arrow_->set(shaft_length, 0.01 * scale, head_length, 0.04 * scale);
734 
735  if (distance > 0.001f)
736  {
737  frame->parent_arrow_->getSceneNode()->setVisible(show_arrows_property_->getBool() &&
738  frame_enabled);
739  }
740  else
741  {
742  frame->parent_arrow_->getSceneNode()->setVisible(false);
743  }
744 
745  frame->parent_arrow_->setPosition(position);
746  frame->parent_arrow_->setOrientation(orient);
747  }
748  else
749  {
750  frame->parent_arrow_->getSceneNode()->setVisible(false);
751  }
752  }
753  else
754  {
755  frame->parent_arrow_->getSceneNode()->setVisible(false);
756  }
757 
758  // If this frame has no tree property yet or the parent has changed,
759  if (!frame->tree_property_ || old_parent != frame->parent_ ||
760  // or its actual parent was not yet created
761  (has_parent && frame->tree_property_->getParent() == tree_category_))
762  {
763  // Look up the new parent.
764  FrameInfo* parent = has_parent ? getFrameInfo(frame->parent_) : nullptr;
765  // Retrieve tree property to add the new child at
766  rviz::Property* parent_tree_property;
767  if (parent && parent->tree_property_) // parent already created
768  parent_tree_property = parent->tree_property_;
769  else // create (temporarily) at root
770  parent_tree_property = tree_category_;
771 
772  if (!frame->tree_property_)
773  { // create new tree node
774  frame->tree_property_ = new Property(QString::fromStdString(frame->name_));
775  parent_tree_property->insertChildSorted(frame->tree_property_);
776  }
777  else if (frame->tree_property_->getParent() != parent_tree_property)
778  { // re-parent existing tree property
780  parent_tree_property->insertChildSorted(frame->tree_property_);
781  }
782  }
783 
784  frame->parent_property_->setStdString(frame->parent_);
785  frame->selection_handler_->setParentName(frame->parent_);
786 }
787 
788 TFDisplay::M_FrameInfo::iterator TFDisplay::deleteFrame(M_FrameInfo::iterator it, bool delete_properties)
789 {
790  FrameInfo* frame = it->second;
791  it = frames_.erase(it);
792 
793  delete frame->axes_;
795  delete frame->parent_arrow_;
796  delete frame->name_text_;
797  scene_manager_->destroySceneNode(frame->name_node_->getName());
798  if (delete_properties)
799  {
800  delete frame->enabled_property_;
801  // re-parent all children to root tree node
802  for (int i = frame->tree_property_->numChildren() - 1; i >= 0; --i)
803  {
804  auto* child = frame->tree_property_->takeChild(frame->tree_property_->childAtUnchecked(i));
806  }
807  delete frame->tree_property_;
808  }
809  delete frame;
810  return it;
811 }
812 
814 {
816 }
817 
819 {
820  Display::reset();
821  clear();
822 }
823 
825 // FrameInfo
826 
828  : display_(display)
829  , axes_(nullptr)
830  , axes_coll_(0)
831  , parent_arrow_(nullptr)
832  , name_text_(nullptr)
833  , distance_to_parent_(0.0f)
834  , arrow_orientation_(Ogre::Quaternion::IDENTITY)
835  , tree_property_(nullptr)
836 {
837 }
838 
840 {
841  bool enabled = enabled_property_->getBool();
842  selection_handler_->setEnabled(enabled);
843  setEnabled(enabled);
844 }
845 
847 {
848  bool enabled = selection_handler_->getEnabled();
849  enabled_property_->setBool(enabled);
850  setEnabled(enabled);
851 }
852 
853 void FrameInfo::setEnabled(bool enabled)
854 {
855  if (name_node_)
856  {
857  name_node_->setVisible(display_->show_names_property_->getBool() && enabled);
858  }
859 
860  if (axes_)
861  {
862  axes_->getSceneNode()->setVisible(display_->show_axes_property_->getBool() && enabled);
863  }
864 
865  if (parent_arrow_)
866  {
867  if (distance_to_parent_ > 0.001f)
868  {
869  parent_arrow_->getSceneNode()->setVisible(display_->show_arrows_property_->getBool() && enabled);
870  }
871  else
872  {
873  parent_arrow_->getSceneNode()->setVisible(false);
874  }
875  }
876 
877  if (display_->all_enabled_property_->getBool() && !enabled)
878  {
882  }
883 
884  // Update the configuration that stores the enabled state of all frames
885  display_->frame_config_enabled_state_[this->name_] = enabled;
886 
888 }
889 
890 } // namespace rviz
891 
bool getParent(const std::string &frame_id, ros::Time time, std::string &parent) const
Ogre::ColourValue lerpColor(const Ogre::ColourValue &start, const Ogre::ColourValue &end, float t)
Definition: tf_display.cpp:566
Property * frames_category_
Definition: tf_display.h:125
void setStatusStd(StatusProperty::Level level, const std::string &name, const std::string &text)
Show status level and text, using a std::string. Convenience function which converts std::string to Q...
Definition: display.h:163
FrameInfo(TFDisplay *display)
Definition: tf_display.cpp:827
void setMin(float min)
FloatProperty * scale_property_
Definition: tf_display.h:122
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation of the object.
Definition: axes.cpp:88
bool changing_single_frame_enabled_state_
Definition: tf_display.h:128
void updateVisibilityFromSelection()
Update whether the frame is visible or not, based on the enabled_property_ in the selection handler...
Definition: tf_display.cpp:846
void reset() override
Called to tell the display to clear its state.
Definition: tf_display.cpp:818
std::string name_
Definition: tf_display.h:153
BoolProperty * show_arrows_property_
Definition: tf_display.h:116
virtual bool setVector(const Ogre::Vector3 &vector)
Quaternion getRotation() const
RegexFilterProperty(const QString &name, const std::regex &regex, Property *parent)
Definition: tf_display.cpp:219
Ogre::SceneNode * root_node_
Definition: tf_display.h:103
f
virtual tf::TransformListener * getTFClient() const =0
Convenience function: returns getFrameManager()->getTFClient().
std::set< FrameInfo * > S_FrameInfo
Definition: tf_display.cpp:238
QVariant getValue() const
If this config object is valid and is a Value type, this returns its value. Otherwise it returns an i...
Definition: config.cpp:324
StringProperty * parent_property_
Definition: tf_display.cpp:80
DisplayContext * context_
This DisplayContext pointer is the main connection a Display has into the rest of rviz...
Definition: display.h:287
void changed()
Emitted by setValue() just after the value has changed.
Property * getParent() const
Return the parent Property.
Definition: property.cpp:231
M_FrameInfo::iterator deleteFrame(M_FrameInfo::iterator it, bool delete_properties)
Definition: tf_display.cpp:788
void updateShowNames()
Definition: tf_display.cpp:358
RegexValidator(QLineEdit *editor)
Definition: tf_display.cpp:174
Ogre::SceneNode * names_node_
Definition: tf_display.h:104
StringProperty * parent_property_
Definition: tf_display.h:172
void setPosition(const Ogre::Vector3 &position) override
Set the position of the base of the arrow.
Definition: arrow.cpp:114
Property * tree_category_
Definition: tf_display.h:126
void setEnabled(bool enabled)
Definition: tf_display.cpp:137
Ogre::SceneNode * arrows_node_
Definition: tf_display.h:105
Displays a visual representation of the TF hierarchy.
Definition: tf_display.h:65
A single element of a property tree, with a name, value, description, and possibly children...
Definition: property.h:100
float distance_to_parent_
Definition: tf_display.h:162
void setReadOnly(bool read_only) override
Overridden from Property to propagate read-only-ness to children.
M_EnabledState frame_config_enabled_state_
Definition: tf_display.h:111
static const Ogre::ColourValue & getDefaultYColor()
Definition: axes.cpp:151
void removeObject(CollObjectHandle obj)
ros::Time last_update_
Definition: tf_display.h:165
void load(const Config &config) override
Load the settings for this display from the given Config node, which must be a map.
Definition: display.cpp:228
void updateShowAxes()
Definition: tf_display.cpp:372
void allEnabledChanged()
Definition: tf_display.cpp:400
Internal class needed only by TFDisplay.
Definition: tf_display.h:133
void updateShowArrows()
Definition: tf_display.cpp:386
FrameSelectionHandler(FrameInfo *frame, TFDisplay *display, DisplayContext *context)
Definition: tf_display.cpp:85
bool isValid()
Return true if the iterator currently points to a valid entry, false if not.
Definition: config.cpp:397
Config mapGetChild(const QString &key) const
If the referenced Node is a Map and it has a child with the given key, return a reference to the chil...
Definition: config.cpp:212
void setZColor(const Ogre::ColourValue &col)
Definition: axes.cpp:130
static const Ogre::ColourValue & getDefaultXColor()
Definition: axes.cpp:146
const std::regex & regex() const
Definition: tf_display.cpp:224
Property specialized to enforce floating point max/min.
void set(float shaft_length, float shaft_diameter, float head_length, float head_diameter)
Set the parameters for this arrow.
Definition: arrow.cpp:74
BoolProperty * show_names_property_
Definition: tf_display.h:115
VectorProperty * rel_position_property_
Definition: tf_display.h:168
void setReadOnly(bool read_only) override
Overridden from Property to propagate read-only-ness to children.
geometry_msgs::TransformStamped t
void setYColor(const Ogre::ColourValue &col)
Definition: axes.cpp:125
Ogre::SceneNode * scene_node_
The Ogre::SceneNode to hold all 3D scene elements shown by this Display.
Definition: display.h:295
Ogre::SceneNode * getSceneNode()
Get the scene node associated with this arrow.
Definition: arrow.h:149
static const Ogre::ColourValue ARROW_SHAFT_COLOR(0.8f, 0.8f, 0.3f, 1.0f)
void createProperties(const Picked &obj, Property *parent_property) override
Override to create properties of the given picked object(s).
Definition: tf_display.cpp:99
Property * takeChild(Property *child)
Remove a given child object and return a pointer to it.
Definition: property.cpp:321
Configuration data storage class.
Definition: config.h:124
VectorProperty * position_property_
Definition: tf_display.h:170
QString fixed_frame_
A convenience variable equal to context_->getFixedFrame().
Definition: display.h:312
void updateFrame(FrameInfo *frame)
Definition: tf_display.cpp:571
FrameInfo * getFrameInfo(const std::string &frame)
Definition: tf_display.cpp:430
QuaternionProperty * rel_orientation_property_
Definition: tf_display.h:169
void destroyProperties(const Picked &obj, Property *parent_property) override
Destroy all properties for the given picked object(s).
Definition: tf_display.cpp:118
void setXColor(const Ogre::ColourValue &col)
Definition: axes.cpp:120
static const Ogre::ColourValue ARROW_HEAD_COLOR(1.0f, 0.1f, 0.6f, 1.0f)
virtual void removeChildren(int start_index=0, int count=-1)
Remove and delete some or all child Properties. Does not change the value of this Property...
Definition: property.cpp:104
Pure-virtual base class for objects which give Display subclasses context in which to work...
virtual void clearStatuses()
Delete all status children. This is thread-safe.
Definition: display.cpp:210
CollObjectHandle axes_coll_
Definition: tf_display.h:156
std::string parent_
Definition: tf_display.h:154
virtual void reset()
Called to tell the display to clear its state.
Definition: display.cpp:287
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option) override
Create an editor widget to edit the value of this property.
Definition: tf_display.cpp:229
const boost::shared_ptr< tf::TransformListener > & getTFClientPtr()
Return a boost shared pointer to the tf::TransformListener used to receive transform data...
void setToDefaultColors()
Definition: axes.cpp:135
void onDisable() override
Derived classes override this to do the actual work of disabling themselves.
Definition: tf_display.cpp:352
void updateVisibilityFromFrame()
Update whether the frame is visible or not, based on the enabled_property_ in this FrameInfo...
Definition: tf_display.cpp:839
QValidator::State validate(QString &input, int &) const override
Definition: tf_display.cpp:177
BoolProperty * all_enabled_property_
Definition: tf_display.h:120
BoolProperty * enabled_property_
Definition: tf_display.cpp:79
Ogre::SceneNode * axes_node_
Definition: tf_display.h:106
Iterator class for looping over all entries in a Map type Config Node.
Definition: config.h:288
virtual bool setQuaternion(const Ogre::Quaternion &quaternion)
void setEnabled(bool enabled)
Set this frame to be visible or invisible.
Definition: tf_display.cpp:853
virtual FrameManager * getFrameManager() const =0
Return the FrameManager instance.
virtual SelectionManager * getSelectionManager() const =0
Return a pointer to the SelectionManager.
BoolProperty * enabled_property_
Definition: tf_display.h:173
RegexFilterProperty * filter_whitelist_property_
Definition: tf_display.h:123
TFDisplay * display_
Definition: tf_display.h:152
Property(const QString &name=QString(), const QVariant default_value=QVariant(), const QString &description=QString(), Property *parent=nullptr, const char *changed_slot=nullptr, QObject *receiver=nullptr)
Constructor.
Definition: property.cpp:58
void setOrientation(const Ogre::Quaternion &orientation)
Definition: tf_display.cpp:161
float update_timer_
Definition: tf_display.h:113
void setParentName(std::string parent_name)
Definition: tf_display.cpp:145
~TFDisplay() override
Definition: tf_display.cpp:284
void setTextAlignment(const HorizontalAlignment &horizontalAlignment, const VerticalAlignment &verticalAlignment)
void setShaftColor(float r, float g, float b, float a=1.0f)
Set the color of the arrow&#39;s shaft. Values are in the range [0, 1].
Definition: arrow.cpp:104
Ogre::SceneNode * name_node_
Definition: tf_display.h:160
An object that displays a set of X/Y/Z axes, with X=Red, Y=Green, Z=Blue.
Definition: axes.h:59
std::vector< std::string > V_string
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
Ogre::SceneManager * scene_manager_
A convenience variable equal to context_->getSceneManager().
Definition: display.h:292
FrameSelectionHandlerPtr selection_handler_
Definition: tf_display.h:157
void insertChildSorted(Property *child)
Insert a child property, sorted by name.
Definition: property.cpp:384
void getFrameStrings(std::vector< std::string > &ids) const
FrameInfo * createFrame(const std::string &frame)
Definition: tf_display.cpp:498
RegexFilterProperty * filter_blacklist_property_
Definition: tf_display.h:124
VectorProperty * position_property_
Definition: tf_display.cpp:81
void setPosition(const Ogre::Vector3 &position) override
Set the position of this object.
Definition: axes.cpp:83
BoolProperty(const QString &name=QString(), bool default_value=false, const QString &description=QString(), Property *parent=nullptr, const char *changed_slot=nullptr, QObject *receiver=nullptr)
FloatProperty * update_rate_property_
Definition: tf_display.h:118
int getLatestCommonTime(const std::string &source_frame, const std::string &target_frame, ros::Time &time, std::string *error_string) const
Property specialized for string values.
MovableText * name_text_
Definition: tf_display.h:159
virtual int numChildren() const
Return the number of child objects (Property or otherwise).
Definition: property.h:227
virtual void queueRender()=0
Queues a render. Multiple calls before a render happens will only cause a single render.
BoolProperty * show_axes_property_
Definition: tf_display.h:117
void setColor(const Ogre::ColourValue &color)
Property specialized to provide getter for booleans.
Definition: bool_property.h:38
void onInitialize() override
Override this function to do subclass-specific initialization.
Definition: tf_display.cpp:294
virtual Property * childAtUnchecked(int index) const
Return the child Property with the given index, without checking whether the index is within bounds...
Definition: property.cpp:213
virtual float getFloat() const
void setPosition(const Ogre::Vector3 &position)
Definition: tf_display.cpp:153
bool getTransform(const Header &header, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
Return the pose for a header, relative to the fixed frame, in Ogre classes.
friend class FrameInfo
Definition: tf_display.h:129
An arrow consisting of a cylinder and a cone.
Definition: arrow.h:59
static Time now()
void fixedFrameChanged() override
Called by setFixedFrame(). Override to respond to changes to fixed_frame_.
Definition: tf_display.cpp:813
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option)
Create an editor widget to edit the value of this property.
Definition: property.cpp:525
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation.
Definition: arrow.cpp:119
void onEnable() override
Derived classes override this to do the actual work of enabling themselves.
Definition: tf_display.cpp:343
void setColor(float r, float g, float b, float a) override
Set the color of this arrow. Sets both the head and shaft color to the same value. Values are in the range [0, 1].
Definition: arrow.cpp:89
MapIterator mapIterator() const
Return a new iterator for looping over key/value pairs.
Definition: config.cpp:356
void load(const Config &config) override
Load the value of this property and/or its children from the given Config reference.
Definition: tf_display.cpp:305
bool initialized() const
Returns true if the display has been initialized.
Definition: display.h:275
Arrow * parent_arrow_
Definition: tf_display.h:158
M_FrameInfo frames_
Definition: tf_display.h:108
Ogre::SceneNode * getSceneNode()
Get the scene node associated with this object.
Definition: axes.h:95
Property * tree_property_
Definition: tf_display.h:175
virtual bool getBool() const
ros::Time last_time_to_fixed_
Definition: tf_display.h:166
virtual void setReadOnly(bool read_only)
Prevent or allow users to edit this property from a PropertyTreeWidget.
Definition: property.h:436
void setHeadColor(float r, float g, float b, float a=1.0f)
Set the color of the arrow&#39;s head. Values are in the range [0, 1].
Definition: arrow.cpp:109
bool setStdString(const std::string &std_str)
FloatProperty * frame_timeout_property_
Definition: tf_display.h:119
bool setBool(bool value)
Definition: bool_property.h:62
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
static const Ogre::ColourValue & getDefaultZColor()
Definition: axes.cpp:156
void setScale(const Ogre::Vector3 &scale) override
Set the scale of the object. Always relative to the identity orientation of the object.
Definition: axes.cpp:93
void update(float wall_dt, float ros_dt) override
Called periodically by the visualization manager.
Definition: tf_display.cpp:418
QuaternionProperty * orientation_property_
Definition: tf_display.cpp:82
QuaternionProperty * orientation_property_
Definition: tf_display.h:171
#define ROS_DEBUG(...)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Sat May 27 2023 02:06:25