display.cpp
Go to the documentation of this file.
2 
3 namespace ram_qt_guis
4 {
5 Display::Display(QWidget* parent) :
6  rviz::Panel(parent)
7 {
8  setObjectName("Display");
9  setName(objectName());
10 
11  color_mode_ = new QComboBox;
12  color_mode_->addItem("Layer level");
13  color_mode_->addItem("Layer index");
14  color_mode_->addItem("Speed");
15  color_mode_->addItem("Pose type");
16  QHBoxLayout *color_mode_layout = new QHBoxLayout;
17  color_mode_layout->addWidget(new QLabel("Color by:"));
18  color_mode_layout->addWidget(color_mode_);
19 
20  display_mode_ = new QComboBox;
21  display_mode_->addItem("Wire-frame mode");
22  display_mode_->addItem("Cylinders mode");
23  display_mode_->addItem("Wire-frame + axis mode");
24  display_mode_->addItem("Cylinders + axis mode");
25  QHBoxLayout *display_mode_layout = new QHBoxLayout;
26  display_mode_layout->addWidget(new QLabel("Display mode:"));
27  display_mode_layout->addWidget(display_mode_);
28  connect(display_mode_, SIGNAL(currentIndexChanged(int)), this, SLOT(displayModeChanged()));
29 
30  cylinder_size_ = new QDoubleSpinBox;
31  cylinder_size_->setRange(0.01, 1000.0);
32  cylinder_size_->setSingleStep(0.1);
33  cylinder_size_->setValue(1);
34  cylinder_size_->setSuffix(" mm");
35  QHBoxLayout *cylinder_size_layout = new QHBoxLayout;
36  cylinder_size_layout->addWidget(new QLabel("Cylinder size:"));
37  cylinder_size_layout->addWidget(cylinder_size_);
38  cylinder_size_widget_ = new QWidget;
39  cylinder_size_widget_->setLayout(cylinder_size_layout);
40 
41  wire_size_ = new QDoubleSpinBox;
42  wire_size_->setRange(0.01, 1000.0);
43  wire_size_->setSingleStep(0.1);
44  wire_size_->setValue(1);
45  wire_size_->setSuffix(" mm");
46  QHBoxLayout *wire_size_layout = new QHBoxLayout;
47  wire_size_layout->addWidget(new QLabel("Wire size:"));
48  wire_size_layout->addWidget(wire_size_);
49  wire_size_widget_ = new QWidget;
50  wire_size_widget_->setLayout(wire_size_layout);
51 
52  axis_size_ = new QDoubleSpinBox;
53  axis_size_->setRange(0.01, 5000.0);
54  axis_size_->setSingleStep(1);
55  axis_size_->setValue(2);
56  axis_size_->setSuffix(" mm");
57  QHBoxLayout *axis_size_layout = new QHBoxLayout;
58  axis_size_layout->addWidget(new QLabel("Axis size:"));
59  axis_size_layout->addWidget(axis_size_);
60  axis_size_widget_ = new QWidget;
61  axis_size_widget_->setLayout(axis_size_layout);
62 
63  display_labels_ = new QCheckBox;
64  display_labels_->setText("Display labels");
65  display_labels_->setChecked(true);
66  connect(display_labels_, SIGNAL(clicked()), this, SLOT(enableLabelsBox()));
67 
68  label_type_ = new QComboBox;
69  label_type_->addItem("Pose ID");
70  label_type_->addItem("Layer level");
71  label_type_->addItem("Layer index");
72  label_type_->addItem("Pose ID within layer");
73 
74  label_text_size_ = new QDoubleSpinBox;
75  label_text_size_->setRange(0.01, 1000.0);
76  label_text_size_->setSingleStep(0.1);
77  label_text_size_->setValue(1);
78  label_text_size_->setSuffix(" mm");
79 
80  labels_container_ = new QWidget;
81  labels_container_->setEnabled(false);
82  QGridLayout* labels_container_layout = new QGridLayout(labels_container_);
83  labels_container_layout->addWidget(new QLabel("Labels type:"), 0, 0);
84  labels_container_layout->addWidget(label_type_, 0, 1);
85  labels_container_layout->addWidget(new QLabel("Labels size:"));
86  labels_container_layout->addWidget(label_text_size_);
87 
88  range_of_layers_ = new QCheckBox("Display a range of layers (levels)");
89  range_of_layers_->setChecked(true);
90 
91  first_layer_ = new QSpinBox;
92  first_layer_->setRange(0, 50000);
93  first_layer_->setValue(0);
94 
95  last_layer_ = new QSpinBox;
96  last_layer_->setRange(0, 50000);
97  last_layer_->setValue(0);
98 
99  range_of_layers_container_ = new QWidget;
100  range_of_layers_container_->setEnabled(false);
101  QGridLayout* range_of_layers_layout = new QGridLayout(range_of_layers_container_);
102  range_of_layers_layout->addWidget(new QLabel("First layer:"), 0, 0);
103  range_of_layers_layout->addWidget(first_layer_, 0, 1);
104  range_of_layers_layout->addWidget(new QLabel("Last layer:"), 1, 0);
105  range_of_layers_layout->addWidget(last_layer_, 1, 1);
106  connect(first_layer_, SIGNAL(valueChanged(int)), this, SLOT(tweakFirstLayer()));
107  connect(last_layer_, SIGNAL(valueChanged(int)), this, SLOT(tweakLastLayer()));
108  connect(range_of_layers_, SIGNAL(clicked()), this, SLOT(enableRangeLimitsBox()));
109 
110  mesh_color_ = new QPushButton("Pick mesh color");
111 
112  display_button_ = new QPushButton("Display markers");
113  delete_button_ = new QPushButton("Clear markers");
114  QHBoxLayout *buttons = new QHBoxLayout;
115  buttons->addWidget(display_button_);
116  buttons->addWidget(delete_button_);
117 
118  QVBoxLayout *scroll_widget_layout = new QVBoxLayout();
119  QWidget *scroll_widget = new QWidget;
120  scroll_widget->setLayout(scroll_widget_layout);
121  QScrollArea *scroll_area = new QScrollArea;
122  scroll_area->setWidget(scroll_widget);
123  scroll_area->setWidgetResizable(true);
124  scroll_area->setFrameShape(QFrame::NoFrame);
125  QVBoxLayout* main_layout = new QVBoxLayout(this);
126  main_layout->addWidget(scroll_area);
127 
128  scroll_widget_layout->addLayout(color_mode_layout);
129  scroll_widget_layout->addLayout(display_mode_layout);
130  scroll_widget_layout->addWidget(cylinder_size_widget_);
131  scroll_widget_layout->addWidget(wire_size_widget_);
132  scroll_widget_layout->addWidget(axis_size_widget_);
133  scroll_widget_layout->addWidget(display_labels_);
134  scroll_widget_layout->addWidget(labels_container_);
135  scroll_widget_layout->addWidget(range_of_layers_);
136  scroll_widget_layout->addWidget(range_of_layers_container_);
137  scroll_widget_layout->addWidget(mesh_color_);
138  scroll_widget_layout->addStretch(1);
139 
140  main_layout->addLayout(buttons);
141 
142  connect(mesh_color_, SIGNAL(clicked()), this, SLOT(pickColor()));
143  connect(display_button_, SIGNAL(clicked()), this, SLOT(sendDisplayInformationButtonHandler()));
144  connect(delete_button_, SIGNAL(clicked()), this, SLOT(sendDeleteInformationButtonHandler()));
145  connect(this, SIGNAL(displayErrorMessageBox(const QString, const QString, const QString)), this,
146  SLOT(displayErrorBoxHandler(const QString, const QString, const QString)));
147 
148  // connect with configChanged signal
149  connect(color_mode_, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged())); // Combo box
150  connect(display_mode_, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
151  connect(cylinder_size_, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); // double spin box
152  connect(wire_size_, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); // double spin box
153  connect(axis_size_, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); // double spin box
154  connect(display_labels_, SIGNAL(clicked()), this, SIGNAL(configChanged())); // QCheckBox
155  connect(label_type_, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged())); // Combo box
156  connect(label_text_size_, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); // double spin box
157  connect(range_of_layers_, SIGNAL(clicked()), this, SIGNAL(configChanged()));
158  connect(first_layer_, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
159  connect(last_layer_, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
160 
161  // Setup service clients
162  display_client_ = nh_.serviceClient<ram_display::DisplayTrajectory>("ram/display/add_trajectory");
163  delete_client_ = nh_.serviceClient<ram_display::DeleteTrajectory>("ram/display/delete_trajectory");
164  update_mesh_color_client_ = nh_.serviceClient<ram_display::UpdateMeshColor>("ram/display/update_mesh_color");
165 
166  // Check connection of client
167  QtConcurrent::run(this, &Display::connectToServices);
168 }
169 
171 {
172 }
173 
175 {
176  while (nh_.ok())
177  {
178  if (client.waitForExistence(ros::Duration(2)))
179  {
181  "RViz panel " << getName().toStdString() << " connected to the service " << client.getService());
182  break;
183  }
184  else
185  {
187  "RViz panel " << getName().toStdString() << " could not connect to ROS service: " << client.getService());
188  ros::Duration(1).sleep();
189  }
190  }
191 }
192 
194 {
195  Q_EMIT setEnabled(false);
199  ROS_INFO_STREAM("RViz panel " << getName().toStdString() << " services connections have been made");
200  Q_EMIT setEnabled(true);
201 }
202 
204 {
205  params_.request.axis_size = axis_size_->value() / 1000.0;
206  params_.request.cylinder_size = cylinder_size_->value() / 1000.0;
207  params_.request.label_type = label_type_->currentIndex();
208  params_.request.display_mode = display_mode_->currentIndex();
209  params_.request.labels_size = label_text_size_->value() / 1000.0;
210  params_.request.color_mode = color_mode_->currentIndex();
211  params_.request.wire_size = wire_size_->value() / 1000.0;
212  params_.request.display_labels = display_labels_->isChecked();
213  params_.request.display_range_of_layers = range_of_layers_->isChecked();
214  params_.request.first_layer = first_layer_->value();
215  params_.request.last_layer = last_layer_->value();
216  // Color is being modified in pickColor();
217 }
218 
220 {
221  switch (display_mode_->currentIndex())
222  {
223  case 0:
224  // Wire-frame mode
225  cylinder_size_widget_->setEnabled(false);
226  wire_size_widget_->setEnabled(true);
227  axis_size_widget_->setEnabled(false);
228  break;
229  case 1:
230  // Cylinders mode
231  cylinder_size_widget_->setEnabled(true);
232  wire_size_widget_->setEnabled(false);
233  axis_size_widget_->setEnabled(false);
234  break;
235  case 2:
236  // Wire-frame + axis mode
237  cylinder_size_widget_->setEnabled(false);
238  wire_size_widget_->setEnabled(true);
239  axis_size_widget_->setEnabled(true);
240  break;
241  case 3:
242  // Cylinders + axis mode
243  cylinder_size_widget_->setEnabled(true);
244  wire_size_widget_->setEnabled(false);
245  axis_size_widget_->setEnabled(true);
246  break;
247  default:
248  cylinder_size_widget_->setEnabled(true);
249  wire_size_widget_->setEnabled(true);
250  axis_size_widget_->setEnabled(true);
251  break;
252  }
253 }
254 
256 {
257  Q_EMIT setEnabled(false);
258 
259  QColorDialog color;
260  color.setModal(true);
261 
262  QColor old_color((int)(params_.request.mesh_color.r * 255),
263  (int)(params_.request.mesh_color.g * 255),
264  (int)(params_.request.mesh_color.b * 255),
265  (int)(params_.request.mesh_color.a * 255));
266  QColor rgba = color.getColor(old_color, this, "Mesh color", QColorDialog::ShowAlphaChannel);
267 
268  if (!rgba.isValid())
269  {
270  Q_EMIT setEnabled(true);
271  return;
272  }
273 
274  params_.request.mesh_color.r = rgba.red() / 255.0;
275  params_.request.mesh_color.g = rgba.green() / 255.0;
276  params_.request.mesh_color.b = rgba.blue() / 255.0;
277  params_.request.mesh_color.a = rgba.alpha() / 255.0;
278 
279  ram_display::UpdateMeshColor srv;
280  srv.request.color = params_.request.mesh_color;
282  Q_EMIT displayErrorBoxHandler("Update mesh color", "Updating the mesh color failed",
283  QString::fromStdString(update_mesh_color_client_.getService()));
284 
285  Q_EMIT setEnabled(true);
286 }
287 
289 {
290  Q_EMIT configChanged();
291  Q_EMIT setEnabled(false);
292 
294 
295  // Run in a separate thread
296  QtConcurrent::run(this, &Display::sendDisplayInformation);
297 }
298 
300 {
301  // Call service
302  bool success(display_client_.call(params_));
303 
304  if (!success)
305  {
306  Q_EMIT displayErrorMessageBox("Service call failed", QString::fromStdString(display_client_.getService()),
307  "Check the logs!");
308  }
309  else
310  {
311  if (!params_.response.error.empty())
312  {
313  Q_EMIT displayErrorMessageBox(QString::fromStdString(display_client_.getService()),
314  QString::fromStdString(params_.response.error),
315  "");
316  }
317  }
318  Q_EMIT setEnabled(true);
319 }
320 
322 {
323  Q_EMIT setEnabled(false);
324  // Run in a separate thread
325  QtConcurrent::run(this, &Display::sendDeleteInformation);
326 }
327 
329 {
330  // Call service
331  ram_display::DeleteTrajectory delete_traj;
332  bool success(delete_client_.call(delete_traj));
333 
334  if (!success)
335  {
336  Q_EMIT displayErrorMessageBox("Service call failed", QString::fromStdString(delete_client_.getService()),
337  "Check the logs!");
338  }
339  Q_EMIT setEnabled(true);
340 }
341 
343 {
344  range_of_layers_container_->setEnabled(range_of_layers_->isChecked());
345 }
346 
348 {
349  labels_container_->setEnabled(display_labels_->isChecked());
350 }
351 
353 {
354  if (first_layer_->value() > last_layer_->value())
355  last_layer_->setValue(first_layer_->value());
356 }
357 
359 {
360  if (first_layer_->value() > last_layer_->value())
361  first_layer_->setValue(last_layer_->value());
362 }
363 
364 void Display::load(const rviz::Config& config)
365 {
366  bool tmp_bool(false);
367  int tmp_int(0);
368  float tmp_float(0.01);
369 
370  if (config.mapGetInt("color_mode", &tmp_int))
371  color_mode_->setCurrentIndex(tmp_int);
372 
373  if (config.mapGetInt("display_mode", &tmp_int))
374  display_mode_->setCurrentIndex(tmp_int);
375 
376  if (config.mapGetFloat("cylinder_size", &tmp_float))
377  cylinder_size_->setValue(tmp_float);
378 
379  if (config.mapGetFloat("wire_size", &tmp_float))
380  wire_size_->setValue(tmp_float);
381 
382  if (config.mapGetFloat("label_text_size", &tmp_float))
383  label_text_size_->setValue (tmp_float);
384 
385  tmp_float = 0.05;
386  if (config.mapGetFloat("axis_size", &tmp_float))
387  axis_size_->setValue(tmp_float);
388 
389  if (config.mapGetInt("display_pose_layer", &tmp_int))
390  label_type_->setCurrentIndex(tmp_int);
391 
392  if (config.mapGetBool("display_labels", &tmp_bool))
393  display_labels_->setChecked(tmp_bool);
394  else
395  display_labels_->setChecked(true);
396 
397  enableLabelsBox();
398 
399  if (config.mapGetBool("range_of_layers", &tmp_bool))
400  range_of_layers_->setChecked(tmp_bool);
401  else
402  range_of_layers_->setChecked(false);
403 
405 
406  if (config.mapGetInt("first_layer", &tmp_int))
407  first_layer_->setValue(tmp_int);
408 
409  if (config.mapGetInt("last_layer", &tmp_int))
410  last_layer_->setValue(tmp_int);
411 
412  if (config.mapGetFloat("mesh_red", &tmp_float))
413  params_.request.mesh_color.r = tmp_float;
414  else
415  params_.request.mesh_color.r = 0.7;
416 
417  if (config.mapGetFloat("mesh_green", &tmp_float))
418  params_.request.mesh_color.g = tmp_float;
419  else
420  params_.request.mesh_color.g = 0.7;
421 
422  if (config.mapGetFloat("mesh_blue", &tmp_float))
423  params_.request.mesh_color.b = tmp_float;
424  else
425  params_.request.mesh_color.b = 0.7;
426 
427  if (config.mapGetFloat("mesh_alpha", &tmp_float))
428  params_.request.mesh_color.a = tmp_float;
429  else
430  params_.request.mesh_color.a = 0.75;
431 
432  rviz::Panel::load(config);
433  QtConcurrent::run(this, &Display::sendLoadedInformation);
434 }
435 
437 {
439 
440  // Try to send parameters
441  unsigned count(0);
442  while (1)
443  {
444  if (display_client_.exists())
445  {
446  Q_EMIT setEnabled(false);
448  ros::spinOnce();
449  Q_EMIT setEnabled(true);
450  break;
451  }
452  ros::Duration(0.5).sleep();
453 
454  if (++count > 5)
455  break;
456  }
457 }
458 
459 void Display::save(rviz::Config config) const
460  {
461  config.mapSetValue("color_mode", color_mode_->currentIndex());
462  config.mapSetValue("display_mode", display_mode_->currentIndex());
463  config.mapSetValue("cylinder_size", cylinder_size_->value());
464  config.mapSetValue("wire_size", wire_size_->value());
465  config.mapSetValue("axis_size", axis_size_->value());
466  config.mapSetValue("display_pose_layer", label_type_->currentIndex());
467  config.mapSetValue("label_text_size", label_text_size_->value());
468  config.mapSetValue("display_labels", display_labels_->isChecked());
469  config.mapSetValue("range_of_layers", range_of_layers_->isChecked());
470  config.mapSetValue("first_layer", first_layer_->value());
471  config.mapSetValue("last_layer", last_layer_->value());
472  config.mapSetValue("mesh_red", params_.request.mesh_color.r);
473  config.mapSetValue("mesh_green", params_.request.mesh_color.g);
474  config.mapSetValue("mesh_blue", params_.request.mesh_color.b);
475  config.mapSetValue("mesh_alpha", params_.request.mesh_color.a);
476  rviz::Panel::save(config);
477 }
478 
479 void Display::displayErrorBoxHandler(const QString title,
480  const QString message,
481  const QString info_msg)
482 {
483  bool old_state(isEnabled());
484  Q_EMIT setEnabled(false);
485  QMessageBox msg_box;
486  msg_box.setWindowTitle(title);
487  msg_box.setText(message);
488  msg_box.setInformativeText(info_msg);
489  msg_box.setIcon(QMessageBox::Critical);
490  msg_box.setStandardButtons(QMessageBox::Ok);
491  msg_box.exec();
492  Q_EMIT setEnabled(old_state);
493 }
494 
495 }
496 
QWidget * axis_size_widget_
Definition: display.hpp:71
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
QSpinBox * first_layer_
Definition: display.hpp:79
QComboBox * label_type_
Definition: display.hpp:74
void updateInternalParameters()
Definition: display.cpp:203
ram_display::DisplayTrajectory params_
Definition: display.hpp:89
void connectToService(ros::ServiceClient &client)
Definition: display.cpp:174
void sendLoadedInformation()
Definition: display.cpp:436
void sendDisplayInformation()
Definition: display.cpp:299
void displayErrorMessageBox(const QString, const QString, const QString)
QDoubleSpinBox * cylinder_size_
Definition: display.hpp:68
ros::NodeHandle nh_
Definition: display.hpp:85
bool sleep() const
bool call(MReq &req, MRes &res)
bool mapGetFloat(const QString &key, float *value_out) const
QWidget * range_of_layers_container_
Definition: display.hpp:78
ros::ServiceClient delete_client_
Definition: display.hpp:87
QDoubleSpinBox * wire_size_
Definition: display.hpp:70
QWidget * wire_size_widget_
Definition: display.hpp:69
void displayModeChanged()
Definition: display.cpp:219
void configChanged()
ros::ServiceClient update_mesh_color_client_
Definition: display.hpp:88
QWidget * labels_container_
Definition: display.hpp:73
QWidget * cylinder_size_widget_
Definition: display.hpp:67
void mapSetValue(const QString &key, QVariant value)
QPushButton * display_button_
Definition: display.hpp:81
QComboBox * display_mode_
Definition: display.hpp:66
ros::ServiceClient display_client_
Definition: display.hpp:86
QSpinBox * last_layer_
Definition: display.hpp:80
QCheckBox * display_labels_
Definition: display.hpp:76
virtual void setName(const QString &name)
QDoubleSpinBox * axis_size_
Definition: display.hpp:72
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
void load(const rviz::Config &config)
Definition: display.cpp:364
void save(rviz::Config config) const
Definition: display.cpp:459
bool mapGetBool(const QString &key, bool *value_out) const
void connectToServices()
Definition: display.cpp:193
virtual QString getName() const
Display(QWidget *parent=NULL)
Definition: display.cpp:5
QComboBox * color_mode_
Definition: display.hpp:65
bool mapGetInt(const QString &key, int *value_out) const
QCheckBox * range_of_layers_
Definition: display.hpp:77
#define ROS_INFO_STREAM(args)
QPushButton * mesh_color_
Definition: display.hpp:83
void enableRangeLimitsBox()
Definition: display.cpp:342
std::string getService()
void sendDeleteInformationButtonHandler()
Definition: display.cpp:321
virtual void save(Config config) const
void sendDeleteInformation()
Definition: display.cpp:328
bool ok() const
#define ROS_ERROR_STREAM(args)
virtual void load(const Config &config)
void displayErrorBoxHandler(const QString title, const QString message, const QString info_msg)
Definition: display.cpp:479
void sendDisplayInformationButtonHandler()
Definition: display.cpp:288
ROSCPP_DECL void spinOnce()
QDoubleSpinBox * label_text_size_
Definition: display.hpp:75
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
virtual ~Display()
Definition: display.cpp:170
QPushButton * delete_button_
Definition: display.hpp:82


ram_qt_guis
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Mon Jun 10 2019 14:50:11