From b850c38cb222fea9d50b26f9d454713fb052e6db Mon Sep 17 00:00:00 2001
From: Fabian Peller-Konrad <fabian.peller-konrad@kit.edu>
Date: Mon, 19 Aug 2024 10:47:25 +0200
Subject: [PATCH] allow the ltm to record in different recording modes

---
 .../armem/server/MemoryToIceAdapter.cpp       | 21 +++++-
 .../armem/server/ltm/detail/MemoryBase.h      | 66 +++++++++++++++++--
 .../armem/server/ltm/detail/MemoryItem.cpp    |  2 +
 3 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
index 4aee9800a..adcf0f0fd 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
@@ -235,9 +235,21 @@ namespace armarx::armem::server
                     ARMARX_DEBUG << "The id " << snapshot.id() << " was removed from wm";
                 }
 
+                // Consolidate to ltm(s) if recording mode is CLONE_WM
+                if (longtermMemory->isRecording() && longtermMemory->getRecordingMode() == server::ltm::RecordingMode::CONSOLIDATE_ALL)
+                {
+                    // convert removedSnapshots to Memory
+                    armem::wm::Memory m(longtermMemory->name());
+                    m.update(update, true, false);
+                    //this removes information about segments, because new memory (wm) is used
+
+                    // store memory
+                    longtermMemory->store(m);
+                }
+
 
-                // Consollidate to ltm(s)
-                if (longtermMemory->isRecording())
+                // Consolidate to ltm(s) if recording mode is CONSOLIDATE_REMOVED
+                if (longtermMemory->isRecording() && longtermMemory->getRecordingMode() == server::ltm::RecordingMode::CONSOLIDATE_REMOVED)
                 {
                     // convert removedSnapshots to Memory
                     armem::wm::Memory m(longtermMemory->name());
@@ -248,6 +260,11 @@ namespace armarx::armem::server
                     longtermMemory->store(m);
                 }
 
+                if (longtermMemory->isRecording() && longtermMemory->getRecordingMode() == server::ltm::RecordingMode::CONSOLIDATE_LATEST)
+                {
+                    ARMARX_WARNING << deactivateSpam() << "THIS IS NOT IMPLEMENTED YET!!!";
+                }
+
                 if (publishUpdates)
                 {
                     data::MemoryID& id = updatedIDs.emplace_back();
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h
index 99df8e2e6..30d9fb60a 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h
@@ -20,6 +20,16 @@
 #include <RobotAPI/libraries/armem/server/test/ForgettingExperiments.h>
 #include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 
+namespace armarx::armem::server::ltm
+{
+    enum class RecordingMode
+    {
+        CONSOLIDATE_REMOVED, // only store whats removed from the WM
+        CONSOLIDATE_ALL, // store whats in the WM (on commit)
+        CONSOLIDATE_LATEST // store the latest snapshots at a fixed frequency (for now 1Hz)
+    };
+}
+
 namespace armarx::armem::server::ltm::detail
 {
     /// @brief Interface functions for the longterm memory classes
@@ -27,6 +37,8 @@ namespace armarx::armem::server::ltm::detail
     class MemoryBase : public MemoryItem
     {
     public:
+
+
         struct Statistics
         {
             armarx::core::time::DateTime lastEnabled = armarx::core::time::DateTime::Invalid();
@@ -47,6 +59,36 @@ namespace armarx::armem::server::ltm::detail
         {
         }
 
+        void setRecordingMode(const std::string& m)
+        {
+                if (m == "CONSOLIDATE_REMOVED")
+                {
+                        this->recordingMode = RecordingMode::CONSOLIDATE_REMOVED;
+                }
+                else if (m == "CONSOLIDATE_ALL")
+                {
+                        this->recordingMode = RecordingMode::CONSOLIDATE_ALL;
+                }
+                else if (m == "CONSOLIDATE_LATEST")
+                {
+                        this->recordingMode = RecordingMode::CONSOLIDATE_LATEST;
+                }
+                else
+                {
+                        ARMARX_WARNING << "Unknown recording mode: " << m;
+                }
+        }
+
+        void setRecordingMode(const RecordingMode m)
+        {
+            this->recordingMode = m;
+        }
+
+        RecordingMode getRecordingMode() const
+        {
+            return recordingMode;
+        }
+
         /// initialize config
         void
         configure()
@@ -55,15 +97,16 @@ namespace armarx::armem::server::ltm::detail
             ARMARX_INFO << VAROUT(p.configuration_on_startup);
             ARMARX_INFO << VAROUT(p.export_name);
             this->setExportName(p.export_name);
+            this->setRecordingMode(p.recordingMode);
 
             try
             {
-                const auto j = nlohmann::json::parse(p.configuration_on_startup);
+                const auto json = nlohmann::json::parse(p.configuration_on_startup);
 
                 // Processors are shared. So we only need to configure the root
-                processors->configure(j);
+                processors->configure(json);
 
-                this->_configure(j);
+                this->_configure(json);
             }
             catch (...)
             {
@@ -201,6 +244,7 @@ namespace armarx::armem::server::ltm::detail
         createPropertyDefinitions(PropertyDefinitionsPtr& defs, const std::string& prefix)
         {
             defs->optional(p.enabled_on_startup, prefix + "enabled");
+            defs->optional(p.recordingMode, prefix + "recordingMode");
             defs->optional(p.configuration_on_startup, prefix + "configuration");
             defs->optional(p.export_name, prefix + "exportName");
         }
@@ -301,12 +345,20 @@ namespace armarx::armem::server::ltm::detail
         // stuff for scenario parameters
         struct Properties
         {
+            // whether the LTM is enabled on startup
             bool enabled_on_startup = false;
-            std::string configuration_on_startup =
-                "{ \"SnapshotFrequencyFilter\": {\"WaitingTimeInMsForFilter\" : 50}, "
-                "\"PngConverter\": {}, \"ExrConverter\": {}}"; //record with 20 fps as standard
+
+            // How data is stored, if the LTM is enabled
+            std::string recordingMode = "CONSOLIDATE_REMOVED";
+
+            // Name and export path (TODO: Should this be part of the base class? Export path is a disk memory thing)
             std::string export_name = "MemoryExport";
             std::string export_path = "/tmp/ltm";
+
+            // Other configuration
+            std::string configuration_on_startup = "{\"SnapshotFilter\": {\"WaitingTimeInMsForFilter\" : 50}, "
+                "\"PngConverter\": {}, \"ExrConverter\": {}}"; //record with 20 fps as standard
+
         } p;
 
     protected:
@@ -315,5 +367,7 @@ namespace armarx::armem::server::ltm::detail
         mutable Statistics statistics;
 
         std::atomic_bool enabled = false;
+
+        RecordingMode recordingMode = RecordingMode::CONSOLIDATE_REMOVED;
     };
 } // namespace armarx::armem::server::ltm::detail
diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp
index 99dfcfee3..29061d0ee 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp
@@ -26,6 +26,8 @@ namespace armarx::armem::server::ltm::detail
         _setExportName(id);
     }
 
+
+
     void
     MemoryItem::setMemoryID(const MemoryID& id)
     {
-- 
GitLab