modify.cpp
Go to the documentation of this file.
1 #include <ram_qt_guis/modify.hpp>
2 
3 namespace ram_qt_guis
4 {
5 Modify::Modify(QWidget* parent) :
6  rviz::Panel(parent),
7  selection_mode_(0),
8  layer_level_(0),
9  is_propagating_(false)
10 {
11  setObjectName("Modify trajectory");
12  setName(objectName());
13 
14  layout_ = new QVBoxLayout();
15  QWidget *scroll_widget = new QWidget;
16  scroll_widget->setLayout(layout_);
17  QScrollArea *scroll_area = new QScrollArea;
18  scroll_area->setWidget(scroll_widget);
19  scroll_area->setWidgetResizable(true);
20  scroll_area->setFrameShape(QFrame::NoFrame);
21  QVBoxLayout* main_layout = new QVBoxLayout(this);
22  main_layout->addWidget(scroll_area);
23 
25 
26  connect(this, SIGNAL(displayErrorMessageBox(const QString, const QString, const QString)), this,
27  SLOT(displayErrorBoxHandler(const QString, const QString, const QString)));
28 
29  // Setup service clients
30  update_selection_client_ = nh_.serviceClient<ram_display::UpdateSelection>(
31  "ram/display/update_selection");
32 
33  get_trajectory_size_client_ = nh_.serviceClient<ram_utils::GetTrajectorySize>(
34  "ram/information/get_trajectory_size");
35 
36  get_number_of_layers_client_ = nh_.serviceClient<ram_utils::GetNumberOfLayersLevels>(
37  "ram/information/get_number_of_layers_levels");
38 
39  get_layer_size_client_ = nh_.serviceClient<ram_utils::GetLayerSize>(
40  "ram/information/get_layer_size");
41 
42  get_poses_from_trajectory_client_ = nh_.serviceClient<ram_modify_trajectory::GetPosesFromTrajectory>(
43  "ram/pose_selector/get_poses_from_trajectory");
44 
45  get_poses_from_layers_list_client_ = nh_.serviceClient<ram_modify_trajectory::GetPosesFromLayersList>(
46  "ram/pose_selector/get_poses_from_layers_list");
47 
48  get_poses_from_layer_client_ = nh_.serviceClient<ram_modify_trajectory::GetPosesFromLayer>(
49  "ram/pose_selector/get_poses_from_layer");
50 
51  // Modify services
52  modify_selected_poses_client_ = nh_.serviceClient<ram_modify_trajectory::ModifySelectedPoses>(
53  "ram/modify_trajectory/modify_selected_poses");
54 
55  delete_selected_poses_client_ = nh_.serviceClient<ram_modify_trajectory::DeleteSelectedPoses>(
56  "ram/modify_trajectory/delete_selected_poses");
57 
58  add_poses_client_ = nh_.serviceClient<ram_modify_trajectory::AddPoses>("ram/modify_trajectory/add_poses");
59 
60  reset_selected_poses_client_ = nh_.serviceClient<ram_modify_trajectory::ResetSelectedPoses>(
61  "ram/modify_trajectory/reset_selected_poses");
62 
63  // Geometric operation services
64  rotate_selected_poses_client_ = nh_.serviceClient<ram_modify_trajectory::RotateSelectedPoses>(
65  "ram/modify_trajectory/rotate_selected_poses");
66 
67  reflect_selected_poses_client_ = nh_.serviceClient<ram_modify_trajectory::ReflectSelectedPoses>(
68  "ram/modify_trajectory/reflect_selected_poses");
69 
70  scale_selected_poses_client_ = nh_.serviceClient<ram_modify_trajectory::ScaleSelectedPoses>(
71  "ram/modify_trajectory/scale_selected_poses");
72 
73  // Trajectory
74  traj_ = nh_.subscribe("ram/trajectory", 10, &Modify::trajReceived, this);
75 
76  // Check connection of client
77  QtConcurrent::run(this, &Modify::connectToServices);
78 }
79 
81 {
82 }
83 
84 void Modify::trajReceived(const ram_msgs::AdditiveManufacturingTrajectory::Ptr& msg)
85 {
86  std::lock_guard<std::mutex> lock(trajectory_mutex_);
87  trajectory_ = *msg;
88 
90 }
91 
92 void Modify::clearLayout(QLayout* layout,
93  bool delete_widgets)
94 {
95  const bool old_state(isEnabled());
96  Q_EMIT setEnabled(false);
97 
98  while (QLayoutItem* item = layout->takeAt(0))
99  {
100  QWidget* widget;
101  if ((delete_widgets)
102  && (widget = item->widget()))
103  {
104  delete widget;
105  }
106  if (QLayout* childLayout = item->layout())
107  {
108  clearLayout(childLayout, delete_widgets);
109  }
110  delete item;
111  }
112 
113  Q_EMIT setEnabled(old_state);
114 }
115 
117 {
118  Q_EMIT setEnabled(false);
120  layers_to_propagate_.clear();
121  is_propagating_ = false;
122 
123  // Clear displayed selection
124  ram_display::UpdateSelection srv; // Empty
126 
127  QGridLayout *buttons = new QGridLayout;
128 
129  selection_buttons_.clear();
130  selection_buttons_.push_back(new QRadioButton(""));
131  selection_buttons_.push_back(new QRadioButton(""));
132  selection_buttons_.push_back(new QRadioButton(""));
133 
134  buttons->addWidget(selection_buttons_[0], 0, 0);
135  QLabel *label_1 = new QLabel("Trajectory\nSelect one pose or more within the trajectory");
136  label_1->setWordWrap(true);
137  buttons->addWidget(label_1, 0, 1);
138 
139  buttons->addWidget(selection_buttons_[1]);
140  QLabel *label_2 = new QLabel("Layers\nSelect one layer or more");
141  label_2->setWordWrap(true);
142  buttons->addWidget(label_2);
143 
144  buttons->addWidget(selection_buttons_[2]);
145  QLabel *label_3 = new QLabel("Within layer\nSelect one pose or more within a specific layer.\n"
146  "You will be able to propagate this selection across layers afterwards.");
147  label_3->setWordWrap(true);
148  buttons->addWidget(label_3);
149 
150  QPushButton *start_selection = new QPushButton("Start selection");
151 
152  layout_->addWidget(new QLabel("Selection mode:"));
153  layout_->addLayout(buttons);
154 
155  selection_buttons_[selection_mode_]->setChecked(true);
156 
157  layout_->addStretch(1);
158  layout_->addWidget(start_selection);
159 
160  connect(start_selection, SIGNAL(clicked()), this, SLOT(selectionModeSelected()));
161  Q_EMIT setEnabled(true);
162 }
163 
165 {
166  // Get selection mode
167  unsigned selected_button(0);
168  for (auto button : selection_buttons_)
169  {
170  if (button->isChecked())
171  break;
172 
173  ++selected_button;
174  }
175  selection_mode_ = selected_button;
176  Q_EMIT configChanged();
177 
178  QString help_string;
179  unsigned min_value, max_value;
180 
181  // Trajectory selection
182  if (selection_mode_ == 0)
183  {
184  ram_utils::GetTrajectorySize srv;
186  {
187  displayErrorMessageBox("Modify trajectory - Selection mode", "Could not get the trajectory size",
188  "");
190  return;
191  }
192 
193  if (srv.response.trajectory_size == 0)
194  {
195  displayErrorMessageBox("Modify trajectory - Selection mode", "The trajectory is empty",
196  "Generate a trajectory first");
198  return;
199  }
200 
201  help_string = "Pick up the poses to be selected:";
202  min_value = 0;
203  max_value = srv.response.trajectory_size - 1;
204  }
205  // Layers selection OR within layer
206  else if (selection_mode_ == 1 || selection_mode_ == 2)
207  {
208  ram_utils::GetNumberOfLayersLevels srv;
210  {
211  displayErrorMessageBox("Modify trajectory - Selection mode", "Could not get the number of layers",
212  "The trajectory is probably empty");
214  return;
215  }
216 
217  if (srv.response.number_of_layers == 0)
218  {
219  displayErrorMessageBox("Modify trajectory - Selection mode", "The trajectory contains zero layer",
220  "The trajectory is probably empty");
222  return;
223  }
224 
225  if (selection_mode_ == 1)
226  {
227  help_string = "Pick up the layers to be selected:";
228  min_value = 0;
229  max_value = srv.response.number_of_layers - 1;
230  }
231  else
232  {
233  // Ask user which layer we are going to work with
234  QDialog *window = new QDialog;
235  window->setWindowTitle("Modify trajectory - Selection");
236  window->setModal(true);
237  QVBoxLayout *window_layout = new QVBoxLayout(window);
238  window->setLayout(window_layout);
239  window_layout->addWidget(new QLabel("Pick a layer to work with:"));
240  QSpinBox *layers_list = new QSpinBox;
241  layers_list->setRange(0, srv.response.number_of_layers - 1);
242  window_layout->addWidget(layers_list);
243 
244  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
245  | QDialogButtonBox::Cancel);
246  window_layout->addStretch(1);
247  window_layout->addWidget(button_box);
248  connect(button_box, &QDialogButtonBox::accepted, window, &QDialog::accept);
249  connect(button_box, &QDialogButtonBox::rejected, window, &QDialog::reject);
250 
251  if (!window->exec())
252  {
254  return;
255  }
256  layer_level_ = layers_list->value();
257 
258  ram_utils::GetLayerSize srv;
259  srv.request.layer_level = layer_level_;
260  if (!get_layer_size_client_.call(srv))
261  {
262  displayErrorMessageBox("Modify trajectory - Selection mode",
263  "Could not get the layer " + QString::number(layer_level_) + " size",
264  "");
266  return;
267  }
268 
269  if (srv.response.layer_size == 0)
270  {
271  displayErrorMessageBox("Modify trajectory - Selection mode",
272  "Could not get the layer " + QString::number(layer_level_) + " size",
273  "It is probably empty!");
274  return;
275  }
276 
277  help_string = "Pick up the poses to be selected inside layer " + QString::number(layer_level_) + ":";
278  min_value = 0;
279  max_value = srv.response.layer_size - 1;
280  }
281  }
282  // Error
283  else
284  {
285  displayErrorMessageBox("Modify trajectory - Selection mode", "Selection mode is out of range!", "");
287  return;
288  }
289 
290  changeGUIToRangeListSelection(help_string, min_value, max_value);
291 }
292 
293 void Modify::changeGUIToRangeListSelection(const QString help_string,
294  const unsigned min,
295  const unsigned max)
296 {
297  Q_EMIT setEnabled(false);
299  range_list_selection_ui_ = new ModifyRangeListSelection(layout_, help_string, min, max);
300 
301  connect(range_list_selection_ui_, SIGNAL(selectionChanged(std::vector<unsigned>)),
302  this,
303  SLOT(updateTemporarySelection(std::vector<unsigned>)));
304  connect(range_list_selection_ui_->button_box_, &QDialogButtonBox::accepted, this, &Modify::getSelection);
305  connect(range_list_selection_ui_->button_box_, &QDialogButtonBox::rejected, this, &Modify::changeGUIToSelectionMode);
306  Q_EMIT setEnabled(true);
307 }
308 
310 {
311  std::vector<unsigned> selected(range_list_selection_ui_->getSelection());
312  if (selected.empty())
313  {
314  displayErrorBoxHandler("Empty selection", "Cannot continue, the selection is empty!", "");
315  return;
316  }
317 
318  Q_EMIT setEnabled(false);
319 
320  // Make a service request to get the selection
321  switch (selection_mode_)
322  {
323  case 0:
324  {
325  ram_modify_trajectory::GetPosesFromTrajectory srv;
326  srv.request.pose_index_list = selected;
328  {
329  displayErrorMessageBox("Selection",
330  "Could not get poses from the trajectory poses indices.",
331  "");
332  Q_EMIT setEnabled(true);
333  return;
334  }
335 
336  selected_poses_ = srv.response.poses;
337  break;
338  }
339  case 1:
340  {
341  ram_modify_trajectory::GetPosesFromLayersList srv;
342  srv.request.layer_level_list = selected;
344  {
345  displayErrorMessageBox("Selection",
346  "Could not get poses from the layers list indices.",
347  "");
348  Q_EMIT setEnabled(true);
349  return;
350  }
351 
352  selected_poses_ = srv.response.poses;
353  if (selected_poses_.empty())
354  {
355  displayErrorMessageBox("Selection",
356  "The selection is empty, cannot continue.",
357  "");
358  Q_EMIT setEnabled(true);
359  return;
360  }
361  break;
362  }
363  case 2:
364  {
365  ram_modify_trajectory::GetPosesFromLayer srv;
366  srv.request.layer_level = layer_level_;
367  srv.request.index_list_relative = selected;
369  {
370  displayErrorMessageBox("Selection",
371  "Could not get poses from the layer relative indices list.",
372  "");
373  Q_EMIT setEnabled(true);
374  return;
375  }
376 
377  relative_indices_ = selected;
378  break;
379  }
380  default:
381  {
382  displayErrorMessageBox("Selection mode not recognized",
383  "Missing implementation in getSelection()",
384  "");
386  Q_EMIT setEnabled(true);
388  return;
389  break;
390  }
391  }
392 
393  Q_EMIT setEnabled(true);
394 
395  // Propagate selection across layers
396  if (selection_mode_ == 2)
397  {
398  ram_utils::GetNumberOfLayersLevels srv;
400  {
401  displayErrorMessageBox("Modify trajectory - Propagate", "Could not get the number of layers",
402  "The trajectory is probably empty");
404  return;
405  }
406 
407  Q_EMIT setEnabled(false);
409  std::vector<unsigned> locked;
410  locked.push_back(layer_level_);
411 
412  range_list_selection_ui_ = new ModifyRangeListSelection(layout_, "Propagate to layers:", 0,
413  srv.response.number_of_layers - 1,
414  locked);
415 
416  is_propagating_ = true;
417  connect(range_list_selection_ui_, SIGNAL(selectionChanged(std::vector<unsigned>)),
418  this,
419  SLOT(updateTemporarySelection(std::vector<unsigned>)));
420  connect(range_list_selection_ui_->button_box_, &QDialogButtonBox::accepted, this, &Modify::propagateSelection);
421  connect(range_list_selection_ui_->button_box_, &QDialogButtonBox::rejected, this,
423  Q_EMIT setEnabled(true);
424  }
425  else
427 }
428 
430 {
432  if (layers_to_propagate_.empty())
433  {
434  displayErrorBoxHandler("Propagate selection", "Layers to propagate vector is empty!", "");
436  return;
437  }
438 
439  if (layers_to_propagate_.size() != 1 && !trajectory_.similar_layers)
440  {
441  Q_EMIT setEnabled(false);
442  QMessageBox msg_box;
443  msg_box.setWindowTitle("Warning: propagating");
444  msg_box.setText("You are trying to propagate a selection on a trajectory with non-similar layers.");
445  msg_box.setInformativeText("Make sure your propagation makes sense!");
446  msg_box.setIcon(QMessageBox::Warning);
447  msg_box.setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
448  if (msg_box.exec() != QMessageBox::Ok)
449  {
450  Q_EMIT setEnabled(true);
451  return;
452  }
453 
454  Q_EMIT setEnabled(true);
455  }
456 
457  selected_poses_.clear();
458 
459  // Call GetPosesFromLayer multiple times and check whether this is ok
460  for (unsigned i(0); i < layers_to_propagate_.size(); ++i)
461  {
462  ram_modify_trajectory::GetPosesFromLayer srv;
463  srv.request.index_list_relative = relative_indices_;
464  srv.request.layer_level = layers_to_propagate_[i];
466  {
468  "Propagate selection",
469  QString::fromStdString("Failed to propagate selection to layer " + std::to_string(layers_to_propagate_[i])),
470  "De-select this layer and try again.");
471  return;
472  }
473 
474  // Append to selection vector
475  selected_poses_.insert(selected_poses_.end(), srv.response.poses.begin(), srv.response.poses.end());
476  }
477 
478  is_propagating_ = false;
480 }
481 
483 {
484  Q_EMIT setEnabled(false);
486 
487  ram_display::UpdateSelection srv;
488  srv.request.selected_poses = selected_poses_;
489  srv.request.temporary = false;
490  if (!update_selection_client_.call(srv))
491  {
492  displayErrorBoxHandler("Failed to display selection", "The selection cannot be displayed", "Aborting operation");
494  }
495 
496  layout_->addWidget(
497  new QLabel(QString::fromStdString(std::to_string(selected_poses_.size()) + " poses are selected.")));
498  layout_->addStretch(1);
499 
500  layout_->addWidget(new QLabel("<b>Operation:</b>"));
501 
502  QRadioButton *button_0 = new QRadioButton("Modify");
503  QRadioButton *button_1 = new QRadioButton("Add");
504  QRadioButton *button_2 = new QRadioButton("Delete");
505  QRadioButton *button_3 = new QRadioButton("Reset");
506  operations_.clear();
507  operations_.push_back(button_0);
508  operations_.push_back(button_1);
509  operations_.push_back(button_2);
510  operations_.push_back(button_3);
511  button_0->setChecked(true);
512 
513  for (auto button : operations_)
514  layout_->addWidget(button);
515 
516  layout_->addStretch(1);
517  layout_->addWidget(new QLabel("<b>Geometric operation:</b>"));
518 
519  QRadioButton *button_4 = new QRadioButton("Rotate");
520  QRadioButton *button_5 = new QRadioButton("Reflect");
521  QRadioButton *button_6 = new QRadioButton("Scale");
522 
523  geometric_operations_.clear();
524  geometric_operations_.push_back(button_4);
525  geometric_operations_.push_back(button_5);
526  geometric_operations_.push_back(button_6);
527 
528  for (auto button : geometric_operations_)
529  layout_->addWidget(button);
530 
531  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
532  | QDialogButtonBox::Cancel);
533  layout_->addStretch(2);
534  layout_->addWidget(button_box);
535 
536  connect(button_box, &QDialogButtonBox::accepted, this, &Modify::operationSelected);
537  connect(button_box, &QDialogButtonBox::rejected, this, &Modify::changeGUIToSelectionMode);
538  Q_EMIT setEnabled(true);
539 }
540 
542 {
543  unsigned operation_mode(0);
544  for (auto button : operations_)
545  if (button && button->isChecked())
546  break;
547  else
548  ++operation_mode;
549 
550  if (operation_mode == operations_.size())
551  {
552  for (auto button : geometric_operations_)
553  if (button && button->isChecked())
554  break;
555  else
556  ++operation_mode;
557  }
558 
559  Q_EMIT setEnabled(false);
560 
561  switch (operation_mode)
562  {
563  // Modify poses
564  case 0:
565  {
567  return;
568  break;
569  }
570  // Add poses
571  case 1:
572  {
573  ram_modify_trajectory::AddPoses srv;
574  srv.request.poses = selected_poses_;
575  if (!add_poses_client_.call(srv))
576  {
577  displayErrorBoxHandler("Error", "Could not add poses!",
578  "Pick another one.");
579  Q_EMIT setEnabled(true);
580  return;
581  }
582  break;
583  }
584  // Delete poses
585  case 2:
586  {
587  ram_modify_trajectory::DeleteSelectedPoses srv;
588  srv.request.poses = selected_poses_;
590  {
591  displayErrorBoxHandler("Error", "Could not delete the selection!",
592  "Pick another one. Note that you cannot delete the whole trajectory");
593  Q_EMIT setEnabled(true);
594  return;
595  }
596  break;
597  }
598  // Reset poses
599  case 3:
600  {
601  ram_modify_trajectory::ResetSelectedPoses srv;
602  srv.request.poses = selected_poses_;
604  {
605  displayErrorBoxHandler("Error", "Could not reset the selection!",
606  "Pick another one.");
607  Q_EMIT setEnabled(true);
608  return;
609  }
610  break;
611  }
612  // Rotate poses
613  case 4:
614  {
616  return;
617  break;
618  }
619  // Reflect poses
620  case 5:
621  {
623  return;
624  break;
625  }
626  // Dilate poses
627  case 6:
628  {
630  return;
631  break;
632  }
633 
634  default:
635  displayErrorBoxHandler("Operation", "Error selecting operation mode", "");
636  return;
637  break;
638  }
639 
640  Q_EMIT setEnabled(true);
642 }
643 
645 {
646  Q_EMIT setEnabled(false);
648 
649  // Determine if all poses have the same motion type or not
650  // If yes, modifying speed is enabled
651  // If no, modifying speed is only enabled if movement type is modified
652  if (selected_poses_.empty())
653  {
655  displayErrorBoxHandler("Modify poses", "Empty selection, aborting.", "");
656  Q_EMIT setEnabled(true);
657  return;
658  }
659 
660  std::vector<ram_msgs::AdditiveManufacturingParams::_movement_type_type> move_types;
661  for (auto pose : selected_poses_)
662  move_types.push_back(pose.params.movement_type);
663 
664  if (std::all_of(move_types.cbegin(), move_types.cend(), [](int i)
665  { return i == 0;}))
666  {
668  }
669  else if (std::all_of(move_types.cbegin(), move_types.cend(), [](int i)
670  { return i == 1;}))
671  {
673  }
674  else
676 
677  connect(modify_poses_ui_, SIGNAL(setEnabled(bool)), this, SLOT(setEnabled(bool)));
678  connect(modify_poses_ui_->button_box_, &QDialogButtonBox::accepted, this, &Modify::modifyPoses);
679  connect(modify_poses_ui_->button_box_, &QDialogButtonBox::rejected, this, &Modify::changeGUIToSelectionMode);
680  Q_EMIT setEnabled(true);
681 }
682 
684 {
685  // Check that at least one tick is checked!
686  std::vector<QCheckBox *> checkboxes;
687  checkboxes.push_back(modify_poses_ui_->approach_type_modify_);
688  checkboxes.push_back(modify_poses_ui_->blend_radius_modify_);
689  checkboxes.push_back(modify_poses_ui_->feed_rate_modify_);
690  checkboxes.push_back(modify_poses_ui_->laser_power_modify_);
691  checkboxes.push_back(modify_poses_ui_->movement_type_modify_);
692  checkboxes.push_back(modify_poses_ui_->polygon_end_modify_);
693  checkboxes.push_back(modify_poses_ui_->polygon_start_modify_);
694  checkboxes.push_back(modify_poses_ui_->pose_modify_);
695  checkboxes.push_back(modify_poses_ui_->speed_modify_);
696 
697  std::vector<bool> checkbox_ticks;
698  for (auto checkbox : checkboxes)
699  checkbox_ticks.push_back(checkbox->isChecked());
700 
701  if (std::all_of(checkbox_ticks.begin(), checkbox_ticks.end(), [](bool v)
702  { return !v;}))
703  {
704  displayErrorBoxHandler("Modify", "No item is ticked to be modified", "Please tick at least one item");
705  return;
706  }
707 
708  // Some fields are left un-initialized, this is fine because
709  // we are NOT using these fields. (eg: we cannot change the UUID of a pose!)
710  ram_modify_trajectory::ModifySelectedPoses srv;
711  srv.request.poses = selected_poses_;
712 
713  if (!modify_poses_ui_->pose_modify_->isChecked())
714  {
715  // Don't modify = send identity pose + relative mode
716  Eigen::Affine3d id(Eigen::Affine3d::Identity());
717  tf::poseEigenToMsg(id, srv.request.pose_reference.pose);
718  srv.request.pose = false; // Relative mode
719  }
720  else
721  {
722  srv.request.pose = modify_poses_ui_->pose_abs_rel_->currentIndex();
723  tf::poseEigenToMsg(modify_poses_ui_->pose_->getPose(), srv.request.pose_reference.pose);
724  }
725 
726  srv.request.pose_reference.params.approach_type = modify_poses_ui_->approach_type_->currentIndex();
727  srv.request.approach_type = modify_poses_ui_->approach_type_modify_->isChecked();
728 
729  srv.request.movement_type = modify_poses_ui_->movement_type_modify_->isChecked();
730  srv.request.pose_reference.params.movement_type = modify_poses_ui_->movement_type_->currentIndex();
731 
732  srv.request.polygon_end = modify_poses_ui_->polygon_end_modify_->isChecked();
733  srv.request.pose_reference.polygon_end = modify_poses_ui_->polygon_end_->currentIndex();
734 
735  srv.request.polygon_start = modify_poses_ui_->polygon_start_modify_->isChecked();
736  srv.request.pose_reference.polygon_start = modify_poses_ui_->polygon_start_->currentIndex();
737 
738  // Blend radius
739  if (!modify_poses_ui_->blend_radius_modify_->isChecked())
740  {
741  // Don't modify = send 0 + relative mode
742  srv.request.pose_reference.params.blend_radius = 0;
743  srv.request.blend_radius = false; // Relative
744  }
745  else
746  {
747  srv.request.blend_radius = modify_poses_ui_->blend_radius_abs_rel_->currentIndex();
748  srv.request.pose_reference.params.blend_radius = modify_poses_ui_->blend_radius_->value();
749  }
750 
751  // Speed
752  if (!modify_poses_ui_->speed_modify_->isChecked())
753  {
754  // Don't modify = send 0 + relative mode
755  srv.request.pose_reference.params.speed = 0;
756  srv.request.speed = false; // Relative
757  }
758  else
759  {
760  srv.request.speed = modify_poses_ui_->speed_abs_rel_->currentIndex();
761  // Convert meters/min in meters/sec
762  srv.request.pose_reference.params.speed = modify_poses_ui_->speed_->value()
764  }
765 
766  // Laser power
767  if (!modify_poses_ui_->laser_power_modify_->isChecked())
768  {
769  // Don't modify = send 0 + relative mode
770  srv.request.pose_reference.params.laser_power = 0;
771  srv.request.laser_power = false; // Relative
772  }
773  else
774  {
775  srv.request.laser_power = modify_poses_ui_->laser_power_abs_rel_->currentIndex();
776  srv.request.pose_reference.params.laser_power = modify_poses_ui_->laser_power_->value();
777  }
778 
779  // Feed rate
780  if (!modify_poses_ui_->feed_rate_modify_->isChecked())
781  {
782  // Don't modify = send 0 + relative mode
783  srv.request.pose_reference.params.feed_rate = 0;
784  srv.request.feed_rate = false; // Relative
785  }
786  else
787  {
788  srv.request.feed_rate = modify_poses_ui_->feed_rate_abs_rel_->currentIndex();
789  // Convert meters/min in meters/sec
790  srv.request.pose_reference.params.feed_rate = modify_poses_ui_->feed_rate_->value() / 60.0;
791  }
792 
794  {
795  displayErrorBoxHandler("Error", "Could not modify the selection!",
796  "Make sure none of the values go below zero!");
797  return;
798  }
799 
801 }
802 
804 {
805  Q_EMIT setEnabled(false);
807 
808  rotation_angle_ = new QDoubleSpinBox;
809  rotation_angle_->setRange(-180, 180);
810  rotation_angle_->setSuffix(" °");
811 
812  QHBoxLayout * rotation_angle_layout = new QHBoxLayout;
813  rotation_angle_layout->addWidget(new QLabel("Rotation angle in z-axis:"));
814  rotation_angle_layout->addWidget(rotation_angle_);
815 
816  rotation_point_x_ = new QDoubleSpinBox;
817  rotation_point_x_->setSuffix(" mm");
818  rotation_point_x_->setRange(-9999, 9999);
819 
820  rotation_point_y_ = new QDoubleSpinBox;
821  rotation_point_y_->setSuffix(" mm");
822  rotation_point_y_->setRange(-9999, 9999);
823 
824  QHBoxLayout * rotation_point_layout = new QHBoxLayout;
825  rotation_point_layout->addWidget(new QLabel("Rotation point:"));
826  rotation_point_layout->addWidget(new QLabel("X:"));
827  rotation_point_layout->addWidget(rotation_point_x_);
828  rotation_point_layout->addWidget(new QLabel("Y:"));
829  rotation_point_layout->addWidget(rotation_point_y_);
830 
831  layout_->addLayout(rotation_angle_layout);
832  layout_->addLayout(rotation_point_layout);
833  layout_->addStretch(1);
834 
835  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
836  | QDialogButtonBox::Cancel);
837  layout_->addStretch(2);
838  layout_->addWidget(button_box);
839 
840  connect(button_box, &QDialogButtonBox::accepted, this, &Modify::rotatePoses);
841  connect(button_box, &QDialogButtonBox::rejected, this, &Modify::changeGUIToSelectionMode);
842  Q_EMIT setEnabled(true);
843 }
844 
846 {
847  ram_modify_trajectory::RotateSelectedPoses srv;
848 
849  srv.request.poses = selected_poses_;
850 
851  srv.request.rotation_angle = rotation_angle_->value() * M_PI / 180.0;
852  srv.request.center_of_rotation.x = rotation_point_x_->value() / 1000.0;
853  srv.request.center_of_rotation.y = rotation_point_y_->value() / 1000.0;
854  srv.request.center_of_rotation.z = 0;
855 
857  {
858  displayErrorBoxHandler("Error", "Could not rotate the selection!",
859  "");
860  return;
861  }
862 
864 
865 }
866 
868 {
869  Q_EMIT setEnabled(false);
871 
872  reflect_vector_x_ = new QDoubleSpinBox;
873  reflect_vector_x_->setRange(-9999, 9999);
874  reflect_vector_x_->setValue(1);
875 
876  reflect_vector_y_ = new QDoubleSpinBox;
877  reflect_vector_y_->setRange(-9999, 9999);
878  reflect_vector_y_->setValue(0);
879 
880  QHBoxLayout * reflect_vector_layout = new QHBoxLayout;
881  reflect_vector_layout->addWidget(new QLabel("X:"));
882  reflect_vector_layout->addWidget(reflect_vector_x_);
883  reflect_vector_layout->addWidget(new QLabel("Y:"));
884  reflect_vector_layout->addWidget(reflect_vector_y_);
885 
886  //
887  reflect_point_x_ = new QDoubleSpinBox;
888  reflect_point_x_->setSuffix(" mm");
889  reflect_point_x_->setRange(-9999, 9999);
890 
891  reflect_point_y_ = new QDoubleSpinBox;
892  reflect_point_y_->setSuffix(" mm");
893  reflect_point_y_->setRange(-9999, 9999);
894 
895  QHBoxLayout * reflect_point_layout = new QHBoxLayout;
896  reflect_point_layout->addWidget(new QLabel("X:"));
897  reflect_point_layout->addWidget(reflect_point_x_);
898  reflect_point_layout->addWidget(new QLabel("Y:"));
899  reflect_point_layout->addWidget(reflect_point_y_);
900 
901  layout_->addWidget(new QLabel("Normal vector to reflection plane:"));
902  layout_->addLayout(reflect_vector_layout);
903  layout_->addWidget(new QLabel("Point on reflection plane:"));
904  layout_->addLayout(reflect_point_layout);
905  layout_->addStretch(1);
906 
907  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
908  | QDialogButtonBox::Cancel);
909  layout_->addStretch(2);
910  layout_->addWidget(button_box);
911 
912  connect(button_box, &QDialogButtonBox::accepted, this, &Modify::reflectPoses);
913  connect(button_box, &QDialogButtonBox::rejected, this, &Modify::changeGUIToSelectionMode);
914  Q_EMIT setEnabled(true);
915 }
916 
918 {
919  ram_modify_trajectory::ReflectSelectedPoses srv;
920 
921  srv.request.poses = selected_poses_;
922 
923  srv.request.normal_vector.x = reflect_vector_x_->value() / 1000.0;
924  srv.request.normal_vector.y = reflect_vector_y_->value() / 1000.0;
925  srv.request.normal_vector.z = 0;
926 
927  srv.request.point_on_plane.x = reflect_point_x_->value() / 1000.0;
928  srv.request.point_on_plane.y = reflect_point_y_->value() / 1000.0;
929  srv.request.point_on_plane.z = 0;
930 
932  {
933  displayErrorBoxHandler("Error", "Could not reflect the selection!",
934  "");
935  return;
936  }
937 
939 
940 }
941 
943 {
944  Q_EMIT setEnabled(false);
946 
947  scale_factor_ = new QDoubleSpinBox;
948  scale_factor_->setRange(0, 999);
949  scale_factor_->setValue(1);
950  scale_factor_->setSingleStep(0.01);
951 
952  QHBoxLayout * scale_factor_layout = new QHBoxLayout;
953  scale_factor_layout->addWidget(new QLabel("Scale factor :"));
954  scale_factor_layout->addWidget(scale_factor_);
955 
956  scale_center_x_ = new QDoubleSpinBox;
957  scale_center_x_->setSuffix(" mm");
958  scale_center_x_->setRange(-9999, 9999);
959 
960  scale_center_y_ = new QDoubleSpinBox;
961  scale_center_y_->setSuffix(" mm");
962  scale_center_y_->setRange(-9999, 9999);
963 
964  QHBoxLayout * scale_center_layout = new QHBoxLayout;
965  scale_center_layout->addWidget(new QLabel("Center of scaling :"));
966  scale_center_layout->addWidget(new QLabel("X:"));
967  scale_center_layout->addWidget(scale_center_x_);
968  scale_center_layout->addWidget(new QLabel("Y:"));
969  scale_center_layout->addWidget(scale_center_y_);
970 
971  layout_->addLayout(scale_factor_layout);
972  layout_->addLayout(scale_center_layout);
973  layout_->addStretch(1);
974 
975  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
976  | QDialogButtonBox::Cancel);
977  layout_->addStretch(2);
978  layout_->addWidget(button_box);
979 
980  connect(button_box, &QDialogButtonBox::accepted, this, &Modify::scalePoses);
981  connect(button_box, &QDialogButtonBox::rejected, this, &Modify::changeGUIToSelectionMode);
982  Q_EMIT setEnabled(true);
983 
984 }
985 
987 {
988  displayErrorBoxHandler("Warning", "This operation modifies trajectory parameters", "");
989 
990  ram_modify_trajectory::ScaleSelectedPoses srv;
991 
992  srv.request.poses = selected_poses_;
993 
994  srv.request.scale_factor = scale_factor_->value();
995 
996  srv.request.center_of_scaling.x = scale_center_x_->value() / 1000.0;
997  srv.request.center_of_scaling.y = scale_center_x_->value() / 1000.0;
998  srv.request.center_of_scaling.z = 0;
999 
1001  {
1002  displayErrorBoxHandler("Error", "Could not reflect the selection!",
1003  "");
1004  return;
1005  }
1006 
1008 }
1009 
1011 {
1012  while (nh_.ok())
1013  {
1014  if (client.waitForExistence(ros::Duration(2)))
1015  {
1017  "RViz panel " << getName().toStdString() << " connected to the service " << client.getService());
1018  break;
1019  }
1020  else
1021  {
1023  "RViz panel " << getName().toStdString() << " could not connect to ROS service: " << client.getService());
1024  ros::Duration(1).sleep();
1025  }
1026  }
1027 }
1028 
1030 {
1031  Q_EMIT setEnabled(false);
1032  // Display
1034  // Pose selector
1041  // Modify services
1046  // Geometric operation services
1049 
1050  ROS_INFO_STREAM("RViz panel " << getName().toStdString() << " services connections have been made");
1051  Q_EMIT setEnabled(true);
1052 }
1053 
1054 void Modify::load(const rviz::Config& config)
1055 {
1056  int tmp;
1057  Q_EMIT configChanged();
1058  if (config.mapGetInt("selection_mode", &tmp))
1059  {
1060  selection_mode_ = (unsigned)tmp;
1061  selection_buttons_[selection_mode_]->setChecked(true);
1062  }
1063  rviz::Panel::load(config);
1064 }
1065 
1066 void Modify::save(rviz::Config config) const
1067  {
1068  config.mapSetValue("selection_mode", selection_mode_);
1069  rviz::Panel::save(config);
1070 }
1071 
1072 void Modify::displayErrorBoxHandler(const QString title,
1073  const QString message,
1074  const QString info_msg)
1075 {
1076  bool old_state(isEnabled());
1077  Q_EMIT setEnabled(false);
1078  QMessageBox msg_box;
1079  msg_box.setWindowTitle(title);
1080  msg_box.setText(message);
1081  msg_box.setInformativeText(info_msg);
1082  msg_box.setIcon(QMessageBox::Critical);
1083  msg_box.setStandardButtons(QMessageBox::Ok);
1084  msg_box.exec();
1085  Q_EMIT setEnabled(old_state);
1086 }
1087 
1088 void Modify::updateTemporarySelection(std::vector<unsigned> selection)
1089 {
1090  ram_display::UpdateSelection srv_tmp_select;
1091  srv_tmp_select.request.temporary = true;
1092 
1093  switch (selection_mode_)
1094  {
1095  case 0:
1096  {
1097  ram_modify_trajectory::GetPosesFromTrajectory srv;
1098  srv.request.pose_index_list = selection;
1100  srv_tmp_select.request.selected_poses = srv.response.poses;
1101  break;
1102  }
1103  case 1:
1104  {
1105  ram_modify_trajectory::GetPosesFromLayersList srv;
1106  srv.request.layer_level_list = selection;
1108  srv_tmp_select.request.selected_poses = srv.response.poses;
1109  break;
1110  }
1111  case 2:
1112  {
1113  if (!is_propagating_)
1114  {
1115  ram_modify_trajectory::GetPosesFromLayer srv;
1116  srv.request.index_list_relative = selection;
1117  srv.request.layer_level = layer_level_;
1118 
1120  srv_tmp_select.request.selected_poses.clear();
1121  else
1122  srv_tmp_select.request.selected_poses = srv.response.poses;
1123  }
1124  else
1125  {
1126  // Call GetPosesFromLayer multiple times and check whether this is ok
1127  for (unsigned i(0); i < selection.size(); ++i)
1128  {
1129  ram_modify_trajectory::GetPosesFromLayer srv;
1130  srv.request.index_list_relative = relative_indices_;
1131  srv.request.layer_level = selection[i];
1132  if (!get_poses_from_layer_client_.call(srv)) // If one of the call fails, don't display anything
1133  {
1134  srv_tmp_select.request.selected_poses.clear();
1135  break;
1136  }
1137  else
1138  {
1139  // Append to selection vector
1140  srv_tmp_select.request.selected_poses.insert(srv_tmp_select.request.selected_poses.end(),
1141  srv.response.poses.begin(),
1142  srv.response.poses.end());
1143  }
1144  }
1145  }
1146  break;
1147  }
1148  default:
1149  {
1150  ROS_ERROR_STREAM("Missing implementation in Modify Qt panel inside updateTemporarySelection");
1151  return;
1152  break;
1153  }
1154  }
1155 
1156  if (!update_selection_client_.call(srv_tmp_select))
1157  ROS_WARN_STREAM("Could not update temporary selection in Modify Qt panel");
1158 }
1159 
1160 }
1161 
QDoubleSpinBox * reflect_point_y_
Definition: modify.hpp:115
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
QComboBox * feed_rate_abs_rel_
ros::ServiceClient modify_selected_poses_client_
Definition: modify.hpp:153
void selectionModeSelected()
Definition: modify.cpp:164
QDoubleSpinBox * reflect_vector_y_
Definition: modify.hpp:112
QDoubleSpinBox * reflect_point_x_
Definition: modify.hpp:114
void changeGUIToRangeListSelection(const QString help_string, const unsigned min, const unsigned max)
Definition: modify.cpp:293
void connectToService(ros::ServiceClient &client)
Definition: modify.cpp:1010
ros::ServiceClient reset_selected_poses_client_
Definition: modify.hpp:156
void trajReceived(const ram_msgs::AdditiveManufacturingTrajectory::Ptr &msg)
Definition: modify.cpp:84
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::ServiceClient update_selection_client_
Definition: modify.hpp:142
QCheckBox * approach_type_modify_
ros::ServiceClient get_poses_from_trajectory_client_
Definition: modify.hpp:149
QCheckBox * polygon_end_modify_
ModifyPoses * modify_poses_ui_
Definition: modify.hpp:103
bool sleep() const
std::vector< unsigned > relative_indices_
Definition: modify.hpp:132
void changeGUIToOperationSelection()
Definition: modify.cpp:482
ros::NodeHandle nh_
Definition: modify.hpp:134
QDoubleSpinBox * rotation_point_y_
Definition: modify.hpp:108
void changeGUIToRotatePoses()
Definition: modify.cpp:803
bool call(MReq &req, MRes &res)
void propagateSelection()
Definition: modify.cpp:429
QDoubleSpinBox * speed_
std::mutex trajectory_mutex_
Definition: modify.hpp:138
QComboBox * blend_radius_abs_rel_
void configChanged()
unsigned layer_level_
Definition: modify.hpp:129
void getPose(Eigen::Affine3d &pose)
void operationSelected()
Definition: modify.cpp:541
void clearLayout(QLayout *layout, bool delete_widgets=true)
Definition: modify.cpp:92
ros::ServiceClient get_poses_from_layer_client_
Definition: modify.hpp:147
void connectToServices()
Definition: modify.cpp:1029
void mapSetValue(const QString &key, QVariant value)
Modify(QWidget *parent=NULL)
Definition: modify.cpp:5
std::vector< unsigned > layers_to_propagate_
Definition: modify.hpp:131
void changeGUIToReflectPoses()
Definition: modify.cpp:867
unsigned selection_mode_
Definition: modify.hpp:128
void save(rviz::Config config) const
Definition: modify.cpp:1066
QVector< QRadioButton * > selection_buttons_
Definition: modify.hpp:100
QCheckBox * movement_type_modify_
QDoubleSpinBox * scale_factor_
Definition: modify.hpp:118
virtual void setName(const QString &name)
std::vector< QRadioButton * > operations_
Definition: modify.hpp:123
void updateTemporarySelection(std::vector< unsigned > selection)
Definition: modify.cpp:1088
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
QDoubleSpinBox * feed_rate_
ros::ServiceClient get_trajectory_size_client_
Definition: modify.hpp:150
QCheckBox * polygon_start_modify_
QCheckBox * laser_power_modify_
QDoubleSpinBox * scale_center_y_
Definition: modify.hpp:120
void displayErrorBoxHandler(const QString title, const QString message, const QString info_msg)
Definition: modify.cpp:1072
ros::ServiceClient scale_selected_poses_client_
Definition: modify.hpp:159
ros::ServiceClient rotate_selected_poses_client_
Definition: modify.hpp:157
QDoubleSpinBox * rotation_point_x_
Definition: modify.hpp:107
virtual QString getName() const
void load(const rviz::Config &config)
Definition: modify.cpp:1054
void changeGUIToSelectionMode()
Definition: modify.cpp:116
ros::ServiceClient get_number_of_layers_client_
Definition: modify.hpp:146
ros::Subscriber traj_
Definition: modify.hpp:137
#define ROS_WARN_STREAM(args)
void displayErrorMessageBox(const QString, const QString, const QString)
bool mapGetInt(const QString &key, int *value_out) const
std::vector< ram_msgs::AdditiveManufacturingPose > selected_poses_
Definition: modify.hpp:127
void changeGUIToModifyPoses()
Definition: modify.cpp:644
ros::ServiceClient get_layer_size_client_
Definition: modify.hpp:145
QVBoxLayout * layout_
Definition: modify.hpp:95
#define ROS_INFO_STREAM(args)
QDialogButtonBox * button_box_
ros::ServiceClient reflect_selected_poses_client_
Definition: modify.hpp:158
ros::ServiceClient get_poses_from_layers_list_client_
Definition: modify.hpp:148
ros::ServiceClient add_poses_client_
Definition: modify.hpp:155
ros::ServiceClient delete_selected_poses_client_
Definition: modify.hpp:154
std::vector< QRadioButton * > geometric_operations_
Definition: modify.hpp:124
std::string getService()
virtual void save(Config config) const
QDoubleSpinBox * reflect_vector_x_
Definition: modify.hpp:111
virtual ~Modify()
Definition: modify.cpp:80
QCheckBox * blend_radius_modify_
bool ok() const
void changeGUIToScalePoses()
Definition: modify.cpp:942
#define ROS_ERROR_STREAM(args)
QDoubleSpinBox * rotation_angle_
Definition: modify.hpp:106
virtual void load(const Config &config)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
QComboBox * laser_power_abs_rel_
QDoubleSpinBox * scale_center_x_
Definition: modify.hpp:119
ram_msgs::AdditiveManufacturingTrajectory trajectory_
Definition: modify.hpp:139
ModifyRangeListSelection * range_list_selection_ui_
Definition: modify.hpp:97


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