controllers_widget.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018, Mohamad Ayman.
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  * * The name of Mohamad Ayman may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *********************************************************************/
33 
34 /* Author: Mohamad Ayman */
35 
36 // SA
37 #include "controllers_widget.h"
38 #include "double_list_widget.h"
39 #include "controller_edit_widget.h"
40 #include "header_widget.h"
41 #include <moveit_msgs/JointLimits.h>
42 // Qt
43 #include <QApplication>
44 #include <QDoubleValidator>
45 #include <QFormLayout>
46 #include <QGroupBox>
47 #include <QHBoxLayout>
48 #include <QLabel>
49 #include <QLineEdit>
50 #include <QMessageBox>
51 #include <QPushButton>
52 #include <QScrollArea>
53 #include <QStackedWidget>
54 #include <QString>
55 #include <QTableWidget>
56 #include <QTreeWidget>
57 #include <QTreeWidgetItem>
58 #include <QVBoxLayout>
59 
60 #include <regex>
62 
63 namespace moveit_setup_assistant
64 {
65 // ******************************************************************************************
66 // Outer User Interface for MoveIt Configuration Assistant
67 // ******************************************************************************************
68 ControllersWidget::ControllersWidget(QWidget* parent, const MoveItConfigDataPtr& config_data)
69  : SetupScreenWidget(parent), config_data_(config_data)
70 {
71  // Basic widget container
72  QVBoxLayout* layout = new QVBoxLayout();
73 
74  layout->setAlignment(Qt::AlignTop);
75 
76  // Title
77  this->setWindowTitle("Controller Configuration"); // title of window
78 
79  // Top Header Area ------------------------------------------------
81  "Setup Controllers",
82  "Configure controllers to be used by MoveIt's controller manager(s) to operate the robot's physical hardware",
83  this);
84  layout->addWidget(header);
85 
86  // Tree Box ----------------------------------------------------------------------
87  controllers_tree_widget_ = createContentsWidget();
88 
89  // Joints edit widget
90  joints_widget_ = new moveit_setup_assistant::DoubleListWidget(this, config_data_, "Joint Collection", "Joint");
91  connect(joints_widget_, SIGNAL(cancelEditing()), this, SLOT(cancelEditing()));
92  connect(joints_widget_, SIGNAL(doneEditing()), this, SLOT(saveJointsScreen()));
93  connect(joints_widget_, SIGNAL(previewSelected(std::vector<std::string>)), this,
94  SLOT(previewSelectedJoints(std::vector<std::string>)));
95 
96  // Joints Groups Widget
97  joint_groups_widget_ =
98  new moveit_setup_assistant::DoubleListWidget(this, config_data_, "Group Joints Collection", "Group");
99  connect(joint_groups_widget_, SIGNAL(cancelEditing()), this, SLOT(cancelEditing()));
100  connect(joint_groups_widget_, SIGNAL(doneEditing()), this, SLOT(saveJointsGroupsScreen()));
101  connect(joint_groups_widget_, SIGNAL(previewSelected(std::vector<std::string>)), this,
102  SLOT(previewSelectedGroup(std::vector<std::string>)));
103 
104  // Controller Edit Widget
105  controller_edit_widget_ = new ControllerEditWidget(this, config_data_);
106  connect(controller_edit_widget_, SIGNAL(cancelEditing()), this, SLOT(cancelEditing()));
107  connect(controller_edit_widget_, SIGNAL(deleteController()), this, SLOT(deleteController()));
108  connect(controller_edit_widget_, SIGNAL(save()), this, SLOT(saveControllerScreenEdit()));
109  connect(controller_edit_widget_, SIGNAL(saveJoints()), this, SLOT(saveControllerScreenJoints()));
110  connect(controller_edit_widget_, SIGNAL(saveJointsGroups()), this, SLOT(saveControllerScreenGroups()));
111 
112  // Combine into stack
113  stacked_widget_ = new QStackedWidget(this);
114  stacked_widget_->addWidget(controllers_tree_widget_); // screen index 0
115  stacked_widget_->addWidget(joints_widget_); // screen index 1
116  stacked_widget_->addWidget(controller_edit_widget_); // screen index 2
117  stacked_widget_->addWidget(joint_groups_widget_); // screen index 3
118  layout->addWidget(stacked_widget_);
119 
120  this->setLayout(layout);
121 }
122 
123 // ******************************************************************************************
124 // Create the main tree view widget
125 // ******************************************************************************************
127 {
128  // Main widget
129  QWidget* content_widget = new QWidget(this);
130 
131  // Basic widget container
132  QVBoxLayout* layout = new QVBoxLayout(this);
133 
134  QHBoxLayout* upper_controls_layout = new QHBoxLayout();
135 
136  // Add default controller
137  QPushButton* btn_add_default =
138  new QPushButton("Auto Add &FollowJointsTrajectory \n Controllers For Each Planning Group", this);
139  btn_add_default->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
140  btn_add_default->setMaximumWidth(600);
141  connect(btn_add_default, SIGNAL(clicked()), this, SLOT(addDefaultControllers()));
142  upper_controls_layout->addWidget(btn_add_default);
143  upper_controls_layout->setAlignment(btn_add_default, Qt::AlignLeft);
144 
145  // Add Controls to layout
146  layout->addLayout(upper_controls_layout);
147 
148  // Tree Box ----------------------------------------------------------------------
149  controllers_tree_ = new QTreeWidget(this);
150  controllers_tree_->setColumnCount(2);
151  QStringList labels;
152  labels << "Controller"
153  << "Controller Type";
154  controllers_tree_->setHeaderLabels(labels);
155  controllers_tree_->setColumnWidth(0, 250);
156  connect(controllers_tree_, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(editSelected()));
157  connect(controllers_tree_, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this,
158  SLOT(previewSelected(QTreeWidgetItem*, int)));
159  connect(controllers_tree_, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
160  layout->addWidget(controllers_tree_);
161 
162  // Bottom Controls -------------------------------------------------------------
163 
164  controls_layout_ = new QHBoxLayout();
165 
166  // Expand/Contract controls
167  QLabel* expand_controls = new QLabel(this);
168  expand_controls->setText("<a href='expand'>Expand All</a> <a href='contract'>Collapse All</a>");
169  connect(expand_controls, SIGNAL(linkActivated(const QString)), this, SLOT(alterTree(const QString)));
170  controls_layout_->addWidget(expand_controls);
171 
172  // Spacer
173  controls_layout_->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
174 
175  // Delete
176  btn_delete_ = new QPushButton("&Delete Controller", this);
177  btn_delete_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
178  btn_delete_->setMaximumWidth(200);
179  connect(btn_delete_, SIGNAL(clicked()), this, SLOT(deleteController()));
180  controls_layout_->addWidget(btn_delete_);
181  controls_layout_->setAlignment(btn_delete_, Qt::AlignRight);
182 
183  // Add Controller Button
184  btn_add_ = new QPushButton("&Add Controller", this);
185  btn_add_->setMaximumWidth(300);
186  connect(btn_add_, SIGNAL(clicked()), this, SLOT(addController()));
187  controls_layout_->addWidget(btn_add_);
188  controls_layout_->setAlignment(btn_add_, Qt::AlignRight);
189 
190  // Edit
191  btn_edit_ = new QPushButton("&Edit Selected", this);
192  btn_edit_->setMaximumWidth(300);
193  connect(btn_edit_, SIGNAL(clicked()), this, SLOT(editSelected()));
194  controls_layout_->addWidget(btn_edit_);
195  controls_layout_->setAlignment(btn_edit_, Qt::AlignRight);
196 
197  // Add Controls to layout
198  layout->addLayout(controls_layout_);
199 
200  // Set layout
201  content_widget->setLayout(layout);
202 
203  return content_widget;
204 }
205 
206 // ******************************************************************************************
207 // Displays data in the controller_configs_ data structure into a QtTableWidget
208 // ******************************************************************************************
210 {
211  // Disable Tree
212  controllers_tree_->setUpdatesEnabled(false); // prevent table from updating until we are completely done
213  controllers_tree_->setDisabled(true); // make sure we disable it so that the cellChanged event is not called
214  controllers_tree_->clear(); // reset the tree
215 
216  // Display all controllers by looping through them
217  for (ControllerConfig& controller : config_data_->getControllers())
218  {
219  loadToControllersTree(controller);
220  }
221 
222  // Reenable Tree
223  controllers_tree_->setUpdatesEnabled(true); // prevent table from updating until we are completely done
224  controllers_tree_->setDisabled(false); // make sure we disable it so that the cellChanged event is not called
225  current_edit_controller_.clear(); // no controller is being edited
226  alterTree("expand");
227 }
228 
229 // ******************************************************************************************
230 // Displays data in the controller_config_ data structure into a QtTableWidget
231 // ******************************************************************************************
233 {
234  // Fonts for tree
235  const QFont top_level_font(QFont().defaultFamily(), 11, QFont::Bold);
236  const QFont type_font(QFont().defaultFamily(), 11, QFont::Normal, QFont::StyleItalic);
237 
238  QTreeWidgetItem* controller;
239 
240  controller = new QTreeWidgetItem();
241 
242  // First column
243  controller->setText(0, controller_it.name_.c_str());
244  controller->setFont(0, top_level_font);
245  controller->setData(0, Qt::UserRole, QVariant::fromValue(0));
246 
247  // Second column
248  controller->setText(1, controller_it.type_.c_str());
249  controller->setFont(1, type_font);
250  controller->setData(1, Qt::UserRole, QVariant::fromValue(4));
251  controllers_tree_->addTopLevelItem(controller);
252 
253  if (!controller_it.joints_.empty())
254  {
255  // Joints --------------------------------------------------------------
256  QTreeWidgetItem* joints = new QTreeWidgetItem(controller);
257  joints->setText(0, "Joints");
258  joints->setFont(0, type_font);
259  joints->setData(0, Qt::UserRole, QVariant::fromValue(1));
260  controller->addChild(joints);
261 
262  // Loop through all available joints
263  for (const std::string& joint : controller_it.joints_)
264  {
265  QTreeWidgetItem* joint_item = new QTreeWidgetItem(joints);
266  joint_item->setData(0, Qt::UserRole, QVariant::fromValue(2));
267 
268  // Add to tree
269  joint_item->setText(0, joint.c_str());
270  joints->addChild(joint_item);
271  }
272  }
273 }
274 
275 // ******************************************************************************************
276 // Called when setup assistant navigation switches to this screen
277 // ******************************************************************************************
279 {
280  // load controllers tree
281  btn_edit_->setEnabled(false);
282  btn_delete_->setEnabled(false);
284 }
285 
286 // ******************************************************************************************
287 // Load the popup screen with correct data for joints
288 // ******************************************************************************************
290 {
291  // Retrieve pointer to the shared kinematic model
292  const moveit::core::RobotModelConstPtr& model = config_data_->getRobotModel();
293 
294  // Get the names of the all joints
295  const std::vector<std::string>& joints = model->getJointModelNames();
296 
297  if (joints.empty())
298  {
299  QMessageBox::critical(this, "Error Loading", "No joints found for robot model");
300  return;
301  }
302 
303  // Set the available joints (left box)
304  joints_widget_->setAvailable(joints);
305 
306  // Set the selected joints (right box)
307  joints_widget_->setSelected(this_controller->joints_);
308 
309  // Set the title
310  joints_widget_->title_->setText(
311  QString("Edit '").append(QString::fromUtf8(this_controller->name_.c_str())).append("' Joint Collection"));
312 
313  // Remember what is currently being edited so we can later save changes
314  current_edit_controller_ = this_controller->name_;
315 }
316 
317 // ******************************************************************************************
318 // Load the popup screen with correct data for gcroups
319 // ******************************************************************************************
321 {
322  // Load all groups into the subgroup screen
323  std::vector<std::string> groups;
324 
325  // Display all groups by looping through them
326  for (const srdf::Model::Group& group : config_data_->srdf_->srdf_model_->getGroups())
327  {
328  // Add to available groups list
329  groups.push_back(group.name_);
330  }
331 
332  // Set the available groups (left box)
334 
335  // Set the selected groups (right box)
336  joint_groups_widget_->setSelected(this_controller->joints_);
337 
338  // Set the title
339  joint_groups_widget_->title_->setText(
340  QString("Edit '").append(QString::fromUtf8(this_controller->name_.c_str())).append("' Joints groups collection"));
341 
342  // Remember what is currently being edited so we can later save changes
343  current_edit_controller_ = this_controller->name_;
344 }
345 
346 // ******************************************************************************************
347 // Delete a controller
348 // ******************************************************************************************
350 {
351  std::string controller_name = current_edit_controller_;
352 
353  if (controller_name.empty())
354  {
355  QTreeWidgetItem* item = controllers_tree_->currentItem();
356  // Check that something was actually selected
357  if (item == nullptr)
358  return;
359 
360  // Get the user custom properties of the currently selected row
361  int type = item->data(0, Qt::UserRole).value<int>();
362  if (type == 0)
363  controller_name = item->text(0).toUtf8().constData();
364  }
365 
366  // Confirm user wants to delete controller
367  if (QMessageBox::question(
368  this, "Confirm Controller Deletion",
369  QString("Are you sure you want to delete the controller '").append(controller_name.c_str()).append(" ?"),
370  QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
371  {
372  return;
373  }
374  // Delete actual controller
375  if (config_data_->deleteController(controller_name))
376  {
377  ROS_INFO_STREAM_NAMED("Setup Assistant", "Controller " << controller_name << " deleted succefully");
378  }
379  else
380  {
381  ROS_WARN_STREAM_NAMED("Setup Assistant", "Couldn't delete Controller " << controller_name);
382  }
383 
384  current_edit_controller_.clear();
385 
386  // Switch to main screen
387  showMainScreen();
388 
389  // Reload main screen table
391 }
392 
393 // ******************************************************************************************
394 // Create a new controller
395 // ******************************************************************************************
397 {
398  // New Controller
399  adding_new_controller_ = true;
400 
401  // Load the data
402  loadControllerScreen(nullptr); // NULL indicates this is a new controller, not an existing one
403  changeScreen(2); // 1 is index of controller edit
404 }
405 
406 // ******************************************************************************************
407 // Add a Follow Joint Trajectory action Controller for each Planning Group
408 // ******************************************************************************************
410 {
411  if (!config_data_->addDefaultControllers())
412  QMessageBox::warning(this, "Error adding contollers", "No Planning Groups configured!");
414 }
415 
416 // ******************************************************************************************
417 // Load the popup screen with correct data for controllers
418 // ******************************************************************************************
420 {
421  // Load the avail controllers. This function only runs once
423 
424  if (this_controller == nullptr) // this is a new screen
425  {
426  current_edit_controller_.clear(); // provide a blank controller name
427  controller_edit_widget_->setTitle("Create New Controller");
429  controller_edit_widget_->showNewButtonsWidget(); // helps user choose next step
430  controller_edit_widget_->showSave(); // this is only for edit mode
431  }
432  else // load the controller name into the widget
433  {
434  current_edit_controller_ = this_controller->name_;
435  controller_edit_widget_->setTitle(QString("Edit Controller '").append(current_edit_controller_.c_str()).append("'"));
437  controller_edit_widget_->hideNewButtonsWidget(); // not necessary for existing controllers
438  controller_edit_widget_->showSave(); // this is only for edit mode
439  }
440 
441  // Set the data in the edit box
443 }
444 
445 // ******************************************************************************************
446 // Call when edit screen is canceled
447 // ******************************************************************************************
449 {
451  {
453  if (editing && editing->joints_.empty())
454  {
455  config_data_->deleteController(current_edit_controller_);
456  current_edit_controller_.clear();
457 
458  // Load the data to the tree
460  }
461  }
462  else
463  {
464  current_edit_controller_.clear();
465  }
466 
467  // Switch to main screen
468  showMainScreen();
469 }
470 
471 // ******************************************************************************************
472 // Called from Double List widget to highlight joints
473 // ******************************************************************************************
474 void ControllersWidget::previewSelectedJoints(const std::vector<std::string>& joints)
475 {
476  // Unhighlight all links
477  Q_EMIT unhighlightAll();
478 
479  for (const std::string& joint : joints)
480  {
481  const moveit::core::JointModel* joint_model = config_data_->getRobotModel()->getJointModel(joint);
482 
483  // Check that a joint model was found
484  if (!joint_model)
485  {
486  continue;
487  }
488 
489  // Get the name of the link
490  const std::string link = joint_model->getChildLinkModel()->getName();
491 
492  if (link.empty())
493  {
494  continue;
495  }
496 
497  // Highlight link
498  Q_EMIT highlightLink(link, QColor(255, 0, 0));
499  }
500 }
501 
502 // ******************************************************************************************
503 // Called from Double List widget to highlight a group
504 // ******************************************************************************************
505 void ControllersWidget::previewSelectedGroup(const std::vector<std::string>& groups)
506 {
507  // Unhighlight all links
508  Q_EMIT unhighlightAll();
509 
510  for (const std::string& group : groups)
511  {
512  // Highlight group
513  Q_EMIT highlightGroup(group);
514  }
515 }
516 
517 // ******************************************************************************************
518 // Called when an item is seleceted from the controllers tree
519 // ******************************************************************************************
520 void ControllersWidget::previewSelected(QTreeWidgetItem* selected_item, int /*column*/)
521 {
522  // Get the user custom properties of the currently selected row
523  int type = selected_item->data(0, Qt::UserRole).value<int>();
524  btn_edit_->setEnabled(true);
525 
526  // Enable delete button if a controller was selected
527  if (type == 0)
528  {
529  btn_delete_->setEnabled(true);
530  }
531  else
532  {
533  btn_delete_->setEnabled(false);
534  }
535 }
536 
537 // ******************************************************************************************
538 // Call when a new controller is created and ready to progress to next screen
539 // ******************************************************************************************
541 {
542  // Save the controller
543  if (!saveControllerScreen())
544  return;
545 
546  // Find the controller we are editing based on the controller name string
547  moveit_setup_assistant::ControllerConfig* editing_controller =
548  config_data_->findControllerByName(current_edit_controller_);
549 
550  loadJointsScreen(editing_controller);
551 
552  // Switch to screen
553  changeScreen(1); // 1 is index of joints
554 }
555 
556 // ******************************************************************************************
557 // Call when a new controller is created and ready to progress to next screen
558 // ******************************************************************************************
560 {
561  // Save the controller
562  if (!saveControllerScreen())
563  return;
564 
565  // Find the controller we are editing based on the controller name string
566  moveit_setup_assistant::ControllerConfig* editing_controller =
567  config_data_->findControllerByName(current_edit_controller_);
568 
569  loadGroupsScreen(editing_controller);
570 
571  // Switch to screen
572  changeScreen(3); // 3 is index of groups
573 }
574 
575 // ******************************************************************************************
576 // Call when joints edit sceen is done and needs to be saved
577 // ******************************************************************************************
579 {
580  // Find the controller we are editing based on the controller name string
581  moveit_setup_assistant::ControllerConfig* searched_controller =
582  config_data_->findControllerByName(current_edit_controller_);
583 
584  // Clear the old data
585  searched_controller->joints_.clear();
586 
587  // Copy the data
588  for (int i = 0; i < joints_widget_->selected_data_table_->rowCount(); ++i)
589  {
590  searched_controller->joints_.push_back(joints_widget_->selected_data_table_->item(i, 0)->text().toStdString());
591  }
592 
593  // Switch to main screen
594  showMainScreen();
595 
596  // Reload main screen table
598 }
599 
600 // ******************************************************************************************
601 // Call when joints edit sceen is done and needs to be saved
602 // ******************************************************************************************
604 {
605  // Find the controller we are editing based on the controller name string
606  moveit_setup_assistant::ControllerConfig* searched_controller =
607  config_data_->findControllerByName(current_edit_controller_);
608 
609  // Clear the old data
610  searched_controller->joints_.clear();
611 
612  // Copy the data
613  for (int i = 0; i < joint_groups_widget_->selected_data_table_->rowCount(); ++i)
614  {
615  // Get list of associated joints
616  const moveit::core::JointModelGroup* joint_model_group = config_data_->getRobotModel()->getJointModelGroup(
617  joint_groups_widget_->selected_data_table_->item(i, 0)->text().toStdString());
618  const std::vector<const moveit::core::JointModel*>& joint_models = joint_model_group->getActiveJointModels();
619 
620  // Iterate through the joints
621  for (const moveit::core::JointModel* joint : joint_models)
622  {
623  if (joint->isPassive() || joint->getMimic() != nullptr || joint->getType() == moveit::core::JointModel::FIXED)
624  continue;
625  searched_controller->joints_.push_back(joint->getName());
626  }
627  }
628 
629  // Switch to main screen
630  showMainScreen();
631 
632  // Reload main screen table
634 }
635 
636 // ******************************************************************************************
637 // Call when joints edit sceen is done and needs to be saved
638 // ******************************************************************************************
640 {
641  // Save the controller
642  if (!saveControllerScreen())
643  return;
644 
645  // Switch to main screen
646  showMainScreen();
647 }
648 
649 // ******************************************************************************************
650 // Call when controller edit sceen is done and needs to be saved
651 // ******************************************************************************************
653 {
654  // Get a reference to the supplied strings
655  const std::string& controller_name = controller_edit_widget_->getControllerName();
656  const std::string& controller_type = controller_edit_widget_->getControllerType();
657 
658  // Used for editing existing controllers
659  moveit_setup_assistant::ControllerConfig* searched_controller = nullptr;
660 
661  std::smatch invalid_name_match;
662  std::regex invalid_reg_ex("[^a-z|^0-9|^_]");
663 
664  // Check that a valid controller name has been given
665  if (controller_name.empty() || std::regex_search(controller_name, invalid_name_match, invalid_reg_ex))
666  {
667  QMessageBox::warning(this, "Error Saving", "Invalid controller name");
668  return false;
669  }
670 
671  // Check if this is an existing controller
672  if (!current_edit_controller_.empty())
673  {
674  // Find the controller we are editing based on the goup name string
675  searched_controller = config_data_->findControllerByName(current_edit_controller_);
676  }
677 
678  // Check that the controller name is unique
679  for (const auto& controller : config_data_->getControllers())
680  {
681  if (controller.name_.compare(controller_name) == 0) // the names are the same
682  {
683  // is this our existing controller? check if controller pointers are same
684  if (&controller != searched_controller)
685  {
686  QMessageBox::warning(this, "Error Saving", "A controller already exists with that name!");
687  return false;
688  }
689  }
690  }
691 
692  adding_new_controller_ = false;
693 
694  // Save the new controller name or create the new controller
695  if (searched_controller == nullptr) // create new
696  {
698  new_controller.name_ = controller_name;
699  new_controller.type_ = controller_type;
700  config_data_->addController(new_controller);
701 
702  adding_new_controller_ = true; // remember this controller is new
703  }
704  else
705  {
706  // Remember old controller name and type
707  const std::string old_controller_name = searched_controller->name_;
708 
709  // Change controller name
710  searched_controller->name_ = controller_name;
711  searched_controller->type_ = controller_type;
712  }
713 
714  // Reload main screen table
716 
717  // Update the current edit controller so that we can proceed to the next screen, if user desires
718  current_edit_controller_ = controller_name;
719 
720  return true;
721 }
722 
723 // ******************************************************************************************
724 // Edit whenever element is selected in the controllers tree view
725 // ******************************************************************************************
727 {
728  QTreeWidgetItem* item = controllers_tree_->currentItem();
729  QTreeWidgetItem* controller_item;
730 
731  // Check that something was actually selected
732  if (item == nullptr)
733  return;
734 
735  adding_new_controller_ = false;
736 
737  // Get the user custom properties of the currently selected row
738  int type = item->data(0, Qt::UserRole).value<int>();
739 
740  if (type == 2)
741  {
742  // The controller this joint belong to
743  controller_item = item->parent()->parent();
744  current_edit_controller_ = controller_item->text(0).toUtf8().constData();
746  config_data_->findControllerByName(current_edit_controller_);
747 
748  // Load the data
749  loadJointsScreen(this_controller);
750 
751  // Switch to screen
752  changeScreen(1); // 1 is index of joints
753  }
754  else if (type == 1)
755  {
756  controller_item = item->parent();
757  current_edit_controller_ = controller_item->text(0).toUtf8().constData();
759  config_data_->findControllerByName(current_edit_controller_);
760 
761  // Load the data
762  loadJointsScreen(this_controller);
763 
764  // Switch to screen
765  changeScreen(1); // 1 is index of joints
766  }
767  else if (type == 0)
768  {
769  // Load the data
770  current_edit_controller_ = item->text(0).toUtf8().constData();
772  config_data_->findControllerByName(current_edit_controller_);
773  loadControllerScreen(this_controller);
774 
775  // Switch to screen
776  changeScreen(2); // 1 is index of controller edit
777  }
778  else
779  {
780  QMessageBox::critical(this, "Error Loading", "An internal error has occured while loading.");
781  }
782 }
783 
784 // ******************************************************************************************
785 // Edit a controller
786 // ******************************************************************************************
788 {
789  QTreeWidgetItem* item = controllers_tree_->currentItem();
790 
791  // Check that something was actually selected
792  if (item == nullptr)
793  return;
794 
795  adding_new_controller_ = false;
796 
798 
799  // Switch to screen
800  changeScreen(2); // 1 is index of controller edit
801 }
802 
803 // ******************************************************************************************
804 // Switch to current controllers view
805 // ******************************************************************************************
807 {
808  stacked_widget_->setCurrentIndex(0);
809 
810  // Announce that this widget is not in modal mode
811  Q_EMIT isModal(false);
812 }
813 
814 // ******************************************************************************************
815 // Switch which screen is being shown
816 // ******************************************************************************************
817 void ControllersWidget::changeScreen(int index)
818 {
819  stacked_widget_->setCurrentIndex(index);
820 
821  // Announce this widget's mode
822  Q_EMIT isModal(index != 0);
823 }
824 
825 // ******************************************************************************************
826 // Expand/Collapse Tree
827 // ******************************************************************************************
828 void ControllersWidget::alterTree(const QString& link)
829 {
830  if (link.contains("expand"))
831  controllers_tree_->expandAll();
832  else
833  controllers_tree_->collapseAll();
834 }
835 
837 {
838  QList<QTreeWidgetItem*> selected_items = controllers_tree_->selectedItems();
839  if (selected_items.empty())
840  {
841  btn_edit_->setEnabled(false);
842  btn_delete_->setEnabled(false);
843  }
844 }
845 
846 } // namespace moveit_setup_assistant
moveit_setup_assistant::ControllersWidget::createContentsWidget
QWidget * createContentsWidget()
Builds the main screen list widget.
Definition: controllers_widget.cpp:157
moveit_setup_assistant::ControllersWidget::config_data_
moveit_setup_assistant::MoveItConfigDataPtr config_data_
Contains all the configuration data for the setup assistant.
Definition: controllers_widget.h:145
moveit::core::JointModelGroup::getActiveJointModels
const std::vector< const JointModel * > & getActiveJointModels() const
moveit_setup_assistant::ControllerEditWidget::saveJoints
void saveJoints()
Button event for new groups, progressing to adding joints.
moveit_setup_assistant::ControllersWidget::btn_add_
QPushButton * btn_add_
Definition: controllers_widget.h:132
moveit_setup_assistant::DoubleListWidget::setSelected
void setSelected(const std::vector< std::string > &items)
Set the right box.
Definition: double_list_widget.cpp:216
moveit_setup_assistant::ControllersWidget::stacked_widget_
QStackedWidget * stacked_widget_
For changing between table and different add/edit views.
Definition: controllers_widget.h:128
moveit_setup_assistant::ControllersWidget::saveControllerScreenGroups
void saveControllerScreenGroups()
Definition: controllers_widget.cpp:590
moveit_setup_assistant::DoubleListWidget
Definition: double_list_widget.h:51
moveit_setup_assistant::ControllersWidget::loadControllersTree
void loadControllersTree()
Definition: controllers_widget.cpp:240
double_list_widget.h
moveit_setup_assistant::ControllersWidget::loadJointsScreen
void loadJointsScreen(moveit_setup_assistant::ControllerConfig *this_controller)
Definition: controllers_widget.cpp:320
moveit_setup_assistant::ControllersWidget::previewSelectedGroup
void previewSelectedGroup(const std::vector< std::string > &groups)
Called from Double List widget to highlight a group.
Definition: controllers_widget.cpp:536
moveit_setup_assistant::DoubleListWidget::selected_data_table_
QTableWidget * selected_data_table_
Definition: double_list_widget.h:86
moveit_setup_assistant::ControllersWidget::editController
void editController()
Edit an existing controller.
Definition: controllers_widget.cpp:818
moveit_setup_assistant::ControllersWidget::showMainScreen
void showMainScreen()
Definition: controllers_widget.cpp:837
moveit_setup_assistant::ControllersWidget::ControllersWidget
ControllersWidget(QWidget *parent, const MoveItConfigDataPtr &config_data)
Definition: controllers_widget.cpp:99
moveit_setup_assistant::ControllersWidget::itemSelectionChanged
void itemSelectionChanged()
Called sleceted item changed.
Definition: controllers_widget.cpp:867
moveit_setup_assistant::ControllersWidget::cancelEditing
void cancelEditing()
Definition: controllers_widget.cpp:479
moveit_setup_assistant::ControllersWidget::loadToControllersTree
void loadToControllersTree(const moveit_setup_assistant::ControllerConfig &controller_it)
Definition: controllers_widget.cpp:263
moveit_setup_assistant::ControllerEditWidget::saveJointsGroups
void saveJointsGroups()
Button event for new groups, progressing to adding subgroups.
moveit_setup_assistant::ControllersWidget::saveControllerScreenJoints
void saveControllerScreenJoints()
Call when screen is done being edited.
Definition: controllers_widget.cpp:571
moveit_setup_assistant::ControllerEditWidget::hideDelete
void hideDelete()
Hide delete controller button.
Definition: controller_edit_widget.cpp:241
moveit_setup_assistant::ControllerEditWidget::ControllerEditWidget
ControllerEditWidget(QWidget *parent, const MoveItConfigDataPtr &config_data)
Constructor.
Definition: controller_edit_widget.cpp:84
moveit_setup_assistant::ControllerEditWidget::deleteController
void deleteController()
Event sent when delete is being requested for controller.
SetupScreenWidget::isModal
void isModal(bool isModal)
Event for when the current screen is in modal view. Essential disabled the left navigation.
moveit_setup_assistant::ControllersWidget::addController
void addController()
Create a new controller.
Definition: controllers_widget.cpp:427
SetupScreenWidget::highlightLink
void highlightLink(const std::string &name, const QColor &)
Event for telling rviz to highlight a link of the robot.
moveit::core::JointModel::getChildLinkModel
const LinkModel * getChildLinkModel() const
moveit_setup_assistant::ControllersWidget::addDefaultControllers
void addDefaultControllers()
Definition: controllers_widget.cpp:440
moveit_setup_assistant::ControllersWidget::controls_layout_
QHBoxLayout * controls_layout_
Definition: controllers_widget.h:134
moveit_setup_assistant::ControllersWidget::saveJointsScreen
void saveJointsScreen()
Definition: controllers_widget.cpp:609
moveit_setup_assistant::ControllerEditWidget::getControllerType
std::string getControllerType()
Get controller type.
Definition: controller_edit_widget.cpp:281
moveit_setup_assistant::ControllersWidget::adding_new_controller_
bool adding_new_controller_
Remember whethere we're editing a controller or adding a new one.
Definition: controllers_widget.h:142
moveit_setup_assistant::ControllerEditWidget::showNewButtonsWidget
void showNewButtonsWidget()
Show new buttons widget.
Definition: controller_edit_widget.cpp:266
moveit_setup_assistant::ControllerConfig::type_
std::string type_
Definition: moveit_config_data.h:118
moveit_setup_assistant::ControllersWidget::btn_delete_
QPushButton * btn_delete_
Definition: controllers_widget.h:131
moveit_setup_assistant::ControllerEditWidget::cancelEditing
void cancelEditing()
Event sent when user presses cancel button.
moveit_setup_assistant::ControllersWidget::joint_groups_widget_
moveit_setup_assistant::DoubleListWidget * joint_groups_widget_
Definition: controllers_widget.h:136
moveit_setup_assistant::ControllersWidget::saveJointsGroupsScreen
void saveJointsGroupsScreen()
Definition: controllers_widget.cpp:634
SetupScreenWidget
Definition: setup_screen_widget.h:44
moveit_setup_assistant::ControllerEditWidget::setTitle
void setTitle(const QString &title)
Set widget title.
Definition: controller_edit_widget.cpp:271
moveit_setup_assistant::ControllerEditWidget::showSave
void showSave()
Show save controller button.
Definition: controller_edit_widget.cpp:261
SetupScreenWidget::unhighlightAll
void unhighlightAll()
Event for telling rviz to unhighlight all links of the robot.
moveit_setup_assistant::ControllersWidget::controllers_tree_
QTreeWidget * controllers_tree_
Main table for holding controllers.
Definition: controllers_widget.h:124
moveit_setup_assistant::ControllersWidget::joints_widget_
moveit_setup_assistant::DoubleListWidget * joints_widget_
Definition: controllers_widget.h:135
moveit_setup_assistant::ControllerEditWidget::setSelected
void setSelected(const std::string &controller_name)
Set the previous data.
Definition: controller_edit_widget.cpp:192
moveit_setup_assistant::DoubleListWidget::setAvailable
void setAvailable(const std::vector< std::string > &items)
Loads the availble data list.
Definition: double_list_widget.cpp:204
moveit_setup_assistant::ControllersWidget::saveControllerScreen
bool saveControllerScreen()
Definition: controllers_widget.cpp:683
moveit_setup_assistant::ControllerEditWidget::hideNewButtonsWidget
void hideNewButtonsWidget()
Hide new buttons widget.
Definition: controller_edit_widget.cpp:251
moveit_setup_assistant::ControllersWidget::controller_edit_widget_
ControllerEditWidget * controller_edit_widget_
Definition: controllers_widget.h:129
moveit_setup_assistant::ControllersWidget::previewSelectedJoints
void previewSelectedJoints(const std::vector< std::string > &joints)
Called from Double List widget to highlight a joint.
Definition: controllers_widget.cpp:505
header_widget.h
moveit_setup_assistant::ControllersWidget::loadGroupsScreen
void loadGroupsScreen(moveit_setup_assistant::ControllerConfig *this_controller)
Definition: controllers_widget.cpp:351
ROS_WARN_STREAM_NAMED
#define ROS_WARN_STREAM_NAMED(name, args)
moveit_setup_assistant
Definition: compute_default_collisions.h:46
moveit_setup_assistant::ControllersWidget::deleteController
void deleteController()
Delete an existing controller.
Definition: controllers_widget.cpp:380
moveit_setup_assistant::ControllersWidget::editSelected
void editSelected()
Called whenever element is selected in the controllers tree view.
Definition: controllers_widget.cpp:757
moveit_setup_assistant::ControllerConfig::name_
std::string name_
Definition: moveit_config_data.h:117
append
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
controller_edit_widget.h
moveit_setup_assistant::ControllersWidget::current_edit_controller_
std::string current_edit_controller_
Remember what controller we are editing when an edit screen is being shown.
Definition: controllers_widget.h:139
moveit_setup_assistant::ControllersWidget::previewSelected
void previewSelected(QTreeWidgetItem *selected_item, int column)
Called when an item is seleceted from the controllers tree.
Definition: controllers_widget.cpp:551
moveit_setup_assistant::ControllerEditWidget::loadControllersTypesComboBox
void loadControllersTypesComboBox()
Populate the combo dropdown box with controllers types.
Definition: controller_edit_widget.cpp:221
moveit_setup_assistant::ControllersWidget::loadControllerScreen
void loadControllerScreen(moveit_setup_assistant::ControllerConfig *this_controller)
Definition: controllers_widget.cpp:450
moveit_setup_assistant::HeaderWidget
Definition: header_widget.h:51
moveit_setup_assistant::ControllersWidget::alterTree
void alterTree(const QString &link)
Definition: controllers_widget.cpp:859
moveit::core::JointModelGroup
moveit_setup_assistant::ControllersWidget::saveControllerScreenEdit
void saveControllerScreenEdit()
Definition: controllers_widget.cpp:670
moveit_setup_assistant::ControllerConfig::joints_
std::vector< std::string > joints_
Definition: moveit_config_data.h:119
index
unsigned int index
ROS_INFO_STREAM_NAMED
#define ROS_INFO_STREAM_NAMED(name, args)
moveit_setup_assistant::ControllerEditWidget::getControllerName
std::string getControllerName()
Get controller name.
Definition: controller_edit_widget.cpp:276
conversions.h
moveit_setup_assistant::ControllerEditWidget::showDelete
void showDelete()
Show delete controller button.
Definition: controller_edit_widget.cpp:256
moveit_setup_assistant::ControllersWidget::btn_edit_
QPushButton * btn_edit_
Definition: controllers_widget.h:133
srdf::Model::Group
moveit::core::LinkModel::getName
const std::string & getName() const
moveit_setup_assistant::ControllerEditWidget::save
void save()
Button event for just saving, when in edit mode.
moveit_setup_assistant::ControllerConfig
Definition: moveit_config_data.h:115
header
const std::string header
moveit_setup_assistant::ControllersWidget::changeScreen
void changeScreen(int index)
Definition: controllers_widget.cpp:848
moveit_setup_assistant::ControllerEditWidget::config_data_
moveit_setup_assistant::MoveItConfigDataPtr config_data_
Contains all the configuration data for the setup assistant.
Definition: controller_edit_widget.h:141
moveit::core::JointModel::FIXED
FIXED
moveit_setup_assistant::DoubleListWidget::title_
QLabel * title_
Definition: double_list_widget.h:87
SetupScreenWidget::highlightGroup
void highlightGroup(const std::string &name)
Event for telling rviz to highlight a group of the robot.
moveit::core::JointModel
controllers_widget.h
moveit_setup_assistant::ControllersWidget::focusGiven
void focusGiven() override
Received when this widget is chosen from the navigation menu.
Definition: controllers_widget.cpp:309
group
group


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Sat May 3 2025 02:28:04