From ebcb55409b6984272c2c9874595ea00fc792df9d Mon Sep 17 00:00:00 2001 From: phesch <ulila@student.kit.edu> Date: Mon, 23 May 2022 23:07:42 +0200 Subject: [PATCH] Add memory implementation for pred. engine support --- .../RobotAPI/libraries/armem/CMakeLists.txt | 1 + .../armem/core/base/CoreSegmentBase.h | 22 ++++-- .../libraries/armem/core/base/MemoryBase.h | 12 ++- .../armem/core/base/ProviderSegmentBase.h | 48 ++++++++++-- .../armem/core/base/detail/Predictive.h | 73 +++++++++++++++++++ .../armem/server/MemoryToIceAdapter.cpp | 32 ++++++++ .../armem/server/MemoryToIceAdapter.h | 3 + .../server/plugins/ReadWritePluginUser.cpp | 2 +- .../server/segment/SpecializedCoreSegment.cpp | 12 ++- .../server/segment/SpecializedCoreSegment.h | 6 +- .../segment/SpecializedProviderSegment.cpp | 29 ++++++-- .../segment/SpecializedProviderSegment.h | 7 +- 12 files changed, 218 insertions(+), 29 deletions(-) create mode 100644 source/RobotAPI/libraries/armem/core/base/detail/Predictive.h diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index cff3ea8a1..8dba8b8e7 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -106,6 +106,7 @@ set(LIB_HEADERS core/base/detail/iteration_mixins.h core/base/detail/lookup_mixins.h core/base/detail/negative_index_semantics.h + core/base/detail/Predictive.h core/base/CoreSegmentBase.h core/base/EntityBase.h diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h index 8f158a3fe..56526eb1c 100644 --- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h @@ -8,6 +8,7 @@ #include "detail/MemoryContainerBase.h" #include "detail/iteration_mixins.h" #include "detail/lookup_mixins.h" +#include "detail/Predictive.h" #include <ArmarXCore/core/logging/Logging.h> @@ -21,6 +22,7 @@ namespace armarx::armem::base class CoreSegmentBase : public detail::MemoryContainerBase<std::map<std::string, _ProviderSegmentT>, _Derived> , public detail::AronTyped + , public detail::Predictive<_Derived> , public detail::ForEachEntityInstanceMixin<_Derived> , public detail::ForEachEntitySnapshotMixin<_Derived> , public detail::ForEachEntityMixin<_Derived> @@ -66,17 +68,23 @@ namespace armarx::armem::base CoreSegmentBase() { } - explicit CoreSegmentBase(const std::string& name, aron::type::ObjectPtr aronType = nullptr) : - CoreSegmentBase(name, MemoryID(), aronType) + explicit CoreSegmentBase(const std::string& name, + aron::type::ObjectPtr aronType = nullptr, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + CoreSegmentBase(name, MemoryID(), aronType, predictionEngines) { } - explicit CoreSegmentBase(const std::string& name, const MemoryID& parentID, aron::type::ObjectPtr aronType = nullptr) : - CoreSegmentBase(parentID.withCoreSegmentName(name), aronType) + explicit CoreSegmentBase(const std::string& name, + const MemoryID& parentID, + aron::type::ObjectPtr aronType = nullptr, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + CoreSegmentBase(parentID.withCoreSegmentName(name), aronType, predictionEngines) { } - explicit CoreSegmentBase(const MemoryID& id, aron::type::ObjectPtr aronType = nullptr) : - Base(id), - AronTyped(aronType) + explicit CoreSegmentBase(const MemoryID& id, + aron::type::ObjectPtr aronType = nullptr, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + Base(id), AronTyped(aronType), detail::Predictive<_Derived>(predictionEngines) { } diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h index 0bb30f689..991cc609e 100644 --- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h +++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h @@ -7,6 +7,7 @@ #include "detail/MemoryContainerBase.h" #include "detail/iteration_mixins.h" #include "detail/lookup_mixins.h" +#include "detail/Predictive.h" namespace armarx::armem::base @@ -18,6 +19,7 @@ namespace armarx::armem::base template <class _CoreSegmentT, class _Derived> class MemoryBase : public detail::MemoryContainerBase<std::map<std::string, _CoreSegmentT>, _Derived> + , public detail::Predictive<_Derived> , public detail::ForEachEntityInstanceMixin<_Derived> , public detail::ForEachEntitySnapshotMixin<_Derived> , public detail::ForEachEntityMixin<_Derived> @@ -67,12 +69,14 @@ namespace armarx::armem::base MemoryBase() { } - explicit MemoryBase(const std::string& name) : - MemoryBase(MemoryID().withMemoryName(name)) + explicit MemoryBase(const std::string& name, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + MemoryBase(MemoryID().withMemoryName(name), predictionEngines) { } - explicit MemoryBase(const MemoryID& id) : - Base(id) + explicit MemoryBase(const MemoryID& id, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + Base(id), detail::Predictive<_Derived>(predictionEngines) { } diff --git a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h index 7deccd836..ffa8bbda1 100644 --- a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h @@ -3,6 +3,8 @@ #include <map> #include <string> +#include <RobotAPI/interface/armem/prediction.h> + #include "EntityBase.h" #include "detail/AronTyped.h" #include "detail/MemoryContainerBase.h" @@ -53,6 +55,9 @@ namespace armarx::armem::base {} }; + private: + + prediction::data::PredictionEngineSeq supportedEngines; public: @@ -60,17 +65,26 @@ namespace armarx::armem::base { } - explicit ProviderSegmentBase(const std::string& name, aron::type::ObjectPtr aronType = nullptr) : - ProviderSegmentBase(name, MemoryID(), aronType) + explicit ProviderSegmentBase( + const std::string& name, + aron::type::ObjectPtr aronType = nullptr, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + ProviderSegmentBase(name, MemoryID(), aronType, predictionEngines) { } - explicit ProviderSegmentBase(const std::string& name, const MemoryID parentID, aron::type::ObjectPtr aronType = nullptr) : - ProviderSegmentBase(parentID.withProviderSegmentName(name), aronType) + explicit ProviderSegmentBase( + const std::string& name, + const MemoryID parentID, + aron::type::ObjectPtr aronType = nullptr, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + ProviderSegmentBase(parentID.withProviderSegmentName(name), aronType, predictionEngines) { } - explicit ProviderSegmentBase(const MemoryID id, aron::type::ObjectPtr aronType = nullptr) : - Base(id), - AronTyped(aronType) + explicit ProviderSegmentBase( + const MemoryID id, + aron::type::ObjectPtr aronType = nullptr, + const prediction::data::PredictionEngineSeq& predictionEngines = {}) : + Base(id), AronTyped(aronType), supportedEngines(predictionEngines) { } @@ -274,6 +288,26 @@ namespace armarx::armem::base return child; } + // PREDICTION ENGINES + prediction::data::PredictionEngineSeq& + predictionEngines() + { + return supportedEngines; + } + + std::map<MemoryID, prediction::data::PredictionEngineSeq> + getAllPredictionEngines() + { + auto engines = predictionEngines(); + if (engines.empty()) + { + return {}; + } + // Type inference fails when using initializer lists here, not sure why. + std::map<MemoryID, prediction::data::PredictionEngineSeq> engineMap; + engineMap.emplace(this->id(), engines); + return engineMap; + } // MISC diff --git a/source/RobotAPI/libraries/armem/core/base/detail/Predictive.h b/source/RobotAPI/libraries/armem/core/base/detail/Predictive.h new file mode 100644 index 000000000..096ba6429 --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/base/detail/Predictive.h @@ -0,0 +1,73 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @package RobotAPI::armem::core::base::detail + * @author phesch ( phesch at student dot kit dot edu ) + * @date 2022 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <RobotAPI/interface/armem/prediction.h> +#include <RobotAPI/libraries/armem/core/MemoryID.h> + +#include "derived.h" + +namespace armarx::armem::base::detail +{ + /** + * @brief Something that supports a set of prediction engines. + */ + template <class DerivedT> + class Predictive + { + public: + explicit Predictive(const prediction::data::PredictionEngineSeq& engines = {}) : + supportedEngines(engines) + { + } + + prediction::data::PredictionEngineSeq& + predictionEngines() + { + return supportedEngines; + } + + std::map<MemoryID, prediction::data::PredictionEngineSeq> + getAllPredictionEngines() + { + std::map<MemoryID, prediction::data::PredictionEngineSeq> engines; + auto& derivedContainer = derived<DerivedT>(this); + derivedContainer.forEachChild( + [&engines](auto& child) + { + auto childMap = child.getAllPredictionEngines(); + engines.insert(childMap.begin(), childMap.end()); + }); + auto ownEngines = derivedContainer.predictionEngines(); + if (!ownEngines.empty()) + { + engines.emplace(derivedContainer.id(), derivedContainer.predictionEngines()); + } + + return engines; + } + + protected: + prediction::data::PredictionEngineSeq supportedEngines; + }; +} // namespace armarx::armem::base::detail diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp index a838e9e0f..930c1c15d 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp @@ -360,4 +360,36 @@ namespace armarx::armem::server return output; } + // PREDICTION + prediction::data::EngineSupportMap MemoryToIceAdapter::getAvailableEngines() + { + prediction::data::EngineSupportMap result; + auto wmMap = workingMemory->getAllPredictionEngines(); + for (const auto& [memoryID, engines] : wmMap) + { + result.emplace(armarx::toIce<data::MemoryID>(memoryID), engines); + } + + auto ltmMap = workingMemory->getAllPredictionEngines(); + for (const auto& [memoryID, engines] : ltmMap) + { + auto dtoID = armarx::toIce<data::MemoryID>(memoryID); + auto entryIter = result.find(dtoID); + if (entryIter == result.end()) + { + result.emplace(armarx::toIce<data::MemoryID>(memoryID), engines); + } + else + { + // Merge LTM-supported engines with WM-supported engines, removing duplicates + std::set<prediction::data::PredictionEngine> engineSet; + engineSet.insert(entryIter->second.begin(), entryIter->second.end()); + engineSet.insert(engines.begin(), engines.end()); + entryIter->second.assign(engineSet.begin(), engineSet.end()); + } + } + + return result; + } + } diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h index 33e788ff5..96c1e822d 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h @@ -52,6 +52,9 @@ namespace armarx::armem::server // LTM STORING data::StoreResult store(const armem::data::StoreInput& input); + // PREDICTION + prediction::data::EngineSupportMap getAvailableEngines(); + public: server::wm::Memory* workingMemory; diff --git a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp index f690cbaee..53027b903 100644 --- a/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp +++ b/source/RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.cpp @@ -137,7 +137,7 @@ namespace armarx::armem::server::plugins armem::prediction::data::EngineSupportMap ReadWritePluginUser::getAvailableEngines() { - return {}; + return iceAdapter().getAvailableEngines(); } armem::prediction::data::PredictionResultSeq diff --git a/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.cpp b/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.cpp index b0afa2826..e33009bbb 100644 --- a/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.cpp +++ b/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.cpp @@ -14,9 +14,11 @@ namespace armarx::armem::server::segment armem::server::MemoryToIceAdapter& iceMemory, const std::string& defaultCoreSegmentName, aron::type::ObjectPtr coreSegmentAronType, - int defaultMaxHistorySize) : + int defaultMaxHistorySize, + const prediction::data::PredictionEngineSeq& predictionEngines) : Base(iceMemory), aronType(coreSegmentAronType), + predictionEngines(predictionEngines), properties({defaultCoreSegmentName, defaultMaxHistorySize}) { Logging::setTag("armarx::armem::SpecializedCoreSegment"); @@ -60,6 +62,7 @@ namespace armarx::armem::server::segment segmentPtr->aronType() = aronType; segmentPtr->setMaxHistorySize(properties.maxHistorySize); + segmentPtr->predictionEngines() = predictionEngines; } } @@ -80,6 +83,13 @@ namespace armarx::armem::server::segment this->aronType = aronType; } + void + SpecializedCoreSegment::setPredictionEngines( + const prediction::data::PredictionEngineSeq& predictionEngines) + { + this->predictionEngines = predictionEngines; + } + wm::CoreSegment& SpecializedCoreSegment::getCoreSegment() { ARMARX_CHECK_NOT_NULL(segmentPtr); diff --git a/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.h b/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.h index d94fa1aed..059d9c7bc 100644 --- a/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.h +++ b/source/RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.h @@ -27,7 +27,8 @@ namespace armarx::armem::server::segment MemoryToIceAdapter& iceMemory, const std::string& defaultCoreSegmentName = "", aron::type::ObjectPtr coreSegmentAronType = nullptr, - int defaultMaxHistorySize = -1); + int defaultMaxHistorySize = -1, + const prediction::data::PredictionEngineSeq& predictionEngines = {}); virtual ~SpecializedCoreSegment() override; @@ -43,6 +44,8 @@ namespace armarx::armem::server::segment void setDefaultCoreSegmentName(const std::string& coreSegmentName); void setDefaultMaxHistorySize(int64_t maxHistorySize); void setAronType(aron::type::ObjectPtr aronType); + void + setPredictionEngines(const prediction::data::PredictionEngineSeq& predictionEngines); wm::CoreSegment& getCoreSegment(); const wm::CoreSegment& getCoreSegment() const; @@ -51,6 +54,7 @@ namespace armarx::armem::server::segment public: aron::type::ObjectPtr aronType; + prediction::data::PredictionEngineSeq predictionEngines; struct Properties { diff --git a/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.cpp b/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.cpp index 747b2bec8..541f5ce07 100644 --- a/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.cpp +++ b/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.cpp @@ -10,15 +10,22 @@ namespace armarx::armem::server::segment { SpecializedProviderSegment::SpecializedProviderSegment( - armem::server::MemoryToIceAdapter& iceMemory, - const std::string& defaultProviderSegmentName, - const std::string& defaultCoreSegmentName, - aron::type::ObjectPtr providerSegmentAronType, - aron::type::ObjectPtr coreSegmentAronType, - int defaultMaxHistorySize) : + armem::server::MemoryToIceAdapter& iceMemory, + const std::string& defaultProviderSegmentName, + const std::string& defaultCoreSegmentName, + aron::type::ObjectPtr providerSegmentAronType, + aron::type::ObjectPtr coreSegmentAronType, + int defaultMaxHistorySize, + const prediction::data::PredictionEngineSeq& providerSegmentPredictionEngines, + const prediction::data::PredictionEngineSeq& coreSegmentPredictionEngines) : Base(iceMemory), aronType(providerSegmentAronType), - coreSegment(iceMemory, defaultCoreSegmentName, coreSegmentAronType), + predictionEngines(providerSegmentPredictionEngines), + coreSegment(iceMemory, + defaultCoreSegmentName, + coreSegmentAronType, + -1, + providerSegmentPredictionEngines), properties({defaultProviderSegmentName, defaultMaxHistorySize}) { Logging::setTag("armarx::armem::SpecializedProviderSegment"); @@ -65,6 +72,7 @@ namespace armarx::armem::server::segment segmentPtr->aronType() = aronType; segmentPtr->setMaxHistorySize(properties.maxHistorySize); + segmentPtr->predictionEngines() = predictionEngines; } } @@ -85,6 +93,13 @@ namespace armarx::armem::server::segment this->aronType = aronType; } + void + SpecializedProviderSegment::setPredictionEngines( + const prediction::data::PredictionEngineSeq& predictionEngines) + { + this->predictionEngines = predictionEngines; + } + wm::ProviderSegment& SpecializedProviderSegment::getProviderSegment() { ARMARX_CHECK_NOT_NULL(segmentPtr); diff --git a/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.h b/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.h index 44db000d1..f8ffa13c0 100644 --- a/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.h +++ b/source/RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.h @@ -29,7 +29,9 @@ namespace armarx::armem::server::segment const std::string& defaultCoreSegmentName = "", aron::type::ObjectPtr providerSegmentAronType = nullptr, aron::type::ObjectPtr coreSegmentAronType = nullptr, - int defaultMaxHistorySize = -1); + int defaultMaxHistorySize = -1, + const prediction::data::PredictionEngineSeq& providerSegmentPredictionEngines = {}, + const prediction::data::PredictionEngineSeq& coreSegmentPredictionEngines = {}); virtual ~SpecializedProviderSegment() override; @@ -39,6 +41,8 @@ namespace armarx::armem::server::segment void setDefaultProviderSegmentName(const std::string& providerSegmentName); void setDefaultMaxHistorySize(int64_t maxHistorySize); void setAronType(aron::type::ObjectPtr aronType); + void + setPredictionEngines(const prediction::data::PredictionEngineSeq& predictionEngines); wm::ProviderSegment& getProviderSegment(); const wm::ProviderSegment& getProviderSegment() const; @@ -47,6 +51,7 @@ namespace armarx::armem::server::segment public: aron::type::ObjectPtr aronType; + prediction::data::PredictionEngineSeq predictionEngines; SpecializedCoreSegment coreSegment; struct Properties -- GitLab