From 83f5905a92d9b3c45d0801ce5693642d018d7622 Mon Sep 17 00:00:00 2001
From: Joana <joana.plewnia@kit.edu>
Date: Fri, 16 Aug 2024 15:21:16 +0200
Subject: [PATCH] feature added: store snapshots from WM on stopRecording() if
 storeOnStop is true in properties of LTM tested in Simulation

---
 .../armem/server/MemoryToIceAdapter.cpp       | 14 +++-
 .../armem/server/ltm/CoreSegment.cpp          |  4 +-
 .../libraries/armem/server/ltm/CoreSegment.h  |  2 +-
 .../libraries/armem/server/ltm/Entity.cpp     | 10 ++-
 .../libraries/armem/server/ltm/Entity.h       |  2 +-
 .../libraries/armem/server/ltm/Memory.cpp     |  8 +-
 .../libraries/armem/server/ltm/Memory.h       |  4 +-
 .../armem/server/ltm/ProviderSegment.cpp      |  4 +-
 .../armem/server/ltm/ProviderSegment.h        |  2 +-
 .../armem/server/ltm/detail/CoreSegmentBase.h |  6 +-
 .../armem/server/ltm/detail/EntityBase.h      |  6 +-
 .../server/ltm/detail/EntitySnapshotBase.h    |  2 +-
 .../armem/server/ltm/detail/MemoryBase.h      | 10 +--
 .../server/ltm/detail/ProviderSegmentBase.h   |  6 +-
 .../ltm/detail/mixins/BufferedMemoryMixin.h   | 15 ++--
 .../server/ltm/processors/filter/Filter.h     |  2 +-
 .../filter/equalityFilter/EqualityFilter.cpp  |  2 +-
 .../filter/equalityFilter/EqualityFilter.h    |  2 +-
 .../frequencyFilter/FrequencyFilter.cpp       | 84 +++++++++++++++++--
 .../filter/frequencyFilter/FrequencyFilter.h  | 15 +++-
 .../importanceFilter/ImportanceFilter.cpp     |  2 +-
 .../importanceFilter/ImportanceFilter.h       |  2 +-
 .../server/plugins/ReadWritePluginUser.h      |  2 +-
 23 files changed, 151 insertions(+), 55 deletions(-)

diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
index 3ec7db60a..94d26b5c5 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
@@ -453,18 +453,26 @@ namespace armarx::armem::server
     {
         ARMARX_TRACE;
         ARMARX_CHECK_NOT_NULL(longtermMemory);
+        ARMARX_CHECK_NOT_NULL(workingMemory);
         ARMARX_IMPORTANT << "Disabling the recording of memory " << longtermMemory->id().str();
 
+        if(longtermMemory->p.storeOnStop){ //if true this means when stopping LTM recording leftover snapshots are transferred to WM using the simulated consolidation
+            ARMARX_INFO << "Starting to save left-over WM data into LTM";
+            longtermMemory->directlyStore(*workingMemory, true);
+            ARMARX_INFO << "Stored leftover WM data into LTM";
+        } else {
+            ARMARX_INFO << "Not storing WM data into LTM on stop, because storeOnStop is " << longtermMemory->p.storeOnStop;
+        }
+
         //put calling stopRecording into a seperate thread and detach to make sure GUI does not freeze
         auto ltm = longtermMemory;
+
         std::thread stopRecordingThread([&ltm](){
             ltm->stopRecording();
-        });
-        std::thread savingDataUpdateThread([&ltm](){
             ltm->bufferFinished();
+            ARMARX_INFO << "Storing finished";
         });
         stopRecordingThread.detach();
-        savingDataUpdateThread.detach();
 
         ARMARX_IMPORTANT
             << "Stopped all LTM recordings, please wait with stopping the component until "
diff --git a/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.cpp
index 3f8d4f8d6..ff955d28e 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.cpp
@@ -155,7 +155,7 @@ namespace armarx::armem::server::ltm
     }
 
     void
-    CoreSegment::_store(const armem::wm::CoreSegment& c)
+    CoreSegment::_store(const armem::wm::CoreSegment& c, bool simulatedVersion)
     {
         std::lock_guard l(ltm_mutex);
 
@@ -207,7 +207,7 @@ namespace armarx::armem::server::ltm
                                   id().withProviderSegmentName(prov.id().providerSegmentName),
                                   processors);
 
-                c.store(prov);
+                c.store(prov, simulatedVersion);
             });
     }
 } // namespace armarx::armem::server::ltm
diff --git a/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.h b/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.h
index 062ce79c3..1c36d1436 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/CoreSegment.h
@@ -30,7 +30,7 @@ namespace armarx::armem::server::ltm
         void _loadAllReferences(armem::wm::CoreSegment&) override;
         void _loadLatestNReferences(int n, armem::wm::CoreSegment& c) override;
         void _resolve(armem::wm::CoreSegment&) override;
-        void _store(const armem::wm::CoreSegment&) override;
+        void _store(const armem::wm::CoreSegment&, bool simulatedVersion) override;
 
     private:
     };
diff --git a/source/RobotAPI/libraries/armem/server/ltm/Entity.cpp b/source/RobotAPI/libraries/armem/server/ltm/Entity.cpp
index 306bd90e2..5ce8cab3d 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/Entity.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/Entity.cpp
@@ -423,7 +423,7 @@ namespace armarx::armem::server::ltm
     }
 
     void
-    Entity::_store(const armem::wm::Entity& c)
+    Entity::_store(const armem::wm::Entity& c, bool simulatedVersion)
     {
         std::lock_guard l(ltm_mutex);
         if (id().entityName.empty())
@@ -464,17 +464,19 @@ namespace armarx::armem::server::ltm
 
                 for (auto& f : processors->snapFilters)
                 {
-
-                    bool accepted = f->accept(snap);
+                    bool accepted = f->accept(snap, simulatedVersion);
+                    
                     if (!accepted)
                     {
-                        //ARMARX_INFO << "Ignoring to put an EntitiySnapshot into the LTM because it got filtered.";
+                        ARMARX_DEBUG << "Ignoring to put an EntitySnapshot into the LTM because it got filtered.";
                         return;
                     } else {
                         //ARMARX_INFO << "Storing EntitySnapshot";
                     }
                 }
 
+                ARMARX_DEBUG << "Snapshot: " << c.id().timestamp << " of coreSegment " << c.id().coreSegmentName;
+
                 c.store(snap);
                 statistics.recordedSnapshots++;
             });
diff --git a/source/RobotAPI/libraries/armem/server/ltm/Entity.h b/source/RobotAPI/libraries/armem/server/ltm/Entity.h
index 82f22a63c..a873f444b 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/Entity.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/Entity.h
@@ -49,7 +49,7 @@ namespace armarx::armem::server::ltm
         void _loadAllReferences(armem::wm::Entity&) override;
         void _loadLatestNReferences(int n, armem::wm::Entity& e) override;
         void _resolve(armem::wm::Entity&) override;
-        void _store(const armem::wm::Entity&) override;
+        void _store(const armem::wm::Entity& e, bool simulatedVersion) override;
 
     private:
     };
diff --git a/source/RobotAPI/libraries/armem/server/ltm/Memory.cpp b/source/RobotAPI/libraries/armem/server/ltm/Memory.cpp
index 39e18a372..a950f1541 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/Memory.cpp
@@ -62,7 +62,7 @@ namespace armarx::armem::server::ltm
     Memory::_disable()
     {
         BufferedBase::stop();
-        MongoDBStorageMixin::stop();
+        //MongoDBStorageMixin::stop();
         ARMARX_IMPORTANT << "Storing of data finished, starting to generate and save statistics...";
         getAndSaveStatistics();
     }
@@ -261,7 +261,7 @@ namespace armarx::armem::server::ltm
     }
 
     void
-    Memory::_directlyStore(const armem::wm::Memory& memory)
+    Memory::_directlyStore(const armem::wm::Memory& memory, bool simulatedVersion)
     {
         std::lock_guard l(ltm_mutex); // we cannot store a memory multiple times simultaneously
 
@@ -280,6 +280,8 @@ namespace armarx::armem::server::ltm
             return;
         }*/
 
+        ARMARX_DEBUG << "CoreSegments: " << memory.getCoreSegmentNames().size();
+
         memory.forEachCoreSegment(
             [&](const auto& core)
             {
@@ -290,7 +292,7 @@ namespace armarx::armem::server::ltm
                               processors);
 
                 // 2. store data
-                c.store(core);
+                c.store(core, simulatedVersion);
                 
 
                 // 3. update statistics
diff --git a/source/RobotAPI/libraries/armem/server/ltm/Memory.h b/source/RobotAPI/libraries/armem/server/ltm/Memory.h
index 4c7b287fc..bb022c1e2 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/Memory.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/Memory.h
@@ -60,8 +60,8 @@ namespace armarx::armem::server::ltm
         void _loadLatestNReferences(int n, armem::wm::Memory& m) final;
         void _loadLatestNReferences(int n, armem::wm::Memory& m, std::list<std::string> coreSegNames) final;
         void _resolve(armem::wm::Memory&) final;
-        void _store(const armem::wm::Memory&) final;
-        void _directlyStore(const armem::wm::Memory&) final;
+        void _store(const armem::wm::Memory& m) final;
+        void _directlyStore(const armem::wm::Memory& m, bool simulatedVersion) final;
         void _loadOnStartup() final;
 
     private:
diff --git a/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.cpp
index 8978aeced..f568b3213 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.cpp
@@ -155,7 +155,7 @@ namespace armarx::armem::server::ltm
     }
 
     void
-    ProviderSegment::_store(const armem::wm::ProviderSegment& p)
+    ProviderSegment::_store(const armem::wm::ProviderSegment& p, bool simulatedVersion)
     {
         std::lock_guard l(ltm_mutex);
 
@@ -206,7 +206,7 @@ namespace armarx::armem::server::ltm
                          id().withEntityName(e.id().entityName),
                          processors);
 
-                c.store(e);
+                c.store(e, simulatedVersion);
                 statistics.recordedEntities++;
             });
         }
diff --git a/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.h b/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.h
index 1d6ac9d36..056740808 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/ProviderSegment.h
@@ -30,7 +30,7 @@ namespace armarx::armem::server::ltm
         void _loadAllReferences(armem::wm::ProviderSegment&) override;
         void _loadLatestNReferences(int n, armem::wm::ProviderSegment& p) override;
         void _resolve(armem::wm::ProviderSegment&) override;
-        void _store(const armem::wm::ProviderSegment&) override;
+        void _store(const armem::wm::ProviderSegment&, bool simulatedVersion) override;
 
     private:
     };
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h
index 79a5cc774..ce70f089d 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h
@@ -50,9 +50,9 @@ namespace armarx::armem::server::ltm::detail
 
         /// encode the content of a wm::Memory and store
         void
-        store(const armem::wm::CoreSegment& coreSeg)
+        store(const armem::wm::CoreSegment& coreSeg, bool simulatedVersion)
         {
-            _store(coreSeg);
+            _store(coreSeg, simulatedVersion);
         }
 
         /// statistics
@@ -95,7 +95,7 @@ namespace armarx::armem::server::ltm::detail
         virtual void _loadAllReferences(armem::wm::CoreSegment&) = 0;
         virtual void _loadLatestNReferences(int n, armem::wm::CoreSegment& c) = 0;
         virtual void _resolve(armem::wm::CoreSegment&) = 0;
-        virtual void _store(const armem::wm::CoreSegment&) = 0;
+        virtual void _store(const armem::wm::CoreSegment& c, bool simulatedVersion=false) = 0;
 
     protected:
         mutable std::recursive_mutex ltm_mutex;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h
index 3bf90a7f4..3de973486 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h
@@ -50,9 +50,9 @@ namespace armarx::armem::server::ltm::detail
 
         /// encode the content of a wm::Memory and store
         void
-        store(const armem::wm::Entity& e)
+        store(const armem::wm::Entity& e, bool simulatedVersion)
         {
-            _store(e);
+            _store(e, simulatedVersion);
         }
 
         /// statistics
@@ -108,7 +108,7 @@ namespace armarx::armem::server::ltm::detail
         virtual void _loadAllReferences(armem::wm::Entity&) = 0;
         virtual void _loadLatestNReferences(int n, armem::wm::Entity& e) = 0;
         virtual void _resolve(armem::wm::Entity&) = 0;
-        virtual void _store(const armem::wm::Entity&) = 0;
+        virtual void _store(const armem::wm::Entity& e, bool simulatedVersion=false) = 0;
 
     protected:
         mutable std::recursive_mutex ltm_mutex;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h
index cebbca955..f6488bad8 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h
@@ -78,7 +78,7 @@ namespace armarx::armem::server::ltm::detail
     protected:
         virtual void _loadAllReferences(armem::wm::EntitySnapshot&) const = 0;
         virtual void _resolve(armem::wm::EntitySnapshot&) const = 0;
-        virtual void _store(const armem::wm::EntitySnapshot&) = 0;
+        virtual void _store(const armem::wm::EntitySnapshot& s) = 0;
 
     protected:
         mutable std::recursive_mutex ltm_mutex;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h
index 4feb13078..eab1c6b74 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h
@@ -213,8 +213,8 @@ namespace armarx::armem::server::ltm::detail
         void
         store(const armem::server::wm::Memory& serverMemory)
         {
-            wm::Memory memory;
-            memory.update(armem::toCommit(serverMemory));
+            armem::wm::Memory memory(serverMemory.name());
+            memory.update(armem::toCommit(serverMemory), true);
             this->store(memory);
         }
 
@@ -234,11 +234,11 @@ namespace armarx::armem::server::ltm::detail
             defs->optional(p.enabled_on_startup, prefix + "enabled");
             defs->optional(p.configuration_on_startup, prefix + "configuration");
             defs->optional(p.export_name, prefix + "exportName");
+            defs->optional(p.storeOnStop, prefix + "storeOnStop");
 
             defs->optional(p.importOnStartUp, prefix + "importOnStartUp");
             defs->optional(p.maxAmountOfSnapshotsLoaded, prefix + "maxAmountSnapshotsLoaded");
             defs->optional(p.coreSegmentsToLoad, prefix + "loadedCoreSegments");
-            
         }
 
         /// enable/disable
@@ -337,7 +337,7 @@ namespace armarx::armem::server::ltm::detail
         virtual void _loadAllReferences(armem::wm::Memory& memory) = 0;
         virtual void _resolve(armem::wm::Memory& memory) = 0;
         virtual void _store(const armem::wm::Memory& memory) = 0;
-        virtual void _directlyStore(const armem::wm::Memory& memory) = 0;
+        virtual void _directlyStore(const armem::wm::Memory& memory, bool simulatedVersion=false) = 0;
         virtual void _loadOnStartup() = 0;
         virtual void _loadLatestNReferences(int n, armem::wm::Memory& memory) = 0;
         virtual void _loadLatestNReferences(int n, armem::wm::Memory& memory, std::list<std::string> coreSegNames) = 0;
@@ -348,7 +348,7 @@ namespace armarx::armem::server::ltm::detail
         {
             bool enabled_on_startup = false;
             std::string configuration_on_startup =
-                "{ \"SnapshotFrequencyFilter\": {\"WaitingTimeInMsForFilter\" : 50}"; //record with 20 fps as standard
+                "{ \"SnapshotFrequencyFilter\": {\"WaitingTimeInMsForFilter\" : 50}}"; //record with 20 fps as standard
             std::string export_name = "MemoryExport";
             std::string export_path = "/tmp/ltm";
             bool storeOnStop = true; 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h
index 0aa25896f..91f853f92 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h
@@ -48,9 +48,9 @@ namespace armarx::armem::server::ltm::detail
 
         /// encode the content of a wm::Memory and store
         void
-        store(const armem::wm::ProviderSegment& provSeg)
+        store(const armem::wm::ProviderSegment& provSeg, bool simulatedVersion)
         {
-            _store(provSeg);
+            _store(provSeg, simulatedVersion);
         }
 
         /// statistics
@@ -91,7 +91,7 @@ namespace armarx::armem::server::ltm::detail
         virtual void _loadAllReferences(armem::wm::ProviderSegment&) = 0;
         virtual void _loadLatestNReferences(int n, armem::wm::ProviderSegment& p) = 0;
         virtual void _resolve(armem::wm::ProviderSegment&) = 0;
-        virtual void _store(const armem::wm::ProviderSegment&) = 0;
+        virtual void _store(const armem::wm::ProviderSegment& p, bool simulatedVersion=false) = 0;
 
     protected:
         mutable std::recursive_mutex ltm_mutex;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/mixins/BufferedMemoryMixin.h b/source/RobotAPI/libraries/armem/server/ltm/detail/mixins/BufferedMemoryMixin.h
index 103811f41..0a17f6adc 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/mixins/BufferedMemoryMixin.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/mixins/BufferedMemoryMixin.h
@@ -28,22 +28,23 @@ namespace armarx::armem::server::ltm::detail::mixin
         virtual ~BufferedMemoryMixin() = default;
 
         void
-        directlyStore(const armem::wm::Memory& memory)
+        directlyStore(const armem::wm::Memory& memory, bool simulatedVersion=false)
         {
             std::lock_guard l(storeMutex);
 
             TIMING_START(LTM_Memory_DirectlyStore);
-            _directlyStore(memory);
+            _directlyStore(memory, simulatedVersion);
             TIMING_END_STREAM(LTM_Memory_DirectlyStore, ARMARX_DEBUG);
         }
 
         void
-        directlyStore(const armem::server::wm::Memory& serverMemory)
+        directlyStore(const armem::server::wm::Memory& serverMemory, bool simulatedVersion=false)
         {
-            wm::Memory memory;
+            armem::wm::Memory memory;
             memory.setName(serverMemory.name());
-            memory.update(armem::toCommit(serverMemory));
-            this->directlyStore(memory);
+            auto ids = memory.update(armem::toCommit(serverMemory), true);
+            ARMARX_DEBUG << "Amount of ids in update: " << ids.size();
+            this->directlyStore(memory, simulatedVersion);
         }
 
         void
@@ -137,7 +138,7 @@ namespace armarx::armem::server::ltm::detail::mixin
             defs->optional(storeFrequency, prefix + "storeFrequency");
         }
 
-        virtual void _directlyStore(const armem::wm::Memory& memory) = 0;
+        virtual void _directlyStore(const armem::wm::Memory& memory, bool simulatedVersion=false) = 0;
 
         void
         addToBuffer(const armem::wm::Memory& memory)
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/Filter.h b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/Filter.h
index 7cd2ade2e..4bf8ec049 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/Filter.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/Filter.h
@@ -29,7 +29,7 @@ namespace armarx::armem::server::ltm::processor
         SnapshotFilter() = default;
         virtual ~SnapshotFilter() = default;
 
-        virtual bool accept(const armem::wm::EntitySnapshot& e) = 0;
+        virtual bool accept(const armem::wm::EntitySnapshot& e, bool simulatedVersion = false) = 0;
         virtual void configure(const nlohmann::json& json);
 
         struct FilterStatistics {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.cpp b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.cpp
index 715520f7b..6f55b623a 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.cpp
@@ -9,7 +9,7 @@
 namespace armarx::armem::server::ltm::processor::filter
 {
     bool
-    SnapshotSimilarityFilter::accept(const armem::wm::EntitySnapshot& e)
+    SnapshotSimilarityFilter::accept(const armem::wm::EntitySnapshot& e, bool simulatedVersion)
     {
         auto start = std::chrono::high_resolution_clock::now();
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.h b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.h
index e5d3a7b1f..407290de8 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/equalityFilter/EqualityFilter.h
@@ -25,7 +25,7 @@ namespace armarx::armem::server::ltm::processor::filter
 
         SnapshotSimilarityFilter() = default;
 
-        virtual bool accept(const armem::wm::EntitySnapshot& e) override;
+        virtual bool accept(const armem::wm::EntitySnapshot& e, bool simulatedVersion) override;
         void configure(const nlohmann::json& json) override;
 
         FilterStatistics getFilterStatistics() override;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.cpp b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.cpp
index 2dd6e1d7c..5f4777423 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.cpp
@@ -6,7 +6,7 @@ namespace armarx::armem::server::ltm::processor::filter
 {
 
     bool
-    SnapshotFrequencyFilter::accept(const armem::wm::EntitySnapshot &e)
+    SnapshotFrequencyFilter::accept(const armem::wm::EntitySnapshot &e, bool simulatedVersion)
     {
         //accepting to many elements makes the filter slow and brings problems with the buffer with itself!
 
@@ -17,13 +17,24 @@ namespace armarx::armem::server::ltm::processor::filter
         // get entity id of this snapshot:
         auto memID = e.id().getEntityID();
 
+        //find out if timestamps are corrupted:
+        if(this->nonCorruptedType == TimestampType::NOT_SET){
+            ARMARX_DEBUG << "Setting timestamp type";
+            this->setNonCorruptedTimestampType(e);
+            ARMARX_DEBUG << VAROUT(this->nonCorruptedType);
+        }
+
+        if(this->nonCorruptedType == TimestampType::ALL_CORRUPTED) {
+            return true;
+        }
+
         if(this->lastTimesPerEntity.end() == this->lastTimesPerEntity.find(memID)){
           //this happens if the key is not in the map, which means this is the first time this
           //entity tries to save a snapshot
-          ARMARX_INFO << "First time this entity is saved";
+          ARMARX_DEBUG << "First time this entity is saved";
           auto firstIndex = e.getInstanceIndices()[0];
           auto firstInsance = e.getInstance(firstIndex);
-          auto lastT = firstInsance.metadata().sentTime.toMilliSecondsSinceEpoch();
+          auto lastT = this->getNonCorruptedTimestamp(firstInsance, simulatedVersion);
           //for statistics sake:
           auto end = std::chrono::high_resolution_clock::now();
           stats.end_time = end;
@@ -33,16 +44,16 @@ namespace armarx::armem::server::ltm::processor::filter
           this->lastTimesPerEntity[memID] = lastT;
           return true; //the first one is always accepted
         } else {
-
             auto lastTime = this->lastTimesPerEntity.at(memID);
 
             // check if any one of the instances for this snapshot were sent in the last x
             // milliseconds since a snapshot was accepted last for this entity:
-            e.forEachInstance([this, &instances_accepted, &current, &lastTime](armem::wm::EntityInstance& i){
-                int difference = std::abs(i.metadata().sentTime.toMilliSecondsSinceEpoch() - lastTime);
+            e.forEachInstance([this, &instances_accepted, &current, &lastTime, &simulatedVersion](armem::wm::EntityInstance& i){
+                auto t = this->getNonCorruptedTimestamp(i, simulatedVersion);
+                int difference = std::abs(t - lastTime);
                 if(difference > this->maxDifference){ //at least one instance is older than the last saved instance
                     instances_accepted = true;
-                    current = i.metadata().sentTime.toMilliSecondsSinceEpoch();
+                    current = this->getNonCorruptedTimestamp(i, simulatedVersion);
                 }
             });
 
@@ -66,6 +77,65 @@ namespace armarx::armem::server::ltm::processor::filter
         return instances_accepted;
     }
 
+    void
+    SnapshotFrequencyFilter::setNonCorruptedTimestampType(const armem::wm::EntitySnapshot &e){
+        auto firstIndex = e.getInstanceIndices()[0];
+        auto firstInsance = e.getInstance(firstIndex);
+        auto sentTime = firstInsance.metadata().sentTime;
+        auto arrivedTime = firstInsance.metadata().arrivedTime;
+        auto referencedTime = firstInsance.metadata().referencedTime;
+
+        ARMARX_DEBUG << VAROUT(sentTime.toMilliSecondsSinceEpoch());
+        ARMARX_DEBUG << VAROUT(arrivedTime.toMilliSecondsSinceEpoch());
+        ARMARX_DEBUG << VAROUT(referencedTime.toMilliSecondsSinceEpoch());
+
+        if(sentTime.toMilliSecondsSinceEpoch() < 946688400000){
+            // we assume the timestamp does not make sense if it is older than the year 2000
+            if(arrivedTime.toMilliSecondsSinceEpoch() < 946688400000){
+                if(referencedTime.toMilliSecondsSinceEpoch() < 946688400000){
+                    ARMARX_WARNING << "LTM recording does not work correctly, as frequency filter is used, but "
+                                   << "time sent, arrived and referenced are all corrupted. \n"
+                                   << "Accepting all snapshots.";
+                    this->nonCorruptedType = TimestampType::ALL_CORRUPTED;
+                } else {
+                    if(!corruptedWarningGiven){ //only print this warning once
+                        ARMARX_INFO << "Time sent and arrived for snapshot corrupted, using time referenced for filtering";
+                        corruptedWarningGiven = true;
+                    }
+                    //use time referenced from now on
+                    this->nonCorruptedType = TimestampType::REFERENCED;
+                }
+            } else {
+                if(!corruptedWarningGiven){ //only print this warning once
+                        ARMARX_INFO << "Time sent for snapshot corrupted, using time arrived for filtering";
+                        corruptedWarningGiven = true;
+                }
+                //use time arrived from now on
+                this->nonCorruptedType = TimestampType::ARRIVED;
+            }
+        } else {
+            this->nonCorruptedType = TimestampType::SENT;
+        }
+    }
+
+    int
+    SnapshotFrequencyFilter::getNonCorruptedTimestamp(const armem::wm::EntityInstance &i, bool simulatedVersion){
+        switch(this->nonCorruptedType) {
+            case TimestampType::SENT:
+                if(!simulatedVersion){
+                    return i.metadata().sentTime.toMilliSecondsSinceEpoch();
+                } else {
+                    [[fallthrough]];
+                }
+            case TimestampType::ARRIVED:
+                return i.metadata().arrivedTime.toMilliSecondsSinceEpoch();
+            case TimestampType::REFERENCED:
+                return i.metadata().referencedTime.toMilliSecondsSinceEpoch();
+            default:
+                return -1;
+        }
+    }
+    
     void
     SnapshotFrequencyFilter::configure(const nlohmann::json& json)
     {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.h b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.h
index e9c9e0021..63e449376 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/frequencyFilter/FrequencyFilter.h
@@ -5,6 +5,13 @@
 
 namespace armarx::armem::server::ltm::processor::filter
 {
+    enum TimestampType{
+        NOT_SET = 0,
+        SENT = 1,
+        ARRIVED = 2,
+        REFERENCED = 3,
+        ALL_CORRUPTED = 4
+    };
 
     class SnapshotFrequencyFilter : public SnapshotFilter
     {
@@ -14,14 +21,20 @@ namespace armarx::armem::server::ltm::processor::filter
 
         SnapshotFrequencyFilter() = default;
 
-        virtual bool accept(const armem::wm::EntitySnapshot &e) override;
+        virtual bool accept(const armem::wm::EntitySnapshot &e, bool simulatedVersion) override;
         void configure(const nlohmann::json& json) override;
 
         FilterStatistics getFilterStatistics() override;
         std::string getName() override;
 
     private:
+        void setNonCorruptedTimestampType(const armem::wm::EntitySnapshot &e);
+        int getNonCorruptedTimestamp(const armem::wm::EntityInstance &i, bool simulatedVersion);
+
         std::map<MemoryID, std::int64_t> lastTimesPerEntity;
         int maxDifference = 0;
+        bool corruptedWarningGiven = false;
+        TimestampType nonCorruptedType = TimestampType::NOT_SET;
+
     };
 } // namespace armarx::armem::server::ltm::processor::filter
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.cpp b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.cpp
index 0ae255a4d..06516bd78 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.cpp
@@ -4,7 +4,7 @@
 namespace armarx::armem::server::ltm::processor::filter
 {
 
-bool SnapshotImportanceFilter::accept(const armem::wm::EntitySnapshot &e)
+bool SnapshotImportanceFilter::accept(const armem::wm::EntitySnapshot &e, bool simulatedVersion)
 {
     auto start = std::chrono::high_resolution_clock::now();
     bool instances_accepted = false;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.h b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.h
index 929bb2e2a..5dcc76b57 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/processors/filter/importanceFilter/ImportanceFilter.h
@@ -23,7 +23,7 @@ public:
 
     SnapshotImportanceFilter() = default;
 
-    virtual bool accept(const armem::wm::EntitySnapshot& e) override;
+    virtual bool accept(const armem::wm::EntitySnapshot& e, bool simulatedVersion) override;
     void configure(const nlohmann::json& json) override;
 
     FilterStatistics getFilterStatistics() override;
diff --git a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h
index 289db2216..935fb0598 100644
--- a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h
+++ b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h
@@ -87,7 +87,7 @@ namespace armarx::armem::server::plugins
         virtual armem::prediction::data::EngineSupportMap
         getAvailableEngines(const ::Ice::Current&) override;
 
-        //test
+        //ReloadFromLTMOnStartup
         armem::CommitResult reloadFromLTM();
 
     public:
-- 
GitLab