moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
controller_edit_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#include <QComboBox>
37#include <QFormLayout>
38#include <QGroupBox>
39#include <QHBoxLayout>
40#include <QLabel>
41#include <QLineEdit>
42#include <QMessageBox>
43#include <QPushButton>
44#include <QString>
45#include <QVBoxLayout>
47
48namespace moveit_setup
49{
50namespace controllers
51{
52// ******************************************************************************************
53// ControllerEditWidget constructor, create controller edit screen GUI
54// ******************************************************************************************
55ControllerEditWidget::ControllerEditWidget(QWidget* parent, const FieldPointers& additional_fields)
56 : QWidget(parent), additional_fields_(additional_fields)
57{
58 // Basic widget container
59 QVBoxLayout* layout = new QVBoxLayout();
60
61 QGroupBox* controller_options_group = new QGroupBox("Controller Options");
62
63 // Label ------------------------------------------------
64 title_ = new QLabel(this); // specify the title from the parent widget
65 QFont group_title_font(QFont().defaultFamily(), 12, QFont::Bold);
66 title_->setFont(group_title_font);
67 layout->addWidget(title_);
68
69 QFormLayout* form_layout = new QFormLayout();
70 form_layout->setContentsMargins(0, 15, 0, 15);
71
72 // Controller Name
73 controller_name_field_ = new QLineEdit(this);
74 controller_name_field_->setMaximumWidth(400);
75 form_layout->addRow("Controller Name:", controller_name_field_);
76
77 // Controller Type
78 controller_type_field_ = new QComboBox(this);
79 controller_type_field_->setEditable(false);
80 controller_type_field_->setMaximumWidth(400);
81 connect(controller_type_field_, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int)));
82 form_layout->addRow("Controller Type:", controller_type_field_);
83
84 for (const auto& field : additional_fields_)
85 {
86 QLineEdit* input = new QLineEdit(this);
87 input->setMaximumWidth(400);
88 form_layout->addRow(field->display_name_.c_str(), input);
89 additional_fields_inputs_.push_back(input);
90 }
91
92 controller_options_group->setLayout(form_layout);
93
94 layout->addWidget(controller_options_group);
95
96 layout->setAlignment(Qt::AlignTop);
97
98 // New Controller Options ---------------------------------------------------------
99 new_buttons_widget_ = new QWidget();
100 QVBoxLayout* new_buttons_layout = new QVBoxLayout();
101
102 QLabel* save_and_add = new QLabel("Next, Add Components To Controller:", this);
103 QFont save_and_add_font(QFont().defaultFamily(), 12, QFont::Bold);
104 save_and_add->setFont(save_and_add_font);
105 new_buttons_layout->addWidget(save_and_add);
106
107 QLabel* add_subtitle = new QLabel("Recommended: ", this);
108 QFont add_subtitle_font(QFont().defaultFamily(), 10, QFont::Bold);
109 add_subtitle->setFont(add_subtitle_font);
110 new_buttons_layout->addWidget(add_subtitle);
111
112 // Save and add groups
113 QPushButton* btn_save_groups_joints = new QPushButton("Add Planning Group Joints", this);
114 btn_save_groups_joints->setMaximumWidth(200);
115 connect(btn_save_groups_joints, SIGNAL(clicked()), this, SIGNAL(saveJointsGroups()));
116 new_buttons_layout->addWidget(btn_save_groups_joints);
117
118 QLabel* add_subtitle2 = new QLabel("Advanced Options:", this);
119 add_subtitle2->setFont(add_subtitle_font);
120 new_buttons_layout->addWidget(add_subtitle2);
121
122 // Save and add joints
123 QPushButton* btn_save_joints = new QPushButton("Add Individual Joints", this);
124 btn_save_joints->setMaximumWidth(200);
125 connect(btn_save_joints, SIGNAL(clicked()), this, SIGNAL(saveJoints()));
126 new_buttons_layout->addWidget(btn_save_joints);
127
128 // Create widget and add to main layout
129 new_buttons_widget_->setLayout(new_buttons_layout);
130 layout->addWidget(new_buttons_widget_);
131
132 // Vertical Spacer
133 layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
134
135 // Bottom Controls ---------------------------------------------------------
136 QHBoxLayout* controls_layout = new QHBoxLayout();
137
138 // Delete
139 btn_delete_ = new QPushButton("&Delete Controller", this);
140 btn_delete_->setMaximumWidth(200);
141 connect(btn_delete_, SIGNAL(clicked()), this, SIGNAL(deleteController()));
142 controls_layout->addWidget(btn_delete_);
143 controls_layout->setAlignment(btn_delete_, Qt::AlignRight);
144
145 // Horizontal Spacer
146 controls_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
147
148 // Save
149 btn_save_ = new QPushButton("&Save", this);
150 btn_save_->setMaximumWidth(200);
151 connect(btn_save_, SIGNAL(clicked()), this, SIGNAL(save()));
152 controls_layout->addWidget(btn_save_);
153 controls_layout->setAlignment(btn_save_, Qt::AlignRight);
154
155 // Cancel
156 QPushButton* btn_cancel = new QPushButton("&Cancel", this);
157 btn_cancel->setMaximumWidth(200);
158 connect(btn_cancel, SIGNAL(clicked()), this, SIGNAL(cancelEditing()));
159 controls_layout->addWidget(btn_cancel);
160 controls_layout->setAlignment(btn_cancel, Qt::AlignRight);
161
162 // Add layout
163 layout->addLayout(controls_layout);
164
165 // Finish Layout --------------------------------------------------
166 setLayout(layout);
167}
168
169// ******************************************************************************************
170// Set the fields with previous values
171// ******************************************************************************************
172void ControllerEditWidget::setSelected(const std::string& controller_name, const ControllerInfo* searched_controller)
173{
174 controller_name_field_->setText(QString(controller_name.c_str()));
175 if (searched_controller != nullptr)
176 {
177 const std::string controller_type = searched_controller->type_;
178 int type_index = controller_type_field_->findText(controller_type.c_str());
179
180 // Set the controller type combo box
181 if (type_index == -1)
182 {
183 QMessageBox::warning(this, "Missing Controller Type", QString("Setting controller type to the default value"));
184 return;
185 }
186 else
187 {
188 controller_type_field_->setCurrentIndex(type_index);
189 }
190
191 for (unsigned int i = 0; i < additional_fields_.size(); i++)
192 {
193 std::string key = additional_fields_[i]->parameter_name_;
194 const auto& it = searched_controller->parameters_.find(key);
195 if (it != searched_controller->parameters_.end())
196 {
197 additional_fields_inputs_[i]->setText(it->second.c_str());
198 }
199 }
200 }
201 else
202 {
203 controller_type_field_->setCurrentIndex(0);
204 }
205}
206
207// ******************************************************************************************
208// Populate the combo dropdown box with controllers types
209// ******************************************************************************************
210void ControllerEditWidget::loadControllersTypesComboBox(const std::vector<std::string>& controller_types)
211{
212 // Only load this combo box once
213 if (has_loaded_)
214 return;
215 has_loaded_ = true;
216
217 // Remove all old items
218 controller_type_field_->clear();
219
220 // Loop through all controller types and add to combo box
221 for (const std::string& type : controller_types)
222 controller_type_field_->addItem(type.c_str());
223}
224
226{
227 btn_delete_->hide();
228}
229
231{
232 btn_save_->hide();
233}
234
236{
237 new_buttons_widget_->hide();
238}
239
241{
242 btn_delete_->show();
243}
244
246{
247 btn_save_->show();
248}
249
251{
252 new_buttons_widget_->show();
253}
254
255void ControllerEditWidget::setTitle(const QString& title)
256{
257 title_->setText(title);
258}
259
261{
262 return controller_name_field_->text().trimmed().toStdString();
263}
264
266{
267 return controller_type_field_->currentText().toStdString();
268}
269
270std::map<std::string, std::string> ControllerEditWidget::getAdditionalParameters()
271{
272 std::map<std::string, std::string> parameters;
273 for (unsigned int i = 0; i < additional_fields_.size(); i++)
274 {
275 std::string key = additional_fields_[i]->parameter_name_;
276 std::string value = additional_fields_inputs_[i]->text().trimmed().toStdString();
277 parameters[key] = value;
278 }
279 return parameters;
280}
281
282void ControllerEditWidget::typeChanged(int /*index*/)
283{
284 std::string controller_type = getControllerType();
285 for (unsigned int i = 0; i < additional_fields_.size(); i++)
286 {
287 std::string new_value = additional_fields_[i]->getDefaultValue(controller_type);
288 additional_fields_inputs_[i]->setText(new_value.c_str());
289 }
290}
291
292} // namespace controllers
293} // namespace moveit_setup
ControllerEditWidget(QWidget *parent, const FieldPointers &additional_fields)
Constructor.
void cancelEditing()
Event sent when user presses cancel button.
void save()
Button event for just saving, when in edit mode.
void saveJoints()
Button event for new groups, progressing to adding joints.
std::map< std::string, std::string > getAdditionalParameters()
Get the names and values for any additional parameters.
void deleteController()
Event sent when delete is being requested for controller.
void setSelected(const std::string &controller_name, const ControllerInfo *info)
Set the previous data.
void saveJointsGroups()
Button event for new groups, progressing to adding subgroups.
void loadControllersTypesComboBox(const std::vector< std::string > &controller_types)
Populate the combo dropdown box with controllers types.
void setTitle(const QString &title)
Set widget title.
std::vector< std::shared_ptr< AdditionalControllerField > > FieldPointers
Convenience alias.
KeyboardReader input
std::map< std::string, std::string > parameters_