interactive_marker_display.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, 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 <rviz/frame_manager.h>
34 #include <rviz/validate_floats.h>
36 #include <rviz/display_context.h>
37 
39 
40 
41 namespace rviz
42 {
44 bool validateFloats(const visualization_msgs::InteractiveMarker& msg)
45 {
46  bool valid = true;
47  valid = valid && validateFloats(msg.pose);
48  valid = valid && validateFloats(msg.scale);
49  for (unsigned c = 0; c < msg.controls.size(); c++)
50  {
51  valid = valid && validateFloats(msg.controls[c].orientation);
52  for (unsigned m = 0; m < msg.controls[c].markers.size(); m++)
53  {
54  valid = valid && validateFloats(msg.controls[c].markers[m].pose);
55  valid = valid && validateFloats(msg.controls[c].markers[m].scale);
56  valid = valid && validateFloats(msg.controls[c].markers[m].color);
57  valid = valid && validateFloats(msg.controls[c].markers[m].points);
58  }
59  }
60  return valid;
61 }
62 
63 bool validateQuaternions(const visualization_msgs::InteractiveMarker& marker)
64 {
65  if (!validateQuaternions(marker.pose.orientation))
66  return false;
67  for (size_t c = 0; c < marker.controls.size(); ++c)
68  {
69  if (!validateQuaternions(marker.controls[c].orientation))
70  return false;
71  for (size_t m = 0; m < marker.controls[c].markers.size(); ++m)
72  {
73  if (!validateQuaternions(marker.controls[c].markers[m].pose.orientation))
74  return false;
75  }
76  }
77  return true;
78 }
80 
81 
83 {
85  new RosTopicProperty("Update Topic", "",
86  ros::message_traits::datatype<visualization_msgs::InteractiveMarkerUpdate>(),
87  "visualization_msgs::InteractiveMarkerUpdate topic to subscribe to.", this,
89 
91  new BoolProperty("Show Descriptions", true,
92  "Whether or not to show the descriptions of each Interactive Marker.", this,
94 
96  new BoolProperty("Show Axes", false, "Whether or not to show the axes of each Interactive Marker.",
98 
100  "Show Visual Aids", false,
101  "Whether or not to show visual helpers while moving/rotating Interactive Markers.", this,
104  "Enable Transparency", true,
105  "Whether or not to allow transparency for auto-completed markers (e.g. rings and arrows).", this,
107 }
108 
110 {
113 
114  im_client_->setInitCb(boost::bind(&InteractiveMarkerDisplay::initCb, this, boost::placeholders::_1));
115  im_client_->setUpdateCb(
116  boost::bind(&InteractiveMarkerDisplay::updateCb, this, boost::placeholders::_1));
117  im_client_->setResetCb(boost::bind(&InteractiveMarkerDisplay::resetCb, this, boost::placeholders::_1));
118  im_client_->setStatusCb(boost::bind(&InteractiveMarkerDisplay::statusCb, this, boost::placeholders::_1,
119  boost::placeholders::_2, boost::placeholders::_3));
120 
122 
123  onEnable();
124 }
125 
126 void InteractiveMarkerDisplay::setTopic(const QString& topic, const QString& /*datatype*/)
127 {
129 }
130 
132 {
133  subscribe();
134 }
135 
137 {
138  unsubscribe();
139 }
140 
142 {
143  unsubscribe();
144 
145  std::string update_topic = marker_update_topic_property_->getTopicStd();
146 
147  size_t idx = update_topic.find("/update");
148  if (idx != std::string::npos)
149  {
150  topic_ns_ = update_topic.substr(0, idx);
151  subscribe();
152  }
153  else
154  {
155  setStatusStd(StatusProperty::Error, "Topic", "Invalid topic name: " + update_topic);
156  }
157 }
158 
160 {
161  if (isEnabled())
162  {
163  im_client_->subscribe(topic_ns_);
164 
165  std::string feedback_topic = topic_ns_ + "/feedback";
166  feedback_pub_ =
167  update_nh_.advertise<visualization_msgs::InteractiveMarkerFeedback>(feedback_topic, 100, false);
168  }
169 }
170 
171 void InteractiveMarkerDisplay::publishFeedback(visualization_msgs::InteractiveMarkerFeedback& feedback)
172 {
173  feedback.client_id = client_id_;
174  feedback_pub_.publish(feedback);
175 }
176 
178  const std::string& name,
179  const std::string& text)
180 {
181  setStatusStd(level, name, text);
182 }
183 
185 {
186  if (im_client_)
187  {
188  im_client_->shutdown();
189  }
191  Display::reset();
192 }
193 
194 void InteractiveMarkerDisplay::update(float wall_dt, float /*ros_dt*/)
195 {
196  im_client_->update();
197 
198  M_StringToStringToIMPtr::iterator server_it;
199  for (server_it = interactive_markers_.begin(); server_it != interactive_markers_.end(); server_it++)
200  {
201  M_StringToIMPtr::iterator im_it;
202  for (im_it = server_it->second.begin(); im_it != server_it->second.end(); im_it++)
203  {
204  im_it->second->update(wall_dt);
205  }
206  }
207 }
208 
210 InteractiveMarkerDisplay::getImMap(const std::string& server_id)
211 {
212  M_StringToStringToIMPtr::iterator im_map_it = interactive_markers_.find(server_id);
213 
214  if (im_map_it == interactive_markers_.end())
215  {
216  im_map_it = interactive_markers_.insert(std::make_pair(server_id, M_StringToIMPtr())).first;
217  }
218 
219  return im_map_it->second;
220 }
221 
223  const std::string& server_id,
224  const std::vector<visualization_msgs::InteractiveMarker>& markers)
225 {
226  M_StringToIMPtr& im_map = getImMap(server_id);
227 
228  for (size_t i = 0; i < markers.size(); i++)
229  {
230  const visualization_msgs::InteractiveMarker& marker = markers[i];
231 
232  if (!validateFloats(marker))
233  {
234  setStatusStd(StatusProperty::Error, marker.name, "Marker contains invalid floats!");
235  // setStatusStd( StatusProperty::Error, "General", "Marker " + marker.name + " contains invalid
236  // floats!" );
237  continue;
238  }
239 
240  if (!validateQuaternions(marker))
241  {
242  ROS_WARN_ONCE_NAMED("quaternions",
243  "Interactive marker '%s' contains unnormalized quaternions. "
244  "This warning will only be output once but may be true for others; "
245  "enable DEBUG messages for ros.rviz.quaternions to see more details.",
246  marker.name.c_str());
247  ROS_DEBUG_NAMED("quaternions", "Interactive marker '%s' contains unnormalized quaternions.",
248  marker.name.c_str());
249  }
250  ROS_DEBUG("Processing interactive marker '%s'. %d", marker.name.c_str(), (int)marker.controls.size());
251 
252  std::map<std::string, IMPtr>::iterator int_marker_entry = im_map.find(marker.name);
253 
254  if (int_marker_entry == im_map.end())
255  {
256  int_marker_entry =
257  im_map
258  .insert(std::make_pair(marker.name, IMPtr(new InteractiveMarker(getSceneNode(), context_))))
259  .first;
260  connect(int_marker_entry->second.get(), &InteractiveMarker::userFeedback, this,
262  connect(int_marker_entry->second.get(), &InteractiveMarker::statusUpdate, this,
264  }
265 
266  if (int_marker_entry->second->processMessage(marker))
267  {
268  int_marker_entry->second->setShowAxes(show_axes_property_->getBool());
269  int_marker_entry->second->setShowVisualAids(show_visual_aids_property_->getBool());
270  int_marker_entry->second->setShowDescription(show_descriptions_property_->getBool());
271  }
272  else
273  {
274  unsubscribe();
275  return;
276  }
277  }
278 }
279 
280 void InteractiveMarkerDisplay::eraseMarkers(const std::string& server_id,
281  const std::vector<std::string>& erases)
282 {
283  M_StringToIMPtr& im_map = getImMap(server_id);
284 
285  for (size_t i = 0; i < erases.size(); i++)
286  {
287  im_map.erase(erases[i]);
288  deleteStatusStd(erases[i]);
289  }
290 }
291 
293  const std::string& server_id,
294  const std::vector<visualization_msgs::InteractiveMarkerPose>& marker_poses)
295 {
296  M_StringToIMPtr& im_map = getImMap(server_id);
297 
298  for (size_t i = 0; i < marker_poses.size(); i++)
299  {
300  const visualization_msgs::InteractiveMarkerPose& marker_pose = marker_poses[i];
301 
302  if (!validateFloats(marker_pose.pose))
303  {
304  setStatusStd(StatusProperty::Error, marker_pose.name, "Pose message contains invalid floats!");
305  return;
306  }
307 
308  if (!validateQuaternions(marker_pose.pose))
309  {
310  setStatusStd(StatusProperty::Error, marker_pose.name,
311  "Pose message contains invalid quaternions (length not equal to 1)!");
312  return;
313  }
314 
315  std::map<std::string, IMPtr>::iterator int_marker_entry = im_map.find(marker_pose.name);
316 
317  if (int_marker_entry != im_map.end())
318  {
319  int_marker_entry->second->processMessage(marker_pose);
320  }
321  else
322  {
323  setStatusStd(StatusProperty::Error, marker_pose.name,
324  "Pose received for non-existing marker '" + marker_pose.name);
325  unsubscribe();
326  return;
327  }
328  }
329 }
330 
331 void InteractiveMarkerDisplay::initCb(const visualization_msgs::InteractiveMarkerInitConstPtr& msg)
332 {
333  resetCb(msg->server_id);
334  updateMarkers(msg->server_id, msg->markers);
335 }
336 
337 void InteractiveMarkerDisplay::updateCb(const visualization_msgs::InteractiveMarkerUpdateConstPtr& msg)
338 {
339  updateMarkers(msg->server_id, msg->markers);
340  updatePoses(msg->server_id, msg->poses);
341  eraseMarkers(msg->server_id, msg->erases);
342 }
343 
344 void InteractiveMarkerDisplay::resetCb(const std::string& server_id)
345 {
346  interactive_markers_.erase(server_id);
347  deleteStatusStd(server_id);
348 }
349 
351  const std::string& server_id,
352  const std::string& msg)
353 {
354  setStatusStd(static_cast<StatusProperty::Level>(status), server_id, msg);
355 }
356 
358 {
359  if (im_client_)
360  im_client_->setTargetFrame(fixed_frame_.toStdString());
361  reset();
362 }
363 
365 {
366  Display::reset();
367  unsubscribe();
368  subscribe();
369 }
370 
372 {
374 
375  M_StringToStringToIMPtr::iterator server_it;
376  for (server_it = interactive_markers_.begin(); server_it != interactive_markers_.end(); server_it++)
377  {
378  M_StringToIMPtr::iterator im_it;
379  for (im_it = server_it->second.begin(); im_it != server_it->second.end(); im_it++)
380  {
381  im_it->second->setShowDescription(show);
382  }
383  }
384 }
385 
387 {
388  bool show = show_axes_property_->getBool();
389 
390  M_StringToStringToIMPtr::iterator server_it;
391  for (server_it = interactive_markers_.begin(); server_it != interactive_markers_.end(); server_it++)
392  {
393  M_StringToIMPtr::iterator im_it;
394  for (im_it = server_it->second.begin(); im_it != server_it->second.end(); im_it++)
395  {
396  im_it->second->setShowAxes(show);
397  }
398  }
399 }
400 
402 {
404 
405  M_StringToStringToIMPtr::iterator server_it;
406  for (server_it = interactive_markers_.begin(); server_it != interactive_markers_.end(); server_it++)
407  {
408  M_StringToIMPtr::iterator im_it;
409  for (im_it = server_it->second.begin(); im_it != server_it->second.end(); im_it++)
410  {
411  im_it->second->setShowVisualAids(show);
412  }
413  }
414 }
415 
417 {
418  // This is not very efficient... but it should do the trick.
419  unsubscribe();
420  im_client_->setEnableAutocompleteTransparency(enable_transparency_property_->getBool());
421  subscribe();
422 }
423 
424 } // namespace rviz
425 
rviz::FrameManager::getTF2BufferPtr
const std::shared_ptr< tf2_ros::Buffer > getTF2BufferPtr()
Definition: frame_manager.h:209
interactive_marker_display.h
rviz::BoolProperty::getBool
virtual bool getBool() const
Definition: bool_property.cpp:48
interactive_markers::InteractiveMarkerClient::StatusT
StatusT
rviz::Display::isEnabled
bool isEnabled() const
Return true if this Display is enabled, false if not.
Definition: display.cpp:271
rviz::InteractiveMarkerDisplay::onStatusUpdate
void onStatusUpdate(StatusProperty::Level level, const std::string &name, const std::string &text)
Definition: interactive_marker_display.cpp:177
rviz::RosTopicProperty
Definition: ros_topic_property.h:39
rviz::InteractiveMarkerDisplay
Displays Interactive Markers.
Definition: interactive_marker_display.h:64
validate_floats.h
rviz::InteractiveMarkerDisplay::unsubscribe
void unsubscribe()
Definition: interactive_marker_display.cpp:184
frame_manager.h
rviz::InteractiveMarkerDisplay::onEnable
void onEnable() override
Derived classes override this to do the actual work of enabling themselves.
Definition: interactive_marker_display.cpp:131
rviz::InteractiveMarkerDisplay::show_descriptions_property_
BoolProperty * show_descriptions_property_
Definition: interactive_marker_display.h:133
boost::shared_ptr
rviz::InteractiveMarkerDisplay::updateShowAxes
void updateShowAxes()
Definition: interactive_marker_display.cpp:386
rviz::StatusProperty::Error
@ Error
Definition: status_property.h:46
rviz::InteractiveMarkerDisplay::setTopic
void setTopic(const QString &topic, const QString &datatype) override
Set the ROS topic to listen to for this display.
Definition: interactive_marker_display.cpp:126
ros_topic_property.h
rviz::Property::show
void show()
Show this Property in any PropertyTreeWidgets.
Definition: property.h:471
rviz::InteractiveMarkerDisplay::eraseMarkers
void eraseMarkers(const std::string &server_id, const std::vector< std::string > &names)
Definition: interactive_marker_display.cpp:280
rviz::StatusProperty::Level
Level
Definition: status_property.h:42
rviz::EditableEnumProperty::setString
virtual void setString(const QString &str)
Definition: editable_enum_property.cpp:74
rviz::InteractiveMarkerDisplay::im_client_
boost::shared_ptr< interactive_markers::InteractiveMarkerClient > im_client_
Definition: interactive_marker_display.h:138
rviz::InteractiveMarkerDisplay::updateCb
void updateCb(const visualization_msgs::InteractiveMarkerUpdateConstPtr &msg)
Definition: interactive_marker_display.cpp:337
rviz::InteractiveMarkerDisplay::topic_ns_
std::string topic_ns_
Definition: interactive_marker_display.h:142
rviz::Property::getNameStd
std::string getNameStd() const
Return the name of this Property as a std::string.
Definition: property.h:240
rviz::validateFloats
bool validateFloats(const sensor_msgs::CameraInfo &msg)
Definition: camera_display.cpp:72
rviz::InteractiveMarkerDisplay::updateMarkers
void updateMarkers(const std::string &server_id, const std::vector< visualization_msgs::InteractiveMarker > &markers)
Definition: interactive_marker_display.cpp:222
ROS_WARN_ONCE_NAMED
#define ROS_WARN_ONCE_NAMED(name,...)
rviz::InteractiveMarkerDisplay::statusCb
void statusCb(interactive_markers::InteractiveMarkerClient::StatusT, const std::string &server_id, const std::string &msg)
Definition: interactive_marker_display.cpp:350
selection_manager.h
rviz::InteractiveMarker::statusUpdate
void statusUpdate(StatusProperty::Level level, const std::string &name, const std::string &text)
rviz::Display::fixed_frame_
QString fixed_frame_
A convenience variable equal to context_->getFixedFrame().
Definition: display.h:312
rviz::InteractiveMarkerDisplay::fixedFrameChanged
void fixedFrameChanged() override
Called by setFixedFrame(). Override to respond to changes to fixed_frame_.
Definition: interactive_marker_display.cpp:357
validate_quaternions.h
bool_property.h
rviz::InteractiveMarkerDisplay::subscribe
void subscribe()
Definition: interactive_marker_display.cpp:159
rviz::InteractiveMarkerDisplay::getImMap
M_StringToIMPtr & getImMap(const std::string &server_id)
Definition: interactive_marker_display.cpp:210
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
rviz::BoolProperty::BoolProperty
BoolProperty(const QString &name=QString(), bool default_value=false, const QString &description=QString(), Property *parent=nullptr)
Definition: bool_property.cpp:36
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
rviz::Display::deleteStatusStd
void deleteStatusStd(const std::string &name)
Delete the status entry with the given std::string name. This is thread-safe.
Definition: display.h:172
rviz::Property::connect
QMetaObject::Connection connect(const QObject *receiver, const char *slot, Qt::ConnectionType type=Qt::AutoConnection)
Connect changed() signal to given slot of receiver.
Definition: property.cpp:78
rviz::Display
Definition: display.h:63
rviz::InteractiveMarkerDisplay::initCb
void initCb(const visualization_msgs::InteractiveMarkerInitConstPtr &msg)
Definition: interactive_marker_display.cpp:331
rviz::InteractiveMarkerDisplay::show_axes_property_
BoolProperty * show_axes_property_
Definition: interactive_marker_display.h:134
rviz::InteractiveMarkerDisplay::updatePoses
void updatePoses(const std::string &server_id, const std::vector< visualization_msgs::InteractiveMarkerPose > &marker_poses)
Definition: interactive_marker_display.cpp:292
rviz::InteractiveMarkerDisplay::show_visual_aids_property_
BoolProperty * show_visual_aids_property_
Definition: interactive_marker_display.h:135
rviz::InteractiveMarkerDisplay::onDisable
void onDisable() override
Derived classes override this to do the actual work of disabling themselves.
Definition: interactive_marker_display.cpp:136
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
ros::Publisher::shutdown
void shutdown()
ROS_DEBUG
#define ROS_DEBUG(...)
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
rviz
Definition: add_display_dialog.cpp:54
rviz::InteractiveMarkerDisplay::enable_transparency_property_
BoolProperty * enable_transparency_property_
Definition: interactive_marker_display.h:136
rviz::validateQuaternions
bool validateQuaternions(const visualization_msgs::InteractiveMarker &marker)
Definition: interactive_marker_display.cpp:63
rviz::InteractiveMarkerDisplay::client_id_
std::string client_id_
Definition: interactive_marker_display.h:129
rviz::DisplayContext::getFrameManager
virtual FrameManager * getFrameManager() const =0
Return the FrameManager instance.
rviz::InteractiveMarkerDisplay::publishFeedback
void publishFeedback(visualization_msgs::InteractiveMarkerFeedback &feedback)
Definition: interactive_marker_display.cpp:171
rviz::InteractiveMarkerDisplay::updateShowDescriptions
void updateShowDescriptions()
Definition: interactive_marker_display.cpp:371
rviz::RosTopicProperty::getTopicStd
std::string getTopicStd() const
Definition: ros_topic_property.h:85
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
rviz::InteractiveMarkerDisplay::updateTopic
void updateTopic()
Definition: interactive_marker_display.cpp:141
rviz::InteractiveMarkerDisplay::update
void update(float wall_dt, float ros_dt) override
Called periodically by the visualization manager.
Definition: interactive_marker_display.cpp:194
rviz::InteractiveMarkerDisplay::M_StringToIMPtr
std::map< std::string, IMPtr > M_StringToIMPtr
Definition: interactive_marker_display.h:123
rviz::Display::setStatusStd
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
rviz::Display::context_
DisplayContext * context_
This DisplayContext pointer is the main connection a Display has into the rest of rviz....
Definition: display.h:287
rviz::InteractiveMarkerDisplay::interactive_markers_
M_StringToStringToIMPtr interactive_markers_
Definition: interactive_marker_display.h:125
rviz::InteractiveMarkerDisplay::updateEnableTransparency
void updateEnableTransparency()
Definition: interactive_marker_display.cpp:416
rviz::Display::getSceneNode
Ogre::SceneNode * getSceneNode() const
Return the Ogre::SceneNode holding all 3D scene elements shown by this Display.
Definition: display.h:186
class_list_macros.hpp
rviz::InteractiveMarkerDisplay::marker_update_topic_property_
RosTopicProperty * marker_update_topic_property_
Definition: interactive_marker_display.h:132
rviz::InteractiveMarkerDisplay::updateShowVisualAids
void updateShowVisualAids()
Definition: interactive_marker_display.cpp:401
rviz::Display::reset
virtual void reset()
Called to tell the display to clear its state.
Definition: display.cpp:290
rviz::InteractiveMarkerDisplay::InteractiveMarkerDisplay
InteractiveMarkerDisplay()
Definition: interactive_marker_display.cpp:82
rviz::InteractiveMarkerDisplay::reset
void reset() override
Called to tell the display to clear its state.
Definition: interactive_marker_display.cpp:364
tf
display_context.h
rviz::InteractiveMarker
Definition: interactive_marker.h:69
interactive_markers::InteractiveMarkerClient
rviz::InteractiveMarkerDisplay::resetCb
void resetCb(const std::string &server_id)
Definition: interactive_marker_display.cpp:344
rviz::InteractiveMarkerDisplay::feedback_pub_
ros::Publisher feedback_pub_
Definition: interactive_marker_display.h:140
rviz::InteractiveMarkerDisplay::onInitialize
void onInitialize() override
Override this function to do subclass-specific initialization.
Definition: interactive_marker_display.cpp:109
rviz::Display::update_nh_
ros::NodeHandle update_nh_
A NodeHandle whose CallbackQueue is run from the main GUI thread (the "update" thread).
Definition: display.h:300
rviz::InteractiveMarker::userFeedback
void userFeedback(visualization_msgs::InteractiveMarkerFeedback &feedback)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust, William Woodall
autogenerated on Fri Aug 2 2024 08:43:09