linear_gauge_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 "linear_gauge_display.h"
38 #include <rviz/display_context.h>
39 #include <QPainter>
40 
41 namespace jsk_rviz_plugins
42 {
44  : rviz::Display(), data_(0.0), first_time_(true),
45  width_padding_(5), height_padding_(5)
46  {
48  "Topic", "",
49  ros::message_traits::datatype<std_msgs::Float32>(),
50  "std_msgs::Float32 topic to subscribe to.",
51  this, SLOT(updateTopic()));
53  "Show Value", true,
54  "Show value on plotter",
55  this, SLOT(updateShowValue()));
56 
58  "Vertical Gauge", false,
59  "set gauge vertical",
60  this, SLOT(updateVerticalGauge()));
61 
62  width_property_ = new rviz::IntProperty("width", 500,
63  "width of the plotter window",
64  this, SLOT(updateWidth()));
66  width_property_->setMax(2000);
67  height_property_ = new rviz::IntProperty("height", 50,
68  "height of the plotter window",
69  this, SLOT(updateHeight()));
71  height_property_->setMax(2000);
72  left_property_ = new rviz::IntProperty("left", 128,
73  "left of the plotter window",
74  this, SLOT(updateLeft()));
76  top_property_ = new rviz::IntProperty("top", 128,
77  "top of the plotter window",
78  this, SLOT(updateTop()));
80 
82  "max value", 100.0,
83  "max value, used only if auto scale is disabled",
84  this, SLOT(updateMaxValue()));
86  "min value", 0.0,
87  "min value, used only if auto scale is disabled",
88  this, SLOT(updateMinValue()));
90  "foreground color", QColor(25, 255, 240),
91  "color to draw line",
92  this, SLOT(updateFGColor()));
94  "foreground alpha", 0.7,
95  "alpha belnding value for foreground",
96  this, SLOT(updateFGAlpha()));
100  "background color", QColor(0, 0, 0),
101  "background color",
102  this, SLOT(updateBGColor()));
104  "backround alpha", 0.0,
105  "alpha belnding value for background",
106  this, SLOT(updateBGAlpha()));
109  line_width_property_ = new rviz::IntProperty("linewidth", 1,
110  "linewidth of the plot",
111  this, SLOT(updateLineWidth()));
115  "border", true,
116  "show border or not",
117  this, SLOT(updateShowBorder()));
118  text_size_property_ = new rviz::IntProperty("text size", 12,
119  "text size of the caption",
120  this, SLOT(updateTextSize()));
124  "show caption", true,
125  "show caption or not",
126  this, SLOT(updateShowCaption()));
128  "update interval", 0.04,
129  "update interval of the plotter",
130  this, SLOT(updateUpdateInterval()));
134  = new rviz::BoolProperty("auto color change",
135  false,
136  "change the color automatically",
137  this, SLOT(updateAutoColorChange()));
139  = new rviz::ColorProperty(
140  "max color",
141  QColor(255, 0, 0),
142  "only used if auto color change is set to True.",
143  this, SLOT(updateMaxColor()));
144  }
145 
147  {
148  onDisable();
149  // delete update_topic_property_;
150  // delete buffer_length_property_;
151  // delete fg_color_property_;
152  // delete bg_color_property_;
153  // delete fg_alpha_property_;
154  // delete bg_alpha_property_;
155  // delete top_property_;
156  // delete left_property_;
157  // delete width_property_;
158  // delete height_property_;
159  // delete line_width_property_;
160  // delete show_border_property_;
161  // delete auto_color_change_property_;
162  // delete max_color_property_;
163  // delete update_interval_property_;
164  // delete show_caption_property_;
165  // delete text_size_property_;
166  // delete min_value_property_;
167  // delete max_value_property_;
168  // delete auto_color_change_property_;
169  }
170 
172  {
173  static int count = 0;
175  ss << "LinearGaugeDisplayObject" << count++;
176  overlay_.reset(new OverlayObject(ss.str()));
177  onEnable();
178  updateShowValue();
180  updateWidth();
181  updateHeight();
182  updateLeft();
183  updateTop();
184  updateFGColor();
185  updateBGColor();
186  updateFGAlpha();
187  updateBGAlpha();
188  updateLineWidth();
192  updateMaxColor();
194  updateTextSize();
195  updateMinValue();
196  updateMaxValue();
197  overlay_->updateTextureSize(width_property_->getInt(),
199  }
200 
202  {
203  QColor fg_color(fg_color_);
204  QColor bg_color(bg_color_);
205  double max_gauge_length = 0.0;
206 
207  fg_color.setAlpha(fg_alpha_);
208  bg_color.setAlpha(bg_alpha_);
209 
210  if (auto_color_change_) {
211  double r
212  = std::min(std::max(data_ / (max_value_ - min_value_),
213  0.0), 1.0);
214  if (r > 0.3) {
215  double r2 = (r - 0.3) / 0.7;
216  fg_color.setRed((max_color_.red() - fg_color_.red()) * r2
217  + fg_color_.red());
218  fg_color.setGreen((max_color_.green() - fg_color_.green()) * r2
219  + fg_color_.green());
220  fg_color.setBlue((max_color_.blue() - fg_color_.blue()) * r2
221  + fg_color_.blue());
222  }
223  }
224 
225  {
226  ScopedPixelBuffer buffer = overlay_->getBuffer();
227  QImage Hud = buffer.getQImage(*overlay_);
228  // initilize by the background color
229  for (int i = 0; i < overlay_->getTextureWidth(); i++) {
230  for (int j = 0; j < overlay_->getTextureHeight(); j++) {
231  Hud.setPixel(i, j, bg_color.rgba());
232  }
233  }
234  // paste in HUD speedometer. I resize the image and offset it by 8 pixels from
235  // the bottom left edge of the render window
236  QPainter painter( &Hud );
237  painter.setRenderHint(QPainter::Antialiasing, true);
238  painter.setPen(QPen(fg_color, line_width_, Qt::SolidLine));
239 
240  uint16_t w = overlay_->getTextureWidth();
241  uint16_t h = overlay_->getTextureHeight() - caption_offset_;
242 
243  //draw gauge
244  if(vertical_gauge_)
245  {
246  double normalised_value = std::min(std::max((double)data_ - min_value_, 0.0), max_value_ - min_value_)*(h-2*height_padding_)/(max_value_-min_value_);
247  painter.fillRect(width_padding_, h-normalised_value-height_padding_, w-2*width_padding_, normalised_value, fg_color);
248  }
249  else
250  {
251  double normalised_value = std::min(std::max((double)data_ - min_value_, 0.0), max_value_ - min_value_)*(w-2*width_padding_)/(max_value_-min_value_);
252  painter.fillRect(width_padding_, height_padding_, normalised_value, h-(2*height_padding_), fg_color);
253  }
254 
255  // draw border
256  if (show_border_) {
257  painter.drawLine(0, 0, 0, h);
258  painter.drawLine(0, h, w, h);
259  painter.drawLine(w, h, w, 0);
260  painter.drawLine(w, 0, 0, 0);
261  }
262  // draw caption
263  if (show_caption_) {
264  QFont font = painter.font();
265  font.setPointSize(text_size_);
266  font.setBold(true);
267  painter.setFont(font);
268  painter.drawText(0, h, w, caption_offset_,
269  Qt::AlignCenter | Qt::AlignVCenter,
270  getName());
271  }
272 
273  //draw value
274  if (show_value_) {
275  QFont font = painter.font();
276  font.setPointSize(std::min(w-2*width_padding_, h-2*height_padding_));
277  font.setBold(true);
278  painter.setFont(font);
279  std::ostringstream ss;
280  ss << std::fixed << std::setprecision(2) << data_;
281 
282  if(w<h) //rotate text to fit gauge if needed
283  {
284  painter.translate(0, h);
285  painter.rotate(-90);
286  painter.drawText(0, 0, h, w,
287  Qt::AlignCenter | Qt::AlignVCenter,
288  ss.str().c_str());
289  painter.rotate(90);
290  painter.translate(0, -h);
291  }
292  else
293  {
294  painter.drawText(0, 0, w, h,
295  Qt::AlignCenter | Qt::AlignVCenter,
296  ss.str().c_str());
297  }
298  }
299 
300  // done
301  painter.end();
302  }
303  }
304 
305  void LinearGaugeDisplay::processMessage(const std_msgs::Float32::ConstPtr& msg)
306  {
307  boost::mutex::scoped_lock lock(mutex_);
308 
309  if (!isEnabled() || !overlay_->isVisible()) {
310  return;
311  }
312  if (data_ != msg->data || first_time_) {
313  first_time_ = false;
314  data_ = msg->data;
315  draw_required_ = true;
316  }
317 
318  }
319 
320  void LinearGaugeDisplay::update(float wall_dt, float ros_dt)
321  {
322  if (draw_required_) {
323  if (wall_dt + last_time_ > update_interval_) {
324  overlay_->updateTextureSize(texture_width_,
326  overlay_->setPosition(left_, top_);
327  overlay_->setDimensions(overlay_->getTextureWidth(), overlay_->getTextureHeight());
328  last_time_ = 0;
329  drawPlot();
330  draw_required_ = false;
331  }
332  else {
333  last_time_ = last_time_ + wall_dt;
334  }
335  }
336  }
337 
339  {
340  std::string topic_name = update_topic_property_->getTopicStd();
341  if (topic_name.length() > 0 && topic_name != "/") {
342  ros::NodeHandle n;
343  sub_ = n.subscribe(topic_name, 1, &LinearGaugeDisplay::processMessage, this);
344  }
345  }
346 
348  {
349  sub_.shutdown();
350  }
351 
353  {
354  last_time_ = 0;
355  draw_required_ = false;
356  subscribe();
357  overlay_->show();
358  }
359 
361  {
362  unsubscribe();
363  overlay_->hide();
364  }
365 
367  {
368  boost::mutex::scoped_lock lock(mutex_);
370  draw_required_ = true;
371  }
372 
374  {
375  boost::mutex::scoped_lock lock(mutex_);
377  draw_required_ = true;
378  }
379 
381  {
383  draw_required_ = true;
384  }
385 
387  {
389  draw_required_ = true;
390  }
391 
393  {
395  draw_required_ = true;
396  }
397 
399  {
401  draw_required_ = true;
402  }
403 
405  {
407  draw_required_ = true;
408  }
409 
411  {
413  draw_required_ = true;
414  }
415 
417  {
418  unsubscribe();
419  subscribe();
420  }
421 
423  {
425  draw_required_ = true;
426  }
427 
429  {
431  draw_required_ = true;
432  }
433 
435  {
437  draw_required_ = true;
438  }
439 
441  {
443  draw_required_ = true;
444  }
445 
447  {
449  if (auto_color_change_) {
451  }
452  else {
454  }
455  draw_required_ = true;
456  }
457 
459  {
461  draw_required_ = true;
462  }
463 
465  {
467  }
468 
470  {
472  QFont font;
473  font.setPointSize(text_size_);
474  caption_offset_ = QFontMetrics(font).height();
475  draw_required_ = true;
476  }
477 
479  {
481  if (show_caption_) {
483  }
484  else {
486  }
487  draw_required_ = true;
488  }
489 
491  {
493  }
494 
496  {
498  }
499 
500 
501 
503  {
504  return (top_ < y && top_ + texture_height_ > y &&
505  left_ < x && left_ + texture_width_ > x);
506  }
507 
509  {
510  top_ = y;
511  left_ = x;
512  }
513 
515  {
518  }
519 
520 
521 }
522 
void setMin(float min)
void setMax(float max)
virtual QImage getQImage(unsigned int width, unsigned int height)
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::BoolProperty * auto_color_change_property_
rviz::FloatProperty * update_interval_property_
void setMin(int min)
std::string getTopicStd() const
void setMax(int max)
virtual QString getName() const
virtual void update(float wall_dt, float ros_dt)
rviz::RosTopicProperty * update_topic_property_
virtual int getInt() const
bool isEnabled() const
bool setValue(const QVariant &new_value) override
w
virtual float getFloat() const
virtual bool getBool() const
virtual void processMessage(const std_msgs::Float32::ConstPtr &msg)


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