42 #include <QApplication>
44 #include <QFormLayout>
46 #include <QHBoxLayout>
49 #include <QMessageBox>
50 #include <QPushButton>
51 #include <QScrollArea>
52 #include <QStackedWidget>
54 #include <QTableWidget>
55 #include <QVBoxLayout>
68 QVBoxLayout* layout =
new QVBoxLayout();
73 "Setup your robot's end effectors. These are planning groups "
74 "corresponding to grippers or tools, attached to a parent "
75 "planning group (an arm). The specified parent link is used as the "
76 "reference frame for IK attempts.",
78 layout->addWidget(header);
92 this->setLayout(layout);
98 QWidget* EndEffectorsWidget::createContentsWidget()
101 QWidget* content_widget =
new QWidget(
this);
104 QVBoxLayout* layout =
new QVBoxLayout(
this);
111 data_table_->setSelectionBehavior(QAbstractItemView::SelectRows);
112 connect(
data_table_, SIGNAL(cellDoubleClicked(
int,
int)),
this, SLOT(editDoubleClicked(
int,
int)));
113 connect(
data_table_, SIGNAL(cellClicked(
int,
int)),
this, SLOT(previewClicked(
int,
int)));
117 QStringList header_list;
118 header_list.append(
"End Effector Name");
119 header_list.append(
"Group Name");
120 header_list.append(
"Parent Link");
121 header_list.append(
"Parent Group");
122 data_table_->setHorizontalHeaderLabels(header_list);
126 QHBoxLayout* controls_layout =
new QHBoxLayout();
129 controls_layout->addItem(
new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
132 btn_edit_ =
new QPushButton(
"&Edit Selected",
this);
133 btn_edit_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
136 connect(
btn_edit_, SIGNAL(clicked()),
this, SLOT(editSelected()));
138 controls_layout->setAlignment(
btn_edit_, Qt::AlignRight);
141 btn_delete_ =
new QPushButton(
"&Delete Selected",
this);
142 connect(
btn_delete_, SIGNAL(clicked()),
this, SLOT(deleteSelected()));
144 controls_layout->setAlignment(
btn_delete_, Qt::AlignRight);
147 QPushButton* btn_add =
new QPushButton(
"&Add End Effector",
this);
148 btn_add->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
149 btn_add->setMaximumWidth(300);
150 connect(btn_add, SIGNAL(clicked()),
this, SLOT(showNewScreen()));
151 controls_layout->addWidget(btn_add);
152 controls_layout->setAlignment(btn_add, Qt::AlignRight);
155 layout->addLayout(controls_layout);
158 content_widget->setLayout(layout);
160 return content_widget;
166 QWidget* EndEffectorsWidget::createEditWidget()
169 QWidget* edit_widget =
new QWidget(
this);
171 QVBoxLayout* layout =
new QVBoxLayout();
174 QFormLayout* form_layout =
new QFormLayout();
176 form_layout->setRowWrapPolicy(QFormLayout::WrapAllRows);
187 SLOT(previewClickedString(
const QString&)));
199 layout->addLayout(form_layout);
203 QHBoxLayout* controls_layout =
new QHBoxLayout();
204 controls_layout->setContentsMargins(0, 25, 0, 15);
207 controls_layout->addItem(
new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
210 btn_save_ =
new QPushButton(
"&Save",
this);
212 connect(
btn_save_, SIGNAL(clicked()),
this, SLOT(doneEditing()));
214 controls_layout->setAlignment(
btn_save_, Qt::AlignRight);
219 connect(
btn_cancel_, SIGNAL(clicked()),
this, SLOT(cancelEditing()));
221 controls_layout->setAlignment(
btn_cancel_, Qt::AlignRight);
224 layout->addLayout(controls_layout);
227 edit_widget->setLayout(layout);
235 void EndEffectorsWidget::showNewScreen()
238 current_edit_effector_.clear();
256 void EndEffectorsWidget::editDoubleClicked(
int ,
int )
264 void EndEffectorsWidget::previewClicked(
int ,
int )
267 QList<QTableWidgetItem*> selected =
data_table_->selectedItems();
270 if (selected.empty())
274 srdf::Model::EndEffector* effector = getEndEffector(selected[0]->
text().toStdString());
286 void EndEffectorsWidget::previewClickedString(
const QString&
name)
302 void EndEffectorsWidget::editSelected()
305 QList<QTableWidgetItem*> selected =
data_table_->selectedItems();
308 if (selected.empty())
312 edit(selected[0]->
text().toStdString());
318 void EndEffectorsWidget::edit(
const std::string&
name)
321 current_edit_effector_ =
name;
324 srdf::Model::EndEffector* effector = getEndEffector(
name);
333 QMessageBox::critical(
this,
"Error Loading",
"Unable to find parent link in drop down box");
342 QMessageBox::critical(
this,
"Error Loading",
"Unable to find group name in drop down box");
351 QMessageBox::critical(
this,
"Error Loading",
"Unable to find parent group name in drop down box");
366 void EndEffectorsWidget::loadGroupsComboBox()
374 for (
const std::string& group_name : setup_step_.
getGroupNames())
384 void EndEffectorsWidget::loadParentComboBox()
391 for (
const std::string& link_name : setup_step_.
getLinkNames())
400 srdf::Model::EndEffector* EndEffectorsWidget::getEndEffector(
const std::string&
name)
402 srdf::Model::EndEffector* searched_group = setup_step_.
find(
name);
405 if (searched_group ==
nullptr)
407 QMessageBox::critical(
this,
"Error Saving",
"An internal error has occurred while saving. Quitting.");
408 QApplication::quit();
411 return searched_group;
417 void EndEffectorsWidget::deleteSelected()
420 QList<QTableWidgetItem*> selected =
data_table_->selectedItems();
423 if (selected.empty())
427 current_edit_effector_ = selected[0]->text().toStdString();
430 if (QMessageBox::question(
this,
"Confirm End Effector Deletion",
431 QString(
"Are you sure you want to delete the end effector '")
432 .
append(current_edit_effector_.c_str())
434 QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
439 setup_step_.
remove(current_edit_effector_);
448 void EndEffectorsWidget::doneEditing()
454 if (effector_name.empty())
456 QMessageBox::warning(
this,
"Error Saving",
"A name must be specified for the end effector!");
463 QMessageBox::warning(
this,
"Error Saving",
"A group that contains the links of the end-effector must be chosen!");
470 QMessageBox::warning(
this,
"Error Saving",
"A parent link must be chosen!");
479 QMessageBox::warning(
this,
"Error Saving",
480 QString::fromStdString(
"The specified parent group '" +
482 "' must contain the specified parent link '" +
492 srdf::Model::EndEffector* searched_data = setup_step_.
get(effector_name, current_edit_effector_);
498 catch (
const std::runtime_error& e)
500 QMessageBox::warning(
this,
"Error Saving", e.what());
519 void EndEffectorsWidget::cancelEditing()
525 previewClicked(0, 0);
534 void EndEffectorsWidget::loadDataTable()
548 for (
const auto& eef : end_effectors)
551 QTableWidgetItem* data_name =
new QTableWidgetItem(eef.name_.c_str());
552 data_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
553 QTableWidgetItem* group_name =
new QTableWidgetItem(eef.component_group_.c_str());
554 group_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
555 QTableWidgetItem* parent_name =
new QTableWidgetItem(eef.parent_link_.c_str());
556 group_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
557 QTableWidgetItem* parent_group_name =
new QTableWidgetItem(eef.parent_group_.c_str());
558 parent_group_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
581 if (!end_effectors.empty())
597 loadGroupsComboBox();
598 loadParentComboBox();
604 #include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(cached_ik_kinematics_plugin::CachedIKKinematicsPlugin< kdl_kinematics_plugin::KDLKinematicsPlugin >, kinematics::KinematicsBase)
void highlightGroup(const std::string &group_name)
std::vector< std::string > getLinkNames() const
std::vector< srdf::Model::EndEffector > & getEndEffectors()
bool isLinkInGroup(const std::string &link, const std::string &group) const
std::vector< std::string > getGroupNames() const
void setProperties(srdf::Model::EndEffector *eef, const std::string &parent_link, const std::string &component_group, const std::string &parent_group)
T * find(const std::string &name)
Return a pointer to an item with the given name if it exists, otherwise null.
T * get(const std::string &name, const std::string &old_name="")
Get a pointer to an item with the given name, creating if necessary. If old_name is provided (and is ...
bool remove(const std::string &name)
Delete an item with the given name from the list.
std::string append(const std::string &left, const std::string &right)