From c22c1b2d12b42ec859b911a6acec94863a4b26e5 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Mon, 20 Nov 2023 18:50:30 +0100
Subject: [PATCH] Add convenience functions for calling sub skills

---
 .../RobotAPI/libraries/skills/core/Skill.cpp  | 33 +++++++++
 source/RobotAPI/libraries/skills/core/Skill.h | 68 +++++++++++++++++--
 2 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/source/RobotAPI/libraries/skills/core/Skill.cpp b/source/RobotAPI/libraries/skills/core/Skill.cpp
index 0b7a32df2..22e1fc21e 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.cpp
+++ b/source/RobotAPI/libraries/skills/core/Skill.cpp
@@ -37,6 +37,39 @@ namespace armarx
             return eid;
         }
 
+        std::optional<TerminatedSkillStatusUpdate>
+        Skill::callSubskillWithParameters(const SkillID& skillId,
+                                          const aron::data::DictPtr& parameters)
+        {
+            SkillProxy proxy(manager, skillId);
+            return callSubskill(proxy, parameters);
+        }
+
+        std::optional<TerminatedSkillStatusUpdate>
+        Skill::callSubskillBasedOnDefaultParameters(
+            const SkillID& skillId,
+            std::function<void(aron::data::DictPtr&)> parametersFunction)
+        {
+            SkillProxy proxy(manager, skillId);
+
+            aron::data::DictPtr parameters = proxy.getRootProfileParameters();
+            if (not parameters)
+            {
+                parameters = armarx::aron::make_dict();
+            }
+
+            parametersFunction(parameters);
+
+            return callSubskill(proxy, parameters);
+        }
+
+        std::optional<TerminatedSkillStatusUpdate>
+        Skill::callSubskillWithDefaultParameters(const SkillID& skillId)
+        {
+            auto parametersFn = [](aron::data::DictPtr&) {};
+            return callSubskillBasedOnDefaultParameters(skillId, parametersFn);
+        }
+
         void
         Skill::updateParameters(const aron::data::DictPtr& d)
         {
diff --git a/source/RobotAPI/libraries/skills/core/Skill.h b/source/RobotAPI/libraries/skills/core/Skill.h
index 5ec80e77d..dac1767a0 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.h
+++ b/source/RobotAPI/libraries/skills/core/Skill.h
@@ -1,15 +1,11 @@
 #pragma once
 
-// std/stl
 #include <functional>
 #include <mutex>
 #include <queue>
 #include <thread>
 
-// base class
 #include <ArmarXCore/core/logging/Logging.h>
-
-// ArmarX
 #include <ArmarXCore/core/time/DateTime.h>
 #include <ArmarXCore/core/time/Metronome.h>
 
@@ -194,6 +190,70 @@ namespace armarx
             skills::SkillExecutionID callSubskillAsync(const skills::SkillProxy& prx,
                                                        const aron::data::DictPtr& = nullptr);
 
+            /**
+             * @brief Call a subskill with the given ID and parameters.
+             * @param skillId The subskill's ID.
+             * @param parameters The parameters.
+             * @return The terminated skill status update.
+             */
+            std::optional<TerminatedSkillStatusUpdate>
+            callSubskillWithParameters(const SkillID& skillId,
+                                       const aron::data::DictPtr& parameters);
+
+
+            /**
+             * @brief Call a subskill with parameters based on the default parameters.
+             *
+             * Creates the skill's default parameters, and calls `parametersFunction` on them.
+             * This allows the caller to modify the parameters before executing the skill.
+             *
+             * @param skillId The subskill's ID.
+             * @param parametersFunction Function which edits the parameters.
+             * @return The terminated skill status update.
+             */
+            std::optional<TerminatedSkillStatusUpdate> callSubskillBasedOnDefaultParameters(
+                const SkillID& skillId,
+                std::function<void(aron::data::DictPtr& parameters)> parametersFunction);
+
+            /**
+             * @brief Call a subskill with its default parameters.
+             * @param skillId The subskill's ID.
+             * @return The terminated skill status update.
+             */
+            std::optional<TerminatedSkillStatusUpdate>
+            callSubskillWithDefaultParameters(const SkillID& skillId);
+
+            /**
+             * @brief Call a subskill with parameters based on the default parameters.
+             *
+             * Creates the skill's default parameters, converts them to `ParameterT`,
+             * and calls `parametersFunction` on them.
+             * This allows the caller to modify the parameters as `ParameterT` before executing
+             * the skill.
+             *
+             * @param skillId The subskill's ID.
+             * @param parametersFunction Function which edits the parameters.
+             * @return The terminated skill status update.
+             */
+            template <class ParameterT>
+            std::optional<TerminatedSkillStatusUpdate>
+            callSubskillBasedOnDefaultParameters(
+                const SkillID& skillId,
+                std::function<void(ParameterT& parameters)> parametersFunction)
+            {
+                SkillProxy proxy(manager, skillId);
+
+                ParameterT parameters;
+                if (auto parametersAron = proxy.getRootProfileParameters())
+                {
+                    parameters = ParameterT::FromAron(parametersAron);
+                }
+
+                parametersFunction(parameters);
+
+                return callSubskill(proxy, parameters.toAron());
+            }
+
         public:
             // running params
             armarx::core::time::DateTime started = armarx::core::time::DateTime::Now();
-- 
GitLab