From 3f64986f22bac046fa11ccab14c45404f9c1f9ad Mon Sep 17 00:00:00 2001 From: Fabian Paus <fabian.paus@kit.edu> Date: Wed, 8 Mar 2017 14:56:53 +0100 Subject: [PATCH] Hokuyo: Added simple GUI plugin --- .../HokuyoLaserUnit/HokuyoLaserUnit.cpp | 5 + .../drivers/HokuyoLaserUnit/HokuyoLaserUnit.h | 3 +- source/RobotAPI/gui-plugins/CMakeLists.txt | 2 + .../LaserScannerPlugin/CMakeLists.txt | 40 +++++ .../LaserScannerPluginGuiPlugin.cpp | 34 +++++ .../LaserScannerPluginGuiPlugin.h | 51 +++++++ .../LaserScannerPluginWidget.ui | 63 ++++++++ .../LaserScannerPluginWidgetController.cpp | 138 ++++++++++++++++++ .../LaserScannerPluginWidgetController.h | 131 +++++++++++++++++ .../interface/units/LaserScannerUnit.ice | 2 + 10 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 source/RobotAPI/gui-plugins/LaserScannerPlugin/CMakeLists.txt create mode 100644 source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.cpp create mode 100644 source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.h create mode 100644 source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidget.ui create mode 100644 source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.cpp create mode 100644 source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h diff --git a/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.cpp b/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.cpp index ac411a211..fc78cf268 100644 --- a/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.cpp +++ b/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.cpp @@ -134,6 +134,11 @@ armarx::PropertyDefinitionsPtr HokuyoLaserUnit::createPropertyDefinitions() getConfigIdentifier())); } +std::string HokuyoLaserUnit::getReportTopicName(const Ice::Current& c) const +{ + return topicName; +} + void HokuyoLaserUnit::updateScanData() { LaserScan scan; diff --git a/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.h b/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.h index e8d018f39..2445d3a03 100644 --- a/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.h +++ b/source/RobotAPI/drivers/HokuyoLaserUnit/HokuyoLaserUnit.h @@ -111,6 +111,8 @@ namespace armarx */ virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions(); + std::string getReportTopicName(const Ice::Current& c) const override; + private: void updateScanData(); @@ -121,7 +123,6 @@ namespace armarx float angleOffset = 0.0f; std::vector<HokuyoLaserScanDevice> devices; PeriodicTask<HokuyoLaserUnit>::pointer_type task; - }; } diff --git a/source/RobotAPI/gui-plugins/CMakeLists.txt b/source/RobotAPI/gui-plugins/CMakeLists.txt index 8e1b05f0d..fc363790a 100644 --- a/source/RobotAPI/gui-plugins/CMakeLists.txt +++ b/source/RobotAPI/gui-plugins/CMakeLists.txt @@ -10,3 +10,5 @@ add_subdirectory(RobotViewerPlugin) add_subdirectory(DebugDrawerViewer) add_subdirectory(ViewSelection) + +add_subdirectory(LaserScannerPlugin) \ No newline at end of file diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/CMakeLists.txt b/source/RobotAPI/gui-plugins/LaserScannerPlugin/CMakeLists.txt new file mode 100644 index 000000000..1c1e4e282 --- /dev/null +++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/CMakeLists.txt @@ -0,0 +1,40 @@ + +armarx_set_target("LaserScannerPluginGuiPlugin") + +find_package(Qt4 COMPONENTS QtCore QtGui QtDesigner) + +armarx_build_if(QT_FOUND "Qt not available") +# ArmarXGui gets included through depends_on_armarx_package(ArmarXGui "OPTIONAL") +# in the toplevel CMakeLists.txt +armarx_build_if(ArmarXGui_FOUND "ArmarXGui not available") + + +# all include_directories must be guarded by if(Xyz_FOUND) +# for multiple libraries write: if(X_FOUND AND Y_FOUND).... +if(QT_FOUND) + include(${QT_USE_FILE}) +endif() + +set(SOURCES +./LaserScannerPluginGuiPlugin.cpp ./LaserScannerPluginWidgetController.cpp +#@TEMPLATE_LINE@@COMPONENT_PATH@/@COMPONENT_NAME@GuiPlugin.cpp @COMPONENT_PATH@/@COMPONENT_NAME@WidgetController.cpp +) + +set(HEADERS +./LaserScannerPluginGuiPlugin.h ./LaserScannerPluginWidgetController.h +#@TEMPLATE_LINE@@COMPONENT_PATH@/@COMPONENT_NAME@GuiPlugin.h @COMPONENT_PATH@/@COMPONENT_NAME@WidgetController.h +) + +set(GUI_MOC_HDRS ${HEADERS}) + +set(GUI_UIS +./LaserScannerPluginWidget.ui +#@TEMPLATE_LINE@@COMPONENT_PATH@/@COMPONENT_NAME@Widget.ui +) + +# Add more libraries you depend on here, e.g. ${QT_LIBRARIES}. +set(COMPONENT_LIBS HokuyoLaserUnit SimpleConfigDialog ${QT_LIBRARIES}) + +if(ArmarXGui_FOUND) + armarx_gui_library(LaserScannerPluginGuiPlugin "${SOURCES}" "${GUI_MOC_HDRS}" "${GUI_UIS}" "" "${COMPONENT_LIBS}") +endif() diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.cpp b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.cpp new file mode 100644 index 000000000..c391a0ff6 --- /dev/null +++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.cpp @@ -0,0 +1,34 @@ +/* + * 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::LaserScannerPluginGuiPlugin + * \author Fabian Paus ( fabian dot paus at kit dot edu ) + * \date 2017 + * \copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "LaserScannerPluginGuiPlugin.h" + +#include "LaserScannerPluginWidgetController.h" + +using namespace armarx; + +LaserScannerPluginGuiPlugin::LaserScannerPluginGuiPlugin() +{ + addWidget < LaserScannerPluginWidgetController > (); +} + +Q_EXPORT_PLUGIN2(armarx_gui_LaserScannerPluginGuiPlugin, LaserScannerPluginGuiPlugin) diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.h b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.h new file mode 100644 index 000000000..1a5c4214e --- /dev/null +++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginGuiPlugin.h @@ -0,0 +1,51 @@ +/* + * 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::LaserScannerPlugin + * \author Fabian Paus ( fabian dot paus at kit dot edu ) + * \date 2017 + * \copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#ifndef _ARMARX_RobotAPI_LaserScannerPlugin_GuiPlugin_H +#define _ARMARX_RobotAPI_LaserScannerPlugin_GuiPlugin_H + +#include <ArmarXCore/core/system/ImportExportComponent.h> +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h> +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h> + +namespace armarx +{ + /** + * \class LaserScannerPluginGuiPlugin + * \ingroup ArmarXGuiPlugins + * \brief LaserScannerPluginGuiPlugin brief description + * + * Detailed description + */ + class ARMARXCOMPONENT_IMPORT_EXPORT LaserScannerPluginGuiPlugin: + public armarx::ArmarXGuiPlugin + { + public: + /** + * All widgets exposed by this plugin are added in the constructor + * via calls to addWidget() + */ + LaserScannerPluginGuiPlugin(); + }; +} + +#endif diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidget.ui b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidget.ui new file mode 100644 index 000000000..097f7d74a --- /dev/null +++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidget.ui @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LaserScannerPluginWidget</class> + <widget class="QWidget" name="LaserScannerPluginWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>490</width> + <height>379</height> + </rect> + </property> + <property name="windowTitle"> + <string>LaserScannerPluginWidget</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinAndMaxSize</enum> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Device:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="deviceComboBox"/> + </item> + </layout> + </item> + <item> + <widget class="QGraphicsView" name="graphicsView"> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="resizeAnchor"> + <enum>QGraphicsView::AnchorViewCenter</enum> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.cpp b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.cpp new file mode 100644 index 000000000..233f94be9 --- /dev/null +++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.cpp @@ -0,0 +1,138 @@ +/* + * 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::LaserScannerPluginWidgetController + * \author Fabian Paus ( fabian dot paus at kit dot edu ) + * \date 2017 + * \copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "LaserScannerPluginWidgetController.h" + +#include <QGraphicsView> +#include <QGraphicsLineItem> + +#include <string> + +using namespace armarx; + +LaserScannerPluginWidgetController::LaserScannerPluginWidgetController() +{ + widget.setupUi(getWidget()); + + widget.graphicsView->setScene(&scene); +} + + +LaserScannerPluginWidgetController::~LaserScannerPluginWidgetController() +{ + +} + + +void LaserScannerPluginWidgetController::loadSettings(QSettings* settings) +{ + +} + +void LaserScannerPluginWidgetController::saveSettings(QSettings* settings) +{ + +} + + +void LaserScannerPluginWidgetController::onInitComponent() +{ + usingProxy(laserScannerUnitName); + + connect(this, SIGNAL(newSensorValuesReported()), this, SLOT(onNewSensorValuesReported()), Qt::QueuedConnection); +} + + +void LaserScannerPluginWidgetController::onConnectComponent() +{ + laserScannerUnit = getProxy<LaserScannerUnitInterfacePrx>(laserScannerUnitName); + std::string topicName = laserScannerUnit->getReportTopicName(); + usingTopic(topicName); +} + +QPointer<QDialog> LaserScannerPluginWidgetController::getConfigDialog(QWidget *parent) +{ + if (!dialog) + { + dialog = new SimpleConfigDialog(parent); + dialog->addProxyFinder<LaserScannerUnitInterfacePrx>({"LaserScannerUnit", "", "*LaserUnit"}); + } + return qobject_cast<SimpleConfigDialog*>(dialog); +} + +void LaserScannerPluginWidgetController::configured() +{ + if (dialog) + { + laserScannerUnitName = dialog->getProxyName("LaserScannerUnit"); + } +} + +void LaserScannerPluginWidgetController::reportSensorValues(const std::string &device, const std::string &name, const LaserScan &newScan, const TimestampBasePtr ×tamp, const Ice::Current &c) +{ + { + boost::mutex::scoped_lock lock(scanMutex); + + LaserScan& scan = scans[device]; + // TODO: Do some filtering? aggregation? + scan = newScan; + } + + emit newSensorValuesReported(); +} + +void LaserScannerPluginWidgetController::onNewSensorValuesReported() +{ + // TODO: Draw something on the canvas + + QComboBox* deviceBox = widget.deviceComboBox; + + boost::mutex::scoped_lock lock(scanMutex); + for (auto& pair : scans) + { + QString deviceName(QString::fromStdString(pair.first.c_str())); + if (deviceBox->findText(deviceName) < 0) + { + deviceBox->addItem(deviceName); + } + } + + std::string deviceName(deviceBox->currentText().toUtf8().data()); + + QGraphicsView* view = widget.graphicsView; + int outerR =std::min(view->width() / 2, view->height() / 2); + int r = outerR - 10; + + + scene.clear(); + scene.addEllipse(-outerR, -outerR, 2*outerR,2*outerR, QPen(QColor(255,255,255))); + scene.addEllipse(-r, -r, 2*r,2*r, QPen(QColor(200,200,200))); + auto line = [&](float angle, float d){ scene.addLine(0, 0, std::cos(angle) * d * r, std::sin(angle) * d * r); }; + + LaserScan& scan = scans[deviceName]; + for (LaserScanStep& step : scan) + { + line(step.angle, step.distance / 30000.0f); + } + + view->fitInView(scene.itemsBoundingRect(), Qt::KeepAspectRatio); +} diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h new file mode 100644 index 000000000..0ee3571d0 --- /dev/null +++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h @@ -0,0 +1,131 @@ +/* + * 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::LaserScannerPluginWidgetController + * @author Fabian Paus ( fabian dot paus at kit dot edu ) + * @date 2017 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#ifndef _ARMARX_RobotAPI_LaserScannerPlugin_WidgetController_H +#define _ARMARX_RobotAPI_LaserScannerPlugin_WidgetController_H + +#include "ui_LaserScannerPluginWidget.h" + +#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/interface/units/LaserScannerUnit.h> + +namespace armarx +{ + /** + \page ArmarXGui-GuiPlugins-LaserScannerPlugin LaserScannerPlugin + \brief The LaserScannerPlugin allows visualizing ... + + \image html LaserScannerPlugin.png + The user can + + API Documentation \ref LaserScannerPluginWidgetController + + \see LaserScannerPluginGuiPlugin + */ + + /** + * \class LaserScannerPluginWidgetController + * \brief LaserScannerPluginWidgetController brief one line description + * + * Detailed description + */ + class ARMARXCOMPONENT_IMPORT_EXPORT + LaserScannerPluginWidgetController: + public armarx::ArmarXComponentWidgetController, + public armarx::LaserScannerUnitListener + { + Q_OBJECT + + public: + /** + * Controller Constructor + */ + explicit LaserScannerPluginWidgetController(); + + /** + * Controller destructor + */ + virtual ~LaserScannerPluginWidgetController(); + + /** + * @see ArmarXWidgetController::loadSettings() + */ + virtual void loadSettings(QSettings* settings); + + /** + * @see ArmarXWidgetController::saveSettings() + */ + virtual void saveSettings(QSettings* settings); + + /** + * Returns the Widget name displayed in the ArmarXGui to create an + * instance of this class. + */ + virtual QString getWidgetName() const + { + return "LaserScannerPlugin"; + } + + /** + * \see armarx::Component::onInitComponent() + */ + virtual void onInitComponent(); + + /** + * \see armarx::Component::onConnectComponent() + */ + virtual void onConnectComponent(); + + QPointer<QDialog> getConfigDialog(QWidget *parent) override; + + void configured() override; + + void reportSensorValues(const std::string & device, const std::string & name, + const LaserScan & scan, const TimestampBasePtr & timestamp, + const Ice::Current & c) override; + public slots: + void onNewSensorValuesReported(); + + signals: + void newSensorValuesReported(); + + private: + /** + * Widget Form + */ + Ui::LaserScannerPluginWidget widget; + QPointer<SimpleConfigDialog> dialog; + + std::string laserScannerUnitName; + LaserScannerUnitInterfacePrx laserScannerUnit; + + Mutex scanMutex; + std::unordered_map<std::string, LaserScan> scans; + + QGraphicsScene scene; + }; +} + +#endif diff --git a/source/RobotAPI/interface/units/LaserScannerUnit.ice b/source/RobotAPI/interface/units/LaserScannerUnit.ice index c8ea86f95..113d5331f 100644 --- a/source/RobotAPI/interface/units/LaserScannerUnit.ice +++ b/source/RobotAPI/interface/units/LaserScannerUnit.ice @@ -54,6 +54,8 @@ module armarx interface LaserScannerUnitInterface extends armarx::SensorActorUnitInterface { + ["cpp:const"] + idempotent string getReportTopicName() throws NotInitializedException; }; interface LaserScannerUnitListener -- GitLab