diff --git a/source/RobotAPI/gui-plugins/CMakeLists.txt b/source/RobotAPI/gui-plugins/CMakeLists.txt index b0335a392cdc7eef28caf85ba2d36dae2011cfea..fab91a6927b88f7bf0bacff9d3e569907413cad6 100644 --- a/source/RobotAPI/gui-plugins/CMakeLists.txt +++ b/source/RobotAPI/gui-plugins/CMakeLists.txt @@ -19,8 +19,9 @@ add_subdirectory(ObjectPoseGui) add_subdirectory(CartesianImpedanceController) add_subdirectory(BimanualCartesianAdmittanceControllerGui) - add_subdirectory(ArVizDrawerGui) add_subdirectory(FTSensorCalibrationGui) add_subdirectory(SkillObserverMonitor) +add_subdirectory(GraspCandidateViewer) add_subdirectory(BoxToGraspCandidates) + diff --git a/source/RobotAPI/gui-plugins/GraspCandidateViewer/CMakeLists.txt b/source/RobotAPI/gui-plugins/GraspCandidateViewer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3f929d1a40cce30263eab1cdf0dca4d71c2d49d6 --- /dev/null +++ b/source/RobotAPI/gui-plugins/GraspCandidateViewer/CMakeLists.txt @@ -0,0 +1,15 @@ +set(LIB_NAME "GraspCandidateViewerGuiPlugin") +armarx_set_target("${LIB_NAME}") + +armarx_build_if(ArmarXGui_FOUND "ArmarXGui not available") + +set(SOURCES GraspCandidateViewerWidgetController.cpp) +set(HEADERS GraspCandidateViewerWidgetController.h) +set(GUI_UIS GraspCandidateViewerWidget.ui) + +set(COMPONENT_LIBS RobotAPIComponentPlugins SimpleConfigDialog GraspingUtility) + +if(ArmarXGui_FOUND) + armarx_gui_plugin("${LIB_NAME}" "${SOURCES}" "" "${GUI_UIS}" "" "${COMPONENT_LIBS}") +endif() + diff --git a/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidget.ui b/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidget.ui new file mode 100644 index 0000000000000000000000000000000000000000..d69a5d6aa2bb70aec0981896adb77c38974a0134 --- /dev/null +++ b/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidget.ui @@ -0,0 +1,413 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>GraspCandidateViewerWidget</class> + <widget class="QWidget" name="GraspCandidateViewerWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1620</width> + <height>881</height> + </rect> + </property> + <property name="windowTitle"> + <string>GraspCandidateViewerWidget</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="0" column="0"> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QWidget" name="widget" native="true"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="0"> + <widget class="QTreeWidget" name="treeWidgetGC"> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string notr="true">1</string> + </property> + </column> + </widget> + </item> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="pushButtonUpdateGC"> + <property name="text"> + <string>Update</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="widget_2" native="true"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="6" column="5"> + <widget class="QLabel" name="labelRPoseRY"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="labelGApprTX"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="8" column="0" colspan="7"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QLabel" name="labelGPoseTY"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="3" column="4"> + <widget class="QLabel" name="label_38"> + <property name="text"> + <string>RX</string> + </property> + </widget> + </item> + <item row="3" column="5"> + <widget class="QLabel" name="label_39"> + <property name="text"> + <string>RY</string> + </property> + </widget> + </item> + <item row="9" column="1" colspan="6"> + <widget class="QLabel" name="labelSrcFrame"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="labelGPoseTX"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="6"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="labelGCIdx"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>/</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelNumGC"> + <property name="text"> + <string>---</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="0" colspan="7"> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>grasp probability</string> + </property> + </widget> + </item> + <item row="10" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>target frame</string> + </property> + </widget> + </item> + <item row="5" column="4"> + <widget class="QLabel" name="labelGPoseRX"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_11"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Grasp pose (X,Y,Z / R,P,Y)</string> + </property> + </widget> + </item> + <item row="6" column="4"> + <widget class="QLabel" name="labelRPoseRX"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Candidate</string> + </property> + </widget> + </item> + <item row="5" column="6"> + <widget class="QLabel" name="labelGPoseRZ"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Robot Pose (X,Y,Z / R,P,Y)</string> + </property> + </widget> + </item> + <item row="3" column="6"> + <widget class="QLabel" name="label_28"> + <property name="text"> + <string>RZ</string> + </property> + </widget> + </item> + <item row="6" column="3"> + <widget class="QLabel" name="labelRPoseTZ"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="15" column="0"> + <widget class="QLabel" name="label_19"> + <property name="text"> + <string>provider name</string> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>side</string> + </property> + </widget> + </item> + <item row="5" column="5"> + <widget class="QLabel" name="labelGPoseRY"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="17" column="0"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="14" column="1" colspan="6"> + <widget class="QLabel" name="labelGraspObjType"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Approach Vector (X,Y,Z / R,P,Y)</string> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QLabel" name="labelGApprTY"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QLabel" name="labelRPoseTY"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="12" column="1" colspan="6"> + <widget class="QLabel" name="labelGraspProb"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="10" column="1" colspan="6"> + <widget class="QLabel" name="labelTrgFrame"/> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="label_26"> + <property name="text"> + <string>TX</string> + </property> + </widget> + </item> + <item row="5" column="3"> + <widget class="QLabel" name="labelGPoseTZ"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="15" column="1" colspan="6"> + <widget class="QLabel" name="labelGraspProviderName"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QLabel" name="label_37"> + <property name="text"> + <string>TZ</string> + </property> + </widget> + </item> + <item row="6" column="6"> + <widget class="QLabel" name="labelRPoseRZ"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="11" column="1" colspan="6"> + <widget class="QLabel" name="labelSide"/> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>object type</string> + </property> + </widget> + </item> + <item row="7" column="3"> + <widget class="QLabel" name="labelGApprTZ"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLabel" name="label_27"> + <property name="text"> + <string>TY</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="labelRPoseTX"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item row="9" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>source frame</string> + </property> + </widget> + </item> + <item row="13" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>group nr</string> + </property> + </widget> + </item> + <item row="13" column="1" colspan="6"> + <widget class="QLabel" name="labelGraspgroupNr"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidgetController.cpp b/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidgetController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a46e191dcc34615698951568a86ceddac3231ac3 --- /dev/null +++ b/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidgetController.cpp @@ -0,0 +1,276 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * \package RobotAPI::gui-plugins::GraspCandidateViewerWidgetController + * \author Raphael Grimm ( raphael dot grimm at kit dot edu ) + * \date 2020 + * \copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include <string> + +#include <SimoxUtility/math/convert/quat_to_rpy.h> + +#include <RobotAPI/libraries/GraspingUtility/grasp_candidate_drawer.h> +#include "GraspCandidateViewerWidgetController.h" + +//setting management +namespace armarx +{ + void GraspCandidateViewerWidgetController::loadSettings(QSettings* settings) + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + getRobotStateComponentPlugin().setRobotStateComponentName(settings->value("rsc", "Armar6StateComponent").toString().toStdString()); + getGraspCandidateObserverComponentPlugin().setGraspCandidateObserverName(settings->value("gco", "GraspCandidateObserver").toString().toStdString()); + + } + void GraspCandidateViewerWidgetController::saveSettings(QSettings* settings) + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + settings->setValue("rsc", QString::fromStdString(getRobotStateComponentPlugin().getRobotStateComponentName())); + settings->setValue("rsc", QString::fromStdString(getGraspCandidateObserverComponentPlugin().getGraspCandidateObserverName())); + + } + QPointer<QDialog> GraspCandidateViewerWidgetController::getConfigDialog(QWidget* parent) + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + if (!_dialog) + { + _dialog = new SimpleConfigDialog(parent); + _dialog->addProxyFinder<RobotStateComponentInterfacePrx>("rsc", "Robot State Component", "*Component"); + _dialog->addProxyFinder<grasping::GraspCandidateObserverInterfacePrx>("gco", "Grasp Candidate Observer", "*Observer"); + } + return qobject_cast<SimpleConfigDialog*>(_dialog); + } + void GraspCandidateViewerWidgetController::configured() + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + getRobotStateComponentPlugin().setRobotStateComponentName(_dialog->getProxyName("rsc")); + getGraspCandidateObserverComponentPlugin().setGraspCandidateObserverName(_dialog->getProxyName("gco")); + } +} +//ctor +namespace armarx +{ + GraspCandidateViewerWidgetController::GraspCandidateViewerWidgetController() + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + _ui.setupUi(getWidget()); + + connect(_ui.pushButtonUpdateGC, &QPushButton::clicked, + this, &GraspCandidateViewerWidgetController::update_gc); + connect(_ui.treeWidgetGC, &QTreeWidget::itemSelectionChanged, + this, &GraspCandidateViewerWidgetController::selected_item_changed); + + connect(_ui.treeWidgetGC, SIGNAL(itemChanged(QTreeWidgetItem*, int)), + this, SLOT(check_state_changed())); + } + + GraspCandidateViewerWidgetController::~GraspCandidateViewerWidgetController() + {} + + void GraspCandidateViewerWidgetController::update_gc() + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + if (!getGraspCandidateObserver()) + { + return; + } + //clean + { + _ui.treeWidgetGC->clear(); + for (auto& [prname, pr] : _providers) + { + pr.candidates.clear(); + pr.item = nullptr; + } + _tree_item_to_gc.clear(); + } + //fill + { + for (const auto& gc : getGraspCandidateObserver()->getAllCandidates()) + { + ARMARX_CHECK_NOT_NULL(gc); + const auto& pname = gc->providerName; + auto& pr = _providers[pname]; + pr.provider_name = pname; + if (!pr.item) + { + pr.item = new QTreeWidgetItem; + pr.item->setCheckState(0, Qt::Unchecked); + _ui.treeWidgetGC-> addTopLevelItem(pr.item); + pr.item->setText(0, QString::fromStdString(pname)); + } + + auto& gcdata = pr.candidates.emplace_back(); + gcdata.gc = gc; + gcdata.idx = pr.candidates.size() - 1; + gcdata.provider = ≺ + gcdata.item = new QTreeWidgetItem; + gcdata.item->setCheckState(0, Qt::Unchecked); + pr.item->addChild(gcdata.item); + gcdata.item->setText(0, QString::fromStdString(gcdata.name())); + _tree_item_to_gc[gcdata.item] = &gcdata; + } + } + } + + void GraspCandidateViewerWidgetController::check_state_changed() + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + synchronizeLocalClone(_robot); + armarx::grasp_candidate_drawer gc_drawer{getRobotNameHelper(), _robot}; + + std::vector<viz::Layer> layers; + for (const auto& [pname, pr] : _providers) + { + layers.emplace_back(getArvizClient().layer(pname)); + auto& l = layers.back(); + for (const auto& gc : pr.candidates) + { + if (gc.item->checkState(0) == Qt::Unchecked) + { + gc_drawer.draw(gc.gc, l); + } + } + } + getArvizClient().commit(layers); + } + void GraspCandidateViewerWidgetController::selected_item_changed() + { + ARMARX_TRACE; + std::lock_guard g{_mutex}; + const auto& selected = _ui.treeWidgetGC->selectedItems(); + ARMARX_CHECK_GREATER(2, selected.size()); + if (selected.empty()) + { + show_entry(nullptr); + //clear + } + else if (_tree_item_to_gc.count(selected.value(0))) + { + show_entry(_tree_item_to_gc.at(selected.value(0))); + } + //provider item selected -> do nothing + } + + void GraspCandidateViewerWidgetController::show_entry(entry_gc* e) + { + if (!e) + { + _ui.labelGCIdx ->setText("-"); + _ui.labelNumGC ->setText("-"); + + _ui.labelGPoseTX ->setText("-"); + _ui.labelGPoseTY ->setText("-"); + _ui.labelGPoseTZ ->setText("-"); + _ui.labelGPoseRX ->setText("-"); + _ui.labelGPoseRY ->setText("-"); + _ui.labelGPoseRZ ->setText("-"); + + _ui.labelRPoseTX ->setText("-"); + _ui.labelRPoseTY ->setText("-"); + _ui.labelRPoseTZ ->setText("-"); + _ui.labelRPoseRX ->setText("-"); + _ui.labelRPoseRY ->setText("-"); + _ui.labelRPoseRZ ->setText("-"); + + _ui.labelGApprTX ->setText("-"); + _ui.labelGApprTY ->setText("-"); + _ui.labelGApprTZ ->setText("-"); + + _ui.labelSrcFrame ->setText("-"); + _ui.labelTrgFrame ->setText("-"); + _ui.labelSide ->setText("-"); + _ui.labelGraspProb ->setText("-"); + _ui.labelGraspgroupNr ->setText("-"); + _ui.labelGraspObjType ->setText("-"); + _ui.labelGraspProviderName->setText("-"); + return; + } + ARMARX_CHECK_NOT_NULL(e->gc); + ARMARX_CHECK_NOT_NULL(e->gc->graspPose->position); + ARMARX_CHECK_NOT_NULL(e->gc->robotPose->position); + ARMARX_CHECK_NOT_NULL(e->gc->graspPose->orientation); + ARMARX_CHECK_NOT_NULL(e->gc->robotPose->orientation); + ARMARX_CHECK_NOT_NULL(e->gc->approachVector); + _ui.labelGCIdx ->setText(QString::number(e->idx + 1)); + _ui.labelNumGC ->setText(QString::number(e->provider->candidates.size())); + + _ui.labelGPoseTX ->setText(QString::number(e->gc->graspPose->position->x)); + _ui.labelGPoseTY ->setText(QString::number(e->gc->graspPose->position->y)); + _ui.labelGPoseTZ ->setText(QString::number(e->gc->graspPose->position->z)); + const Eigen::Vector3f vec_g = simox::math::quat_to_rpy( + { + e->gc->graspPose->orientation->qw, + e->gc->graspPose->orientation->qx, + e->gc->graspPose->orientation->qy, + e->gc->graspPose->orientation->qz + + } + ); + _ui.labelGPoseRX ->setText(QString::number(vec_g(0))); + _ui.labelGPoseRY ->setText(QString::number(vec_g(1))); + _ui.labelGPoseRZ ->setText(QString::number(vec_g(2))); + + _ui.labelRPoseTX ->setText(QString::number(e->gc->robotPose->position->x)); + _ui.labelRPoseTY ->setText(QString::number(e->gc->robotPose->position->y)); + _ui.labelRPoseTZ ->setText(QString::number(e->gc->robotPose->position->z)); + const Eigen::Vector3f vec_r = simox::math::quat_to_rpy( + { + e->gc->robotPose->orientation->qw, + e->gc->robotPose->orientation->qx, + e->gc->robotPose->orientation->qy, + e->gc->robotPose->orientation->qz + + } + ); + _ui.labelRPoseRX ->setText(QString::number(vec_r(0))); + _ui.labelRPoseRY ->setText(QString::number(vec_r(1))); + _ui.labelRPoseRZ ->setText(QString::number(vec_r(2))); + + _ui.labelGApprTX ->setText(QString::number(e->gc->approachVector->x)); + _ui.labelGApprTY ->setText(QString::number(e->gc->approachVector->y)); + _ui.labelGApprTZ ->setText(QString::number(e->gc->approachVector->z)); + + _ui.labelSrcFrame ->setText(QString::fromStdString(e->gc->sourceFrame)); + _ui.labelTrgFrame ->setText(QString::fromStdString(e->gc->targetFrame)); + _ui.labelSide ->setText(QString::fromStdString(e->gc->side)); + _ui.labelGraspProb ->setText(QString::number(e->gc->graspSuccessProbability)); + _ui.labelGraspgroupNr ->setText(QString::number(e->gc->groupNr)); + switch (e->gc->objectType) + { + case grasping::ObjectTypeEnum::AnyObject : + _ui.labelGraspObjType->setText("AnyObject"); + break; + case grasping::ObjectTypeEnum::KnownObject : + _ui.labelGraspObjType->setText("KnownObject"); + break; + case grasping::ObjectTypeEnum::UnknownObject : + _ui.labelGraspObjType->setText("UnknownObject"); + break; + } + _ui.labelGraspProviderName->setText(QString::fromStdString(e->gc->providerName)); + } + +} diff --git a/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidgetController.h b/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidgetController.h new file mode 100644 index 0000000000000000000000000000000000000000..72cd448b1d63b8047fde3bd84873b129223e2f38 --- /dev/null +++ b/source/RobotAPI/gui-plugins/GraspCandidateViewer/GraspCandidateViewerWidgetController.h @@ -0,0 +1,140 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @package RobotAPI::gui-plugins::GraspCandidateViewerWidgetController + * @author Raphael Grimm ( raphael dot grimm at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ +#pragma once + +#include <deque> + +#include <ArmarXCore/core/system/ImportExportComponent.h> + +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h> +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h> +#include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h> + +#include <RobotAPI/libraries/RobotAPIComponentPlugins/GraspCandidateObserverComponentPlugin.h> +#include <RobotAPI/libraries/RobotAPIComponentPlugins/RobotStateComponentPlugin.h> +#include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h> +#include <RobotAPI/components/ArViz/Client/Layer.h> +#include <RobotAPI/components/ArViz/Client/elements/Robot.h> + +#include <RobotAPI/gui-plugins/GraspCandidateViewer/ui_GraspCandidateViewerWidget.h> + +namespace armarx +{ + /** + \page RobotAPI-GuiPlugins-GraspCandidateViewer GraspCandidateViewer + \brief The GraspCandidateViewer allows visualizing ... + + \image html GraspCandidateViewer.png + The user can + + API Documentation \ref GraspCandidateViewerWidgetController + + \see GraspCandidateViewerGuiPlugin + */ + + + /** + * \class GraspCandidateViewerGuiPlugin + * \ingroup ArmarXGuiPlugins + * \brief GraspCandidateViewerGuiPlugin brief description + * + * Detailed description + */ + + /** + * \class GraspCandidateViewerWidgetController + * \brief GraspCandidateViewerWidgetController brief one line description + * + * Detailed description + */ + class ARMARXCOMPONENT_IMPORT_EXPORT + GraspCandidateViewerWidgetController: + public armarx::ArmarXComponentWidgetControllerTemplate < GraspCandidateViewerWidgetController >, + virtual public RobotStateComponentPluginUser, + virtual public ArVizComponentPluginUser, + virtual public GraspCandidateObserverComponentPluginUser + { + Q_OBJECT + + struct entry_gc; + struct entry_prov; + public: + explicit GraspCandidateViewerWidgetController(); + virtual ~GraspCandidateViewerWidgetController(); + + static QString GetWidgetName() + { + return "Grasping.GraspCandidateViewer"; + } + + void onInitComponent() override {} + void onConnectComponent() override + { + _robot = addRobot("state robot", VirtualRobot::RobotIO::eStructure); + } + void onDisconnectComponent() override {} + void onExitComponent() override {} + public: + void loadSettings(QSettings* settings) override; + void saveSettings(QSettings* settings) override; + QPointer<QDialog> getConfigDialog(QWidget* parent) override; + void configured() override; + public slots: + void update_gc(); + void selected_item_changed(); + void check_state_changed(); + + private: + void show_entry(entry_gc* e); + private: + + struct entry_prov + { + QTreeWidgetItem* item = nullptr; + std::string provider_name; + std::deque<entry_gc> candidates; + }; + + struct entry_gc + { + QTreeWidgetItem* item = nullptr; + grasping::GraspCandidatePtr gc = nullptr; + entry_prov* provider = nullptr; + int idx = -1; + bool show = false; + + std::string name() const + { + return provider->provider_name + "_" + std::to_string(idx + 1); + } + }; + + mutable std::recursive_mutex _mutex; + QPointer<SimpleConfigDialog> _dialog; + Ui::GraspCandidateViewerWidget _ui; + VirtualRobot::RobotPtr _robot; + std::map<std::string, entry_prov> _providers; + std::map<QTreeWidgetItem*, entry_gc*> _tree_item_to_gc; + }; +} + +