ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Why custom Rviz displays need stamped messages?

asked 2015-09-15 17:14:06 -0500

tysik gravatar image

updated 2015-09-16 08:32:02 -0500

Hi,

I am trying to create a custom Rviz display which would show a fading-out path of the robot. I wanted to use Pose2D message because it posess all the data I need. But it appears that I cannot inherit on rviz::MessageFilterDisplay<geometry_msgs::Pose2D> because it doesn't have header member. It just freaks me out to prepare the tf broadcaster with quaternions and time stamp when I could get all the info just from this simple Pose2D message.

When I call the processMessage() function, the frame manager looks for the transformation based on the header of the message. In my case it make no sense, because I could get the transformation from the message. I could even easily prepare a fake tf here and get the position and orientation for a displayed element from the message. But the problem is that the compiler throws errors that the Pose2D doesn't have header.

Is there a way to display non-stamped messages in Rviz?

--- EDIT ---

Thank you so much for your answer ahendrix. I did as you recommended and it worked but I am now having problems in creating a proper class for the display. I am getting the following error when I load the display in Rviz:

Error: MultiLibraryClassLoader: Could not create class of type mtracker_gui::PoseDisplay

When using rviz::Display as base class, how can I handle the subscription for a specific messages (topic)? The MessageFilterDisplay<T> class seems to handle this problem on its own. Below is the structure of my class:

class PoseDisplay : public rviz::Display
{
Q_OBJECT
public:
  PoseDisplay();
  virtual ~PoseDisplay();
  virtual void onInitialize();
  virtual void reset();

private Q_SLOTS:
  void updateTopic();
  void updateColorAndAlpha();
  void updateHistoryLength();

 private:
  void processMessage(const geometry_msgs::Pose2D::ConstPtr& msg);

  boost::circular_buffer<boost::shared_ptr <PoseVisual> > visuals_;

  rviz::ColorProperty* color_property_;
  rviz::FloatProperty* alpha_property_;
  rviz::IntProperty*   history_length_property_;
  rviz::RosTopicProperty* topic_property_;
};

And further below is its implementation:

PoseDisplay::PoseDisplay() : Display()
{
  topic_property_ = new rviz::RosTopicProperty( "Topic", "",
                                          QString::fromStdString( ros::message_traits::datatype<geometry_msgs::Pose2D>() ),
                                          "geometry_msgs::Pose2D topic to subscribe to.",
                                          this, SLOT( updateTopic() ));

  color_property_ = new rviz::ColorProperty( "Color", QColor( 204, 51, 204 ),
                                             "Color to draw the pose arrows.",
                                             this, SLOT( updateColorAndAlpha() ));

  alpha_property_ = new rviz::FloatProperty( "Alpha", 1.0,
                                             "0 is fully transparent, 1.0 is fully opaque.",
                                             this, SLOT( updateColorAndAlpha() ));

  history_length_property_ = new rviz::IntProperty( "History Length", 1,
                                                    "Number of prior measurements to display.",
                                                    this, SLOT( updateHistoryLength() ));
  history_length_property_->setMin( 1 );
  history_length_property_->setMax( 100000 );
}

PoseDisplay::~PoseDisplay()
{
}

void PoseDisplay::onInitialize()
{
  updateHistoryLength();
}

void PoseDisplay::reset()
{
  visuals_.clear();
}

void PoseDisplay::updateTopic()
{
  // ???
}

void PoseDisplay::updateColorAndAlpha()
{
  float alpha = alpha_property_->getFloat();
  Ogre::ColourValue color = color_property_->getOgreColor();

  for (size_t i = 0; i < visuals_.size(); i++)
  {
    visuals_[i]->setColor(color.r, color.g, color.b, alpha);
  }
}

void PoseDisplay::updateHistoryLength()
{
  visuals_.rset_capacity(history_length_property_->getInt());
}

void PoseDisplay::processMessage(const geometry_msgs::Pose2D::ConstPtr& msg)
{
  boost::shared_ptr<PoseVisual> visual;
  if (visuals_.full())
  {
    visual = visuals_.front();
  }
  else
  {
    visual.reset(new PoseVisual(context_->getSceneManager(), scene_node_));
  }

  visual->setMessage(msg);

  float alpha = alpha_property_->getFloat();
  Ogre::ColourValue color = color_property_->getOgreColor();
  visual->setColor(color.r, color.g, color.b, alpha);

  visuals_.push_back(visual);
}
edit retag flag offensive close merge delete

Comments

This is off-topic. Please ask a new question instead of continuing this thread.

ahendrix gravatar image ahendrix  ( 2015-09-17 00:28:33 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2015-09-15 19:22:40 -0500

ahendrix gravatar image

The simple answer here is: don't inherit from rviz::MessageFilterDisplay ; inherit from rivz::Display instead.

You should still be able to access things like rviz's global tf buffer through the API: http://docs.ros.org/jade/api/rviz/htm...

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-09-15 17:14:06 -0500

Seen: 635 times

Last updated: Sep 16 '15