nav_grid_display.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2020, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
37 #include <boost/bind.hpp>
38 
39 #include <OgreSharedPtr.h>
40 #include <OgreVector3.h>
41 
42 #include <ros/ros.h>
43 #include <algorithm>
44 #include <memory>
45 #include <string>
46 #include <vector>
47 
48 #include <rviz/ogre_helpers/grid.h>
49 #include <rviz/display_context.h>
50 
51 
52 namespace robot_nav_rviz_plugins
53 {
54 NavGridDisplay::NavGridDisplay(const std::string& data_type, bool include_ignore_property)
55  : Display()
56  , panel_display_(nullptr)
57  , palette_loader_("robot_nav_rviz_plugins", "robot_nav_rviz_plugins::NavGridPalette")
58 {
59  connect(this, SIGNAL(mapUpdated(nav_core2::UIntBounds)), this, SLOT(showMap(nav_core2::UIntBounds)));
60 
61  topic_property_ = new rviz::RosTopicProperty("Topic", "",
62  QString::fromStdString(data_type), QString::fromStdString(data_type + std::string(" topic to subscribe to.")),
63  this, SLOT(updateTopic()));
64 
65  alpha_property_ = new rviz::FloatProperty("Alpha", 0.7,
66  "Amount of transparency to apply to the map.",
67  this, SLOT(updateAlpha()));
70 
71  color_scheme_property_ = new rviz::EnumProperty("Color Scheme", "map", "How to color the occupancy values.",
72  this, SLOT(updatePalette()));
73 
74  draw_behind_property_ = new rviz::BoolProperty("Draw Behind", false,
75  "Rendering option, controls whether or not the map is always"
76  " drawn behind everything else.",
77  this, SLOT(updateAlpha()));
78 
79  resolution_property_ = new rviz::FloatProperty("Resolution", 0, "Resolution of the map. (not editable)", this);
81 
82  width_property_ = new rviz::IntProperty("Width", 0, "Width of the map, in cells. (not editable)", this);
84 
85  height_property_ = new rviz::IntProperty("Height", 0, "Height of the map, in cells. (not editable)", this);
87 
88  unreliable_property_ = new rviz::BoolProperty("Unreliable", false,
89  "Prefer UDP topic transport",
90  this,
91  SLOT(updateTopic()));
92 
93  if (include_ignore_property)
94  {
95  ignore_type_property_ = new rviz::EnumProperty("Ignore Value Type", "None", "Way to exclude certain value(s)", this,
96  SLOT(updateIgnoreType()));
97  ignore_type_property_->addOption("None", static_cast<int>(IgnoreType::NONE));
98  ignore_type_property_->addOption("Value", static_cast<int>(IgnoreType::VALUE));
99  ignore_type_property_->addOption("Limit", static_cast<int>(IgnoreType::LIMIT));
100 
101  ignore_property_ = new rviz::FloatProperty("Ignore Value", -1.0, "Value to not include in the min/max",
102  this, SLOT(updateIgnore()));
104  }
105 }
106 
108 {
109  unsubscribe();
110  clear();
111 }
112 
113 /**********************************************************************************
114  * Overrides from Display
115  **********************************************************************************/
117 {
118  // Lazy initialization of the panel_display_ to ensure we have the non-null pointers to the ogre objects
119  if (panel_display_) return;
120 
121  panel_display_ = std::make_shared<OgrePanel>(panel_data_, *scene_manager_, *scene_node_);
122 
123  for (auto plugin_name : palette_loader_.getDeclaredClasses())
124  {
125  auto palette = palette_loader_.createInstance(plugin_name);
126 
127  std::string name = palette->getName();
128  color_scheme_property_->addOption(name.c_str(), static_cast<int>(color_scheme_names_.size()));
129  color_scheme_names_.push_back(name);
130  panel_display_->addPalette(*palette);
131  }
132  // Set the current values
133  updatePalette();
134 }
135 
137 {
138  subscribe();
139 }
140 
142 {
143  unsubscribe();
144  clear();
145 }
146 
148 {
149  Display::reset();
150 
151  // Force resubscription so that the map will be re-sent
152  updateTopic();
153 }
154 
155 void NavGridDisplay::setTopic(const QString &topic, const QString &datatype)
156 {
157  topic_property_->setString(topic);
158 }
159 
160 void NavGridDisplay::update(float wall_dt, float ros_dt)
161 {
162  // periodically make sure the map is in the right spot
163  transformMap();
164 }
165 
167 {
168  // retransform if frame changed
169  transformMap();
170 }
171 
172 /**********************************************************************************
173  * Custom Events triggered by properties
174  **********************************************************************************/
176 {
178 }
179 
181 {
182  unsubscribe();
183  clear();
184  subscribe();
185 }
186 
188 {
189  int palette_index = color_scheme_property_->getOptionInt();
190  panel_display_->setPalette(color_scheme_names_[palette_index]);
191  updateAlpha();
192 }
193 
195 {
196  if (updated_bounds.isEmpty())
197  {
198  return;
199  }
200 
202  // Only process the info if the info has changed
203  if (info != cached_info_)
204  {
205  if (!validateFloats(info))
206  {
207  setStatus(rviz::StatusProperty::Error, "Map", "Message contained invalid floating point values (nans or infs)");
208  return;
209  }
210 
211  if (info.width * info.height == 0)
212  {
213  std::stringstream ss;
214  ss << "Map is zero-sized (" << info.width << "x" << info.height << ")";
215  setStatus(rviz::StatusProperty::Error, "Map", QString::fromStdString(ss.str()));
216  return;
217  }
218 
219  // If the data has changed size or resolution, update the panel display's info
220  if (info.resolution != cached_info_.resolution ||
221  info.width != cached_info_.width || info.height != cached_info_.height)
222  {
223  panel_display_->updateInfo(info);
227  }
228  cached_info_ = info;
229  }
230 
231  setStatus(rviz::StatusProperty::Ok, "Message", "Map received");
232 
233  panel_display_->updateData(updated_bounds);
234 
235  updatePalette();
236 
237  transformMap();
238 
239  setStatus(rviz::StatusProperty::Ok, "Map", "Map OK");
241 }
242 
243 
245 {
246  switch (getIgnoreType())
247  {
248  case IgnoreType::VALUE:
249  case IgnoreType::LIMIT:
251  break;
252  default:
254  }
255  updateIgnore();
256 }
257 
258 
259 /**********************************************************************************
260  * Other Methods
261  **********************************************************************************/
262 
264 {
265  // Make sure the topic is enabled and non-empty.
266  // Also sets status if there is a problem
267 
268  if (!isEnabled())
269  {
270  return;
271  }
272 
273  if (!topic_property_->getTopic().isEmpty())
274  {
275  try
276  {
278  setStatus(rviz::StatusProperty::Ok, "Topic", "OK");
279  }
280  catch (ros::Exception& e)
281  {
282  setStatus(rviz::StatusProperty::Error, "Topic", QString("Error subscribing: ") + e.what());
283  }
284  }
285 }
286 
288 {
289  onUnsubscribe();
290 }
291 
293 {
294  setStatus(rviz::StatusProperty::Warn, "Message", "No map received");
295  panel_display_->clear();
296 }
297 
299 {
300  if (panel_display_->transformMap(*context_->getFrameManager()))
301  {
302  setStatus(rviz::StatusProperty::Ok, "Transform", "Transform OK");
303  }
304  else
305  {
306  std::string frame = panel_data_.getFrameId();
308  "No transform from [" + QString::fromStdString(frame) + "] to [" + fixed_frame_ + "]");
309  }
310 }
311 } // namespace robot_nav_rviz_plugins
void setMin(float min)
virtual bool setValue(const QVariant &new_value)
void showMap(const nav_core2::UIntBounds &updated_bounds)
virtual void setString(const QString &str)
void setMax(float max)
DisplayContext * context_
void clear()
Clear the data and remove the objects from the screen.
void setTopic(const QString &topic, const QString &datatype) override
virtual float getFloat() const
void unsubscribe()
Called to trigger unsubscribing.
Ogre::SceneNode * scene_node_
std::vector< std::string > color_scheme_names_
std::string getFrameId() const
virtual bool setValue(const QVariant &new_value)
bool isEnabled() const
QString fixed_frame_
virtual void onSubscribe(const std::string &topic)
Actual subscription logic, called by subscribe.
virtual void addOption(const QString &option, int value=0)
rviz::RosTopicProperty * topic_property_
nav_grid::VectorNavGrid< unsigned char > panel_data_
void update(float wall_dt, float ros_dt) override
Several reusable pieces for displaying polygons.
NavGridDisplay(const std::string &data_type, bool include_ignore_property=false)
Constructor for the display.
virtual FrameManager * getFrameManager() const =0
virtual void onUnsubscribe()
Actual unsubscription logic, called by unsubscribe.
Ogre::SceneManager * scene_manager_
virtual void queueRender()=0
void mapUpdated(const nav_core2::UIntBounds &updated_bounds)
Custom signal emitted when new map data is received.
QString getTopic() const
void transformMap()
Put the map in its proper place.
NavGridInfo getInfo() const
virtual QVariant getValue() const
void subscribe()
Called to trigger subscription, handles empty topics setting status.
pluginlib::ClassLoader< NavGridPalette > palette_loader_
std::string getTopicStd() const
virtual void setReadOnly(bool read_only)
virtual int getOptionInt()
bool validateFloats(const nav_grid::NavGridInfo &info)
virtual void setStatus(StatusProperty::Level level, const QString &name, const QString &text)


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