From 7a01369f7bff755d41bbef112417b87274a66c89 Mon Sep 17 00:00:00 2001
From: Mirko Waechter <mirko.waechter@kit.edu>
Date: Thu, 22 Dec 2016 17:04:27 +0100
Subject: [PATCH] plotter supports observers history now

---
 .../ArmarXPlotter/ArmarXPlotter.cpp           | 73 +++++++++++++++++--
 .../core/remoterobot/RobotStateObserver.h     |  4 +-
 2 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp
index 5c43f0c87..0eb423190 100644
--- a/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp
+++ b/source/RobotAPI/gui-plugins/SensorActorWidgetsPlugin/ArmarXPlotter/ArmarXPlotter.cpp
@@ -274,7 +274,7 @@ namespace armarx
             {
                 logstream << "Timestamp";
 
-                for (auto & channel : selectedChannels)
+                for (auto& channel : selectedChannels)
                 {
                     logstream <<  "," << channel.toStdString();
                 }
@@ -334,7 +334,7 @@ namespace armarx
         ScopedLock lock(dataMutex);
         IceUtil::Time curTime = TimeUtil::GetTime();
         // erase old markers
-        for (auto & markerChannel : markers)
+        for (auto& markerChannel : markers)
         {
             for (auto it = markerChannel.second.begin(); it != markerChannel.second.end();)
             {
@@ -383,7 +383,7 @@ namespace armarx
                     marker->setLineStyle(QwtPlotMarker::VLine);
                     marker->setLabelAlignment(Qt::AlignBottom | Qt::AlignLeft);
                     int i = 0;
-                    for (auto & markerSubMap : markers)
+                    for (auto& markerSubMap : markers)
                     {
                         if (markerSubMap.first == datafieldId)
                         {
@@ -623,7 +623,8 @@ namespace armarx
         {
 
             ScopedLock lock(dataMutex);
-
+            auto now = TimeUtil::GetTime();
+            std::map<std::string, ChannelHistory> histories;
             markers.clear();
             for (int i = 0; i < selectedChannels.size(); i++)
             {
@@ -633,6 +634,22 @@ namespace armarx
                     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)
@@ -646,6 +663,15 @@ namespace armarx
 
                         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
                     {
@@ -674,7 +700,42 @@ namespace armarx
                                 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 (...)
                 {
@@ -822,7 +883,7 @@ namespace armarx
                     {
                         auto dict = JSONObject::ConvertToBasicVariantMap(json, var);
 
-                        for (const auto & e : dict)
+                        for (const auto& e : dict)
                         {
                             if (e.first == "timestamp") // TimedVariants always contain a timestamp field which is irrelevant
                             {
@@ -885,7 +946,7 @@ namespace armarx
         {
             logstream << (time - logStartTime).toMilliSecondsDouble() << ",";
 
-            for (auto & channel : selectedChannels)
+            for (auto& channel : selectedChannels)
             {
                 logstream << dataMaptoAppend.at(channel.toStdString())->Variant::getOutputValueOnly();
                 if (!selectedChannels.endsWith(channel))
diff --git a/source/RobotAPI/libraries/core/remoterobot/RobotStateObserver.h b/source/RobotAPI/libraries/core/remoterobot/RobotStateObserver.h
index 2c4eae006..972e9c155 100644
--- a/source/RobotAPI/libraries/core/remoterobot/RobotStateObserver.h
+++ b/source/RobotAPI/libraries/core/remoterobot/RobotStateObserver.h
@@ -49,11 +49,11 @@ namespace armarx
      * RobotStatePropertyDefinition Property Definitions
      */
     class RobotStateObserverPropertyDefinitions:
-        public ComponentPropertyDefinitions
+        public ObserverPropertyDefinitions
     {
     public:
         RobotStateObserverPropertyDefinitions(std::string prefix):
-            ComponentPropertyDefinitions(prefix)
+            ObserverPropertyDefinitions(prefix)
         {
             defineOptionalProperty<std::string>("TCPsToReport", "", "comma seperated list of nodesets' endeffectors, which poses and velocities that should be reported. * for all, empty for none");
         }
-- 
GitLab