group_edit_widget.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012, Willow Garage, Inc.
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  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Dave Coleman */
36 
37 #include <QVBoxLayout>
38 #include <QHBoxLayout>
39 #include <QMessageBox>
40 #include <QFormLayout>
41 #include <QString>
42 #include <QGroupBox>
43 #include "group_edit_widget.h"
44 #include <pluginlib/class_loader.hpp> // for loading all avail kinematic planners
45 
46 namespace moveit_setup_assistant
47 {
48 // ******************************************************************************************
49 //
50 // ******************************************************************************************
51 GroupEditWidget::GroupEditWidget(QWidget* parent, moveit_setup_assistant::MoveItConfigDataPtr config_data)
52  : QWidget(parent), config_data_(config_data)
53 {
54  // Basic widget container
55  QVBoxLayout* layout = new QVBoxLayout();
56 
57  QGroupBox* group1 = new QGroupBox("Kinematics");
58  QGroupBox* group2 = new QGroupBox("OMPL Planning");
59 
60  // Label ------------------------------------------------
61  title_ = new QLabel(this); // specify the title from the parent widget
62  QFont group_title_font(QFont().defaultFamily(), 12, QFont::Bold);
63  title_->setFont(group_title_font);
64  layout->addWidget(title_);
65 
66  // Kinematic form -------------------------------------------
67  QFormLayout* form_layout = new QFormLayout();
68  form_layout->setContentsMargins(0, 12, 0, 12);
69 
70  // Name input
71  group_name_field_ = new QLineEdit(this);
72  group_name_field_->setMaximumWidth(400);
73  form_layout->addRow("Group Name:", group_name_field_);
74 
75  // Kinematic solver
76  kinematics_solver_field_ = new QComboBox(this);
77  kinematics_solver_field_->setEditable(false);
78  kinematics_solver_field_->setMaximumWidth(400);
79  form_layout->addRow("Kinematic Solver:", kinematics_solver_field_);
80 
81  // resolution to use with solver
82  kinematics_resolution_field_ = new QLineEdit(this);
83  kinematics_resolution_field_->setMaximumWidth(400);
84  form_layout->addRow("Kin. Search Resolution:", kinematics_resolution_field_);
85 
86  // resolution to use with solver
87  kinematics_timeout_field_ = new QLineEdit(this);
88  kinematics_timeout_field_->setMaximumWidth(400);
89  form_layout->addRow("Kin. Search Timeout (sec):", kinematics_timeout_field_);
90 
91  // number of IK attempts
92  kinematics_attempts_field_ = new QLineEdit(this);
93  kinematics_attempts_field_->setMaximumWidth(400);
94  form_layout->addRow("Kin. Solver Attempts:", kinematics_attempts_field_);
95 
96  group1->setLayout(form_layout);
97 
98  // OMPL Planner form --------------------------------------------
99 
100  QFormLayout* form_layout2 = new QFormLayout();
101  form_layout2->setContentsMargins(0, 12, 0, 12);
102 
103  // Kinematic default planner
104  default_planner_field_ = new QComboBox(this);
105  default_planner_field_->setEditable(false);
106  default_planner_field_->setMaximumWidth(400);
107  form_layout2->addRow("Group Default Planner:", default_planner_field_);
108 
109  group2->setLayout(form_layout2);
110 
111  layout->addWidget(group1);
112  layout->addWidget(group2);
113 
114  layout->setAlignment(Qt::AlignTop);
115 
116  // New Group Options ---------------------------------------------------------
117  new_buttons_widget_ = new QWidget();
118 
119  QVBoxLayout* new_buttons_layout_container = new QVBoxLayout();
120  QHBoxLayout* label_layout = new QHBoxLayout();
121  QHBoxLayout* recommended_options = new QHBoxLayout();
122  QHBoxLayout* advanced_options = new QHBoxLayout();
123 
124  QLabel* save_and_add = new QLabel("Next, Add Components To Group:", this);
125  QFont save_and_add_font(QFont().defaultFamily(), 12, QFont::Bold);
126  save_and_add->setFont(save_and_add_font);
127  label_layout->addWidget(save_and_add);
128 
129  // Recommended options
130  QLabel* add_subtitle = new QLabel("Recommended: ", this);
131  QFont add_subtitle_font(QFont().defaultFamily(), 10, QFont::Bold);
132  add_subtitle->setFont(add_subtitle_font);
133  recommended_options->addWidget(add_subtitle, 0, Qt::AlignLeft);
134 
135  // Save and add joints
136  QPushButton* btn_save_joints = new QPushButton("Add Joints", this);
137  btn_save_joints->setMaximumWidth(200);
138  connect(btn_save_joints, SIGNAL(clicked()), this, SIGNAL(saveJoints()));
139  recommended_options->addWidget(btn_save_joints);
140 
141  // Advanced options
142  QLabel* add_subtitle2 = new QLabel("Advanced Options:", this);
143  add_subtitle2->setFont(add_subtitle_font);
144  advanced_options->addWidget(add_subtitle2, 0, Qt::AlignLeft);
145 
146  // Save and add links
147  QPushButton* btn_save_links = new QPushButton("Add Links", this);
148  btn_save_links->setMaximumWidth(200);
149  connect(btn_save_links, SIGNAL(clicked()), this, SIGNAL(saveLinks()));
150  advanced_options->addWidget(btn_save_links);
151 
152  // Save and add chain
153  QPushButton* btn_save_chain = new QPushButton("Add Kin. Chain", this);
154  btn_save_chain->setMaximumWidth(200);
155  connect(btn_save_chain, SIGNAL(clicked()), this, SIGNAL(saveChain()));
156  advanced_options->addWidget(btn_save_chain);
157 
158  // Save and add subgroups
159  QPushButton* btn_save_subgroups = new QPushButton("Add Subgroups", this);
160  btn_save_subgroups->setMaximumWidth(200);
161  connect(btn_save_subgroups, SIGNAL(clicked()), this, SIGNAL(saveSubgroups()));
162  advanced_options->addWidget(btn_save_subgroups);
163 
164  // Add layouts
165  new_buttons_layout_container->addLayout(label_layout);
166  new_buttons_layout_container->addLayout(recommended_options);
167  new_buttons_layout_container->addLayout(advanced_options);
168 
169  // Create widget and add to main layout
170  new_buttons_widget_->setLayout(new_buttons_layout_container);
171  layout->addWidget(new_buttons_widget_);
172 
173  // Verticle Spacer -----------------------------------------------------
174  QWidget* vspacer = new QWidget(this);
175  vspacer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
176  layout->addWidget(vspacer);
177 
178  // Bottom Controls ---------------------------------------------------------
179  QHBoxLayout* controls_layout = new QHBoxLayout();
180 
181  // Delete
182  btn_delete_ = new QPushButton("&Delete Group", this);
183  btn_delete_->setMaximumWidth(200);
184  connect(btn_delete_, SIGNAL(clicked()), this, SIGNAL(deleteGroup()));
185  controls_layout->addWidget(btn_delete_);
186  controls_layout->setAlignment(btn_delete_, Qt::AlignRight);
187 
188  // Horizontal Spacer
189  QWidget* spacer = new QWidget(this);
190  spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
191  controls_layout->addWidget(spacer);
192 
193  // Save
194  btn_save_ = new QPushButton("&Save", this);
195  btn_save_->setMaximumWidth(200);
196  connect(btn_save_, SIGNAL(clicked()), this, SIGNAL(save()));
197  controls_layout->addWidget(btn_save_);
198  controls_layout->setAlignment(btn_save_, Qt::AlignRight);
199 
200  // Cancel
201  QPushButton* btn_cancel = new QPushButton("&Cancel", this);
202  btn_cancel->setMaximumWidth(200);
203  connect(btn_cancel, SIGNAL(clicked()), this, SIGNAL(cancelEditing()));
204  controls_layout->addWidget(btn_cancel);
205  controls_layout->setAlignment(btn_cancel, Qt::AlignRight);
206 
207  // Add layout
208  layout->addLayout(controls_layout);
209 
210  // Finish Layout --------------------------------------------------
211  this->setLayout(layout);
212 }
213 
214 // ******************************************************************************************
215 // Set the link field with previous value
216 // ******************************************************************************************
217 void GroupEditWidget::setSelected(const std::string& group_name)
218 {
219  group_name_field_->setText(QString(group_name.c_str()));
220 
221  // Load properties from moveit_config_data.cpp ----------------------------------------------
222 
223  // Load resolution
224  double* resolution = &config_data_->group_meta_data_[group_name].kinematics_solver_search_resolution_;
225  if (*resolution == 0)
226  {
227  // Set default value
229  }
230  kinematics_resolution_field_->setText(QString::number(*resolution));
231 
232  // Load timeout
233  double* timeout = &config_data_->group_meta_data_[group_name].kinematics_solver_timeout_;
234  if (*timeout == 0)
235  {
236  // Set default value
237  *timeout = DEFAULT_KIN_SOLVER_TIMEOUT_;
238  }
239  kinematics_timeout_field_->setText(QString::number(*timeout));
240 
241  // Load attempts
242  int* attempts = &config_data_->group_meta_data_[group_name].kinematics_solver_attempts_;
243  if (*attempts == 0)
244  {
245  // Set default value
246  *attempts = DEFAULT_KIN_SOLVER_ATTEMPTS_;
247  }
248  kinematics_attempts_field_->setText(QString::number(*attempts));
249 
250  // Set kin solver
251  std::string kin_solver = config_data_->group_meta_data_[group_name].kinematics_solver_;
252 
253  // If this group doesn't have a solver, reset it to 'None'
254  if (kin_solver.empty())
255  {
256  kin_solver = "None";
257  }
258 
259  // Set the kin solver combo box
260  int index = kinematics_solver_field_->findText(kin_solver.c_str());
261  if (index == -1)
262  {
263  QMessageBox::warning(this, "Missing Kinematic Solvers",
264  QString("Unable to find the kinematic solver '")
265  .append(kin_solver.c_str())
266  .append("'. Trying running rosmake for this package. Until fixed, this setting will be "
267  "lost the next time the MoveIt! configuration files are generated"));
268  return;
269  }
270  else
271  {
272  kinematics_solver_field_->setCurrentIndex(index);
273  }
274 
275  // Set default planner
276  std::string default_planner = config_data_->group_meta_data_[group_name].default_planner_;
277 
278  // If this group doesn't have a solver, reset it to 'None'
279  if (default_planner.empty())
280  {
281  default_planner = "None";
282  }
283 
284  index = default_planner_field_->findText(default_planner.c_str());
285  if (index == -1)
286  {
287  QMessageBox::warning(this, "Missing Default Planner",
288  QString("Unable to find the default planner '%1'").arg(default_planner.c_str()));
289  }
290  else
291  {
292  default_planner_field_->setCurrentIndex(index);
293  }
294 }
295 
296 // ******************************************************************************************
297 // Populate the combo dropdown box with kinematic planners
298 // ******************************************************************************************
300 {
301  // Only load this combo box once
302  static bool hasLoaded = false;
303  if (hasLoaded)
304  return;
305  hasLoaded = true;
306 
307  // Remove all old items
308  kinematics_solver_field_->clear();
309  default_planner_field_->clear();
310 
311  // Add none option, the default
312  kinematics_solver_field_->addItem("None");
313  default_planner_field_->addItem("None");
314 
315  // load all avail kin planners
316  std::unique_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase>> loader;
317  try
318  {
319  loader.reset(new pluginlib::ClassLoader<kinematics::KinematicsBase>("moveit_core", "kinematics::KinematicsBase"));
320  }
322  {
323  QMessageBox::warning(this, "Missing Kinematic Solvers", "Exception while creating class loader for kinematic "
324  "solver plugins");
325  ROS_ERROR_STREAM(ex.what());
326  return;
327  }
328 
329  // Get classes
330  const std::vector<std::string>& classes = loader->getDeclaredClasses();
331 
332  // Warn if no plugins are found
333  if (classes.empty())
334  {
335  QMessageBox::warning(this, "Missing Kinematic Solvers", "No MoveIt!-compatible kinematics solvers found. Try "
336  "installing moveit_kinematics (sudo apt-get install "
337  "ros-${ROS_DISTRO}-moveit-kinematics)");
338  return;
339  }
340 
341  // Loop through all planners and add to combo box
342  for (std::vector<std::string>::const_iterator plugin_it = classes.begin(); plugin_it != classes.end(); ++plugin_it)
343  {
344  kinematics_solver_field_->addItem(plugin_it->c_str());
345  }
346 
347  std::vector<OMPLPlannerDescription> planners = config_data_->getOMPLPlanners();
348  for (std::size_t i = 0; i < planners.size(); ++i)
349  {
350  std::string planner_name = planners[i].name_;
351  default_planner_field_->addItem(planner_name.c_str());
352  }
353 }
354 
355 } // namespace
void cancelEditing()
Event sent when user presses cancel button.
GroupEditWidget(QWidget *parent, moveit_setup_assistant::MoveItConfigDataPtr config_data)
Constructor.
static const int DEFAULT_KIN_SOLVER_ATTEMPTS_
moveit_setup_assistant::MoveItConfigDataPtr config_data_
Contains all the configuration data for the setup assistant.
static const double DEFAULT_KIN_SOLVER_TIMEOUT_
void saveSubgroups()
Button event for new groups, progressing to adding subgroups.
unsigned int index
void save()
Button event for just saving, when in edit mode.
void deleteGroup()
Event sent when delete is being requested for group.
void saveLinks()
Button event for new groups, progressing to adding links.
static const double DEFAULT_KIN_SOLVER_SEARCH_RESOLUTION_
void saveChain()
Button event for new groups, progressing to adding a chain.
void loadKinematicPlannersComboBox()
Populate the combo dropdown box with kinematic planners.
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
void saveJoints()
Button event for new groups, progressing to adding joints.
#define ROS_ERROR_STREAM(args)
void setSelected(const std::string &group_name)
Set the previous data.


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Sun Oct 18 2020 13:19:28