From fabc3dbac023d76835abc9f1ee071d8b03f86183 Mon Sep 17 00:00:00 2001 From: Mirko Waechter <mirko.waechter@kit.edu> Date: Thu, 5 Jan 2017 20:20:47 +0100 Subject: [PATCH] moved plotter to gui package --- .../ArmarXPlotter/ArmarXPlotter.cpp | 964 ------------------ .../ArmarXPlotter/ArmarXPlotter.h | 220 ---- .../ArmarXPlotter/ArmarXPlotter.ui | 164 --- .../ArmarXPlotter/ArmarXPlotterDialog.cpp | 207 ---- .../ArmarXPlotter/ArmarXPlotterDialog.h | 100 -- .../ArmarXPlotter/ArmarXPlotterDialog.ui | 302 ------ .../SensorActorWidgetsPlugin/CMakeLists.txt | 13 +- .../SensorActorWidgetsPlugin.cpp | 3 - 8 files changed, 3 insertions(+), 1970 deletions(-) delete mode 100644 source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp delete mode 100644 source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.h delete mode 100644 source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.ui delete mode 100644 source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.cpp delete mode 100644 source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.h delete mode 100644 source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.ui diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp deleted file mode 100644 index 0eb423190..000000000 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp +++ /dev/null @@ -1,964 +0,0 @@ -/* -* 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 ArmarX::Gui -* @author Mirko Waechter ( mirko.waechter at kit dot edu) -* @date 2012 -* @copyright http://www.gnu.org/licenses/gpl-2.0.txt -* GNU General Public License -*/ - -#include "ArmarXPlotter.h" -#include "ArmarXPlotterDialog.h" - -#include <ArmarXCore/core/time/TimeUtil.h> -#include <ArmarXCore/observers/ObserverObjectFactories.h> -#include <ArmarXCore/observers/variant/DataFieldIdentifier.h> -#include <ArmarXCore/observers/exceptions/local/InvalidChannelException.h> - -//ignore errors about extra ; from qwt -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#include <qwt_plot.h> -#include <qwt_plot_marker.h> -#include <qwt_plot_curve.h> -#include <qwt_plot_panner.h> -#include <qwt_plot_magnifier.h> -#include <qwt_plot_canvas.h> -#include <qwt_legend.h> -#include <qwt_legend_item.h> -#include <qwt_series_data.h> -#include <qwt_thermo.h> -#include <qwt_scale_draw.h> -#pragma GCC diagnostic pop - -//QT -#include <QTimer> -#include <QTime> -#include <QSettings> -#include <QDir> -#include <QStackedLayout> -#include <QTextEdit> - -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/filesystem/path.hpp> - -#include <IceUtil/IceUtil.h> - -#include <sstream> - - -using namespace std; - -namespace armarx -{ - - ArmarXPlotter::ArmarXPlotter() : - ArmarXComponentWidgetController(), - updateInterval(100), - shownInterval(60), - startUpTime(QDateTime::currentDateTime()) - - - { - setTag("Plotter"); - ui.setupUi(getWidget()); - timer = new QTimer(getWidget()); - //bars = new std::vector<QwtThermo*>(); - barlayout = new QHBoxLayout; - //////////////// - // Setup Plotter - /////////////// - // panning with the left mouse button - (void) new QwtPlotPanner(ui.qwtPlot->canvas()); - - // zoom in/out with the wheel - QwtPlotMagnifier* magnifier = new QwtPlotMagnifier(ui.qwtPlot->canvas()); - magnifier->setAxisEnabled(QwtPlot::xBottom, false); - - ui.qwtPlot->canvas()->setPaintAttribute(QwtPlotCanvas::BackingStore, false); //increases performance for incremental drawing - - QwtLegend* legend = new QwtLegend; - legend->setItemMode(QwtLegend::CheckableItem); - ui.qwtPlot->insertLegend(legend, QwtPlot::BottomLegend); - - - ui.qwtPlot->setAxisTitle(QwtPlot::xBottom, "Time (in sec)"); - ui.qwtPlot->enableAxis(QwtPlot::yLeft, false); - - ui.qwtPlot->enableAxis(QwtPlot::yRight, true); - ui.qwtPlot->setAxisAutoScale(QwtPlot::yRight, true); - // ui.qwtPlot->setAutoReplot(); - - dialog = new ArmarXPlotterDialog(getWidget(), NULL); - loggingDir = (QDir::currentPath()); - dialog->ui.editLoggingDirectory->setText(loggingDir); - - graphStyle = ui.CBgraphStyle->currentIndex(); - stackedLayout = new QStackedLayout(ui.verticalLayout); - stackedLayout->addWidget(ui.qwtPlot); - - QWidget* barsWidget = new QWidget(getWidget()); - barsWidget->setLayout(barlayout); - barsWidget->setAccessibleName("barsWidget"); - stackedLayout->addWidget(barsWidget); - - getWidget()->setLayout(stackedLayout); - - } - - ArmarXPlotter::~ArmarXPlotter() - { - // if(dialog && this->getState() == eManagedIceObjectInitialized) - // getArmarXManager()->removeObjectNonBlocking(dialog); - // delete dialog; - - } - - - - - - - - void ArmarXPlotter::onInitComponent() - { - json = new JSONObject(getIceManager()->getCommunicator()); - - } - - void ArmarXPlotter::onConnectComponent() - { - ARMARX_VERBOSE << "ArmarXPlotter started" << flush; - dialog->setIceManager(getIceManager()); - - connect(dialog, SIGNAL(accepted()), this, SLOT(configDone())); - connect(ui.BTNEdit, SIGNAL(clicked()), this, SLOT(configDialog())); - connect(timer, SIGNAL(timeout()), this, SLOT(updateGraph())); - connect(ui.BTNPlotterStatus, SIGNAL(toggled(bool)), this, SLOT(plottingPaused(bool))); - - connect(ui.BTNAutoScale, SIGNAL(toggled(bool)), this, SLOT(autoScale(bool))); - connect(ui.qwtPlot, SIGNAL(legendChecked(QwtPlotItem*, bool)), - SLOT(showCurve(QwtPlotItem*, bool))); - - connect(ui.btnLogToFile, SIGNAL(toggled(bool)), this, SLOT(toggleLogging(bool))); - - connect(ui.CBgraphStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(onGraphStyleChanged(int))); - - if (!QMetaObject::invokeMethod(this, "setupCurves")) - { - ARMARX_WARNING << "Failed to invoke enable"; - } - - - usingTopic("TopicReplayerListener"); - - } - - - void ArmarXPlotter::onExitComponent() - { - unsubscribeFromTopic("TopicReplayerListener"); - - if (pollingTask) - { - pollingTask->stop(); - } - - } - - void ArmarXPlotter::onCloseWidget(QCloseEvent* event) - { - ARMARX_VERBOSE << "closing" << flush; - timer->stop(); - - if (logstream.is_open()) - { - logstream.close(); - } - } - - void ArmarXPlotter::ButtonAddSensorChannelClicked() - { - } - - void ArmarXPlotter::configDialog() - { - if (!dialog) - { - return; - } - - dialog->ui.spinBoxUpdateInterval->setValue(updateInterval); - dialog->ui.spinBoxShownInterval->setValue(shownInterval); - dialog->ui.syncDataLogging->setChecked(syncDataLogging); - dialog->ui.listWidget->clear(); - dialog->ui.listWidget->addItems(selectedChannels); - // if(dialog->exec()) - // configDone(); - dialog->setModal(true); - dialog->show(); - // dialog->raise(); - // dialog->activateWindow(); - // dialog->setParent(0); - } - - void ArmarXPlotter::configDone() - { - { - ScopedLock lock(dataMutex); - updateInterval = dialog->ui.spinBoxUpdateInterval->value(); - shownInterval = dialog->ui.spinBoxShownInterval->value(); - pollingInterval = dialog->ui.spinBoxPollingInterval->value(); - selectedChannels = dialog->getSelectedChannels(); - loggingDir = dialog->ui.editLoggingDirectory->text(); - syncDataLogging = dialog->ui.syncDataLogging->isChecked(); - ui.btnLogToFile->setChecked(false); - ui.BTNPlotterStatus->setChecked(false); - markers.clear(); - curves.clear(); - dataMap.clear(); - ui.qwtPlot->detachItems(); - clearBarList(); - } - - setupCurves(); - } - - void ArmarXPlotter::toggleLogging(bool toggled) - { - std::lock_guard<std::mutex> lock(mutex); - - if (toggled) - { - boost::filesystem::path outputPath; - if (filename.empty()) - { - outputPath = loggingDir.toStdString() + "/datalog.csv"; - - std::string time = IceUtil::Time::now().toDateTime(); - boost::replace_all(time, "/", "-"); - boost::replace_all(time, " ", "_"); - boost::replace_all(time, ":", "-"); - outputPath = outputPath.parent_path() / (outputPath.stem().string() + "-" + time + outputPath.extension().string()); - - } - else - { - boost::filesystem::path path = filename; - outputPath = loggingDir.toStdString() + "/" + path.stem().string() + ".csv"; - } - - ARMARX_INFO << "Logging to " << outputPath.string(); - logstream.open(outputPath.string()); - logStartTime = IceUtil::Time::now(); - - if (!logstream.is_open()) - { - ARMARX_ERROR << "Could not open file for logging: " << outputPath.string(); - ui.btnLogToFile->setChecked(false); - } - else - { - logstream << "Timestamp"; - - for (auto& channel : selectedChannels) - { - logstream << "," << channel.toStdString(); - } - - logstream << std::endl; - } - } - else - { - filename = ""; - logstream.flush(); - ARMARX_INFO << "done writing log"; - logstream.close(); - } - } - - void ArmarXPlotter::onGraphStyleChanged(int idx) - { - if (graphStyle != idx) - { - graphStyle = idx; - stackedLayout->setCurrentIndex(graphStyle); - - switch (idx) - { - case 0: //curves can have various scalings - - ui.BTNAutoScale->setDisabled(false); - break; - - case 1: //bar chart only autoscale possible - - ui.BTNAutoScale->setDisabled(true); - break; - - default: - break; - } - } - } - - void ArmarXPlotter::pollingExec() - { - std::map<string, VariantPtr> newData = getData(selectedChannels); - - - if (ui.btnLogToFile->isChecked()) - { - logToFile(IceUtil::Time::now(), newData); - } - } - - - - void ArmarXPlotter::updateGraph() - { - ScopedLock lock(dataMutex); - IceUtil::Time curTime = TimeUtil::GetTime(); - // erase old markers - for (auto& markerChannel : markers) - { - for (auto it = markerChannel.second.begin(); it != markerChannel.second.end();) - { - if ((curTime - it->first).toSecondsDouble() > shownInterval) - { - it = markerChannel.second.erase(it); - } - else - { - it++; - } - } - } - - QPointF p; - - // int size = shownInterval*1000/updateInterval; - GraphDataMap::iterator it = dataMap.begin(); - - - for (; it != dataMap.end(); ++it) - { - - QVector<QPointF> pointList; - pointList.clear(); - auto datafieldId = it->first; - std::vector<TimeData>& dataVec = it->second; - // int newSize = min(size,(int)dataVec.size()); - pointList.resize(dataVec.size()); - auto addMarker = [this](IceUtil::Time & age, VariantPtr & var, std::string & datafieldId) - { - std::map < std::string, boost::shared_ptr<QwtPlotMarker>>& markerSubMap = markers[datafieldId][age]; - - std::string value = var->getString(); - auto it2 = markerSubMap.find(value); - if (it2 != markerSubMap.end()) - { - boost::shared_ptr<QwtPlotMarker> marker = it2->second; - marker->setXValue(0.001 * age.toMilliSecondsDouble()); - } - else - { - boost::shared_ptr<QwtPlotMarker> marker(new QwtPlotMarker()); - marker->setValue(0.001 * age.toMilliSecondsDouble(), 0); - marker->setLabel(QwtText(QString::fromStdString(value))); - marker->setLineStyle(QwtPlotMarker::VLine); - marker->setLabelAlignment(Qt::AlignBottom | Qt::AlignLeft); - int i = 0; - for (auto& markerSubMap : markers) - { - if (markerSubMap.first == datafieldId) - { - break; - } - i++; - } - marker->setLinePen(QColor(Qt::GlobalColor((i) % 5 + 13))); - marker->attach(ui.qwtPlot); - markerSubMap[value] = marker; - } - - }; - - try - { - int j = 0; - - for (int i = dataVec.size() - 1; i >= 0 ; --i) - { - TimeData& data = dataVec[i]; - IceUtil::Time age = (data.time - curTime); - - if (age.toMilliSecondsDouble() <= shownInterval * 1000) - { - VariantPtr var = VariantPtr::dynamicCast(data.data); - - if (var->getInitialized()) - { - float xValue = 0.001 * age.toMilliSecondsDouble(); - auto type = var->getType(); - double yValue = 0; - if (type == VariantType::Float && var->getFloat() != std::numeric_limits<float>::infinity()) - { - yValue = (var->getFloat()); - } - else if (type == VariantType::Double && var->getDouble() != std::numeric_limits<double>::infinity()) - { - yValue = (var->getDouble()); - } - else if (type == VariantType::Int && var->getInt() != std::numeric_limits<int>::infinity()) - { - yValue = (var->getInt()); - } - else if (type == VariantType::Bool) - { - yValue = (var->getBool() ? 1 : -1); - } - else if (type == VariantType::String) - { - addMarker(age, var, datafieldId); - } - else - { - continue; - } - - if ((signed int)j < pointList.size()) - { - pointList[j].setY(yValue); - pointList[j].setX(xValue); - } - else - { - - p.setY(yValue); - p.setX(xValue); - pointList.push_back(p); - } - - j++; - } - else - { - ARMARX_WARNING << deactivateSpam(3) << "uninitialized field: " << it->first; - } - - } - else - { - break; // data too old from now - } - } - } - catch (...) - { - handleExceptions(); - } - - QwtSeriesData<QPointF>* pointSeries = new QwtPointSeriesData(pointList); - - if (pointList.size() > 0 && curves.find(it->first) != curves.end() && bars.find(it->first) != bars.end()) - { - QwtPlotCurve* curve = curves[it->first]; - curve->setData(pointSeries); - curve->setYAxis(QwtPlot::yRight); - QwtThermo* bar = bars[it->first]; - bar->setValue(pointList.first().y()); - - bar->setRange(curve->minYValue(), (curve->maxYValue())); //this autoscales the graph - } - - - } - - - ui.qwtPlot->setAxisScale(QwtPlot::xBottom, shownInterval * -1, 0.f); - - if (ui.BTNAutoScale->isChecked()) - { - ui.qwtPlot->setAxisAutoScale(QwtPlot::yRight, true); - } - - // ui.qwtPlot->setAxisScale( QwtPlot::yLeft, -1, 1); - - ui.qwtPlot->replot(); - } - - void ArmarXPlotter::showCurve(QwtPlotItem* item, bool on) - { - item->setVisible(on); - - QwtLegendItem* legendItem = - qobject_cast<QwtLegendItem*>(ui.qwtPlot->legend()->find(item)); - - if (legendItem) - { - legendItem->setChecked(on); - } - - ui.qwtPlot->replot(); - } - - void ArmarXPlotter::autoScale(bool toggled) - { - ARMARX_VERBOSE << "clicked autoscale" << flush; - - ui.qwtPlot->setAxisAutoScale(QwtPlot::yRight, toggled); - ui.qwtPlot->replot(); - - } - - void ArmarXPlotter::plottingPaused(bool toggled) - { - __plottingPaused = toggled; - - if (pollingTask) - { - pollingTask->stop(); - } - - if (__plottingPaused) - { - timer->stop(); - } - else - { - pollingTask = new PeriodicTask<ArmarXPlotter>(this, & ArmarXPlotter::pollingExec, pollingInterval, false, "DataPollingTask", false); - pollingTask->start(); - timer->start(); - } - } - - - - void ArmarXPlotter::saveSettings(QSettings* settings) - { - ScopedLock lock(dataMutex); - settings->setValue("updateInterval", updateInterval); - settings->setValue("shownInterval", shownInterval); - settings->setValue("pollingInterval", pollingInterval); - settings->setValue("selectedChannels", selectedChannels); - settings->setValue("autoScaleActive", ui.BTNAutoScale->isChecked()); - settings->setValue("syncDataLogging", syncDataLogging); - - } - - void ArmarXPlotter::loadSettings(QSettings* settings) - { - ScopedLock lock(dataMutex); - updateInterval = settings->value("updateInterval", 100).toInt(); - shownInterval = settings->value("shownInterval", 60).toInt(); - pollingInterval = settings->value("pollingInterval", 33).toInt(); - selectedChannels = settings->value("selectedChannels", QStringList()).toStringList(); - ui.BTNAutoScale->setChecked(settings->value("autoScaleActive", true).toBool()); - syncDataLogging = settings->value("syncDataLogging", false).toBool(); - - ARMARX_VERBOSE << "Settings loaded" << flush; - } - - QwtPlotCurve* ArmarXPlotter::createCurve(const QString& label) - { - QwtPlotCurve* curve = new QwtPlotCurve(label); - curve->setRenderHint(QwtPlotItem::RenderAntialiased); - curve->setPen(QColor(Qt::GlobalColor((curves.size()) % 15 + 7))); - curve->setStyle(QwtPlotCurve::Lines); - curve->setPaintAttribute(QwtPlotCurve::CacheSymbols, true); - curve->setPaintAttribute(QwtPlotCurve::ClipPolygons, true); - - curve->attach(ui.qwtPlot); - showCurve(curve, true); - - return curve; - } - - QwtThermo* ArmarXPlotter::createBar(const QString& label) - { - //creates a widget containing a bar chart and a label - //with the fill color of chart same as its curve - - QwtThermo* bar = new QwtThermo(getWidget()); - bar->setAccessibleName(label); - bar->setFillBrush(QBrush(QColor(Qt::GlobalColor((bars.size() + 7) % 15)))); - bar->setStyleSheet("* { background-color: rgb(240, 240, 240); }"); //neccessary because white is a picked fill color - - QTextEdit* lab = new QTextEdit(label, getWidget()); - lab->setStyleSheet("* { background-color: rgb(240, 240, 240); }"); - lab->setLineWrapMode(QTextEdit::WidgetWidth); - lab->setTextInteractionFlags(0); - lab->setFrameStyle(0); - int linecount = lab->document()->blockCount(); - lab->setMaximumHeight(70 * linecount); - lab->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - QVBoxLayout* layout = new QVBoxLayout(); - layout->addWidget(bar); - layout->addWidget(lab); - - QWidget* widget = new QWidget(layout->widget()); - widget->setLayout(layout); - barlayout->addWidget(widget); - - return bar; - } - - void ArmarXPlotter::setupCurves() - { - { - - ScopedLock lock(dataMutex); - auto now = TimeUtil::GetTime(); - std::map<std::string, ChannelHistory> histories; - markers.clear(); - for (int i = 0; i < selectedChannels.size(); i++) - { - try - { - ARMARX_VERBOSE << "Channel: " << selectedChannels.at(i).toStdString() << flush; - DataFieldIdentifierPtr identifier = new DataFieldIdentifier(selectedChannels.at(i).toStdString()); - auto prx = getProxy<ObserverInterfacePrx>(identifier->observerName); - - - // get past data of that datafield - auto id = identifier->getIdentifierStr(); - auto historiesIt = histories.find(identifier->channelName); - - if (historiesIt == histories.end()) - { - auto start = IceUtil::Time::now(); - histories[identifier->channelName] = prx->getPartialChannelHistory(identifier->channelName, - (now - IceUtil::Time::seconds(shownInterval)).toMicroSeconds(), now.toMicroSeconds()); - ARMARX_DEBUG << "history data polling took : " << (IceUtil::Time::now() - start).toMilliSecondsDouble() << " got " << histories[identifier->channelName].size() << " entries"; - historiesIt = histories.find(identifier->channelName); - } - - long lastTimestamp = 0; - - VariantPtr var = VariantPtr::dynamicCast(prx->getDataField(identifier)); - auto type = var->getType(); - if (type == VariantType::String) - { - // do nothing for now - } - else if (VariantType::IsBasicType(type)) - { - QwtPlotCurve* curve = createCurve(selectedChannels.at(i)); - curves[selectedChannels.at(i).toStdString()] = curve; - - QwtThermo* bar = createBar(selectedChannels.at(i)); - bars[selectedChannels.at(i).toStdString()] = bar; - - for (auto& entry : historiesIt->second) - { - if (lastTimestamp + pollingInterval < entry.first) - { - dataMap[id].push_back(TimeData(IceUtil::Time::microSeconds(entry.first), VariantPtr::dynamicCast(entry.second[identifier->datafieldName].value))); - lastTimestamp = entry.first; - } - } - } - else - { - auto id = identifier->getIdentifierStr(); - ARMARX_IMPORTANT << id; - auto dict = JSONObject::ConvertToBasicVariantMap(json, var); - - for (auto e : dict) - { - if (e.first == "timestamp") // TimedVariants always contain a timestamp field which is irrelevant - { - continue; - } - VariantTypeId type = e.second->getType(); - - if (type == VariantType::Double - || type == VariantType::Float - || type == VariantType::Int) - { - std::string key = id + "." + e.first; - ARMARX_INFO << key << ": " << *VariantPtr::dynamicCast(e.second); - QwtPlotCurve* curve = createCurve(QString::fromStdString(key)); - curves[key] = curve; - - QwtThermo* bar = createBar(QString::fromStdString(key)); - bars[key] = bar; - } - } - for (auto& entry : historiesIt->second) - { - if (lastTimestamp + pollingInterval < entry.first) - { - auto dict = JSONObject::ConvertToBasicVariantMap(json, entry.second[identifier->datafieldName].value); - for (const auto& e : dict) - { - if (e.first == "timestamp") // TimedVariants always contain a timestamp field which is irrelevant - { - continue; - } - std::string key = id + "." + e.first; - // ARMARX_INFO << key << ": " << *VariantPtr::dynamicCast(e.second); - VariantPtr var = VariantPtr::dynamicCast(e.second); - auto type = var->getType(); - if (type == VariantType::String) - { - // complex contain additional strings often, which cannot be selected right now -> disable strings from complex types - // if (dataMap[id].size() == 0 || dataMap[id].rbegin()->data->getString() != var->getString()) - // { - // // only insert if changed - // dataMap[id].push_back(TimeData(time, var)); - // newData[key] = var; - // } - } - else - { - dataMap[key].push_back(TimeData(IceUtil::Time::microSeconds(entry.first), var)); - } - } - } - } - - - } - - } - catch (...) - { - handleExceptions(); - } - } - - ui.qwtPlot->replot(); - - } - timer->start(updateInterval); - - if (pollingTask) - { - pollingTask->stop(); - } - - pollingTask = new PeriodicTask<ArmarXPlotter>(this, & ArmarXPlotter::pollingExec, pollingInterval, false, "DataPollingTask", false); - pollingTask->start(); - } - - void ArmarXPlotter::clearBarList() - { - //maybe comparing new and old selected list better than doing a new one every time? - QLayoutItem* child; - int containedItems = barlayout->count() - 1; - - for (int i = containedItems; i >= 0 ; i--) //must be done in this order due to internal implementation of layout item numbering - { - child = barlayout->itemAt(i); - barlayout->removeItem(child); - delete(child->widget()); - } - - bars.clear(); - } - - - std::map<string, VariantPtr> ArmarXPlotter::getData(const QStringList& channels) - { - map< std::string, DataFieldIdentifierBaseList > channelsSplittedByObserver; - foreach(QString channel, channels) - { - DataFieldIdentifierPtr identifier = new DataFieldIdentifier(channel.toStdString()); - channelsSplittedByObserver[identifier->getObserverName()].push_back(identifier); - // ARMARX_INFO << identifier; - } - std::map<std::string, VariantPtr> newData; - { - ScopedLock lock(dataMutex); - - // first clear to old entries - auto now = TimeUtil::GetTime(); - GraphDataMap::iterator itmap = dataMap.begin(); - - for (; itmap != dataMap.end(); ++itmap) - { - std::vector<TimeData>& dataVec = itmap->second; - int stepSize = std::max<int>(1, dataVec.size() * 0.01); - int thresholdIndex = -1; - - for (unsigned int i = 0; i < dataVec.size(); i += stepSize) - { - // only delete if entries are older than 2*showninterval - // and delete then all entries that are older than showninterval. - // otherwise it would delete items on every call, which would be very slow - - if ((now - dataVec[i].time).toSecondsDouble() > shownInterval * 2 - || (thresholdIndex != -1 && (now - dataVec[i].time).toSecondsDouble() > shownInterval) - ) - { - thresholdIndex = i; - } - else - { - break; - } - } - - if (thresholdIndex != -1) - { - unsigned int offset = std::min((int)dataVec.size(), thresholdIndex); - - // ARMARX_IMPORTANT << "Erasing " << offset << " fields"; - if (offset > dataVec.size()) - { - dataVec.clear(); - } - else - { - dataVec.erase(dataVec.begin(), dataVec.begin() + offset); - } - } - - // ARMARX_IMPORTANT << deactivateSpam(5) << "size: " << dataVec.size(); - } - - } - - // now get new data - IceUtil::Time time = TimeUtil::GetTime(); - map<string, DataFieldIdentifierBaseList >::iterator it = channelsSplittedByObserver.begin(); - - try - { - for (; it != channelsSplittedByObserver.end(); ++it) - { - std::string observerName = it->first; - - if (proxyMap.find(observerName) == proxyMap.end()) - { - proxyMap[observerName] = getProxy<ObserverInterfacePrx>(observerName); - } - - // QDateTime time(QDateTime::currentDateTime()); - TimedVariantBaseList variants = proxyMap[observerName]->getDataFields(it->second); - - ScopedLock lock(dataMutex); - // # ARMARX_IMPORTANT << "data from observer: " << observerName; - for (unsigned int i = 0; i < variants.size(); ++i) - { - // ARMARX_IMPORTANT << "Variant: " << VariantPtr::dynamicCast(variants[i]); - VariantPtr var = VariantPtr::dynamicCast(variants[i]); - if (!var->getInitialized()) - { - continue; - } - auto id = DataFieldIdentifierPtr::dynamicCast(it->second[i])->getIdentifierStr(); - auto type = var->getType(); - if (type == VariantType::String) - { - if (dataMap[id].size() == 0 || dataMap[id].rbegin()->data->getString() != var->getString()) - { - // only insert if changed - dataMap[id].push_back(TimeData(time, var)); - newData[id] = var; - } - } - else if (VariantType::IsBasicType(type)) - { - dataMap[id].push_back(TimeData(time, var)); - newData[id] = var; - } - else - { - auto dict = JSONObject::ConvertToBasicVariantMap(json, var); - - for (const auto& e : dict) - { - if (e.first == "timestamp") // TimedVariants always contain a timestamp field which is irrelevant - { - continue; - } - std::string key = id + "." + e.first; - // ARMARX_INFO << key << ": " << *VariantPtr::dynamicCast(e.second); - VariantPtr var = VariantPtr::dynamicCast(e.second); - auto type = var->getType(); - if (type == VariantType::String) - { - // complex contain additional strings often, which cannot be selected right now -> disable strings from complex types - // if (dataMap[id].size() == 0 || dataMap[id].rbegin()->data->getString() != var->getString()) - // { - // // only insert if changed - // dataMap[id].push_back(TimeData(time, var)); - // newData[key] = var; - // } - } - else - { - dataMap[key].push_back(TimeData(time, var)); - newData[key] = var; - } - } - } - - } - - } - } - catch (Ice::NotRegisteredException& e) - { - ARMARX_WARNING << deactivateSpam(3) << "Caught Ice::NotRegisteredException: " << e.what(); - } - catch (exceptions::local::InvalidDataFieldException& e) - { - ARMARX_WARNING << deactivateSpam(5) << "Caught InvalidDataFieldException: " << e.what(); - } - catch (exceptions::local::InvalidChannelException& e) - { - ARMARX_WARNING << deactivateSpam(5) << "Caught InvalidChannelException: " << e.what(); - } - catch (armarx::UserException& e) - { - ARMARX_WARNING << deactivateSpam(5) << "Caught UserException: " << e.what() << "\nReason: " << e.reason; - } - catch (...) - { - ARMARX_WARNING << deactivateSpam(5) << GetHandledExceptionString(); - } - - return newData; - } - - void ArmarXPlotter::logToFile(const IceUtil::Time& time, const std::map<std::string, VariantPtr>& dataMaptoAppend) - { - - if (logstream.is_open() && dataMaptoAppend.size() > 0) - { - logstream << (time - logStartTime).toMilliSecondsDouble() << ","; - - for (auto& channel : selectedChannels) - { - logstream << dataMaptoAppend.at(channel.toStdString())->Variant::getOutputValueOnly(); - if (!selectedChannels.endsWith(channel)) - { - logstream << ","; - } - } - - logstream << std::endl; - } - } - - - -} diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.h b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.h deleted file mode 100644 index 2313c9699..000000000 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.h +++ /dev/null @@ -1,220 +0,0 @@ -/* -* 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 ArmarX::Gui -* @author Mirko Waechter ( mirko.waechter at kit dot edu) -* @date 2012 -* @copyright http://www.gnu.org/licenses/gpl-2.0.txt -* GNU General Public License -*/ - -#ifndef ARMARXPLOTTER_H -#define ARMARXPLOTTER_H - -//ignore errors about extra ; from qwt -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#include "ui_ArmarXPlotter.h" -#pragma GCC diagnostic pop - -// ArmarX -#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h> -#include <ArmarXGui/gui-plugins/ObserverPropertiesPlugin/ObserverItemModel.h> - -#include <ArmarXCore/core/Component.h> -#include <ArmarXCore/core/system/ImportExportComponent.h> -#include <ArmarXCore/core/system/AbstractFactoryMethod.h> -#include <ArmarXCore/interface/observers/ConditionHandlerInterface.h> -#include <ArmarXCore/observers/variant/DataFieldIdentifier.h> -#include <ArmarXCore/observers/variant/Variant.h> -#include <ArmarXCore/util/json/JSONObject.h> -#include <ArmarXCore/core/services/tasks/PeriodicTask.h> -#include <ArmarXCore/interface/components/TopicRecorderInterface.h> -// QT -#include <QWidget> -#include <QDialog> -#include <QDateTime> - -#include <vector> -#include <fstream> -#include <mutex> - -//forward declarations -class QwtPlotCurve; -class QwtThermo; -class QStackedLayout; -class QwtPlotMarker; - -namespace armarx -{ - struct TimeData - { - TimeData(const IceUtil::Time& time, const VariantPtr& data): time(time), data(data) {} - - IceUtil::Time time; - VariantPtr data; - }; - - typedef std::map< std::string, ObserverInterfacePrx> ProxyMap; - typedef std::map< std::string, std::vector<TimeData> > GraphDataMap; - - class ArmarXPlotterDialog; - /*! - * \page RobotAPI-GuiPlugins-ArmarXPlotter ArmarXPlotter - * \brief The plotter widget allows the user to plot any sensor channel. - * \image html PlotterGUI.png - * A sensor channel can be selected for plotting by clicking the wrench button at the bottom. - * \ingroup RobotAPI-ArmarXGuiPlugins ArmarXGuiPlugins - */ - class ARMARXCOMPONENT_IMPORT_EXPORT - ArmarXPlotter: - public ArmarXComponentWidgetController, - public TopicReplayerListenerInterface - - { - Q_OBJECT - public: - - - void onStartReplay(const std::string& filename, const Ice::Current& c = Ice::Current()) - { - if (!syncDataLogging) - { - return; - } - - if (!ui.btnLogToFile->isChecked()) - { - this->filename = filename; - ui.btnLogToFile->setChecked(true); - } - else - { - ARMARX_WARNING << "already logging to file"; - } - } - - void onStopReply(const Ice::Current& c = Ice::Current()) - { - if (!syncDataLogging) - { - return; - } - - if (ui.btnLogToFile->isChecked()) - { - ui.btnLogToFile->setChecked(false); - } - else - { - ARMARX_WARNING << "not logging to file."; - } - } - - - std::map<std::string, QwtPlotCurve*> curves; - Ui::ArmarXPlotter ui; - QPointer<ArmarXPlotterDialog> dialog; - QTimer* timer; - ConditionHandlerInterfacePrx handler; - - // Configuration Parameters - int updateInterval; - int shownInterval; - QStringList selectedChannels; - QString loggingDir; - - explicit ArmarXPlotter(); - ~ArmarXPlotter(); - //inherited from ArmarXWidget - virtual QString getWidgetName() const - { - return "Observers.Plotter"; - } - virtual QIcon getWidgetIcon() const - { - return QIcon("://icons/combo_chart.svg"); - } - void loadSettings(QSettings* settings); - void saveSettings(QSettings* settings); - //for AbstractFactoryMethod class - - - // inherited from Component - virtual void onInitComponent(); - virtual void onConnectComponent(); - virtual void onExitComponent(); - - - - /** - * emits the closeRequest signal - */ - void onCloseWidget(QCloseEvent* event); - QwtPlotCurve* createCurve(const QString& label); - QwtThermo* createBar(const QString& label); - signals: - - public slots: - void ButtonAddSensorChannelClicked(); - void configDialog(); - void updateGraph(); - void showCurve(QwtPlotItem* item, bool on); - void autoScale(bool toggled); - void plottingPaused(bool toggled); - void configDone(); - void toggleLogging(bool toggled); - void onGraphStyleChanged(int idx); - - private slots: - void setupCurves(); - protected: - boost::shared_ptr<QSettings> settings; - private: - - void pollingExec(); - QDateTime startUpTime; - GraphDataMap dataMap; - std::map< std::string, ObserverInterfacePrx> proxyMap; - bool __plottingPaused; - JSONObjectPtr json; - - - std::map<std::string, VariantPtr> getData(const QStringList& channels); - void logToFile(const IceUtil::Time& time, const std::map<std::string, VariantPtr>& dataMaptoAppend); - - Mutex dataMutex; - bool syncDataLogging; - PeriodicTask<ArmarXPlotter>::pointer_type pollingTask; - int pollingInterval = 33; - std::ofstream logstream; - IceUtil::Time logStartTime; - std::string filename = ""; - - int graphStyle; - std::map<std::string, std::map<IceUtil::Time, std::map<std::string, boost::shared_ptr<QwtPlotMarker>>>> markers; - QStackedLayout* stackedLayout; - QHBoxLayout* barlayout; - std::map<std::string, QwtThermo*> bars; - void clearBarList(); - - std::mutex mutex; - - - }; - -} - -#endif diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.ui b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.ui deleted file mode 100644 index 6d70dfa3d..000000000 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.ui +++ /dev/null @@ -1,164 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ArmarXPlotter</class> - <widget class="QWidget" name="ArmarXPlotter"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>400</height> - </rect> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>150</width> - <height>150</height> - </size> - </property> - <property name="windowTitle"> - <string>ArmarX Plotter</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="spacing"> - <number>3</number> - </property> - <property name="leftMargin"> - <number>3</number> - </property> - <property name="topMargin"> - <number>3</number> - </property> - <property name="rightMargin"> - <number>3</number> - </property> - <property name="bottomMargin"> - <number>3</number> - </property> - <item> - <widget class="QwtPlot" name="qwtPlot"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="spacing"> - <number>0</number> - </property> - <item> - <widget class="QToolButton" name="BTNEdit"> - <property name="toolTip"> - <string>Edit the plotter settings</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:/icons/configure-3.png</normaloff>:/icons/configure-3.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="BTNPlotterStatus"> - <property name="toolTip"> - <string>Pause the update of the plotter (saves bandwidth and cpu costs)</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:/icons/media-playback-pause.ico</normaloff>:/icons/media-playback-pause.ico</iconset> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="BTNAutoScale"> - <property name="toolTip"> - <string>Automatic scaling of the graph</string> - </property> - <property name="text"> - <string>Auto Scale</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:/icons/zoom-original-2.png</normaloff>:/icons/zoom-original-2.png</iconset> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="btnLogToFile"> - <property name="toolTip"> - <string>Toggle logging to filepath selected in the settings</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset> - <normaloff>://icons/papyrus.svg</normaloff>://icons/papyrus.svg</iconset> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="CBgraphStyle"> - <item> - <property name="text"> - <string>Curve</string> - </property> - </item> - <item> - <property name="text"> - <string>Bar chart</string> - </property> - </item> - </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> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>QwtPlot</class> - <extends>QFrame</extends> - <header>qwt_plot.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.cpp b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.cpp deleted file mode 100644 index 30a7d5844..000000000 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -* 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 ArmarX::Gui -* @author Mirko Waechter ( mirko.waechter at kit dot edu) -* @date 2012 -* @copyright http://www.gnu.org/licenses/gpl-2.0.txt -* GNU General Public License -*/ - -#include "ArmarXPlotterDialog.h" -#include "ArmarXPlotter.h" - -#include <IceUtil/UUID.h> - -#include <QFileDialog> -#include <sstream> - - -using namespace armarx; -using namespace std; - - -ArmarXPlotterDialog::ArmarXPlotterDialog(QWidget* parent, IceManagerPtr iceManager) : - QDialog(parent), - uuid(IceUtil::generateUUID()), - iceManager(iceManager) -{ - ui.setupUi(this); - model = NULL; - - - connect(ui.BTNAddSelectedChannels, SIGNAL(clicked()), this, SLOT(ButtonAddSelectedChannelClicked())); - connect(ui.BTNRemoveSelected, SIGNAL(clicked()), this, SLOT(ButtonRemoveChannelClicked())); - connect(ui.treeViewObservers, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(treeView_doubleClick(QModelIndex))); - connect(ui.listWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(ButtonRemoveChannelClicked(QModelIndex))); - connect(ui.btnRefresh, SIGNAL(clicked()), this, SLOT(updateObservers())); - - -} - -ArmarXPlotterDialog::~ArmarXPlotterDialog() -{ - // ARMARX_INFO << "~ArmarXPlotterDialog" ; -} - -void ArmarXPlotterDialog::setIceManager(IceManagerPtr iceManager) -{ - this->iceManager = iceManager; -} - - - -//string ArmarXPlotterDialog::getDefaultName() const -//{ -// stringstream str; -// str << "ArmarXPlotterDialog" << uuid; -// return str.str(); -//} - - -//void ArmarXPlotterDialog::onInitComponent() -//{ -// usingProxy("ConditionHandler"); -//} - -//void ArmarXPlotterDialog::onConnectComponent() -//{ -// // get proxy of conditionhandler -// handler = getProxy<ConditionHandlerInterfacePrx>("ConditionHandler"); - -// updateObservers(); -//} - -//void ArmarXPlotterDialog::onExitComponent() -//{ - -//} - -void ArmarXPlotterDialog::onCloseWidget(QCloseEvent* event) -{ - -} - -void ArmarXPlotterDialog::updateObservers() -{ - if (!model) - { - model = new ObserverItemModel(iceManager); - ui.treeViewObservers->setModel(model); - - } - - model->updateObservers(); - - // if(!iceManager) - // return; - // ObserverList observerList = iceManager->getIceGridSession()->getRegisteredObjectNames<ObserverInterfacePrx>("*Observer"); - // ObserverList::iterator iter = observerList.begin(); - - // while(iter != observerList.end()) - // { - // model->updateModel(*iter, iceManager->getProxy<ObserverInterfacePrx>(*iter)->getAvailableChannels(), StringConditionCheckMap()); - // iter++; - // } -} - - - - - - -void ArmarXPlotterDialog::ButtonAddSelectedChannelClicked() -{ - QItemSelectionModel* selectionModel = ui.treeViewObservers->selectionModel(); - - for (int i = 0; i < selectionModel->selectedIndexes().size(); ++i) - { - QModelIndex index = selectionModel->selectedIndexes().at(i); - treeView_doubleClick(index); - } - - ui.treeViewObservers->clearSelection(); - -} - -void ArmarXPlotterDialog::ButtonRemoveChannelClicked() -{ - QList<QListWidgetItem*> selectedItems = ui.listWidget->selectedItems(); - - for (int i = 0; i < selectedItems.size(); ++i) - { - delete selectedItems.at(i); - } -} - -void ArmarXPlotterDialog::ButtonRemoveChannelClicked(QModelIndex index) -{ - delete ui.listWidget->item(index.row()); -} - -QStringList ArmarXPlotterDialog::getSelectedChannels() -{ - QStringList result; - QList <QListWidgetItem*> items = ui.listWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard); - foreach(QListWidgetItem * item, items) - result.append(item->text()); - - return result; -} - -void ArmarXPlotterDialog::treeView_selected(const QItemSelection& selected, const QItemSelection& deselected) -{ -} - -void ArmarXPlotterDialog::treeView_doubleClick(const QModelIndex& index) -{ - - QStandardItem* item = model->itemFromIndex(index); - QVariant id = item->data(OBSERVER_ITEM_ID); - - switch (item->data(OBSERVER_ITEM_TYPE).toInt()) - { - case eDataFieldItem: - if (ui.listWidget->findItems(id.toString(), Qt::MatchExactly).size() == 0) - { - ui.listWidget->addItem(id.toString()); - } - - break; - - } -} - -void ArmarXPlotterDialog::destroyed(QObject*) -{ - setParent(0); -} - -void ArmarXPlotterDialog::showEvent(QShowEvent*) -{ - updateObservers(); -} - - -void armarx::ArmarXPlotterDialog::on_btnSelectLoggingDir_clicked() -{ - QString newLoggingDir = QFileDialog::getExistingDirectory(this, "Select a directory to which data should be logged", - ui.editLoggingDirectory->text()); - - if (!newLoggingDir.isEmpty()) - { - ui.editLoggingDirectory->setText(newLoggingDir); - } -} diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.h b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.h deleted file mode 100644 index b912d58f8..000000000 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* 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 ArmarX::Gui -* @author Mirko Waechter ( mirko.waechter at kit dot edu) -* @date 2012 -* @copyright http://www.gnu.org/licenses/gpl-2.0.txt -* GNU General Public License -*/ - -#ifndef ARMARXPLOTTERDIALOG_H -#define ARMARXPLOTTERDIALOG_H - - -// QT -#include "ui_ArmarXPlotterDialog.h" - -#include <ArmarXGui/gui-plugins/ObserverPropertiesPlugin/ObserverItemModel.h> - -#include <ArmarXCore/core/IceManager.h> -#include <ArmarXCore/interface/observers/ConditionHandlerInterface.h> - -#include <QDialog> -#include <QComboBox> -#include <QList> -#include <QMenu> -#include <QAction> -#include <QItemSelectionModel> -#include <QStandardItemModel> - -#include <vector> - - -namespace armarx -{ - class ArmarXPlotter; - class ArmarXPlotterDialog: - public QDialog - { - Q_OBJECT - QStringList availableChannelsList; - ObserverItemModel* model; - std::string uuid; - IceManagerPtr iceManager; - int mdiId; - - - public: - ArmarXPlotterDialog(QWidget* parent, IceManagerPtr iceManager); - ~ArmarXPlotterDialog(); - ConditionHandlerInterfacePrx handler; - struct ChannelWidgetsEntry - { - QComboBox* comboBox; - QLabel* label; - QPushButton* deleteButton; - }; - - void setIceManager(IceManagerPtr iceManager); - - Ui::ArmarXPlotterDialog ui; - std::vector< ChannelWidgetsEntry > sensorChannelList; - QStringList getSelectedChannels(); - - - // // inherited from Component - // std::string getDefaultName() const; - // virtual void onInitComponent(); - // virtual void onConnectComponent(); - // void onExitComponent(); - /** - * emits the closeRequest signal - */ - void onCloseWidget(QCloseEvent* event); - public slots: - void ButtonAddSelectedChannelClicked(); - void ButtonRemoveChannelClicked(); - void ButtonRemoveChannelClicked(QModelIndex index); - void updateObservers(); - void treeView_selected(const QItemSelection& selected, const QItemSelection& deselected); - void treeView_doubleClick(const QModelIndex& index); - void destroyed(QObject*); - void showEvent(QShowEvent*); - private slots: - void on_btnSelectLoggingDir_clicked(); - }; -} -#endif diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.ui b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.ui deleted file mode 100644 index b2dc66d44..000000000 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotterDialog.ui +++ /dev/null @@ -1,302 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ArmarXPlotterDialog</class> - <widget class="QDialog" name="ArmarXPlotterDialog"> - <property name="windowModality"> - <enum>Qt::ApplicationModal</enum> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>586</width> - <height>599</height> - </rect> - </property> - <property name="windowTitle"> - <string>ArmarX Plotter Config Dialog</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <property name="modal"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="4" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Data polling interval (in ms)</string> - </property> - </widget> - </item> - <item row="4" column="2" colspan="2"> - <widget class="QSpinBox" name="spinBoxPollingInterval"> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>999999</number> - </property> - <property name="value"> - <number>33</number> - </property> - </widget> - </item> - <item row="0" column="1"> - <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> - <item row="1" column="2" colspan="2"> - <widget class="QSpinBox" name="spinBoxUpdateInterval"> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>999999999</number> - </property> - <property name="singleStep"> - <number>10</number> - </property> - <property name="value"> - <number>100</number> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="LblUpdateInterval"> - <property name="text"> - <string>Update interval (in ms)</string> - </property> - </widget> - </item> - <item row="6" column="1" colspan="2"> - <widget class="QLineEdit" name="editLoggingDirectory"/> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="LBLShownInterval"> - <property name="text"> - <string>Shown Interval (in s)</string> - </property> - </widget> - </item> - <item row="6" column="3"> - <widget class="QToolButton" name="btnSelectLoggingDir"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="0" column="2" colspan="2"> - <widget class="QSpinBox" name="spinBoxShownInterval"> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>6000</number> - </property> - <property name="value"> - <number>60</number> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Logging directory</string> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QCheckBox" name="syncDataLogging"> - <property name="text"> - <string>Synchronize data logging with TopicReplayer</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="groupBoxSensorChannels"> - <property name="minimumSize"> - <size> - <width>200</width> - <height>200</height> - </size> - </property> - <property name="title"> - <string>Sensor Channels</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QSplitter" name="splitter"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <widget class="FilterableTreeView" name="treeViewObservers"> - <property name="editTriggers"> - <set>QAbstractItemView::NoEditTriggers</set> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="animated"> - <bool>true</bool> - </property> - <property name="headerHidden"> - <bool>true</bool> - </property> - </widget> - <widget class="QListWidget" name="listWidget"> - <property name="editTriggers"> - <set>QAbstractItemView::NoEditTriggers</set> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - </widget> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QToolButton" name="BTNAddSelectedChannels"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Add selected datafields</string> - </property> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset> - <normaloff>:/icons/edit-add.ico</normaloff>:/icons/edit-add.ico</iconset> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="btnRefresh"> - <property name="toolTip"> - <string>Refresh observerlist</string> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:/icons/view-refresh-7.png</normaloff>:/icons/view-refresh-7.png</iconset> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QToolButton" name="BTNRemoveSelected"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Remove selected datafields</string> - </property> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset> - <normaloff>:/icons/dialog-cancel-5.svg</normaloff>:/icons/dialog-cancel-5.svg</iconset> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>FilterableTreeView</class> - <extends>QTreeView</extends> - <header location="global">ArmarXGui/libraries/ArmarXGuiBase/widgets/FilterableTreeView.h</header> - </customwidget> - </customwidgets> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>ArmarXPlotterDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>ArmarXPlotterDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/CMakeLists.txt b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/CMakeLists.txt index b299fbdfb..8fabc7cdd 100644 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/CMakeLists.txt +++ b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/CMakeLists.txt @@ -31,40 +31,33 @@ endif() set(SOURCES SensorActorWidgetsPlugin.cpp - ArmarXPlotter/ArmarXPlotter.cpp - ArmarXPlotter/ArmarXPlotterDialog.cpp - ArmarXTCPMover/TCPMover.cpp ArmarXTCPMover/TCPMoverConfigDialog.cpp ) set(HEADERS SensorActorWidgetsPlugin.h - ArmarXPlotter/ArmarXPlotter.h - ArmarXPlotter/ArmarXPlotterDialog.h ArmarXTCPMover/TCPMover.h ArmarXTCPMover/TCPMoverConfigDialog.h ) set(GUI_MOC_HDRS - ArmarXPlotter/ArmarXPlotter.h - ArmarXPlotter/ArmarXPlotterDialog.h + ArmarXTCPMover/TCPMover.h ArmarXTCPMover/TCPMoverConfigDialog.h ) set(GUI_UIS - ArmarXPlotter/ArmarXPlotter.ui - ArmarXPlotter/ArmarXPlotterDialog.ui + ArmarXTCPMover/TCPMover.ui ArmarXTCPMover/TCPMoverConfigDialog.ui ) -set(COMPONENT_LIBS RobotAPIUnits ArmarXCoreTopicRecording ArmarXCoreObservers ObserverPropertiesGuiPlugin RobotAPIInterfaces ${qwt_LIBRARIES} ${Simox_LIBRARIES} ${QT_LIBRARIES}) +set(COMPONENT_LIBS RobotAPIUnits ArmarXCoreObservers RobotAPIInterfaces ${Simox_LIBRARIES} ${QT_LIBRARIES}) diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/SensorActorWidgetsPlugin.cpp b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/SensorActorWidgetsPlugin.cpp index 1845914fc..1dc259cf1 100644 --- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/SensorActorWidgetsPlugin.cpp +++ b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/SensorActorWidgetsPlugin.cpp @@ -21,8 +21,6 @@ */ #include "SensorActorWidgetsPlugin.h" - -#include "ArmarXPlotter/ArmarXPlotter.h" #include "ArmarXTCPMover/TCPMover.h" namespace armarx @@ -31,7 +29,6 @@ namespace armarx SensorActorPlugin::SensorActorPlugin() { addWidget<TCPMover>(); - addWidget<ArmarXPlotter>(); } Q_EXPORT_PLUGIN2(armarX_gui_SensorActorPlugin, SensorActorPlugin) -- GitLab