From f927794e2843c311b2d64b1f957b26cbd700a630 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Thu, 24 Jun 2021 21:27:09 +0200
Subject: [PATCH] Add loading from scene snapshot by properties

---
 .../armem_objects/server/instance/Segment.cpp | 60 ++++++++++++++-----
 .../armem_objects/server/instance/Segment.h   |  7 ++-
 2 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
index 8d876520b..63d449148 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
@@ -79,6 +79,13 @@ namespace armarx::armem::server::obj::instance
                        "If true, no new snapshots are stored while an object is attached to a robot node.\n"
                        "If false, new snapshots are stored, but the attachment is kept in the new snapshots.");
 
+        defs->optional(p.sceneSnapshotsPackage, prefix + "scene.Package",
+                       "ArmarX package containing the scene snapshots.\n"
+                       "Scene snapshots are expected to be located in Package/data/Package/Scenes/*.json.");
+        defs->optional(p.sceneSnapshotToLoad, prefix + "scene.SnapshotToLoad",
+                       "Scene snapshot to load on startup (e.g. 'Scene_2021-06-24_20-20-03').\n"
+                       "You can also specify paths relative to 'Package/Scenes/'.");
+
         decay.defineProperties(defs, prefix + "decay.");
     }
 
@@ -89,6 +96,13 @@ namespace armarx::armem::server::obj::instance
 
         coreSegment = &iceMemory.workingMemory->addCoreSegment(p.coreSegmentName, arondto::ObjectInstance::toInitialAronType());
         coreSegment->setMaxHistorySize(p.maxHistorySize);
+
+
+        if (not p.sceneSnapshotToLoad.empty())
+        {
+            bool lockMemory = false;
+            commitSceneSnapshotFromFilename(p.sceneSnapshotToLoad, lockMemory);
+        }
     }
 
 
@@ -747,7 +761,6 @@ namespace armarx::armem::server::obj::instance
 
 
     const std::string Segment::timestampPlaceholder = "%TIMESTAMP";
-    const std::string Segment::targetPackage = "ArmarXObjects";
 
 
     std::optional<std::filesystem::path> Segment::resolveSceneFilename(const std::string& _filename)
@@ -763,16 +776,16 @@ namespace armarx::armem::server::obj::instance
 
         if (!finder)
         {
-            finder.reset(new CMakePackageFinder(targetPackage));
+            finder.reset(new CMakePackageFinder(p.sceneSnapshotsPackage));
             if (not finder->packageFound())
             {
-                ARMARX_WARNING << "Could not find CMake package " << targetPackage << ".";
+                ARMARX_WARNING << "Could not find CMake package " << p.sceneSnapshotsPackage << ".";
             }
         }
         if (finder->packageFound())
         {
             std::filesystem::path dataDir = finder->getDataDir();
-            std::filesystem::path path = dataDir / targetPackage / "Scenes" / filename;
+            std::filesystem::path path = dataDir / p.sceneSnapshotsPackage / "Scenes" / filename;
             return path;
         }
         else
@@ -847,6 +860,30 @@ namespace armarx::armem::server::obj::instance
     }
 
 
+    void Segment::commitSceneSnapshotFromFilename(const std::string& filename, bool lockMemory)
+    {
+        ARMARX_INFO << "Loading scene snapshot '" << filename << "' ...";
+        if (auto path = resolveSceneFilename(filename))
+        {
+            if (const auto snapshot = loadScene(path.value()))
+            {
+                std::filesystem::path filename = path->filename();
+                filename.replace_extension();  // Removes extension
+
+                if (lockMemory)
+                {
+                    std::scoped_lock lock(memoryMutex);
+                    commitSceneSnapshot(snapshot.value(), filename.string());
+                }
+                else
+                {
+                    commitSceneSnapshot(snapshot.value(), filename.string());
+                }
+            }
+        }
+    }
+
+
     void Segment::RemoteGui::setup(const Segment& data)
     {
         using namespace armarx::RemoteGui::Client;
@@ -860,7 +897,7 @@ namespace armarx::armem::server::obj::instance
         loadButton.setLabel("Load Scene");
         storeButton.setLabel("Store Scene");
 
-        HBoxLayout storeLoadLineLayout({Label(targetPackage + "/Scenes/"), storeLoadLine, Label(".json")});
+        HBoxLayout storeLoadLineLayout({Label(data.p.sceneSnapshotsPackage + "/Scenes/"), storeLoadLine, Label(".json")});
         HBoxLayout storeLoadButtonsLayout({loadButton, storeButton});
 
         GridLayout grid;
@@ -887,17 +924,8 @@ namespace armarx::armem::server::obj::instance
     {
         if (loadButton.wasClicked())
         {
-            if (auto path = data.resolveSceneFilename(storeLoadLine.getValue()))
-            {
-                if (const auto snapshot = data.loadScene(path.value()))
-                {
-                    std::filesystem::path filename = path->filename();
-                    filename.replace_extension();  // Removes extension
-
-                    std::scoped_lock lock(data.memoryMutex);
-                    data.commitSceneSnapshot(snapshot.value(), filename.string());
-                }
-            }
+            bool lockMemory = true;
+            data.commitSceneSnapshotFromFilename(storeLoadLine.getValue(), lockMemory);
         }
 
         if (storeButton.wasClicked())
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
index 57e918dd0..0ac63b410 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
@@ -150,6 +150,7 @@ namespace armarx::armem::server::obj::instance
 
         armem::obj::SceneSnapshot getSceneSnapshot() const;
         void commitSceneSnapshot(const armem::obj::SceneSnapshot& scene, const std::string& sceneName);
+        void commitSceneSnapshotFromFilename(const std::string& filename, bool lockMemory);
 
 
     public:
@@ -179,6 +180,10 @@ namespace armarx::armem::server::obj::instance
             // -1 would be infinite, but this can let the RAM grow quickly.
             long maxHistorySize = 25;
             bool discardSnapshotsWhileAttached = true;
+
+            /// Package containing the scene snapshots
+            std::string sceneSnapshotsPackage = "ArmarXObjects";
+            std::string sceneSnapshotToLoad = "";
         };
         Properties p;
 
@@ -192,8 +197,6 @@ namespace armarx::armem::server::obj::instance
         std::unique_ptr<CMakePackageFinder> finder;
 
         static const std::string timestampPlaceholder;
-        static const std::string targetPackage;
-
 
     public:
 
-- 
GitLab