From 1b02efe63b00d1f74e98da76bca412a620535358 Mon Sep 17 00:00:00 2001
From: phesch <ulila@student.kit.edu>
Date: Tue, 24 May 2022 21:41:55 +0200
Subject: [PATCH] Migrate existing prediction engines to new impl

---
 .../armem/server/ExampleMemory/ExampleMemory.cpp     |  9 +++------
 .../armem/server/ExampleMemory/ExampleMemory.h       |  2 --
 .../armem/server/ObjectMemory/ObjectMemory.cpp       |  8 --------
 .../armem/server/ObjectMemory/ObjectMemory.h         |  1 -
 .../libraries/armem/core/base/CoreSegmentBase.h      | 11 ++++++++---
 .../RobotAPI/libraries/armem/core/base/MemoryBase.h  | 11 +++++++----
 .../armem/server/plugins/ReadWritePluginUser.h       |  4 ++++
 .../armem_objects/server/instance/Segment.cpp        |  7 +++++--
 .../armem_objects/server/instance/Segment.h          |  1 -
 .../armem_objects/server/instance/SegmentAdapter.cpp | 12 ++++++------
 .../armem_objects/server/instance/SegmentAdapter.h   |  3 +++
 11 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
index c7d941aa5..13a4deeed 100644
--- a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
+++ b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
@@ -72,6 +72,9 @@ namespace armarx
         workingMemory().addCoreSegment("ExampleData", armem::example::ExampleData::ToAronType());
         workingMemory().addCoreSegment("LinkedData", armem::example::LinkedData::ToAronType());
 
+        // We support the "Latest" prediction engine for the entire memory.
+        workingMemory().predictionEngines().push_back({"Latest"});
+
         // For illustration purposes, we add more segments (without types).
         bool trim = true;
         p.core.defaultCoreSegments = simox::alg::split(p.core._defaultSegmentsStr, ",", trim);
@@ -275,12 +278,6 @@ namespace armarx
         return result.toIce();
     }
 
-    armem::prediction::data::EngineSupportMap
-    ExampleMemory::getAvailableEngines()
-    {
-        return {{armarx::toIce<armem::data::MemoryID>(workingMemory().id()), {{"Latest"}}}};
-    }
-
     // REMOTE GUI
 
     void ExampleMemory::createRemoteGuiTab()
diff --git a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.h b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.h
index fa9c2b1ea..76e437bcb 100644
--- a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.h
+++ b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.h
@@ -76,8 +76,6 @@ namespace armarx
         armem::prediction::data::PredictionResultSeq
         predict(const armem::prediction::data::PredictionRequestSeq& requests) override;
 
-        armem::prediction::data::EngineSupportMap getAvailableEngines() override;
-
 
     protected:
 
diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp
index 71eba7787..fe2a74715 100644
--- a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp
+++ b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp
@@ -295,14 +295,6 @@ namespace armarx::armem::server::obj
         return results;
     }
 
-    armem::prediction::data::EngineSupportMap ObjectMemory::getAvailableEngines()
-    {
-        // TODO(phesch): Replace with generic code in Memory implementation
-        return {{armarx::toIce<armem::data::MemoryID>(
-                     workingMemory().id().withCoreSegmentName("Instance")),
-                 {{"Linear Position Regression"}}}};
-    }
-
     void ObjectMemory::createRemoteGuiTab()
     {
         using namespace armarx::RemoteGui::Client;
diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h
index 7067f42da..1a939eebf 100644
--- a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h
+++ b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h
@@ -110,7 +110,6 @@ namespace armarx::armem::server::obj
         // Predictions
         armem::prediction::data::PredictionResultSeq
         predict(const armem::prediction::data::PredictionRequestSeq& requests) override;
-        armem::prediction::data::EngineSupportMap getAvailableEngines() override;
 
         // Remote GUI
         void createRemoteGuiTab();
diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
index a0139d9f4..36334fd3e 100644
--- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
@@ -284,15 +284,20 @@ namespace armarx::armem::base
         }
 
         /**
-         * @brief Add an empty provider segment with the given name and optional provider segment type.
+         * @brief Add an empty provider segment with the given name,
+         *        optional provider segment type and prediction engines.
          * @param name The segment name.
          * @param providerSegmentType The provider type. If nullptr, the core segment type is used.
+         * @param predictionEngines The prediction engines supported by the provider segment (optional).
          * @return The added provider segment.
          */
-        ProviderSegmentT& addProviderSegment(const std::string& name, aron::type::ObjectPtr providerSegmentType = nullptr)
+        ProviderSegmentT&
+        addProviderSegment(const std::string& name,
+                           aron::type::ObjectPtr providerSegmentType = nullptr,
+                           const std::vector<PredictionEngine>& predictionEngines = {})
         {
             aron::type::ObjectPtr type = providerSegmentType ? providerSegmentType : this->aronType();
-            return this->_derived().addProviderSegment(name, name, type);
+            return this->_derived().addProviderSegment(name, name, type, predictionEngines);
         }
 
         /// Copy and insert a provider segment.
diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
index 947b459af..7f9ce5a18 100644
--- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
@@ -219,15 +219,18 @@ namespace armarx::armem::base
         // MODIFICATION
 
         /**
-         * @brief Add an empty core segment with the given name.
+         * @brief Add an empty core segment with the given name, type and prediction engines.
          * @param name The core segment name.
          * @param coreSegmentType The core segment type (optional).
+         * @param predictionEngines The prediction engines supported by the core segment (optional).
          * @return The added core segment.
          */
-        CoreSegmentT& addCoreSegment(
-            const std::string& name, aron::type::ObjectPtr coreSegmentType = nullptr)
+        CoreSegmentT&
+        addCoreSegment(const std::string& name,
+                       aron::type::ObjectPtr coreSegmentType = nullptr,
+                       const std::vector<PredictionEngine>& predictionEngines = {})
         {
-            return this->_derived().addCoreSegment(name, name, coreSegmentType);
+            return this->_derived().addCoreSegment(name, name, coreSegmentType, predictionEngines);
         }
 
         /// Copy and insert a core segment.
diff --git a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h
index 37f25fd8f..8ddf174b1 100644
--- a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h
+++ b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h
@@ -57,6 +57,10 @@ namespace armarx::armem::server::plugins
 
         // PredictingInterface interface
         virtual armem::prediction::data::PredictionResultSeq predict(const armem::prediction::data::PredictionRequestSeq& requests);
+
+        // Unless you need very unusual behavior from this method for your memory server,
+        // it is better to set the available prediction engines in the memory itself
+        // and let it handle the requests than to override this.
         virtual armem::prediction::data::EngineSupportMap getAvailableEngines();
 
         virtual armem::prediction::data::PredictionResultSeq predict(const armem::prediction::data::PredictionRequestSeq& requests, const ::Ice::Current&) override;
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
index 6bad86c0f..aaf23c20e 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
@@ -49,8 +49,11 @@ namespace armarx::armem::server::obj::instance
 {
 
     Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter) :
-        SpecializedCoreSegment(memoryToIceAdapter, "Instance",
-                           arondto::ObjectInstance::ToAronType(), 64)
+        SpecializedCoreSegment(memoryToIceAdapter,
+                               "Instance",
+                               arondto::ObjectInstance::ToAronType(),
+                               64,
+                               predictionEngines)
     {
         oobbCache.setFetchFn([this](const ObjectID & id) -> std::optional<simox::OrientedBoxf>
         {
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
index da1426a6f..ba7c5539d 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
@@ -194,7 +194,6 @@ namespace armarx::armem::server::obj::instance
 
         static const std::string timestampPlaceholder;
 
-
     public:
 
         struct RemoteGui
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp
index 959d3b5fa..228b96f1e 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp
@@ -68,6 +68,7 @@ namespace armarx::armem::server::obj::instance
     {
         segment.setTag(getName());
         segment.decay.setTag(getName());
+        segment.setPredictionEngines(predictionEngines);
         robotHead.setTag(getName());
         visu.setTag(getName());
 
@@ -498,7 +499,7 @@ namespace armarx::armem::server::obj::instance
                         armem::PredictionSettings::fromIce(request.settings);
 
                 if (settings.predictionEngineID.empty()
-                    or settings.predictionEngineID == "Linear Position Regression")
+                    or settings.predictionEngineID == linearPredictionEngineID)
                 {
                     result = objpose::predictObjectPoseLinear(
                         poses.at(i),
@@ -519,10 +520,7 @@ namespace armarx::armem::server::obj::instance
     armem::prediction::data::PredictionEngineSeq
     SegmentAdapter::getAvailableObjectPoseEngines(const Ice::Current&)
     {
-        armem::prediction::data::PredictionEngine engine;
-        // TODO(phesch): Make this a constant somewhere
-        engine.engineID = "Linear Position Regression";
-        return { engine };
+        return armarx::toIce<armem::prediction::data::PredictionEngineSeq>(predictionEngines);
     }
 
     void
@@ -600,7 +598,9 @@ namespace armarx::armem::server::obj::instance
             cycle.waitForCycleDuration();
         }
     }
-
+    
+    const std::string SegmentAdapter::linearPredictionEngineID = "Linear Position Regression";
+    const std::vector<PredictionEngine> SegmentAdapter::predictionEngines{{linearPredictionEngineID}};
 
     void SegmentAdapter::Calibration::defineProperties(PropertyDefinitionsPtr defs, const std::string& prefix)
     {
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h
index 69595f7b6..1000f237a 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h
@@ -127,6 +127,9 @@ namespace armarx::armem::server::obj::instance
 
         void visualizeRun();
 
+    public:
+        static const std::string linearPredictionEngineID;
+        static const std::vector<PredictionEngine> predictionEngines;
 
     private:
 
-- 
GitLab