37 #include <QHBoxLayout> 38 #include <QMessageBox> 39 #include <QProgressDialog> 42 #include <QApplication> 43 #include <QButtonGroup> 44 #include <QRadioButton> 49 #include "../tools/collision_matrix_model.h" 50 #include "../tools/collision_linear_model.h" 51 #include "../tools/rotated_header_view.h" 63 layout_ =
new QVBoxLayout(
this);
67 "Optimize Self-Collision Checking",
68 "This searches for pairs of robot links that can safely be disabled from collision checking, decreasing motion " 69 "planning time. These pairs are disabled when they are always in collision, never in collision, in collision in " 70 "the robot's default position, or when the links are adjacent to each other on the kinematic chain. Sampling " 71 "density specifies how many random robot positions to check for self collision.",
78 QVBoxLayout* controls_box_layout =
new QVBoxLayout(
controls_box_);
80 QHBoxLayout* slider_layout =
new QHBoxLayout();
81 slider_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
82 controls_box_layout->addLayout(slider_layout);
85 QLabel* density_left_label =
new QLabel(
this);
86 density_left_label->setText(
"Sampling Density: Low");
87 slider_layout->addWidget(density_left_label);
103 QLabel* density_right_label =
new QLabel(
this);
104 density_right_label->setText(
"High ");
105 slider_layout->addWidget(density_right_label);
113 QHBoxLayout* buttons_layout =
new QHBoxLayout();
114 buttons_layout->setAlignment(Qt::AlignRight);
115 controls_box_layout->addLayout(buttons_layout);
119 fraction_label_->setText(
"Min. collisions for \"always\"-colliding pairs:");
131 btn_generate_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
157 action =
new QAction(tr(
"Show"),
this);
159 connect(action, SIGNAL(triggered()),
this, SLOT(
showSections()));
160 action =
new QAction(tr(
"Hide"),
this);
162 connect(action, SIGNAL(triggered()),
this, SLOT(
hideSections()));
163 action =
new QAction(tr(
"Hide others"),
this);
169 QHBoxLayout* bottom_layout =
new QHBoxLayout();
170 bottom_layout->setAlignment(Qt::AlignRight);
171 layout_->addLayout(bottom_layout);
186 QRadioButton* radio_btn;
187 radio_btn =
new QRadioButton(
"linear view");
188 bottom_layout->addWidget(radio_btn);
190 radio_btn->setChecked(
true);
192 radio_btn =
new QRadioButton(
"matrix view");
193 bottom_layout->addWidget(radio_btn);
200 btn_revert_->setToolTip(
"Revert current changes to collision matrix");
201 btn_revert_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
207 setWindowTitle(
"Default Collision Matrix");
260 const bool include_never_colliding =
true;
263 config_data_->getPlanningScene()->getAllowedCollisionMatrixNonConst().clear();
267 config_data_->getPlanningScene(), collision_progress, include_never_colliding, num_trials, min_frac, verbose);
270 *collision_progress = 100;
282 QAbstractItemModel* model;
286 model = matrix_model;
292 model = sorted_model;
293 sorted_model->setSourceModel(linear_model);
295 connect(
link_name_filter_, SIGNAL(textChanged(QString)), model, SLOT(setFilterRegExp(QString)));
296 QMetaObject::invokeMethod(model,
"setFilterRegExp", Q_ARG(QString,
link_name_filter_->text()));
307 QHeaderView *horizontal_header, *vertical_header;
312 connect(
selection_model_, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this,
323 horizontal_header->setVisible(
true);
324 vertical_header->setVisible(
true);
326 horizontal_header->setContextMenuPolicy(Qt::CustomContextMenu);
327 connect(horizontal_header, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showHeaderContextMenu(QPoint)));
328 vertical_header->setContextMenuPolicy(Qt::CustomContextMenu);
329 connect(vertical_header, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showHeaderContextMenu(QPoint)));
333 connect(
selection_model_, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this,
339 collision_table_->setHorizontalHeader(horizontal_header =
new QHeaderView(Qt::Horizontal,
this));
340 collision_table_->setVerticalHeader(vertical_header =
new QHeaderView(Qt::Vertical,
this));
345 horizontal_header->setVisible(
true);
346 vertical_header->setVisible(
true);
348 vertical_header->setContextMenuPolicy(Qt::CustomContextMenu);
349 connect(vertical_header, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
showHeaderContextMenu(QPoint)));
351 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) 352 horizontal_header->setSectionsClickable(
true);
353 vertical_header->setSectionsClickable(
true);
355 horizontal_header->setClickable(
true);
356 vertical_header->setClickable(
true);
361 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) 362 connect(
model_, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector<int>)),
this,
373 if (!index.isValid())
378 if ((linear_mode && !selection.contains(index)) ||
380 !(selection.contains(index) ||
381 selection.contains(
model_->index(index.column(), index.row())))))
383 QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::Select | QItemSelectionModel::Current;
385 flags |= QItemSelectionModel::Rows;
426 QHeaderView* header = 0;
430 list <<
index.column();
447 for (
auto index : list)
448 header->setSectionHidden(
index,
true);
454 QHeaderView* header = 0;
459 if (!header->isSectionHidden(
index.column()))
460 list <<
index.column();
466 if (!header->isSectionHidden(
index.row()))
478 for (std::size_t
index = 0, end = header->count();
index != end; ++
index)
479 header->setSectionHidden(
index,
true);
482 for (
auto index : list)
483 header->setSectionHidden(
index,
false);
495 list << 0 <<
model_->columnCount() - 1;
502 list << 0 <<
model_->rowCount() - 1;
508 QHeaderView* header = 0;
512 list <<
index.column();
532 if (logicalIndexes.size() < 2)
535 for (
int next = 1, end = logicalIndexes.size(); next != end; prev = next, ++next)
537 for (
int index = logicalIndexes[prev], index_end = logicalIndexes[next];
index <= index_end; ++
index)
538 header->setSectionHidden(
index,
false);
554 if (event->type() == QEvent::Enter)
560 else if (event->type() == QEvent::KeyPress)
562 QKeyEvent* keyEvent =
static_cast<QKeyEvent*
>(event);
563 if (keyEvent->key() != Qt::Key_Space)
578 for (
int r = 0;
r != rows; ++
r)
581 selection.merge(QItemSelection(
model_->index(
r, 0),
model_->index(
r, cols - 1)), QItemSelectionModel::Deselect);
583 for (
int c = 0; c != cols; ++c)
586 selection.merge(QItemSelection(
model_->index(0, c),
model_->index(rows - 1, c)), QItemSelectionModel::Deselect);
593 QModelIndex input_index;
594 if (cur_idx.flags() & Qt::ItemIsUserCheckable)
595 input_index = cur_idx;
598 for (
const auto idx : selection.indexes())
600 if (idx.flags() & Qt::ItemIsUserCheckable)
606 if (!input_index.isValid())
610 bool current =
model_->data(input_index, Qt::CheckStateRole) == Qt::Checked;
616 bool current =
model_->data(
model_->index(cur_idx.row(), 2), Qt::CheckStateRole) == Qt::Checked;
649 QApplication::processEvents();
672 for (moveit_setup_assistant::LinkPairMap::const_iterator pair_it =
link_pairs_.begin(); pair_it !=
link_pairs_.end();
676 if (pair_it->second.disable_check)
678 dc.
link1_ = pair_it->first.first;
679 dc.
link2_ = pair_it->first.second;
681 config_data_->srdf_->disabled_collisions_.push_back(dc);
698 planning_scene::PlanningScenePtr scene =
config_data_->getPlanningScene()->diff();
705 std::pair<std::string, std::string> link_pair;
708 for (std::vector<srdf::Model::DisabledCollision>::const_iterator collision_it =
710 collision_it !=
config_data_->srdf_->disabled_collisions_.end(); ++collision_it)
713 link_pair.first = collision_it->link1_;
714 link_pair.second = collision_it->link2_;
715 if (link_pair.first >= link_pair.second)
716 std::swap(link_pair.first, link_pair.second);
735 if (!index.isValid())
740 int c = index.column();
747 const QString& first_link =
model_->headerData(r, Qt::Vertical, Qt::DisplayRole).toString();
748 const QString& second_link =
model_->headerData(c, Qt::Horizontal, Qt::DisplayRole).toString();
749 uint check_state =
model_->data(index, Qt::CheckStateRole).toUInt();
751 QColor color = (check_state == Qt::Checked) ? QColor(0, 255, 0) : QColor(255, 0, 0);
761 if (!index.isValid())
765 const QString& first_link =
model_->data(
model_->index(index.row(), 0), Qt::DisplayRole).toString();
766 const QString& second_link =
model_->data(
model_->index(index.row(), 1), Qt::DisplayRole).toString();
767 uint check_state =
model_->data(
model_->index(index.row(), 2), Qt::CheckStateRole).toUInt();
769 QColor color = (check_state == Qt::Checked) ? QColor(0, 255, 0) : QColor(255, 0, 0);
794 if (QMessageBox::No == QMessageBox::question(
this,
"Collision Matrix Generation",
795 "Collision Matrix Generation is still active. Cancel computation?",
796 QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
808 QProgressBar* progress_bar)
809 : progress_(0), canceled_(false)
824 QThread::msleep(100);
MonitorThread(const boost::function< void(unsigned int *)> &f, QProgressBar *progress_bar=NULL)
Store details on a pair of links.
TFSIMD_FORCE_INLINE void setValue(const tfScalar &x, const tfScalar &y, const tfScalar &z)
void computeLinkPairs(const planning_scene::PlanningScene &scene, LinkPairMap &link_pairs)
Generate a list of unique link pairs for all links with geometry. Order pairs alphabetically. n choose 2 pairs.
const std::string disabledReasonToString(DisabledReason reason)
Converts a reason for disabling a link pair into a string.
#define ROS_INFO_STREAM(args)
void setShowAll(bool show_all)
QThread to monitor progress of a boost::thread.
void setEnabled(const QItemSelection &selection, bool value)
LinkPairMap computeDefaultCollisions(const planning_scene::PlanningSceneConstPtr &parent_scene, unsigned int *progress, const bool include_never_colliding, const unsigned int trials, const double min_collision_faction, const bool verbose)
Generate an adjacency list of links that are always and never in collision, to speed up collision det...
void setEnabled(const QItemSelection &selection, bool value)
DisabledReason disabledReasonFromString(const std::string &reason)
Converts a string reason for disabling a link pair into a struct data type.