pie_chart_display.cpp
Go to the documentation of this file.
1 // -*- mode: c++; -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2014, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #include "pie_chart_display.h"
37 
38 #include <OGRE/OgreMaterialManager.h>
39 #include <OGRE/OgreTextureManager.h>
40 #include <OGRE/OgreTexture.h>
41 #include <OGRE/OgreTechnique.h>
42 #include <OGRE/OgreHardwarePixelBuffer.h>
44 #include <rviz/display_context.h>
45 #include <QPainter>
46 
47 namespace jsk_rviz_plugins
48 {
49 
51  : rviz::Display(), update_required_(false), first_time_(true), data_(0.0)
52  {
54  "Topic", "",
55  ros::message_traits::datatype<std_msgs::Float32>(),
56  "std_msgs::Float32 topic to subscribe to.",
57  this, SLOT( updateTopic() ));
58  size_property_ = new rviz::IntProperty("size", 128,
59  "size of the plotter window",
60  this, SLOT(updateSize()));
61  left_property_ = new rviz::IntProperty("left", 128,
62  "left of the plotter window",
63  this, SLOT(updateLeft()));
64  top_property_ = new rviz::IntProperty("top", 128,
65  "top of the plotter window",
66  this, SLOT(updateTop()));
67  fg_color_property_ = new rviz::ColorProperty("foreground color",
68  QColor(25, 255, 240),
69  "color to draw line",
70  this, SLOT(updateFGColor()));
72  = new rviz::FloatProperty("foreground alpha", 0.7,
73  "alpha belnding value for foreground",
74  this, SLOT(updateFGAlpha()));
76  = new rviz::FloatProperty("foreground alpha 2", 0.4,
77  "alpha belnding value for foreground for indicator",
78  this, SLOT(updateFGAlpha2()));
79  bg_color_property_ = new rviz::ColorProperty("background color",
80  QColor(0, 0, 0),
81  "background color",
82  this, SLOT(updateBGColor()));
84  = new rviz::FloatProperty("backround alpha", 0.0,
85  "alpha belnding value for background",
86  this, SLOT(updateBGAlpha()));
88  = new rviz::IntProperty("text size", 14,
89  "text size",
90  this, SLOT(updateTextSize()));
92  = new rviz::BoolProperty("show caption", true,
93  "show caption",
94  this, SLOT(updateShowCaption()));
96  = new rviz::FloatProperty("max value", 1.0,
97  "max value of pie chart",
98  this, SLOT(updateMaxValue()));
100  = new rviz::FloatProperty("min value", 0.0,
101  "min value of pie chart",
102  this, SLOT(updateMinValue()));
104  = new rviz::BoolProperty("auto color change",
105  false,
106  "change the color automatically",
107  this, SLOT(updateAutoColorChange()));
109  = new rviz::ColorProperty("max color",
110  QColor(255, 0, 0),
111  "only used if auto color change is set to True.",
112  this, SLOT(updateMaxColor()));
113 
115  = new rviz::ColorProperty("med color",
116  QColor(255, 0, 0),
117  "only used if auto color change is set to True.",
118  this, SLOT(updateMedColor()));
119 
121  = new rviz::FloatProperty("max color change threthold", 0,
122  "change the max color at threshold",
123  this, SLOT(updateMaxColorThreshold()));
124 
126  = new rviz::FloatProperty("med color change threthold", 0,
127  "change the med color at threshold ",
128  this, SLOT(updateMedColorThreshold()));
129 
131  = new rviz::BoolProperty("clockwise rotate direction",
132  false,
133  "change the rotate direction",
134  this, SLOT(updateClockwiseRotate()));
135  }
136 
138  {
139  if (overlay_->isVisible()) {
140  overlay_->hide();
141  }
142  delete update_topic_property_;
143  delete fg_color_property_;
144  delete bg_color_property_;
145  delete fg_alpha_property_;
146  delete fg_alpha2_property_;
147  delete bg_alpha_property_;
148  delete top_property_;
149  delete left_property_;
150  delete size_property_;
151  delete min_value_property_;
152  delete max_value_property_;
153  delete max_color_property_;
154  delete med_color_property_;
155  delete text_size_property_;
156  delete show_caption_property_;
157  }
158 
160  {
161  static int count = 0;
163  ss << "PieChartDisplayObject" << count++;
164  overlay_.reset(new OverlayObject(ss.str()));
165  onEnable();
166  updateSize();
167  updateLeft();
168  updateTop();
169  updateFGColor();
170  updateBGColor();
171  updateFGAlpha();
172  updateFGAlpha2();
173  updateBGAlpha();
174  updateMinValue();
175  updateMaxValue();
176  updateTextSize();
179  updateMaxColor();
180  updateMedColor();
184  overlay_->updateTextureSize(texture_size_, texture_size_ + caption_offset_);
185  overlay_->hide();
186  }
187 
188  void PieChartDisplay::update(float wall_dt, float ros_dt)
189  {
190  if (update_required_) {
191  update_required_ = false;
192  overlay_->updateTextureSize(texture_size_, texture_size_ + caption_offset_);
193  overlay_->setPosition(left_, top_);
194  overlay_->setDimensions(overlay_->getTextureWidth(),
195  overlay_->getTextureHeight());
196  drawPlot(data_);
197  }
198  }
199 
200  void PieChartDisplay::processMessage(const std_msgs::Float32::ConstPtr& msg)
201  {
202  boost::mutex::scoped_lock lock(mutex_);
203 
204  if (!overlay_->isVisible()) {
205  return;
206  }
207  if (data_ != msg->data || first_time_) {
208  first_time_ = false;
209  data_ = msg->data;
210  update_required_ = true;
211  }
212  }
213 
214  void PieChartDisplay::drawPlot(double val)
215  {
216  QColor fg_color(fg_color_);
217 
218  if (auto_color_change_) {
219  double r
220  = std::min(1.0, fabs((val - min_value_) / (max_value_ - min_value_)));
221  if (r > 0.6) {
222  double r2 = (r - 0.6) / 0.4;
223  fg_color.setRed((max_color_.red() - fg_color_.red()) * r2
224  + fg_color_.red());
225  fg_color.setGreen((max_color_.green() - fg_color_.green()) * r2
226  + fg_color_.green());
227  fg_color.setBlue((max_color_.blue() - fg_color_.blue()) * r2
228  + fg_color_.blue());
229  }
230  if (max_color_threshold_ != 0) {
231  if (r > max_color_threshold_) {
232  fg_color.setRed(max_color_.red());
233  fg_color.setGreen(max_color_.green());
234  fg_color.setBlue(max_color_.blue());
235  }
236  }
237  if (med_color_threshold_ != 0) {
238  if (max_color_threshold_ > r and r > med_color_threshold_ ) {
239  fg_color.setRed(med_color_.red());
240  fg_color.setGreen(med_color_.green());
241  fg_color.setBlue(med_color_.blue());
242  }
243  }
244  }
245 
246 
247  QColor fg_color2(fg_color);
248  QColor bg_color(bg_color_);
249  fg_color.setAlpha(fg_alpha_);
250  fg_color2.setAlpha(fg_alpha2_);
251  bg_color.setAlpha(bg_alpha_);
252  int width = overlay_->getTextureWidth();
253  int height = overlay_->getTextureHeight();
254  {
255  ScopedPixelBuffer buffer = overlay_->getBuffer();
256  QImage Hud = buffer.getQImage(*overlay_, bg_color);
257  QPainter painter( &Hud );
258  painter.setRenderHint(QPainter::Antialiasing, true);
259 
260  const int outer_line_width = 5;
261  const int value_line_width = 10;
262  const int value_indicator_line_width = 2;
263  const int value_padding = 5;
264 
265  const int value_aabb_offset
266  = outer_line_width + value_padding + value_line_width / 2;
267 
268  painter.setPen(QPen(fg_color, outer_line_width, Qt::SolidLine));
269 
270  painter.drawEllipse(outer_line_width / 2, outer_line_width / 2,
271  width - outer_line_width ,
272  height - outer_line_width - caption_offset_);
273 
274  painter.setPen(QPen(fg_color2, value_indicator_line_width, Qt::SolidLine));
275  painter.drawEllipse(value_aabb_offset, value_aabb_offset,
276  width - value_aabb_offset * 2,
277  height - value_aabb_offset * 2 - caption_offset_);
278 
279  const double ratio = (val - min_value_) / (max_value_ - min_value_);
280  const double rotate_direction = clockwise_rotate_ ? -1.0 : 1.0;
281  const double ratio_angle = ratio * 360.0 * rotate_direction;
282  const double start_angle_offset = -90;
283  painter.setPen(QPen(fg_color, value_line_width, Qt::SolidLine));
284  painter.drawArc(QRectF(value_aabb_offset, value_aabb_offset,
285  width - value_aabb_offset * 2,
286  height - value_aabb_offset * 2 - caption_offset_),
287  start_angle_offset * 16 ,
288  ratio_angle * 16);
289  QFont font = painter.font();
290  font.setPointSize(text_size_);
291  font.setBold(true);
292  painter.setFont(font);
293  painter.setPen(QPen(fg_color, value_line_width, Qt::SolidLine));
294  std::ostringstream s;
295  s << std::fixed << std::setprecision(2) << val;
296  painter.drawText(0, 0, width, height - caption_offset_,
297  Qt::AlignCenter | Qt::AlignVCenter,
298  s.str().c_str());
299 
300  // caption
301  if (show_caption_) {
302  painter.drawText(0, height - caption_offset_, width, caption_offset_,
303  Qt::AlignCenter | Qt::AlignVCenter,
304  getName());
305  }
306 
307  // done
308  painter.end();
309  // Unlock the pixel buffer
310  }
311  }
312 
313 
315  {
316  std::string topic_name = update_topic_property_->getTopicStd();
317  if (topic_name.length() > 0 && topic_name != "/") {
318  ros::NodeHandle n;
319  sub_ = n.subscribe(topic_name, 1, &PieChartDisplay::processMessage, this);
320  }
321  }
322 
323 
325  {
326  sub_.shutdown();
327  }
328 
330  {
331  subscribe();
332  overlay_->show();
333  first_time_ = true;
334  }
335 
337  {
338  unsubscribe();
339  overlay_->hide();
340  }
341 
343  {
344  boost::mutex::scoped_lock lock(mutex_);
346  update_required_ = true;
347  }
348 
350  {
352  update_required_ = true;
353  }
354 
356  {
358  update_required_ = true;
359  }
360 
362  {
364  update_required_ = true;
365 
366  }
367 
369  {
371  update_required_ = true;
372 
373  }
374 
376  {
378  update_required_ = true;
379 
380  }
381 
383  {
385  update_required_ = true;
386 
387  }
388 
389 
391  {
393  update_required_ = true;
394 
395  }
396 
398  {
400  update_required_ = true;
401 
402  }
403 
405  {
407  update_required_ = true;
408 
409  }
410 
412  {
413  boost::mutex::scoped_lock lock(mutex_);
415  QFont font;
416  font.setPointSize(text_size_);
417  caption_offset_ = QFontMetrics(font).height();
418  update_required_ = true;
419 
420  }
421 
423  {
425  update_required_ = true;
426 
427  }
428 
429 
431  {
432  unsubscribe();
433  subscribe();
434  }
435 
437  {
439  if (auto_color_change_) {
444  }
445  else {
450  }
451  update_required_ = true;
452 
453  }
454 
456  {
458  update_required_ = true;
459 
460  }
461 
463  {
465  update_required_ = true;
466 
467  }
468 
470  {
472  update_required_ = true;
473  }
474 
476  {
478  update_required_ = true;
479  }
480 
482  {
484  update_required_ = true;
485 
486  }
487 
488  bool PieChartDisplay::isInRegion(int x, int y)
489  {
490  return (top_ < y && top_ + texture_size_ > y &&
491  left_ < x && left_ + texture_size_ > x);
492  }
493 
494  void PieChartDisplay::movePosition(int x, int y)
495  {
496  top_ = y;
497  left_ = x;
498  }
499 
500  void PieChartDisplay::setPosition(int x, int y)
501  {
504  }
505 }
506 
rviz::BoolProperty * auto_color_change_property_
virtual QImage getQImage(unsigned int width, unsigned int height)
rviz::ColorProperty * fg_color_property_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
PLUGINLIB_EXPORT_CLASS(jsk_rviz_plugins::PictogramArrayDisplay, rviz::Display)
virtual QColor getColor() const
rviz::FloatProperty * bg_alpha_property_
rviz::ColorProperty * bg_color_property_
virtual bool isInRegion(int x, int y)
rviz::FloatProperty * med_color_threshold_property_
rviz::ColorProperty * max_color_property_
width
std::string getTopicStd() const
rviz::FloatProperty * fg_alpha_property_
rviz::FloatProperty * min_value_property_
virtual void processMessage(const std_msgs::Float32::ConstPtr &msg)
virtual void setPosition(int x, int y)
rviz::ColorProperty * med_color_property_
virtual void movePosition(int x, int y)
virtual QString getName() const
rviz::FloatProperty * max_value_property_
rviz::BoolProperty * clockwise_rotate_property_
virtual int getInt() const
rviz::RosTopicProperty * update_topic_property_
bool setValue(const QVariant &new_value) override
rviz::BoolProperty * show_caption_property_
virtual float getFloat() const
rviz::FloatProperty * fg_alpha2_property_
virtual void update(float wall_dt, float ros_dt)
height
virtual bool getBool() const
rviz::FloatProperty * max_color_threshold_property_
rviz::IntProperty * text_size_property_


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Thu Jun 1 2023 02:45:58