diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp index 098fe6f1d3de321048b9a942b7ce0c7cca2814fe..6c86b6afa76fe043b4dea16affb609f7db049caf 100644 --- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp +++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp @@ -30,6 +30,7 @@ #include <RobotAPI/libraries/armem/core/error.h> #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h> #include <RobotAPI/libraries/armem_skills/aron_conversions.h> @@ -70,7 +71,7 @@ namespace armarx workingMemory.name() = p.memoryName; { - armarx::armem::wm::CoreSegment& c = workingMemory.addCoreSegment(p.statechartCoreSegmentName, armarx::armem::arondto::Statechart::Transition::toAronType()); + armarx::armem::server::wm::CoreSegment& c = workingMemory.addCoreSegment(p.statechartCoreSegmentName, armarx::armem::arondto::Statechart::Transition::toAronType()); c.addProviderSegment("Transitions", armarx::armem::arondto::Statechart::Transition::toAronType()); } } diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index e63616934d2e5e5f40ed4a3d864bd87131cfd070..2998875d1623e13bcf44f16187a969e224152589 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -33,7 +33,6 @@ set(LIB_FILES core/json_conversions.cpp core/base/detail/MemoryItem.cpp - core/base/detail/MaxHistorySize.cpp core/base/detail/MemoryContainerBase.cpp core/base/detail/EntityContainerBase.cpp core/base/detail/AronTyped.cpp @@ -46,10 +45,10 @@ set(LIB_FILES core/base/EntitySnapshotBase.cpp # core/base/MemoryBase.cpp # core/base/ProviderSegmentBase.cpp + core/base/ice_conversions.cpp core/wm/memory_definitions.cpp core/wm/ice_conversions.cpp - core/wm/ice_conversions.cpp core/wm/aron_conversions.cpp core/wm/visitor/Visitor.cpp core/wm/visitor/FunctionalVisitor.cpp @@ -84,6 +83,10 @@ set(LIB_FILES server/MemoryRemoteGui.cpp server/RemoteGuiAronDataVisitor.cpp + server/wm/memory_definitions.cpp + server/wm/ice_conversions.cpp + server/wm/detail/MaxHistorySize.cpp + server/segment/Segment.cpp server/segment/SpecializedSegment.cpp @@ -93,23 +96,9 @@ set(LIB_FILES server/query_proc/base/CoreSegmentQueryProcessorBase.cpp server/query_proc/base/MemoryQueryProcessorBase.cpp - server/query_proc/workingmemory/BaseQueryProcessor.cpp - server/query_proc/workingmemory/EntityQueryProcessor.cpp - server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp - server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp - server/query_proc/workingmemory/MemoryQueryProcessor.cpp - - server/query_proc/longtermmemory/BaseQueryProcessor.cpp - server/query_proc/longtermmemory/EntityQueryProcessor.cpp - server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp - server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp - server/query_proc/longtermmemory/MemoryQueryProcessor.cpp - - server/query_proc/diskmemory/BaseQueryProcessor.cpp - server/query_proc/diskmemory/EntityQueryProcessor.cpp - server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp - server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp - server/query_proc/diskmemory/MemoryQueryProcessor.cpp + server/query_proc/diskmemory.cpp + server/query_proc/ltm.cpp + server/query_proc/wm.cpp mns/MemoryNameSystem.cpp mns/ComponentPlugin.cpp @@ -119,6 +108,8 @@ set(LIB_FILES set(LIB_HEADERS core.h + core/forward_declarations.h + core/Commit.h core/DataMode.h core/MemoryID.h @@ -137,7 +128,6 @@ set(LIB_HEADERS core/error/mns.h core/base/detail/MemoryItem.h - core/base/detail/MaxHistorySize.h core/base/detail/MemoryContainerBase.h core/base/detail/EntityContainerBase.h core/base/detail/AronTyped.h @@ -150,6 +140,7 @@ set(LIB_HEADERS core/base/EntitySnapshotBase.h core/base/MemoryBase.h core/base/ProviderSegmentBase.h + core/base/ice_conversions.h core/wm.h core/wm/memory_definitions.h @@ -164,9 +155,6 @@ set(LIB_HEADERS core/ltm/mongodb/MemoryManager.h core/ltm/mongodb/ConnectionManager.h - core/ice_conversions_templates.h - core/ice_conversions.h - client.h client/ComponentPlugin.h client/MemoryNameSystem.h @@ -189,45 +177,38 @@ set(LIB_HEADERS client/util/SimpleWriterBase.h server.h + server/forward_declarations.h + server/ComponentPlugin.h server/MemoryToIceAdapter.h server/MemoryRemoteGui.h server/RemoteGuiAronDataVisitor.h + server/wm/memory_definitions.h + server/wm/ice_conversions.h + server/wm/detail/MaxHistorySize.h + server/segment/Segment.h server/segment/SpecializedSegment.h server/query_proc.h + + server/query_proc/base.h server/query_proc/base/BaseQueryProcessorBase.h server/query_proc/base/EntityQueryProcessorBase.h server/query_proc/base/ProviderSegmentQueryProcessorBase.h server/query_proc/base/CoreSegmentQueryProcessorBase.h server/query_proc/base/MemoryQueryProcessorBase.h - server/query_proc/workingmemory/BaseQueryProcessor.h - server/query_proc/workingmemory/EntityQueryProcessor.h - server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h - server/query_proc/workingmemory/CoreSegmentQueryProcessor.h - server/query_proc/workingmemory/MemoryQueryProcessor.h - - server/query_proc/longtermmemory/BaseQueryProcessor.h - server/query_proc/longtermmemory/EntityQueryProcessor.h - server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h - server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h - server/query_proc/longtermmemory/MemoryQueryProcessor.h - - server/query_proc/diskmemory/BaseQueryProcessor.h - server/query_proc/diskmemory/EntityQueryProcessor.h - server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h - server/query_proc/diskmemory/CoreSegmentQueryProcessor.h - server/query_proc/diskmemory/MemoryQueryProcessor.h + server/query_proc/diskmemory.h + server/query_proc/ltm.h + server/query_proc/wm.h mns.h mns/MemoryNameSystem.h mns/ComponentPlugin.h util/util.h - ) armarx_add_library( diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h index 03e3835fad49a951ded49f990358ff3b87c06ce4..0de79cccd0af6a85dd396b8891e91c572ee24fb2 100644 --- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h @@ -6,7 +6,6 @@ #include "ProviderSegmentBase.h" #include "detail/AronTyped.h" #include "detail/EntityContainerBase.h" -#include "detail/MaxHistorySize.h" #include "detail/iteration_mixins.h" @@ -19,7 +18,6 @@ namespace armarx::armem::base template <class _ProviderSegmentT, class _Derived> class CoreSegmentBase : public detail::EntityContainerBase<_ProviderSegmentT, typename _ProviderSegmentT::EntityT, _Derived>, - public detail::MaxHistorySize, public detail::AronTyped, public detail::ForEachEntityInstanceMixin<_Derived>, public detail::ForEachEntitySnapshotMixin<_Derived>, @@ -97,6 +95,11 @@ namespace armarx::armem::base return this->_container.count(name) > 0; } + std::vector<std::string> getProviderSegmentNames() const + { + return simox::alg::get_keys(this->_container); + } + ProviderSegmentT& getProviderSegment(const std::string& name) { return const_cast<ProviderSegmentT&>(const_cast<const CoreSegmentBase*>(this)->getProviderSegment(name)); @@ -276,27 +279,10 @@ namespace armarx::armem::base auto it = this->_container.emplace(providerSegment.name(), std::move(providerSegment)).first; it->second.id().setCoreSegmentID(this->id()); - it->second.setMaxHistorySize(_maxHistorySize); return it->second; } - /** - * @brief Sets the maximum history size of entities in this segment. - * This affects all current entities as well as new ones. - * @see Entity::setMaxHistorySize() - */ - void setMaxHistorySize(long maxSize) - { - MaxHistorySize::setMaxHistorySize(maxSize); - this->forEachChild([maxSize](auto & child) - { - child.setMaxHistorySize(maxSize); - return true; - }); - } - - // MISC bool equalsDeep(const DerivedT& other) const diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp b/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp index 36fe5f8a87877f0f75fffcb387368ca9aeac7486..d3038a357bdad823f04e8d154a569a7eebaf90d5 100644 --- a/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp +++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp @@ -1,9 +1,2 @@ #include "EntityBase.h" -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> - - -void armarx::armem::base::detail::checkLessEqual(size_t historySize, size_t maxHistorySize) -{ - ARMARX_CHECK_LESS_EQUAL(historySize, maxHistorySize); -} diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.h b/source/RobotAPI/libraries/armem/core/base/EntityBase.h index 1a02d65c7f5e79c26cb087fcf70c26387863f312..05cbf780d1e95611d629d320581122b59c5f358c 100644 --- a/source/RobotAPI/libraries/armem/core/base/EntityBase.h +++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.h @@ -9,16 +9,11 @@ #include <RobotAPI/libraries/armem/core/Time.h> #include "EntitySnapshotBase.h" -#include "detail/MaxHistorySize.h" #include "detail/MemoryContainerBase.h" #include "detail/iteration_mixins.h" #include "detail/negative_index_semantics.h" -namespace armarx::armem::base::detail -{ - void checkLessEqual(size_t historySize, size_t maxHistorySize); -} namespace armarx::armem::base { @@ -44,7 +39,6 @@ namespace armarx::armem::base template <class _EntitySnapshotT, class _Derived> class EntityBase : public detail::MemoryContainerBase<std::map<Time, _EntitySnapshotT>, _Derived>, - public detail::MaxHistorySize, public detail::ForEachEntityInstanceMixin<_Derived> { using Base = detail::MemoryContainerBase<std::map<Time, _EntitySnapshotT>, _Derived>; @@ -312,7 +306,7 @@ namespace armarx::armem::base { break; } - if (not func(snapshot)) + if (not call(func, snapshot)) { break; } @@ -347,7 +341,10 @@ namespace armarx::armem::base for (auto it = begin; it != end && it != this->_container.end(); ++it) { - func(it->second); + if (not call(func, it->second)) + { + break; + } } } @@ -380,7 +377,10 @@ namespace armarx::armem::base size_t num = last_ - first_ + 1; // +1 to make last inclusive for (size_t i = 0; i < num; ++i, ++it) { - func(it->second); + if (not call(func, it->second)) + { + break; + } } } } @@ -417,7 +417,7 @@ namespace armarx::armem::base { // Insert into history. snapshot = &addSnapshot(update.timeCreated); - ret.removedSnapshots = truncate(); + // ret.removedSnapshots = this->truncate(); ret.entityUpdateType = UpdateType::InsertedNew; } else @@ -475,17 +475,6 @@ namespace armarx::armem::base } - /** - * @brief Sets the maximum history size. - * - * The current history is truncated if necessary. - */ - void setMaxHistorySize(long maxSize) - { - MaxHistorySize::setMaxHistorySize(maxSize); - truncate(); - } - // MISC @@ -522,22 +511,6 @@ namespace armarx::armem::base protected: - /// If maximum size is set, ensure `history`'s is not higher. - std::vector<EntitySnapshotT> truncate() - { - std::vector<EntitySnapshotT> removedElements; - if (_maxHistorySize >= 0) - { - while (this->_container.size() > size_t(_maxHistorySize)) - { - removedElements.push_back(std::move(this->_container.begin()->second)); - this->_container.erase(this->_container.begin()); - } - detail::checkLessEqual(this->_container.size(), _maxHistorySize); - } - return removedElements; - } - /** * @brief Return the snapshot with the most recent timestamp. * @return The latest snapshot. diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h index a02beda13e3859386a9eed7c3722c987386cd7e7..80b57801d0031c3b66a7e6b72573290ed8c05a5a 100644 --- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h +++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h @@ -94,6 +94,11 @@ namespace armarx::armem::base return this->_container.count(name) > 0; } + std::vector<std::string> getCoreSegmentNames() const + { + return simox::alg::get_keys(this->_container); + } + CoreSegmentT& getCoreSegment(const std::string& name) { return const_cast<CoreSegmentT&>(const_cast<const MemoryBase*>(this)->getCoreSegment(name)); @@ -210,26 +215,20 @@ namespace armarx::armem::base * @param coreSegmentType The core segment type (optional). * @return The added core segment. */ - CoreSegmentT& addCoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType = nullptr) + CoreSegmentT& addCoreSegment( + const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType = nullptr) { - return addCoreSegment(CoreSegmentT(name, this->id(), coreSegmentType)); + return _addCoreSegment(name, name, this->id(), coreSegmentType); } /// Copy and insert a core segment. CoreSegmentT& addCoreSegment(const CoreSegmentT& coreSegment) { - return addCoreSegment(CoreSegmentT(coreSegment)); + return _addCoreSegment(coreSegment.name(), CoreSegmentT(coreSegment)); } /// Move and insert a core segment. CoreSegmentT& addCoreSegment(CoreSegmentT&& coreSegment) { - if (this->_container.count(coreSegment.name()) > 0) - { - throw armem::error::ContainerEntryAlreadyExists(CoreSegmentT::getLevelName(), coreSegment.name(), - this->getLevelName(), this->name()); - } - auto it = this->_container.emplace(coreSegment.name(), std::move(coreSegment)).first; - it->second.id().setMemoryID(this->id()); - return it->second; + return _addCoreSegment(coreSegment.name(), coreSegment); } /** @@ -393,6 +392,32 @@ namespace armarx::armem::base } + private: + + /** + * This function allows to emplace a CoreSegment directly in the + * container from its constructor arguments, instead of constructing + * it outside and moving it. + * This is necessary if CoreSegmentT is not movable. + */ + template <class ...Args> + CoreSegmentT& _addCoreSegment(const std::string& name, Args... args) + { + auto [it, existed] = this->_container.try_emplace(name, args...); + if (existed) + { + throw armem::error::ContainerEntryAlreadyExists( + CoreSegmentT::getLevelName(), name, DerivedT::getLevelName(), this->name()); + } + else + { + it->second.id().setMemoryID(this->id()); + it->second.id().coreSegmentName = name; + return it->second; + } + } + + public: bool _addMissingCoreSegmentDuringUpdate = false; diff --git a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h index 0c54ae2b202cf485bcb0cdf52ac53622475c917b..e5163241738a0e8dbba5edbd35f8e5a568060746 100644 --- a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h @@ -6,7 +6,6 @@ #include "EntityBase.h" #include "detail/AronTyped.h" #include "detail/EntityContainerBase.h" -#include "detail/MaxHistorySize.h" #include "detail/iteration_mixins.h" @@ -19,7 +18,6 @@ namespace armarx::armem::base template <class _EntityT, class _Derived> class ProviderSegmentBase : public detail::EntityContainerBase<_EntityT, _EntityT, _Derived>, - public detail::MaxHistorySize, public detail::AronTyped, public detail::ForEachEntityInstanceMixin<_Derived>, public detail::ForEachEntitySnapshotMixin<_Derived> @@ -93,6 +91,11 @@ namespace armarx::armem::base return this->_container.count(name) > 0; } + std::vector<std::string> getEntityNames() const + { + return simox::alg::get_keys(this->_container); + } + using Base::getEntity; const EntityT& getEntity(const MemoryID& id) const { @@ -189,7 +192,6 @@ namespace armarx::armem::base { // Add entity entry. entity = &addEntity(update.entityID.entityName); - entity->setMaxHistorySize(_maxHistorySize); updateType = UpdateType::InsertedNew; } else @@ -238,22 +240,6 @@ namespace armarx::armem::base } - /** - * @brief Sets the maximum history size of container in this segment. - * This affects all current container as well as new ones. - * @see Entity::setMaxHistorySize() - */ - void setMaxHistorySize(long maxSize) - { - MaxHistorySize::setMaxHistorySize(maxSize); - this->forEachChild([maxSize](auto & child) - { - child.setMaxHistorySize(maxSize); - return true; - }); - } - - // MISC bool equalsDeep(const DerivedT& other) const diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h b/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h deleted file mode 100644 index c46fde11fb83d4580863aaf70aaafab4ba7f60e6..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - - - -namespace armarx::armem::base::detail -{ - // TODO: Replace by ConstrainedHistorySize (not only max entries, e.g. delete oldest / delete least accessed / ...) - class MaxHistorySize - { - public: - - /** - * @brief Sets the maximum history size of entities in this segment. - * This affects all current entities as well as new ones. - * @see Entity::setMaxHistorySize() - */ - void setMaxHistorySize(long maxSize); - long getMaxHistorySize() const; - - - protected: - - /** - * @brief Maximum size of entity histories. - * - * If negative, the size of `history` is not limited. - * - * @see Entity::maxHstorySize - */ - long _maxHistorySize = -1; - - }; -} diff --git a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h index a53e661a83610f1fcc0e8edabe12e9f8cd6c5c83..c923a857e1d016b06b313f7e860ab57ec438a9d4 100644 --- a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h +++ b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h @@ -8,6 +8,25 @@ namespace armarx::armem::base::detail // Helper functions to implement the forEach*() method at the current level. + // Handle functions with different return type. + template <class FunctionT, class ChildT> + bool call(FunctionT&& func, ChildT&& child) + { + if constexpr(std::is_same_v<decltype(func(child)), bool>) + { + if (!func(child)) + { + return false; + } + return true; + } + else + { + func(child); + return true; + } + } + // Single-valued containers. template <class ContainerT, class FunctionT> @@ -15,16 +34,9 @@ namespace armarx::armem::base::detail { for (auto& child : container) { - if constexpr(std::is_same_v<decltype(func(child)), bool>) + if (not call(func, child)) { - if (!func(child)) - { - return false; - } - } - else - { - func(child); + return false; } } return true; @@ -37,16 +49,9 @@ namespace armarx::armem::base::detail { for (auto& [_, child] : container) { - if constexpr(std::is_same_v<decltype(func(child)), bool>) - { - if (!func(child)) - { - return false; - } - } - else + if (not call(func, child)) { - func(child); + return false; } } return true; diff --git a/source/RobotAPI/libraries/armem/core/base/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/base/ice_conversions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..48c084154c41b26b174504d2565fe57d3a49d55a --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/base/ice_conversions.cpp @@ -0,0 +1,78 @@ +#include "ice_conversions.h" + +#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h> +#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h> + +#include <RobotAPI/libraries/armem/core/ice_conversions.h> +#include <RobotAPI/libraries/armem/core/ice_conversions_templates.h> + + +namespace armarx::armem::base +{ + + void detail::toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item) + { + toIce(ice.id, item.id()); + } + void detail::fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item) + { + fromIce(ice.id, item.id()); + } + + + void detail::toIce(aron::data::AronDictPtr& ice, const aron::datanavigator::DictNavigatorPtr& data) + { + ice = data ? data->toAronDictPtr() : nullptr; + } + void detail::fromIce(const aron::data::AronDictPtr& ice, aron::datanavigator::DictNavigatorPtr& data) + { + if (ice) + { + data = aron::datanavigator::DictNavigator::FromAronDictPtr(ice); + } + else + { + data = nullptr; + }; + } + + void detail::toIce(aron::type::AronTypePtr& ice, const aron::typenavigator::ObjectNavigatorPtr& bo) + { + ice = bo ? bo->toAronPtr() : nullptr; + } + void detail::fromIce(const aron::type::AronTypePtr& ice, aron::typenavigator::ObjectNavigatorPtr& bo) + { + bo = ice + ? aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice)) + : nullptr; + } + +} +namespace armarx::armem +{ + void base::toIce(data::EntityInstanceMetadata& ice, const EntityInstanceMetadata& metadata) + { + ice.confidence = metadata.confidence; + toIce(ice.timeArrivedMicroSeconds, metadata.timeArrived); + toIce(ice.timeCreatedMicroSeconds, metadata.timeCreated); + toIce(ice.timeSentMicroSeconds, metadata.timeSent); + } + void base::fromIce(const data::EntityInstanceMetadata& ice, EntityInstanceMetadata& metadata) + { + metadata.confidence = ice.confidence; + fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived); + fromIce(ice.timeCreatedMicroSeconds, metadata.timeCreated); + fromIce(ice.timeSentMicroSeconds, metadata.timeSent); + } + + + void base::toIce(data::EntityInstanceMetadataPtr& ice, const EntityInstanceMetadata& metadata) + { + armem::toIce<data::EntityInstanceMetadata>(ice, metadata); + } + void base::fromIce(const data::EntityInstanceMetadataPtr& ice, EntityInstanceMetadata& metadata) + { + armem::fromIce<data::EntityInstanceMetadata>(ice, metadata); + } + +} diff --git a/source/RobotAPI/libraries/armem/core/base/ice_conversions.h b/source/RobotAPI/libraries/armem/core/base/ice_conversions.h new file mode 100644 index 0000000000000000000000000000000000000000..646754cc4cbfc3d61c0ce0b1e19c333ee2d7f92b --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/base/ice_conversions.h @@ -0,0 +1,195 @@ +#pragma once + +#include "EntityInstanceBase.h" +#include "EntitySnapshotBase.h" +#include "EntityBase.h" +#include "ProviderSegmentBase.h" +#include "CoreSegmentBase.h" +#include "MemoryBase.h" + +#include <RobotAPI/libraries/armem/core/ice_conversions_templates.h> +#include <RobotAPI/libraries/armem/core/ice_conversions.h> + +#include <RobotAPI/libraries/aron/core/navigator/type/forward_declarations.h> + +#include <RobotAPI/interface/armem/memory.h> + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx::armem::base::detail +{ + void toIceItem(data::detail::MemoryItem& ice, const MemoryItem& item); + void fromIceItem(const data::detail::MemoryItem& ice, MemoryItem& item); + + void toIce(aron::data::AronDictPtr& ice, const aron::datanavigator::DictNavigatorPtr& bo); + void fromIce(const aron::data::AronDictPtr& ice, aron::datanavigator::DictNavigatorPtr& bo); + + void toIce(aron::type::AronTypePtr& ice, const aron::typenavigator::ObjectNavigatorPtr& bo); + void fromIce(const aron::type::AronTypePtr& ice, aron::typenavigator::ObjectNavigatorPtr& bo); +} +namespace armarx::armem::base +{ + void toIce(data::EntityInstanceMetadata& ice, const EntityInstanceMetadata& metadata); + void fromIce(const data::EntityInstanceMetadata& ice, EntityInstanceMetadata& metadata); + + void toIce(data::EntityInstanceMetadataPtr& ice, const EntityInstanceMetadata& metadata); + void fromIce(const data::EntityInstanceMetadataPtr& ice, EntityInstanceMetadata& metadata); + + + template <class ...Args> + void toIce(data::EntityInstance& ice, const EntityInstanceBase<Args...>& data) + { + detail::toIceItem(ice, data); + + // detail::toIce(std::ref(ice.data).get(), data.data()); + detail::toIce(ice.data, data.data()); + toIce(ice.metadata, data.metadata()); + } + template <class ...Args> + void fromIce(const data::EntityInstance& ice, EntityInstanceBase<Args...>& data) + { + detail::fromIceItem(ice, data); + + detail::fromIce(ice.data, data.data()); + fromIce(ice.metadata, data.metadata()); + } + + template <class ...Args> + void toIce(data::EntitySnapshot& ice, const EntitySnapshotBase<Args...>& snapshot) + { + detail::toIceItem(ice, snapshot); + + ice.instances.clear(); + snapshot.forEachInstance([&ice](const auto & instance) + { + armem::toIce(ice.instances.emplace_back(), instance); + }); + } + template <class ...Args> + void fromIce(const data::EntitySnapshot& ice, EntitySnapshotBase<Args...>& snapshot) + { + detail::fromIceItem(ice, snapshot); + + snapshot.clear(); + for (const data::EntityInstancePtr& iceInstance : ice.instances) + { + snapshot.addInstance(armem::fromIce<typename EntitySnapshotBase<Args...>::EntityInstanceT>(iceInstance)); + } + } + + template <class ...Args> + void toIce(data::Entity& ice, const EntityBase<Args...>& entity) + { + detail::toIceItem(ice, entity); + + ice.history.clear(); + entity.forEachSnapshot([&ice](const auto & snapshot) + { + armem::toIce(ice.history[armem::toIce<long>(snapshot.time())], snapshot); + }); + } + template <class ...Args> + void fromIce(const data::Entity& ice, EntityBase<Args...>& entity) + { + detail::fromIceItem(ice, entity); + + entity.clear(); + for (const auto& [key, snapshot] : ice.history) + { + entity.addSnapshot(armem::fromIce<typename EntityBase<Args...>::EntitySnapshotT>(snapshot)); + } + } + + + template <class ...Args> + void toIce(data::ProviderSegment& ice, const ProviderSegmentBase<Args...>& providerSegment) + { + detail::toIceItem(ice, providerSegment); + + detail::toIce(ice.aronType, providerSegment.aronType()); + ARMARX_CHECK(!providerSegment.aronType() || ice.aronType); + + // toIce(ice.entities, providerSegment.entities()); + ice.entities.clear(); + providerSegment.forEachEntity([&ice](const auto & entity) + { + armem::toIce(ice.entities[entity.name()], entity); + }); + } + template <class ...Args> + void fromIce(const data::ProviderSegment& ice, ProviderSegmentBase<Args...>& providerSegment) + { + detail::fromIceItem(ice, providerSegment); + + detail::fromIce(ice.aronType, providerSegment.aronType()); + ARMARX_CHECK(!providerSegment.aronType() || ice.aronType); + + // fromIce(ice.entities, providerSegment.entities()); + providerSegment.clear(); + for (const auto& [key, entity] : ice.entities) + { + providerSegment.addEntity( + armem::fromIce<typename ProviderSegmentBase<Args...>::EntityT>(entity)); + } + } + + template <class ...Args> + void toIce(data::CoreSegment& ice, const CoreSegmentBase<Args...>& coreSegment) + { + detail::toIceItem(ice, coreSegment); + + detail::toIce(ice.aronType, coreSegment.aronType()); + ARMARX_CHECK(!coreSegment.aronType() || ice.aronType); + + // toIce(ice.providerSegments, coreSegment.providerSegments()); + ice.providerSegments.clear(); + coreSegment.forEachProviderSegment([&ice](const auto & providerSegment) + { + armem::toIce(ice.providerSegments[providerSegment.name()], providerSegment); + return true; + }); + } + template <class ...Args> + void fromIce(const data::CoreSegment& ice, CoreSegmentBase<Args...>& coreSegment) + { + detail::fromIceItem(ice, coreSegment); + + detail::fromIce(ice.aronType, coreSegment.aronType()); + ARMARX_CHECK(!coreSegment.aronType() || ice.aronType); + + // fromIce(ice.providerSegments, coreSegment.providerSegments()); + coreSegment.clear(); + for (const auto& [key, providerSegment] : ice.providerSegments) + { + coreSegment.addProviderSegment( + armem::fromIce<typename CoreSegmentBase<Args...>::ProviderSegmentT>(providerSegment)); + } + } + + template <class ...Args> + void toIce(data::Memory& ice, const MemoryBase<Args...>& memory) + { + base::detail::toIceItem(ice, memory); + + ice.coreSegments.clear(); + memory.forEachCoreSegment([&ice](const auto & coreSegment) + { + armem::toIce(ice.coreSegments[coreSegment.name()], coreSegment); + return true; + }); + } + template <class ...Args> + void fromIce(const data::Memory& ice, MemoryBase<Args...>& memory) + { + base::detail::fromIceItem(ice, memory); + + memory.clear(); + for (const auto& [key, coreSegment] : ice.coreSegments) + { + // We can avoid using CoreSegment's copy constructor this way: + armem::fromIce(coreSegment, memory.addCoreSegment(coreSegment->id.coreSegmentName)); + } + } + +} diff --git a/source/RobotAPI/libraries/armem/core/forward_declarations.h b/source/RobotAPI/libraries/armem/core/forward_declarations.h new file mode 100644 index 0000000000000000000000000000000000000000..761a8513111d55de8b81ade1af62a60ee18f1f3c --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/forward_declarations.h @@ -0,0 +1,52 @@ +#pragma once + + +namespace armarx::armem +{ + // class Time; // Cannot be forward declared (it's a typedef) + + class MemoryID; + class Commit; + class EntityUpdate; + class CommitResult; + class EntityUpdateResult; +} + +namespace armarx::armem::base +{ + struct NoData; + struct EntityInstanceMetadata; + + template <class _DataT, class _MetadataT> + class EntityInstanceBase; + template <class _EntityInstanceT, class _Derived> + class EntitySnapshotBase; + template <class _EntitySnapshotT, class _Derived> + class EntityBase; + template <class _EntityT, class _Derived> + class ProviderSegmentBase; + template <class _ProviderSegmentT, class _Derived> + class CoreSegmentBase; + template <class _CoreSegmentT, class _Derived> + class MemoryBase; +} + +namespace armarx::armem::wm +{ + class EntityInstance; + class EntitySnapshot; + class Entity; + class ProviderSegment; + class CoreSegment; + class Memory; +} + +namespace armarx::armem::server::wm +{ + using EntityInstance = armem::wm::EntityInstance; + using EntitySnapshot = armem::wm::EntitySnapshot; + class Entity; + class ProviderSegment; + class CoreSegment; + class Memory; +} diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/ice_conversions.cpp index 88ed8fd29ca61af76cf035c3a0be77a10df444a5..cca45a3b2cf04f26ec76d158e9cf1e711bbfecb2 100644 --- a/source/RobotAPI/libraries/armem/core/ice_conversions.cpp +++ b/source/RobotAPI/libraries/armem/core/ice_conversions.cpp @@ -3,20 +3,18 @@ #include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h> -namespace armarx +void IceUtil::toIce(long& ice, const IceUtil::Time& time) { + ice = time.toMicroSeconds(); +} - /* - void armem::fromIce(long ice, Time& time) - { - time = Time::microSeconds(ice); - } +void IceUtil::fromIce(const long& ice, IceUtil::Time& time) +{ + time = Time::microSeconds(ice); +} - void armem::toIce(long& ice, const Time& time) - { - ice = time.toMicroSeconds(); - } - */ +namespace armarx +{ void armem::toIce(data::MemoryID& ice, const MemoryID& id) { @@ -146,14 +144,5 @@ namespace armarx update.timeArrived = timeArrived; } - - void armem::detail::toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item) - { - toIce(ice.id, item.id()); - } - - void armem::detail::fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item) - { - fromIce(ice.id, item.id()); - } } + diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions.h b/source/RobotAPI/libraries/armem/core/ice_conversions.h index 874684cac2a6a52b8742c36dcc2bdea8346e1586..e8f104fe04ebcb721b0ffbf4b70b18ada0af234c 100644 --- a/source/RobotAPI/libraries/armem/core/ice_conversions.h +++ b/source/RobotAPI/libraries/armem/core/ice_conversions.h @@ -6,29 +6,21 @@ #include "ice_conversions_templates.h" #include "Commit.h" -#include "base/detail/MemoryItem.h" +#include "MemoryID.h" +#include "Time.h" namespace IceUtil { // Define in original namespace to allow ADL. - inline void toIce(long& ice, const Time& time) - { - ice = time.toMicroSeconds(); - } - inline void fromIce(const long& ice, Time& time) - { - time = Time::microSeconds(ice); - } + void toIce(long& ice, const Time& time); + void fromIce(const long& ice, Time& time); } namespace armarx::armem { - // void fromIce(long ice, Time& time); - // void toIce(long& ice, const Time& time); - void fromIce(const data::MemoryID& ice, MemoryID& id); void toIce(data::MemoryID& ice, const MemoryID& id); @@ -51,12 +43,5 @@ namespace armarx::armem void fromIce(const data::Commit& ice, Commit& commit, Time timeArrived); void fromIce(const data::EntityUpdate& ice, EntityUpdate& update, Time timeArrived); - - namespace detail - { - void toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item); - void fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item); - } - } diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h b/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h index e0c71faac37cd899d85d174c33196499a29df770..8060e22a0782e23c6bb989fe900fcce99c7ff7c6 100644 --- a/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h +++ b/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h @@ -1,9 +1,12 @@ #pragma once -#include <memory> - #include "Commit.h" +#include <Ice/Handle.h> + +#include <map> +#include <memory> +#include <vector> namespace armarx::armem diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp index c8c4be11ac2c047753f3197209fdaebc2b3ae919..6604c26e935cb4619fc7439d8e9a1f318a14ff63 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp @@ -30,11 +30,6 @@ namespace armarx::armem::ltm int i = 0; for (auto doc : cursor) { - if (i > MAX_HISTORY_SIZE) - { - // TODO: Add logic for most queried data? - break; - } nlohmann::json json = nlohmann::json::parse(bsoncxx::to_json(doc)); auto k = armem::Time::microSeconds(json.at("timestamp")); diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h index e3feb413c11d5fd8d89176ccea2ea40ddafc7510..99bc3a736f0abe803ec101a81f4b1ac75b87d92e 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h @@ -37,11 +37,6 @@ namespace armarx::armem::ltm using Base::EntityBase; - Entity() - { - // the history of snapshots is just a cache of frequently used elements - setMaxHistorySize(MAX_HISTORY_SIZE); - } // Conversion wm::Entity convert() const; @@ -63,8 +58,6 @@ namespace armarx::armem::ltm public: MongoDBConnectionManager::MongoDBSettings dbsettings; - private: - const static constexpr int MAX_HISTORY_SIZE = 200; }; } diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp index 8d7addcd6262d20242cf5868207572e554769687..8cbe688125a7571a3e8f0a19031b25722bb79bbf 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp @@ -21,7 +21,6 @@ namespace armarx::armem::ltm mongocxx::collection coll = db[id().getEntityID().str()]; auto res = coll.find_one(document{} << "id" << id().getEntitySnapshotID().str() << finalize); - if (!res) { throw error::ArMemError("Could not load an instance from the memory '" + id().getEntityID().str() + "'. Tried to access: " + id().getEntitySnapshotID().str()); diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp index 50aee46722c2e7c7f153feed0853e4f8a1226724..ab4cb5d13ec0a30c0e8dc04125b61bd4b031df99 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp @@ -89,10 +89,11 @@ namespace armarx::armem::ltm wm::Memory Memory::convert() const { + wm::Memory m(id()); + std::lock_guard l(mongoDBMutex); if (!checkConnection()) { - wm::Memory m(id()); return m; } @@ -100,7 +101,6 @@ namespace armarx::armem::ltm TIMING_START(LTM_Convert); - wm::Memory m(id()); for (const auto& [_, s] : _container) { m.addCoreSegment(s.convert()); diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h index 870bc0a7a7b668c7afb9f9766f4a4ec4c66faee7..41e82bce38b50f9e122e34056c2b5fd74cec4bac 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h @@ -8,6 +8,8 @@ #include <ArmarXCore/core/application/properties/forward_declarations.h> +#include <mutex> + namespace armarx::armem::ltm { diff --git a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp index a1fc88f19643bf5befa8c741cf6846d3f1a8f76f..70a905a931fd331a6ecdfbc2c278924b0da9144a 100644 --- a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp +++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp @@ -1,186 +1,64 @@ #include "ice_conversions.h" -#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h> -#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h> +#include <RobotAPI/libraries/armem/core/base/ice_conversions.h> namespace armarx::armem { - void toIce(data::EntityInstanceMetadata& ice, const wm::EntityInstanceMetadata& metadata) - { - ice.confidence = metadata.confidence; - toIce(ice.timeArrivedMicroSeconds, metadata.timeArrived); - toIce(ice.timeCreatedMicroSeconds, metadata.timeCreated); - toIce(ice.timeSentMicroSeconds, metadata.timeSent); - } - void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata) - { - metadata.confidence = ice.confidence; - fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived); - fromIce(ice.timeCreatedMicroSeconds, metadata.timeCreated); - fromIce(ice.timeSentMicroSeconds, metadata.timeSent); - } - void toIce(data::EntityInstance& ice, const wm::EntityInstance& data) + void wm::toIce(data::EntityInstance& ice, const EntityInstance& data) { - detail::toIceItem(ice, data); - - if (data.data()) - { - ice.data = data.data()->toAronDictPtr(); - } - toIce(ice.metadata, data.metadata()); + base::toIce(ice, data); } - void fromIce(const data::EntityInstance& ice, wm::EntityInstance& data) + void wm::fromIce(const data::EntityInstance& ice, EntityInstance& data) { - detail::fromIceItem(ice, data); - - if (ice.data) - { - data.data() = aron::datanavigator::DictNavigator::FromAronDictPtr(ice.data); - } - fromIce(ice.metadata, data.metadata()); + base::fromIce(ice, data); } - void toIce(data::EntitySnapshot& ice, const wm::EntitySnapshot& snapshot) + void wm::toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot) { - detail::toIceItem(ice, snapshot); - - ice.instances.clear(); - snapshot.forEachInstance([&ice](const wm::EntityInstance & instance) - { - toIce(ice.instances.emplace_back(), instance); - return true; - }); + base::toIce(ice, snapshot); } - void fromIce(const data::EntitySnapshot& ice, wm::EntitySnapshot& snapshot) + void wm::fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot) { - detail::fromIceItem(ice, snapshot); - - snapshot.clear(); - for (const data::EntityInstancePtr& instance : ice.instances) - { - snapshot.addInstance(fromIce<wm::EntityInstance>(instance)); - } + base::fromIce(ice, snapshot); } - void toIce(data::Entity& ice, const wm::Entity& entity) + void wm::toIce(data::Entity& ice, const Entity& entity) { - detail::toIceItem(ice, entity); - - ice.history.clear(); - entity.forEachSnapshot([&ice](const wm::EntitySnapshot & snapshot) - { - toIce(ice.history[toIce<long>(snapshot.time())], snapshot); - return true; - }); + base::toIce(ice, entity); } - void fromIce(const data::Entity& ice, wm::Entity& entity) + void wm::fromIce(const data::Entity& ice, Entity& entity) { - detail::fromIceItem(ice, entity); - - entity.clear(); - for (const auto& [key, snapshot] : ice.history) - { - entity.addSnapshot(fromIce<wm::EntitySnapshot>(snapshot)); - } + base::fromIce(ice, entity); } - void toIce(data::ProviderSegment& ice, const wm::ProviderSegment& providerSegment) + void wm::toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment) { - detail::toIceItem(ice, providerSegment); - - if (providerSegment.hasAronType()) - { - ice.aronType = providerSegment.aronType()->toAronPtr(); - } - ARMARX_CHECK(!providerSegment.aronType() || ice.aronType); - - // toIce(ice.entities, providerSegment.entities()); - ice.entities.clear(); - providerSegment.forEachEntity([&ice](const wm::Entity & entity) - { - toIce(ice.entities[entity.name()], entity); - return true; - }); + base::toIce(ice, providerSegment); } - void fromIce(const data::ProviderSegment& ice, wm::ProviderSegment& providerSegment) + void wm::fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment) { - detail::fromIceItem(ice, providerSegment); - - if (ice.aronType) - { - providerSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice.aronType)); - } - ARMARX_CHECK(!providerSegment.aronType() || ice.aronType); - - // fromIce(ice.entities, providerSegment.entities()); - providerSegment.clear(); - for (const auto& [key, entity] : ice.entities) - { - providerSegment.addEntity(fromIce<wm::Entity>(entity)); - } + base::fromIce(ice, providerSegment); } - void toIce(data::CoreSegment& ice, const wm::CoreSegment& coreSegment) + void wm::toIce(data::CoreSegment& ice, const CoreSegment& coreSegment) { - detail::toIceItem(ice, coreSegment); - - if (coreSegment.hasAronType()) - { - ice.aronType = coreSegment.aronType()->toAronPtr(); - } - ARMARX_CHECK(!coreSegment.aronType() || ice.aronType); - - // toIce(ice.providerSegments, coreSegment.providerSegments()); - ice.providerSegments.clear(); - coreSegment.forEachProviderSegment([&ice](const wm::ProviderSegment & providerSegment) - { - toIce(ice.providerSegments[providerSegment.name()], providerSegment); - return true; - }); + base::toIce(ice, coreSegment); } - void fromIce(const data::CoreSegment& ice, wm::CoreSegment& coreSegment) + void wm::fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment) { - detail::fromIceItem(ice, coreSegment); - - if (ice.aronType) - { - coreSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice.aronType)); - } - ARMARX_CHECK(!coreSegment.aronType() || ice.aronType); - - // fromIce(ice.providerSegments, coreSegment.providerSegments()); - coreSegment.clear(); - for (const auto& [key, providerSegment] : ice.providerSegments) - { - coreSegment.addProviderSegment(fromIce<wm::ProviderSegment>(providerSegment)); - } + base::fromIce(ice, coreSegment); } - void toIce(data::Memory& ice, const wm::Memory& memory) + void wm::toIce(data::Memory& ice, const Memory& memory) { - detail::toIceItem(ice, memory); - - // toIce(ice.coreSegments, memory.coreSegments()); - ice.coreSegments.clear(); - memory.forEachCoreSegment([&ice](const wm::CoreSegment & coreSegment) - { - toIce(ice.coreSegments[coreSegment.name()], coreSegment); - return true; - }); + base::toIce(ice, memory); } - void fromIce(const data::Memory& ice, wm::Memory& memory) + void wm::fromIce(const data::Memory& ice, Memory& memory) { - detail::fromIceItem(ice, memory); - - // fromIce(ice.coreSegments, memory.coreSegments()); - memory.clear(); - for (const auto& [key, coreSegment] : ice.coreSegments) - { - memory.addCoreSegment(fromIce<wm::CoreSegment>(coreSegment)); - } + base::fromIce(ice, memory); } } diff --git a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h index d2f7ef01f46361734f3092ef6fba1d1cb8df395c..4a58f16aaa6eef4c6f6685a86ed66298c1407454 100644 --- a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h +++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h @@ -6,31 +6,29 @@ #include "memory_definitions.h" -namespace armarx::armem +namespace armarx::armem::wm { - void toIce(data::EntityInstanceMetadata& ice, const wm::EntityInstanceMetadata& metadata); - void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata); - void toIce(data::EntityInstance& ice, const wm::EntityInstance& data); - void fromIce(const data::EntityInstance& ice, wm::EntityInstance& data); + void toIce(data::EntityInstance& ice, const EntityInstance& data); + void fromIce(const data::EntityInstance& ice, EntityInstance& data); - void toIce(data::EntitySnapshot& ice, const wm::EntitySnapshot& snapshot); - void fromIce(const data::EntitySnapshot& ice, wm::EntitySnapshot& snapshot); + void toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot); + void fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot); - void toIce(data::Entity& ice, const wm::Entity& entity); - void fromIce(const data::Entity& ice, wm::Entity& entity); + void toIce(data::Entity& ice, const Entity& entity); + void fromIce(const data::Entity& ice, Entity& entity); - void toIce(data::ProviderSegment& ice, const wm::ProviderSegment& providerSegment); - void fromIce(const data::ProviderSegment& ice, wm::ProviderSegment& providerSegment); + void toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment); + void fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment); - void toIce(data::CoreSegment& ice, const wm::CoreSegment& coreSegment); - void fromIce(const data::CoreSegment& ice, wm::CoreSegment& coreSegment); + void toIce(data::CoreSegment& ice, const CoreSegment& coreSegment); + void fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment); - void toIce(data::Memory& ice, const wm::Memory& memory); - void fromIce(const data::Memory& ice, wm::Memory& memory); + void toIce(data::Memory& ice, const Memory& memory); + void fromIce(const data::Memory& ice, Memory& memory); } // Must be included after the prototypes. Otherwise the compiler cannot find the correct methods in ice_coversion_templates.h -#include "../ice_conversions.h" +#include <RobotAPI/libraries/armem/core/ice_conversions.h> diff --git a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp index c200e6f68176363a9fb7b1344b2cc8dcf1025fc2..c9516fc3b74ce05797d7d8c39b12f83b0bdf740d 100644 --- a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp +++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp @@ -42,42 +42,6 @@ namespace armarx::armem::wm } - CoreSegment::CoreSegment(const CoreSegment& other) : - CoreSegment::Base(other), - _mutex() - { - // Do not copy _mutex. - } - - - CoreSegment::CoreSegment(CoreSegment&& other) : - CoreSegment::Base(std::move(other)) - { - // Do not move _mutex. - } - - - CoreSegment& CoreSegment::operator=(const CoreSegment& other) - { - Base::operator=(other); - // Don't copy _mutex. - return *this; - } - - - CoreSegment& CoreSegment::operator=(CoreSegment&& other) - { - Base::operator=(std::move(other)); - // Don't move _mutex. - return *this; - } - - - std::mutex& CoreSegment::mutex() const - { - return _mutex; - } - std::optional<wm::EntitySnapshot> CoreSegment::getLatestEntitySnapshot(const MemoryID& entityID) const { @@ -125,90 +89,4 @@ namespace armarx::armem::wm } - std::optional<wm::EntitySnapshot> - CoreSegment::getLatestEntitySnapshotLocking(const MemoryID& entityID) const - { - std::scoped_lock lock(_mutex); - return getLatestEntitySnapshot(entityID); - } - - std::optional<wm::EntityInstance> - CoreSegment::getLatestEntityInstanceLocking(const MemoryID& entityID, int instanceIndex) const - { - std::scoped_lock lock(_mutex); - return getLatestEntityInstance(entityID, instanceIndex); - } - - armarx::aron::datanavigator::DictNavigatorPtr - CoreSegment::getLatestEntityInstanceDataLocking(const MemoryID& entityID, int instanceIndex) const - { - std::scoped_lock lock(_mutex); - return getLatestEntityInstanceData(entityID, instanceIndex); - } - - - // TODO: add core segment if param is set - std::vector<Memory::Base::UpdateResult> - Memory::updateLocking(const Commit& commit) - { - // Group updates by core segment, then update each core segment in a batch to only lock it once. - std::map<std::string, std::vector<const EntityUpdate*>> updatesPerCoreSegment; - for (const EntityUpdate& update : commit.updates) - { - updatesPerCoreSegment[update.entityID.coreSegmentName].push_back(&update); - } - - std::vector<Memory::Base::UpdateResult> result; - // To throw an exception after the commit if a core segment is missing and the memory should not create new ones - std::vector<std::string> missingCoreSegmentNames; - for (const auto& [coreSegmentName, updates] : updatesPerCoreSegment) - { - auto it = this->_container.find(coreSegmentName); - if (it != this->_container.end()) - { - CoreSegment& coreSegment = it->second; - - // Lock the core segment for the whole batch. - std::scoped_lock lock(coreSegment.mutex()); - - for (const EntityUpdate* update : updates) - { - auto r = coreSegment.update(*update); - Base::UpdateResult ret { r }; - ret.memoryUpdateType = UpdateType::UpdatedExisting; - result.push_back(ret); - } - } - else - { - // Perform the other updates first, then throw afterwards. - missingCoreSegmentNames.push_back(coreSegmentName); - } - } - // Throw an exception if something went wrong. - if (not missingCoreSegmentNames.empty()) - { - // Just throw an exception for the first entry. We can extend this exception in the future. - throw armem::error::MissingEntry::create<CoreSegment>(missingCoreSegmentNames.front(), *this); - } - return result; - } - - - // TODO: Add core segment if param is set - Memory::Base::UpdateResult - Memory::updateLocking(const EntityUpdate& update) - { - this->_checkContainerName(update.entityID.memoryName, this->name()); - - CoreSegment& segment = getCoreSegment(update.entityID.coreSegmentName); - Base::UpdateResult result; - { - std::scoped_lock lock(segment.mutex()); - result = segment.update(update); - } - result.memoryUpdateType = UpdateType::UpdatedExisting; - return result; - } - } diff --git a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h index 85b320e319259da6f009680e75a44a5cfd5945e0..679153b47809682fec38adb5baea609dd99c5c28 100644 --- a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h +++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h @@ -7,7 +7,6 @@ #include <RobotAPI/libraries/armem/core/base/CoreSegmentBase.h> #include <RobotAPI/libraries/armem/core/base/MemoryBase.h> -#include <mutex> #include <optional> @@ -19,9 +18,7 @@ namespace armarx::armem::wm using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr; - /** - * @brief Data of a single entity instance. - */ + /// @see base::EntityInstanceBase class EntityInstance : public base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata> { @@ -45,9 +42,7 @@ namespace armarx::armem::wm - /** - * @brief Data of an entity at one point in time. - */ + /// @see base::EntitySnapshotBase class EntitySnapshot : public base::EntitySnapshotBase<EntityInstance, EntitySnapshot> { @@ -58,26 +53,7 @@ namespace armarx::armem::wm }; - - /** - * @brief An entity over a period of time. - * - * An entity should be a physical thing or abstract concept existing - * (and potentially evolving) over some time. - * - * Examples are: - * - objects (the green box) - * - agents (robot, human) - * - locations (frige, sink) - * - grasp affordances (general, or for a specific object) - * - images - * - point clouds - * - other sensory values - * - * At each point in time (`EntitySnapshot`), the entity can have a - * (potentially variable) number of instances (`EntityInstance`), - * each containing a single `AronData` object of a specific `AronType`. - */ + /// @see base::EntityBase class Entity : public base::EntityBase<EntitySnapshot, Entity> { @@ -89,9 +65,7 @@ namespace armarx::armem::wm - /** - * @brief Data of a provider segment containing multiple entities. - */ + /// @see base::ProviderSegmentBase class ProviderSegment : public base::ProviderSegmentBase<Entity, ProviderSegment> { @@ -103,9 +77,7 @@ namespace armarx::armem::wm - /** - * @brief Data of a core segment containing multiple provider segments. - */ + /// @see base::CoreSegmentBase class CoreSegment : public base::CoreSegmentBase<ProviderSegment, CoreSegment> { @@ -115,14 +87,6 @@ namespace armarx::armem::wm using Base::CoreSegmentBase; - CoreSegment(const CoreSegment& other); - CoreSegment(CoreSegment&& other); - CoreSegment& operator=(const CoreSegment& other); - CoreSegment& operator=(CoreSegment&& other); - - - std::mutex& mutex() const; - // Non-locking interface @@ -151,51 +115,11 @@ namespace armarx::armem::wm } } - - // Locking interface - - std::optional<wm::EntitySnapshot> getLatestEntitySnapshotLocking( - const MemoryID& entityID) const; - std::optional<wm::EntityInstance> getLatestEntityInstanceLocking( - const MemoryID& entityID, int instanceIndex = 0) const; - armarx::aron::datanavigator::DictNavigatorPtr getLatestEntityInstanceDataLocking( - const MemoryID& entityID, int instanceIndex = 0) const; - - - template <class AronDtoT> - std::optional<AronDtoT> getLatestEntityInstanceDataLockingAs( - const MemoryID& entityID, int instanceIndex = 0) const - { - // Keep lock to a minimum. - wm::EntityInstanceDataPtr data = nullptr; - { - std::scoped_lock lock(_mutex); - data = getLatestEntityInstanceData(entityID, instanceIndex); - } - if (data) - { - AronDtoT aron; - aron.fromAron(data); - return aron; - } - else - { - return std::nullopt; - } - } - - - protected: - - mutable std::mutex _mutex; - }; - /** - * @brief Data of a memory consisting of multiple core segments. - */ + /// @see base::MemoryBase class Memory : public base::MemoryBase<CoreSegment, Memory> { @@ -205,20 +129,6 @@ namespace armarx::armem::wm using Base::MemoryBase; - - /** - * @brief Perform the commit, locking the core segments. - * - * Groups the commits by core segment, and updates each core segment - * in a batch, locking the core segment. - */ - std::vector<Base::UpdateResult> updateLocking(const Commit& commit); - - /** - * @brief Update the memory, locking the updated core segment. - */ - Base::UpdateResult updateLocking(const EntityUpdate& update); - }; } diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp index 8c814a160b49b0367cece67d407b986ac4d372e5..ae847a803dc64e68b53c432b222cb6ddbe2fcd86 100644 --- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp +++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp @@ -1,13 +1,11 @@ #include "ComponentPlugin.h" -#include <ArmarXCore/core/Component.h> -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include "MemoryToIceAdapter.h" #include <RobotAPI/libraries/armem/core/error.h> -#include "MemoryToIceAdapter.h" - -//#include <RobotAPI/libraries/armem/core/io/diskWriter/NlohmannJSON/NlohmannJSONDiskWriter.h> +#include <ArmarXCore/core/Component.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> namespace armarx::armem::server::plugins diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h index 50951ab829b11971420a47d680b07e5ce7e4e115..0b2b872c1ff4686eecefd8ae8508bcfc45600d5f 100644 --- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h +++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h @@ -98,7 +98,7 @@ namespace armarx::armem::server public: /// The actual memory. - wm::Memory workingMemory; + server::wm::Memory workingMemory; // [[deprecated ("The global working memory mutex is deprecated. Use the core segment mutexes instead.")]] // std::mutex workingMemoryMutex; diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp index 2207233b2abb5f1a73595bc32f5d60d86fd06a6d..6664288a0fa5f86da4df906819cba3be385cbcb9 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp @@ -1,19 +1,22 @@ #include "MemoryRemoteGui.h" -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include "RemoteGuiAronDataVisitor.h" #include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h> #include <RobotAPI/libraries/aron/core/navigator/visitors/DataVisitor.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + #include <SimoxUtility/meta/type_name.h> -#include "RemoteGuiAronDataVisitor.h" +#include <mutex> namespace armarx::armem::server { - MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::Memory& memory) const + template <class ...Args> + MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::MemoryBase<Args...>& memory) const { GroupBox group; group.setLabel(makeGroupLabel("Memory", memory.name(), memory.size())); @@ -22,19 +25,16 @@ namespace armarx::armem::server { group.addChild(Label(makeNoItemsMessage("core segments"))); } - memory.forEachCoreSegment([this, &group](const wm::CoreSegment & coreSegment) + memory.forEachCoreSegment([this, &group](const auto & coreSegment) { - group.addChild(makeGroupBox(coreSegment)); - return true; + group.addChild(this->makeGroupBox(coreSegment)); }); return group; } - - MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::CoreSegment& coreSegment) const + template <class ...Args> + MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::CoreSegmentBase<Args...>& coreSegment) const { - std::scoped_lock lock(coreSegment.mutex()); - GroupBox group; group.setLabel(makeGroupLabel("Core Segment", coreSegment.name(), coreSegment.size())); @@ -42,16 +42,15 @@ namespace armarx::armem::server { group.addChild(Label(makeNoItemsMessage("provider segments"))); } - coreSegment.forEachProviderSegment([this, &group](const wm::ProviderSegment & providerSegment) + coreSegment.forEachProviderSegment([this, &group](const auto & providerSegment) { - group.addChild(makeGroupBox(providerSegment)); - return true; + group.addChild(this->makeGroupBox(providerSegment)); }); return group; } - - MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::ProviderSegment& providerSegment) const + template <class ...Args> + MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::ProviderSegmentBase<Args...>& providerSegment) const { GroupBox group; group.setLabel(makeGroupLabel("Provider Segment", providerSegment.name(), providerSegment.size())); @@ -60,16 +59,15 @@ namespace armarx::armem::server { group.addChild(Label(makeNoItemsMessage("entities"))); } - providerSegment.forEachEntity([this, &group](const wm::Entity & entity) + providerSegment.forEachEntity([this, &group](const auto & entity) { - group.addChild(makeGroupBox(entity)); - return true; + group.addChild(this->makeGroupBox(entity)); }); return group; } - - MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::Entity& entity) const + template <class ...Args> + MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::EntityBase<Args...>& entity) const { GroupBox group; group.setLabel(makeGroupLabel("Entity", entity.name(), entity.size())); @@ -79,10 +77,9 @@ namespace armarx::armem::server group.addChild(Label(makeNoItemsMessage("snapshots"))); } - auto addChild = [this, &group](const wm::EntitySnapshot & snapshot) + auto addChild = [this, &group](const armem::wm::EntitySnapshot & snapshot) { group.addChild(makeGroupBox(snapshot)); - return true; }; if (int(entity.size()) <= maxHistorySize) @@ -101,7 +98,55 @@ namespace armarx::armem::server } - MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::EntitySnapshot& snapshot) const + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::Memory& memory) const + { + return this->_makeGroupBox(memory); + } + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::Memory& memory) const + { + return this->_makeGroupBox(memory); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::CoreSegment& coreSegment) const + { + std::scoped_lock lock(coreSegment.mutex()); + return this->_makeGroupBox(coreSegment); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::CoreSegment& coreSegment) const + { + return this->_makeGroupBox(coreSegment); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::ProviderSegment& providerSegment) const + { + return this->_makeGroupBox(providerSegment); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::ProviderSegment& providerSegment) const + { + return this->_makeGroupBox(providerSegment); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::Entity& entity) const + { + return this->_makeGroupBox(entity); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::Entity& entity) const + { + return this->_makeGroupBox(entity); + } + + + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::EntitySnapshot& snapshot) const { GroupBox group; group.setLabel(makeGroupLabel("t", armem::toDateTimeMilliSeconds(snapshot.time()), @@ -111,7 +156,7 @@ namespace armarx::armem::server { group.addChild(Label(makeNoItemsMessage("instances"))); } - snapshot.forEachInstance([this, &group](const wm::EntityInstance & instance) + snapshot.forEachInstance([this, &group](const armem::wm::EntityInstance & instance) { group.addChild(makeGroupBox(instance)); return true; @@ -122,7 +167,7 @@ namespace armarx::armem::server } - MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::EntityInstance& instance) const + MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::EntityInstance& instance) const { GroupBox group; diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h index 0c363e0758ca5caf75fa04d45ca35c879bbabe55..c6aef5c51546ac203c50d38f80696b89f3b6f3b9 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h +++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h @@ -2,7 +2,7 @@ #include <ArmarXGui/libraries/RemoteGui/Client/Widgets.h> -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> namespace armarx::armem::server @@ -17,12 +17,18 @@ namespace armarx::armem::server using GroupBox = armarx::RemoteGui::Client::GroupBox; using Label = armarx::RemoteGui::Client::Label; - GroupBox makeGroupBox(const wm::Memory& memory) const; - GroupBox makeGroupBox(const wm::CoreSegment& coreSegment) const; - GroupBox makeGroupBox(const wm::ProviderSegment& providerSegment) const; - GroupBox makeGroupBox(const wm::Entity& entity) const; - GroupBox makeGroupBox(const wm::EntitySnapshot& entitySnapshot) const; - GroupBox makeGroupBox(const wm::EntityInstance& instance) const; + + GroupBox makeGroupBox(const armem::wm::Memory& memory) const; + GroupBox makeGroupBox(const armem::wm::CoreSegment& coreSegment) const; + GroupBox makeGroupBox(const armem::wm::ProviderSegment& providerSegment) const; + GroupBox makeGroupBox(const armem::wm::Entity& entity) const; + GroupBox makeGroupBox(const armem::wm::EntitySnapshot& entitySnapshot) const; + GroupBox makeGroupBox(const armem::wm::EntityInstance& instance) const; + + GroupBox makeGroupBox(const armem::server::wm::Memory& memory) const; + GroupBox makeGroupBox(const armem::server::wm::CoreSegment& coreSegment) const; + GroupBox makeGroupBox(const armem::server::wm::ProviderSegment& providerSegment) const; + GroupBox makeGroupBox(const armem::server::wm::Entity& entity) const; std::string makeGroupLabel(const std::string& term, const std::string& name, size_t size, @@ -33,6 +39,17 @@ namespace armarx::armem::server int maxHistorySize = 10; + private: + + template <class ...Args> + MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::MemoryBase<Args...>& memory) const; + template <class ...Args> + MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::CoreSegmentBase<Args...>& coreSegment) const; + template <class ...Args> + MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::ProviderSegmentBase<Args...>& providerSegment) const; + template <class ...Args> + MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::EntityBase<Args...>& entity) const; + }; diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp index 9fd9d5ccf68640468ea18235ce2a7afe316d7d3d..52fb496592390a1f7df893d0709c73937da55ae5 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp @@ -1,11 +1,13 @@ #include "MemoryToIceAdapter.h" +#include "query_proc/wm.h" +#include "query_proc/ltm.h" -#include "query_proc/workingmemory/MemoryQueryProcessor.h" -#include "query_proc/longtermmemory/MemoryQueryProcessor.h" +#include <RobotAPI/libraries/armem/server/wm/ice_conversions.h> #include <RobotAPI/libraries/armem/core/error.h> #include <RobotAPI/libraries/armem/core/wm/ice_conversions.h> + #include <RobotAPI/libraries/aron/core/Exception.h> #include <ArmarXCore/core/logging/Logging.h> @@ -36,7 +38,7 @@ namespace armarx::armem::server data::AddSegmentResult output; - armem::wm::CoreSegment* coreSegment = nullptr; + server::wm::CoreSegment* coreSegment = nullptr; try { coreSegment = &workingMemory->getCoreSegment(input.coreSegmentName); @@ -68,7 +70,7 @@ namespace armarx::armem::server // This is ok. if (input.clearWhenExists) { - wm::ProviderSegment& provider = coreSegment->getProviderSegment(input.providerSegmentName); + server::wm::ProviderSegment& provider = coreSegment->getProviderSegment(input.providerSegmentName); provider.clear(); } } @@ -227,11 +229,11 @@ namespace armarx::armem::server ARMARX_CHECK_NOT_NULL(workingMemory); // Core segment processors will aquire the core segment locks. - armem::wm::query_proc::MemoryQueryProcessor wmProcessor( + query_proc::wm_server::MemoryQueryProcessor wmServerProcessor( input.withData ? armem::DataMode::WithData : armem::DataMode::NoData); - wm::Memory wmResult = wmProcessor.process(input, *workingMemory); + armem::wm::Memory wmResult = wmServerProcessor.process(input.memoryQueries, *workingMemory); - armem::ltm::query_proc::MemoryQueryProcessor ltmProcessor; + query_proc::ltm::MemoryQueryProcessor ltmProcessor; ltm::Memory ltmResult = ltmProcessor.process(input, *longtermMemory); armem::query::data::Result result; @@ -244,7 +246,7 @@ namespace armarx::armem::server // This may also affect the data returned by the current query. // However, this is expected behavior, since we copy the data in the processor (copyEmpty) we can safely return the copy and // remove the original memory reference from WM here. - wm::Memory ltmConverted = ltmResult.convert(); + armem::wm::Memory ltmConverted = ltmResult.convert(); if (ltmConverted.empty()) { ARMARX_ERROR << "A converted memory contains no data although the original memory contained data. This indicates that something is wrong."; @@ -260,7 +262,9 @@ namespace armarx::armem::server auto queryInput = armem::client::QueryInput::fromIce(input); queryInput.replaceQueryTarget(query::data::QueryTarget::LTM, query::data::QueryTarget::WM); - wm::Memory merged_result = wmProcessor.process(queryInput.toIce(), wmResult); + query_proc::wm::MemoryQueryProcessor wm2wmProcessor( + input.withData ? armem::DataMode::WithData : armem::DataMode::NoData); + armem::wm::Memory merged_result = wm2wmProcessor.process(queryInput.toIce(), wmResult); if (merged_result.empty()) { ARMARX_ERROR << "A merged and postprocessed Memory has no data although at least the LTM result contains data. This indicates that something is wrong."; @@ -326,7 +330,7 @@ namespace armarx::armem::server if (queryResult.success) { - wm::Memory m; + armem::wm::Memory m; fromIce(queryResult.memory, m); longtermMemory->append(m); } diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h index cc665745970fad337c3e7af8adcdd1b9f713abc8..6aa68b5714ad369e3b2bbad08d7c1ca06ab04bb8 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h @@ -6,12 +6,12 @@ #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h> #include <RobotAPI/libraries/armem/client/Query.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> namespace armarx::armem::server { - /** * @brief Helps connecting a Memory server to the Ice interface. * @@ -23,7 +23,8 @@ namespace armarx::armem::server public: /// Construct an MemoryToIceAdapter from an existing Memory. - MemoryToIceAdapter(wm::Memory* workingMemory = nullptr, ltm::Memory* longtermMemory = nullptr); + MemoryToIceAdapter(server::wm::Memory* workingMemory = nullptr, + ltm::Memory* longtermMemory = nullptr); void setMemoryListener(client::MemoryListenerInterfacePrx memoryListenerTopic); @@ -54,7 +55,7 @@ namespace armarx::armem::server public: - wm::Memory* workingMemory; + server::wm::Memory* workingMemory; ltm::Memory* longtermMemory; client::MemoryListenerInterfacePrx memoryListenerTopic; diff --git a/source/RobotAPI/libraries/armem/server/forward_declarations.h b/source/RobotAPI/libraries/armem/server/forward_declarations.h new file mode 100644 index 0000000000000000000000000000000000000000..6872e2584352195ca8e587043e275acfbffb3739 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/forward_declarations.h @@ -0,0 +1,18 @@ +#pragma once + +#include <RobotAPI/libraries/armem/core/forward_declarations.h> + + +namespace armarx::armem::server +{ + class MemoryToIceAdapter; +} +namespace armarx::armem::server::wm +{ + using EntityInstance = armem::wm::EntityInstance; + using EntitySnapshot = armem::wm::EntitySnapshot; + class Entity; + class ProviderSegment; + class CoreSegment; + class Memory; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base.h b/source/RobotAPI/libraries/armem/server/query_proc/base.h new file mode 100644 index 0000000000000000000000000000000000000000..1d826798cecac7371882ce0783ddc05414a4f237 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/base.h @@ -0,0 +1,12 @@ +#pragma once + +#include <RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h> +#include <RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h> +#include <RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h> +#include <RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h> + + +namespace armarx::armem::server::query_proc::base +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp index 34e2abd99c889d65723065c8b4726b2ea0aa9bd1..a3dfb4eb4102e21ee0cc97d7a9919b55c7c83f35 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp @@ -1,2 +1,21 @@ #include "BaseQueryProcessorBase.h" +#include <ArmarXCore/core/logging/Logging.h> + + +namespace armarx::armem::server::query_proc::base +{ + + std::set<query::data::QueryTarget> + detail::getTargets(const std::vector<query::data::QueryTarget>& _targets) + { + std::set<query::data::QueryTarget> targets(_targets.begin(), _targets.end()); + if (targets.empty()) + { + ARMARX_DEBUG << "Query has no targets - using WM as default."; + targets.insert(query::data::QueryTarget::WM); + } + return targets; + } + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h index 5e2ba4235154d81950f73fc218b302c41c382ffa..73c662e04ebd734cbe79c3b19f676f684223a88c 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h @@ -1,88 +1,91 @@ #pragma once -#include <ArmarXCore/core/logging/Logging.h> #include <RobotAPI/interface/armem/query.h> +#include <Ice/Handle.h> -namespace armarx::armem::base::query_proc +#include <set> +#include <vector> + + +namespace armarx::armem::server::query_proc::base::detail { + // If empty, e.g. when receiving queries from python, we use WM as default. + // We do it here as (Sl)ice does not support default values for vectors. + std::set<query::data::QueryTarget> getTargets(const std::vector<query::data::QueryTarget>& _targets); +} +namespace armarx::armem::server::query_proc::base +{ + + using QueryTarget = query::data::QueryTarget; + /** * @brief Base class for memory query processors. */ - template <class DataT, class QueryT> + template <QueryTarget queryTarget, class DataT, class ResultT, class QueryT> class BaseQueryProcessorBase { public: + using QueryPtrT = ::IceInternal::Handle<QueryT>; using QuerySeqT = std::vector<QueryPtrT>; + public: virtual ~BaseQueryProcessorBase() = default; - DataT process(const QueryT& query, const DataT& data) const + ResultT process(const QueryT& query, const DataT& data) const { - DataT result { data.id() }; - if (getTargets(query.targets).count(getTargetType())) + ResultT result { data.id() }; + if (detail::getTargets(query.targets).count(queryTarget)) { this->process(result, query, data); } return result; } - DataT process(const QueryPtrT& query, const DataT& data) const + ResultT process(const QueryPtrT& query, const DataT& data) const { return this->process(*query, *data); } - DataT process(const QuerySeqT& queries, const DataT& data) const + ResultT process(const QuerySeqT& queries, const DataT& data) const { - DataT result { data.id() }; + ResultT result { data.id() }; this->process(result, queries, data); return result; } - void process(DataT& result, const QuerySeqT& queries, const DataT& data) const + void process(ResultT& result, const QuerySeqT& queries, const DataT& data) const { if (queries.empty()) { - ARMARX_DEBUG << "There are no queries to process."; return; } for (const auto& query : queries) { - if (getTargets(query->targets).count(getTargetType())) + if (detail::getTargets(query->targets).count(queryTarget)) { this->process(result, *query, data); } } } - virtual void process(DataT& result, const QueryT& query, const DataT& data) const = 0; - - protected: + /** + * @brief Process the query and populate `result`. + * + * @param result The result container. + * @param query The query. + * @param data The source container. + */ + virtual void process(ResultT& result, const QueryT& query, const DataT& data) const = 0; - virtual query::data::QueryTarget getTargetType() const = 0; - - - private: + }; - /// If empty, e.g. when receiving queries from python, we use WM as default. - /// We do it here as (Sl)ice does not support default values for vectors. - static std::set<query::data::QueryTarget> getTargets(const std::vector<query::data::QueryTarget>& _targets) - { - std::set<query::data::QueryTarget> targets(_targets.begin(), _targets.end()); - if (targets.empty()) - { - ARMARX_DEBUG << "Query has no targets - using WM as default."; - targets.insert(query::data::QueryTarget::WM); - } - return targets; - } - }; } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h index bb0c5072ebab28eb03cdb15fa3eab9ef315b783c..3050e6e4e91a90bfbfa97feff7f3afc6cb804f41 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h @@ -9,31 +9,46 @@ #include <RobotAPI/libraries/armem/core/error.h> #include "BaseQueryProcessorBase.h" -#include "ProviderSegmentQueryProcessorBase.h" -namespace armarx::armem::base::query_proc +namespace armarx::armem::server::query_proc::base { /** * @brief Handles memory queries. */ - template <class _CoreSegmentT> + template <QueryTarget queryTarget, class _CoreSegmentT, class _ResultCoreSegmentT, class _ChildProcessorT> class CoreSegmentQueryProcessorBase : - virtual public BaseQueryProcessorBase<_CoreSegmentT, armem::query::data::CoreSegmentQuery> + public BaseQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, armem::query::data::CoreSegmentQuery> { - using Base = BaseQueryProcessorBase<_CoreSegmentT, armem::query::data::CoreSegmentQuery>; + using Base = BaseQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, armem::query::data::CoreSegmentQuery>; public: + using CoreSegmentT = _CoreSegmentT; - using ProviderSegmentT = typename _CoreSegmentT::ProviderSegmentT; - using EntityT = typename ProviderSegmentT::EntityT; - using EntitySnapshotT = typename EntityT::EntitySnapshotT; + using ProviderSegmentT = typename CoreSegmentT::ProviderSegmentT; + + using ResultCoreSegmentT = _ResultCoreSegmentT; + using ResultProviderSegmentT = typename ResultCoreSegmentT::ProviderSegmentT; + + using ChildProcessorT = _ChildProcessorT; + + + public: + + CoreSegmentQueryProcessorBase() + { + } + CoreSegmentQueryProcessorBase(ChildProcessorT&& childProcessor) : + childProcessor(childProcessor) + { + } + using Base::process; - virtual void process(_CoreSegmentT& result, + virtual void process(ResultCoreSegmentT& result, const armem::query::data::CoreSegmentQuery& query, - const _CoreSegmentT& coreSegment) const override + const CoreSegmentT& coreSegment) const override { if (auto q = dynamic_cast<const armem::query::data::core::All*>(&query)) { @@ -53,25 +68,24 @@ namespace armarx::armem::base::query_proc } } - void process(_CoreSegmentT& result, + void process(ResultCoreSegmentT& result, const armem::query::data::core::All& query, - const _CoreSegmentT& coreSegment) const + const CoreSegmentT& coreSegment) const { coreSegment.forEachProviderSegment([this, &query, &result](const ProviderSegmentT & providerSegment) { - result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment)); - return true; + childProcessor.process(result.addProviderSegment(providerSegment.name()), query.providerSegmentQueries, providerSegment); }); } - void process(_CoreSegmentT& result, + void process(ResultCoreSegmentT& result, const armem::query::data::core::Single& query, - const _CoreSegmentT& coreSegment) const + const CoreSegmentT& coreSegment) const { try { const ProviderSegmentT& providerSegment = coreSegment.getProviderSegment(query.providerSegmentName); - result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment)); + childProcessor.process(result.addProviderSegment(providerSegment.name()), query.providerSegmentQueries, providerSegment); } catch (const error::MissingEntry&) { @@ -79,9 +93,9 @@ namespace armarx::armem::base::query_proc } } - void process(_CoreSegmentT& result, + void process(ResultCoreSegmentT& result, const armem::query::data::core::Regex& query, - const _CoreSegmentT& coreSegment) const + const CoreSegmentT& coreSegment) const { std::regex regex(query.providerSegmentNameRegex); coreSegment.forEachProviderSegment( @@ -89,13 +103,15 @@ namespace armarx::armem::base::query_proc { if (std::regex_search(providerSegment.name(), regex)) { - result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment)); + childProcessor.process(result.addProviderSegment(providerSegment.name()), query.providerSegmentQueries, providerSegment); } - return true; }); } + protected: - virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& a, const ProviderSegmentT& o) const = 0; + + ChildProcessorT childProcessor; + }; } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h index 6713a3e69a62cca8d9c083513b520c951c005984..0c4a842fa2772ae18b475b9e28ad3b13077bb49d 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h @@ -1,41 +1,42 @@ #pragma once -#include <cstdint> -#include <iterator> +#include "BaseQueryProcessorBase.h" + +#include <RobotAPI/libraries/armem/core/Time.h> +#include <RobotAPI/libraries/armem/core/error.h> +#include <RobotAPI/libraries/armem/core/ice_conversions.h> #include <RobotAPI/interface/armem/query.h> -#include <ArmarXCore/core/exceptions/LocalException.h> -#include <ArmarXCore/core/logging/Logging.h> #include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <ArmarXCore/core/logging/Logging.h> -#include <RobotAPI/libraries/armem/core/error.h> -#include <RobotAPI/libraries/armem/core/ice_conversions.h> - -#include "BaseQueryProcessorBase.h" -#include "RobotAPI/libraries/armem/core/Time.h" +#include <cstdint> +#include <iterator> -namespace armarx::armem::base::query_proc +namespace armarx::armem::server::query_proc::base { - /** - * @brief Handles memory queries. - */ - template <class _EntityT> + template <QueryTarget queryTarget, class _EntityT, class _ResultEntityT> class EntityQueryProcessorBase : - virtual public BaseQueryProcessorBase<_EntityT, armem::query::data::EntityQuery> + public BaseQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT, armem::query::data::EntityQuery> { - using Base = BaseQueryProcessorBase<_EntityT, armem::query::data::EntityQuery>; + using Base = BaseQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT, armem::query::data::EntityQuery>; public: + using EntityT = _EntityT; using EntitySnapshotT = typename EntityT::EntitySnapshotT; + using ResultEntityT = _ResultEntityT; + using ResultSnapshotT = typename ResultEntityT::EntitySnapshotT; + + using Base::process; - void process(_EntityT& result, - const armem::query::data::EntityQuery& query, - const _EntityT& entity) const override + virtual void process(ResultEntityT& result, + const armem::query::data::EntityQuery& query, + const EntityT& entity) const override { if (auto q = dynamic_cast<const armem::query::data::entity::All*>(&query)) { @@ -71,9 +72,10 @@ namespace armarx::armem::base::query_proc } } - void process(_EntityT& result, + + void process(ResultEntityT& result, const armem::query::data::entity::All& query, - const _EntityT& entity) const + const EntityT& entity) const { (void) query; // Copy this entitiy and its contents. @@ -81,13 +83,13 @@ namespace armarx::armem::base::query_proc entity.forEachSnapshot([this, &result](const EntitySnapshotT & snapshot) { addResultSnapshot(result, snapshot); - return true; }); } - void process(_EntityT& result, + + void process(ResultEntityT& result, const armem::query::data::entity::Single& query, - const _EntityT& entity) const + const EntityT& entity) const { if (query.timestamp < 0) { @@ -132,9 +134,10 @@ namespace armarx::armem::base::query_proc } } - void process(_EntityT& result, + + void process(ResultEntityT& result, const armem::query::data::entity::TimeRange& query, - const _EntityT& entity) const + const EntityT& entity) const { if (query.minTimestamp <= query.maxTimestamp || query.minTimestamp < 0 || query.maxTimestamp < 0) { @@ -144,9 +147,10 @@ namespace armarx::armem::base::query_proc } } - void process(_EntityT& result, + + void process(ResultEntityT& result, const armem::query::data::entity::IndexRange& query, - const _EntityT& entity) const + const EntityT& entity) const { entity.forEachSnapshotInIndexRange( query.first, query.last, @@ -156,10 +160,11 @@ namespace armarx::armem::base::query_proc }); } - void process(_EntityT& result, + + void process(ResultEntityT& result, const Time& min, const Time& max, - const _EntityT& entity, + const EntityT& entity, const armem::query::data::EntityQuery& query) const { (void) query; @@ -172,9 +177,9 @@ namespace armarx::armem::base::query_proc } - void process(_EntityT& result, + void process(ResultEntityT& result, const armem::query::data::entity::BeforeOrAtTime& query, - const _EntityT& entity) const + const EntityT& entity) const { const auto referenceTimestamp = fromIce<Time>(query.timestamp); ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp is negative!"; @@ -191,51 +196,40 @@ namespace armarx::armem::base::query_proc } - void process(_EntityT& result, + void process(ResultEntityT& result, const armem::query::data::entity::BeforeTime& query, - const _EntityT& entity) const + const EntityT& entity) const { const armem::Time referenceTimestamp = fromIce<Time>(query.timestamp); ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp must be non-negative."; -#if 0 - try + std::vector<const EntitySnapshotT*> befores; + entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s) { -#endif - std::vector<const EntitySnapshotT*> befores; - entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s) - { - befores.push_back(&s); - return true; - }); - - size_t num = 0; - if (query.maxEntries < 0) - { - num = befores.size(); - } - else - { - num = std::min(befores.size(), static_cast<size_t>(query.maxEntries)); - } + befores.push_back(&s); + }); - for (size_t r = 0; r < num; ++r) - { - size_t i = befores.size() - 1 - r; - addResultSnapshot(result, *befores[i]); - } -#if 0 + size_t num = 0; + if (query.maxEntries < 0) + { + num = befores.size(); } - catch (const error::MissingEntry&) + else { - // Leave empty. + num = std::min(befores.size(), static_cast<size_t>(query.maxEntries)); + } + + for (size_t r = 0; r < num; ++r) + { + size_t i = befores.size() - 1 - r; + addResultSnapshot(result, *befores[i]); } -#endif } - void process(_EntityT& result, + + void process(ResultEntityT& result, const armem::query::data::entity::TimeApprox& query, - const _EntityT& entity) const + const EntityT& entity) const { const auto referenceTimestamp = fromIce<Time>(query.timestamp); ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp is negative!"; @@ -281,14 +275,16 @@ namespace armarx::armem::base::query_proc } catch (const armem::error::MissingEntry&) { - } } protected: - virtual void addResultSnapshot(_EntityT& result, typename _EntityT::ContainerT::const_iterator it) const = 0; - virtual void addResultSnapshot(_EntityT& result, const typename _EntityT::EntitySnapshotT& snapshot) const = 0; + + void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const + { + result.addSnapshot(snapshot); + } }; } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h index 66c2a8042b740ec72c6be3ca653f6ed72fc8c35b..df71683c29f2cb17db976e8be971725934b03348 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h @@ -1,47 +1,56 @@ #pragma once -#include <regex> - -#include <RobotAPI/interface/armem/query.h> - #include "BaseQueryProcessorBase.h" -#include "CoreSegmentQueryProcessorBase.h" +#include <RobotAPI/libraries/armem/core/error.h> +#include <RobotAPI/interface/armem/query.h> #include <ArmarXCore/core/logging/Logging.h> #include <ArmarXCore/core/exceptions/local/ExpressionException.h> -#include <RobotAPI/libraries/armem/core/error.h> +#include <regex> -namespace armarx::armem::base::query_proc +namespace armarx::armem::server::query_proc::base { - /** - * @brief Handles memory queries. - */ - template <class _MemoryT> + + template <QueryTarget queryTarget, class _MemoryT, class _ResultMemoryT, class _ChildProcessorT> class MemoryQueryProcessorBase : - virtual public BaseQueryProcessorBase<_MemoryT, armem::query::data::MemoryQuery> + public BaseQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, armem::query::data::MemoryQuery> { - using Base = BaseQueryProcessorBase<_MemoryT, armem::query::data::MemoryQuery>; + using Base = BaseQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, armem::query::data::MemoryQuery>; public: + using MemoryT = _MemoryT; using CoreSegmentT = typename MemoryT::CoreSegmentT; - using ProviderSegmentT = typename CoreSegmentT::ProviderSegmentT; - using EntityT = typename ProviderSegmentT::EntityT; - using EntitySnapshotT = typename EntityT::EntitySnapshotT; + + using ResultMemoryT = _ResultMemoryT; + using ResultCoreSegmentT = typename ResultMemoryT::CoreSegmentT; + + using ChildProcessorT = _ChildProcessorT; + + + public: + + MemoryQueryProcessorBase() + { + } + MemoryQueryProcessorBase(ChildProcessorT&& childProcessor) : + childProcessor(childProcessor) + { + } using Base::process; - _MemoryT process(const armem::query::data::Input& input, const _MemoryT& memory) const + ResultMemoryT process(const armem::query::data::Input& input, const MemoryT& memory) const { return this->process(input.memoryQueries, memory); } - void process(_MemoryT& result, - const armem::query::data::MemoryQuery& query, - const _MemoryT& memory) const override + virtual void process(ResultMemoryT& result, + const armem::query::data::MemoryQuery& query, + const MemoryT& memory) const override { if (auto q = dynamic_cast<const armem::query::data::memory::All*>(&query)) { @@ -57,51 +66,52 @@ namespace armarx::armem::base::query_proc } else { - throw armem::error::UnknownQueryType("memory segment", query); + throw armem::error::UnknownQueryType(MemoryT::getLevelName(), query); } } - void process(_MemoryT& result, + void process(ResultMemoryT& result, const armem::query::data::memory::All& query, - const _MemoryT& memory) const + const MemoryT& memory) const { memory.forEachCoreSegment([this, &result, &query](const CoreSegmentT & coreSegment) { - result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment)); - return true; + childProcessor.process(result.addCoreSegment(coreSegment.name()), query.coreSegmentQueries, coreSegment); }); } - void process(_MemoryT& result, + void process(ResultMemoryT& result, const armem::query::data::memory::Single& query, - const _MemoryT& memory) const + const MemoryT& memory) const { try { const CoreSegmentT& coreSegment = memory.getCoreSegment(query.coreSegmentName); - result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment)); + childProcessor.process(result.addCoreSegment(coreSegment.name()), query.coreSegmentQueries, coreSegment); } catch (const error::MissingEntry&) { } } - void process(_MemoryT& result, + void process(ResultMemoryT& result, const armem::query::data::memory::Regex& query, - const _MemoryT& memory) const + const MemoryT& memory) const { const std::regex regex(query.coreSegmentNameRegex); memory.forEachCoreSegment([this, &result, &query, ®ex](const CoreSegmentT & coreSegment) { if (std::regex_search(coreSegment.name(), regex)) { - result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment)); + childProcessor.process(result.addCoreSegment(coreSegment.name()), query.coreSegmentQueries, coreSegment); } - return true; }); } + protected: - virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& a, const CoreSegmentT& o) const = 0; + + ChildProcessorT childProcessor; + }; } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h index cb191d02edeaaa471290d5bf67475a5950572213..5102a12829c106e58159e7dcc35a7df0890f93d5 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h @@ -1,39 +1,50 @@ #pragma once -#include <RobotAPI/interface/armem/query.h> - #include "BaseQueryProcessorBase.h" -#include "EntityQueryProcessorBase.h" -#include <regex> +#include <RobotAPI/libraries/armem/core/error.h> -#include <ArmarXCore/core/logging/Logging.h> -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <RobotAPI/interface/armem/query.h> -#include <RobotAPI/libraries/armem/core/error.h> +#include <regex> -namespace armarx::armem::base::query_proc +namespace armarx::armem::server::query_proc::base { - /** - * @brief Handles memory queries. - */ - template <class _ProviderSegmentT> + template <QueryTarget queryTarget, class _ProviderSegmentT, class _ResultProviderSegmentT, class _ChildProcessorT> class ProviderSegmentQueryProcessorBase : - virtual public BaseQueryProcessorBase<_ProviderSegmentT, armem::query::data::ProviderSegmentQuery> + public BaseQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, armem::query::data::ProviderSegmentQuery> { - using Base = BaseQueryProcessorBase<_ProviderSegmentT, armem::query::data::ProviderSegmentQuery>; + using Base = BaseQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, armem::query::data::ProviderSegmentQuery>; + public: + using ProviderSegmentT = _ProviderSegmentT; using EntityT = typename ProviderSegmentT::EntityT; - using EntitySnapshotT = typename EntityT::EntitySnapshotT; + + using ResultProviderSegmentT = _ResultProviderSegmentT; + using ResultEntityT = typename ResultProviderSegmentT::EntityT; + + using ChildProcessorT = _ChildProcessorT; + + + public: + + ProviderSegmentQueryProcessorBase() + { + } + ProviderSegmentQueryProcessorBase(ChildProcessorT&& childProcessor) : + childProcessor(childProcessor) + { + } + using Base::process; - void process(_ProviderSegmentT& result, - const armem::query::data::ProviderSegmentQuery& query, - const _ProviderSegmentT& providerSegment) const override + virtual void process(ResultProviderSegmentT& result, + const armem::query::data::ProviderSegmentQuery& query, + const ProviderSegmentT& providerSegment) const override { if (auto q = dynamic_cast<const armem::query::data::provider::All*>(&query)) { @@ -49,29 +60,28 @@ namespace armarx::armem::base::query_proc } else { - throw armem::error::UnknownQueryType("provider segment", query); + throw armem::error::UnknownQueryType(ProviderSegmentT::getLevelName(), query); } } - void process(_ProviderSegmentT& result, + void process(ResultProviderSegmentT& result, const armem::query::data::provider::All& query, - const _ProviderSegmentT& providerSegment) const + const ProviderSegmentT& providerSegment) const { providerSegment.forEachEntity([this, &result, &query](const EntityT & entity) { - result.addEntity(entityProcessorProcess(query.entityQueries, entity)); - return true; + childProcessor.process(result.addEntity(entity.name()), query.entityQueries, entity); }); } - void process(_ProviderSegmentT& result, + void process(ResultProviderSegmentT& result, const armem::query::data::provider::Single& query, - const _ProviderSegmentT& providerSegment) const + const ProviderSegmentT& providerSegment) const { try { const EntityT& entity = providerSegment.getEntity(query.entityName); - result.addEntity(entityProcessorProcess(query.entityQueries, entity)); + childProcessor.process(result.addEntity(entity.name()), query.entityQueries, entity); } catch (const error::MissingEntry&) { @@ -79,22 +89,25 @@ namespace armarx::armem::base::query_proc } } - void process(_ProviderSegmentT& result, + void process(ResultProviderSegmentT& result, const armem::query::data::provider::Regex& query, - const _ProviderSegmentT& providerSegment) const + const ProviderSegmentT& providerSegment) const { const std::regex regex(query.entityNameRegex); providerSegment.forEachEntity([this, &result, &query, ®ex](const EntityT & entity) { if (std::regex_search(entity.name(), regex)) { - result.addEntity(entityProcessorProcess(query.entityQueries, entity)); + childProcessor.process(result.addEntity(entity.name()), query.entityQueries, entity); } return true; }); } + protected: - virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& a, const EntityT& o) const = 0; + + ChildProcessorT childProcessor; + }; } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a695cf43d51dcbbc2329fa1c48fbe8e63565c24f --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.cpp @@ -0,0 +1,7 @@ +#include "diskmemory.h" + + +namespace armarx::armem::server::query_proc::d_ltm +{ +} + diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.h new file mode 100644 index 0000000000000000000000000000000000000000..0f2ffe791d192b9bc2b5f2a2be311735808427a4 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.h @@ -0,0 +1,32 @@ +#pragma once + +#include <RobotAPI/libraries/armem/core/diskmemory/Memory.h> +#include <RobotAPI/libraries/armem/server/query_proc/base.h> + + +namespace armarx::armem::server::query_proc::d_ltm +{ + static const base::QueryTarget queryTarget = query::data::QueryTarget::LTM; + + + class EntityQueryProcessor : + public base::EntityQueryProcessorBase<queryTarget, armem::d_ltm::Entity, armem::d_ltm::Entity> + { + }; + + class ProviderSegmentQueryProcessor : + public base::ProviderSegmentQueryProcessorBase <queryTarget, armem::d_ltm::ProviderSegment, armem::d_ltm::ProviderSegment, EntityQueryProcessor > + { + }; + + class CoreSegmentQueryProcessor : + public base::CoreSegmentQueryProcessorBase<queryTarget, armem::d_ltm::CoreSegment, armem::d_ltm::CoreSegment, ProviderSegmentQueryProcessor> + { + }; + + class MemoryQueryProcessor : + public base::MemoryQueryProcessorBase <queryTarget, armem::d_ltm::Memory, armem::d_ltm::Memory, CoreSegmentQueryProcessor > + { + }; + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp deleted file mode 100644 index 68821bcd95cdf2aaccf7126d4055495d39d0393d..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "BaseQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h deleted file mode 100644 index 0e3ddac45c6a8eee377f468767a3bc39a580c554..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <RobotAPI/interface/armem/query.h> -#include <RobotAPI/libraries/armem/core/DataMode.h> - -#include "../base/BaseQueryProcessorBase.h" - - -namespace armarx::armem::d_ltm::query_proc -{ - /** - * @brief Base class for memory query processors. - */ - template <class DataT, class QueryT> - class BaseQueryProcessor : - virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT> - { - using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>; - - public: - BaseQueryProcessor() - {} - - protected: - - query::data::QueryTarget getTargetType() const override - { - return query::data::QueryTarget::LTM; - } - - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp deleted file mode 100644 index afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CoreSegmentQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h deleted file mode 100644 index 5c043a2d1dbe2218078591adc3fc0ebac0bfe932..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/CoreSegmentQueryProcessorBase.h" - -#include "../../../core/diskmemory/CoreSegment.h" - -#include "ProviderSegmentQueryProcessor.h" - - -namespace armarx::armem::d_ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class CoreSegmentQueryProcessor : - virtual public BaseQueryProcessor<d_ltm::CoreSegment, armem::query::data::CoreSegmentQuery>, - virtual public base::query_proc::CoreSegmentQueryProcessorBase<d_ltm::CoreSegment> - { - using Base = BaseQueryProcessor<d_ltm::CoreSegment, armem::query::data::CoreSegmentQuery>; - - public: - CoreSegmentQueryProcessor() : - Base() - {} - - protected: - virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override - { - return providerSegmentProcessor.process(q, s); - } - - private: - ProviderSegmentQueryProcessor providerSegmentProcessor; - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp deleted file mode 100644 index c1c321b026b173c6552758fb9d8b9fdf722ea5a4..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "EntityQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h deleted file mode 100644 index 712345e2a3d650f43974af3190225daa51deb13a..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/EntityQueryProcessorBase.h" - -#include "../../../core/diskmemory/Entity.h" - -#include "EntityQueryProcessor.h" - -namespace armarx::armem::d_ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class EntityQueryProcessor : - virtual public BaseQueryProcessor<d_ltm::Entity, armem::query::data::EntityQuery>, - virtual public base::query_proc::EntityQueryProcessorBase<d_ltm::Entity> - { - using Base = BaseQueryProcessor<d_ltm::Entity, armem::query::data::EntityQuery>; - - public: - - EntityQueryProcessor() : - Base() - {} - - - private: - - void addResultSnapshot(d_ltm::Entity& result, d_ltm::Entity::ContainerT::const_iterator it) const override - { - addResultSnapshot(result, it->second); - } - - void addResultSnapshot(d_ltm::Entity& result, const d_ltm::EntitySnapshot& snapshot) const override - { - result.addSnapshot(d_ltm::EntitySnapshot(snapshot)); - } - - }; - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp deleted file mode 100644 index 69b04de6c9e623286a5bda836dddfdc8b551b64a..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "MemoryQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h deleted file mode 100644 index 038523950bfe399c2ef7a65b79fde43376651617..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/MemoryQueryProcessorBase.h" - -#include "../../../core/diskmemory/Memory.h" - -#include "CoreSegmentQueryProcessor.h" - -namespace armarx::armem::d_ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class MemoryQueryProcessor : - virtual public BaseQueryProcessor<d_ltm::Memory, armem::query::data::MemoryQuery>, - virtual public base::query_proc::MemoryQueryProcessorBase<d_ltm::Memory> - { - using Base = BaseQueryProcessor<d_ltm::Memory, armem::query::data::MemoryQuery>; - - public: - MemoryQueryProcessor() : - Base() - {} - - protected: - virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override - { - return coreSegmentProcessor.process(q, s); - } - - private: - CoreSegmentQueryProcessor coreSegmentProcessor; - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp deleted file mode 100644 index 9a2a4405001f0904b74fc6afcf96813eef0879cd..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "ProviderSegmentQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h deleted file mode 100644 index 2043273ec7c5f3fee2d02410a145ef436c47459c..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/ProviderSegmentQueryProcessorBase.h" - -#include "../../../core/diskmemory/ProviderSegment.h" - -#include "EntityQueryProcessor.h" - -namespace armarx::armem::d_ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class ProviderSegmentQueryProcessor : - virtual public BaseQueryProcessor<d_ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>, - virtual public base::query_proc::ProviderSegmentQueryProcessorBase<d_ltm::ProviderSegment> - { - using Base = BaseQueryProcessor<d_ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>; - - public: - ProviderSegmentQueryProcessor() : - Base() - {} - - protected: - virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override - { - return entityProcessor.process(q, s); - } - - private: - EntityQueryProcessor entityProcessor; - - }; - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp deleted file mode 100644 index 68821bcd95cdf2aaccf7126d4055495d39d0393d..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "BaseQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h deleted file mode 100644 index 64f560afff93e5d0cfff4b036f68f0fb4e8cdaba..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <RobotAPI/interface/armem/query.h> -#include <RobotAPI/libraries/armem/core/DataMode.h> - -#include "../base/BaseQueryProcessorBase.h" - - -namespace armarx::armem::ltm::query_proc -{ - /** - * @brief Base class for memory query processors. - */ - template <class DataT, class QueryT> - class BaseQueryProcessor : - virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT> - { - using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>; - - public: - BaseQueryProcessor() - {} - - protected: - - query::data::QueryTarget getTargetType() const override - { - return query::data::QueryTarget::LTM; - } - - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp deleted file mode 100644 index afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CoreSegmentQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h deleted file mode 100644 index dc379f1d88fa82bbe886e412e0341079fa43fce9..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/CoreSegmentQueryProcessorBase.h" - -#include "../../../core/longtermmemory/CoreSegment.h" - -#include "ProviderSegmentQueryProcessor.h" - - -namespace armarx::armem::ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class CoreSegmentQueryProcessor : - virtual public BaseQueryProcessor<ltm::CoreSegment, armem::query::data::CoreSegmentQuery>, - virtual public base::query_proc::CoreSegmentQueryProcessorBase<ltm::CoreSegment> - { - using Base = BaseQueryProcessor<ltm::CoreSegment, armem::query::data::CoreSegmentQuery>; - - public: - CoreSegmentQueryProcessor() : - Base() - {} - - protected: - virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override - { - return providerSegmentProcessor.process(q, s); - } - - private: - ProviderSegmentQueryProcessor providerSegmentProcessor; - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp deleted file mode 100644 index c1c321b026b173c6552758fb9d8b9fdf722ea5a4..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "EntityQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h deleted file mode 100644 index c7f793705e9143bb7b2f947f2750498ee26b8411..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/EntityQueryProcessorBase.h" - -#include "../../../core/longtermmemory/Entity.h" - -#include "EntityQueryProcessor.h" - -namespace armarx::armem::ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class EntityQueryProcessor : - virtual public BaseQueryProcessor<ltm::Entity, armem::query::data::EntityQuery>, - virtual public base::query_proc::EntityQueryProcessorBase<ltm::Entity> - { - using Base = BaseQueryProcessor<ltm::Entity, armem::query::data::EntityQuery>; - - public: - EntityQueryProcessor() : - Base() - {} - - private: - void addResultSnapshot(ltm::Entity& result, ltm::Entity::ContainerT::const_iterator it) const override - { - addResultSnapshot(result, it->second); - } - - void addResultSnapshot(ltm::Entity& result, const ltm::EntitySnapshot& snapshot) const override - { - result.addSnapshot(ltm::EntitySnapshot{snapshot}); - } - - }; - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp deleted file mode 100644 index 69b04de6c9e623286a5bda836dddfdc8b551b64a..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "MemoryQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h deleted file mode 100644 index a5129417262515975efa247398602272865ee5ec..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/MemoryQueryProcessorBase.h" - -#include "../../../core/longtermmemory/Memory.h" - -#include "CoreSegmentQueryProcessor.h" - -namespace armarx::armem::ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class MemoryQueryProcessor : - virtual public BaseQueryProcessor<ltm::Memory, armem::query::data::MemoryQuery>, - virtual public base::query_proc::MemoryQueryProcessorBase<ltm::Memory> - { - using Base = BaseQueryProcessor<ltm::Memory, armem::query::data::MemoryQuery>; - - public: - MemoryQueryProcessor() : - Base() - {} - - protected: - virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override - { - return coreSegmentProcessor.process(q, s); - } - - private: - CoreSegmentQueryProcessor coreSegmentProcessor; - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp deleted file mode 100644 index 9a2a4405001f0904b74fc6afcf96813eef0879cd..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "ProviderSegmentQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h deleted file mode 100644 index e0c6db9e3ef06e6241e9af8c572bb7fc78eec452..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "BaseQueryProcessor.h" -#include "../base/ProviderSegmentQueryProcessorBase.h" - -#include "../../../core/longtermmemory/ProviderSegment.h" - -#include "EntityQueryProcessor.h" - -namespace armarx::armem::ltm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class ProviderSegmentQueryProcessor : - virtual public BaseQueryProcessor<ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>, - virtual public base::query_proc::ProviderSegmentQueryProcessorBase<ltm::ProviderSegment> - { - using Base = BaseQueryProcessor<ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>; - - public: - ProviderSegmentQueryProcessor() : - Base() - {} - - protected: - virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override - { - return entityProcessor.process(q, s); - } - - private: - EntityQueryProcessor entityProcessor; - - }; - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..238cc4b8d1601bf1ffae131caabbf8ca8435899a --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp @@ -0,0 +1,7 @@ +#include "ltm.h" + + +namespace armarx::armem::server::query_proc::ltm +{ +} + diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm.h new file mode 100644 index 0000000000000000000000000000000000000000..ae0dc778c821ae138c98b8554a22237bf26e5989 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm.h @@ -0,0 +1,32 @@ +#pragma once + +#include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h> +#include <RobotAPI/libraries/armem/server/query_proc/base.h> + + +namespace armarx::armem::server::query_proc::ltm +{ + static const base::QueryTarget queryTarget = query::data::QueryTarget::LTM; + + + class EntityQueryProcessor : + public base::EntityQueryProcessorBase<queryTarget, armem::ltm::Entity, armem::ltm::Entity> + { + }; + + class ProviderSegmentQueryProcessor : + public base::ProviderSegmentQueryProcessorBase <queryTarget, armem::ltm::ProviderSegment, armem::ltm::ProviderSegment, EntityQueryProcessor > + { + }; + + class CoreSegmentQueryProcessor : + public base::CoreSegmentQueryProcessorBase <queryTarget, armem::ltm::CoreSegment, armem::ltm::CoreSegment, ProviderSegmentQueryProcessor> + { + }; + + class MemoryQueryProcessor : + public base::MemoryQueryProcessorBase <queryTarget, armem::ltm::Memory, armem::ltm::Memory, CoreSegmentQueryProcessor > + { + }; + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e968623d63aa57213507879608c81823d31c7d6 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp @@ -0,0 +1,70 @@ +#include "wm.h" + + + +namespace armarx::armem::server::query_proc::wm::detail +{ + + HasDataMode::HasDataMode(armem::DataMode dataMode) : dataMode(dataMode) + { + } + +} + + +namespace armarx::armem::server::query_proc::wm +{ + + ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) : + ProviderSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode) + { + } + + + CoreSegmentQueryProcessor::CoreSegmentQueryProcessor(DataMode dataMode) : + CoreSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode) + { + } + + + MemoryQueryProcessor::MemoryQueryProcessor(DataMode dataMode) : + MemoryQueryProcessorBase(dataMode), HasDataMode(dataMode) + { + } + +} + + +namespace armarx::armem::server::query_proc::wm_server +{ + ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) : + ProviderSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode) + { + } + + + CoreSegmentQueryProcessor::CoreSegmentQueryProcessor(DataMode dataMode) : + CoreSegmentQueryProcessorBase(dataMode), + HasDataMode(dataMode) + { + } + + + void CoreSegmentQueryProcessor::process( + armem::wm::CoreSegment& result, + const armem::query::data::CoreSegmentQuery& query, + const CoreSegment& coreSegment) const + { + std::scoped_lock lock(coreSegment.mutex()); + CoreSegmentQueryProcessorBase::process(result, query, coreSegment); + } + + + MemoryQueryProcessor::MemoryQueryProcessor(DataMode dataMode) : + MemoryQueryProcessorBase(dataMode), + HasDataMode(dataMode) + { + } + + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm.h b/source/RobotAPI/libraries/armem/server/query_proc/wm.h new file mode 100644 index 0000000000000000000000000000000000000000..aa52b4ab22fe1c6ef194ef37d4e38f5c7720d6c5 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm.h @@ -0,0 +1,164 @@ +#pragma once + +#include <RobotAPI/libraries/armem/core/DataMode.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/query_proc/base.h> + + +namespace armarx::armem::server::query_proc::wm +{ + static const base::QueryTarget queryTarget = query::data::QueryTarget::WM; +} +namespace armarx::armem::server::query_proc::wm::detail +{ + + class HasDataMode + { + public: + + HasDataMode(armem::DataMode dataMode); + + + protected: + + armem::DataMode dataMode; + + }; + + + + template <class SourceEntityT> + class EntityQueryProcessor : + public base::EntityQueryProcessorBase<queryTarget, SourceEntityT, armem::wm::Entity>, + public HasDataMode + { + public: + + EntityQueryProcessor(DataMode dataMode = DataMode::WithData) : + HasDataMode(dataMode) + {} + + + protected: + + void addResultSnapshot(armem::wm::Entity& result, const typename SourceEntityT::EntitySnapshotT& snapshot) const + { + bool withData = (dataMode == DataMode::WithData); + if (withData) + { + result.addSnapshot(server::wm::EntitySnapshot{ snapshot }); + } + else + { + server::wm::EntitySnapshot copy = snapshot; + copy.forEachInstance([](server::wm::EntityInstance & i) + { + i.data() = nullptr; + return true; + }); + result.addSnapshot(std::move(copy)); + } + } + + }; +} + + +namespace armarx::armem::server::query_proc::wm +{ + + using EntityQueryProcessor = detail::EntityQueryProcessor<armem::wm::Entity>; + + + class ProviderSegmentQueryProcessor : + public base::ProviderSegmentQueryProcessorBase<queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor >, + public detail::HasDataMode + { + public: + + ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); + + }; + + + class CoreSegmentQueryProcessor : + public base::CoreSegmentQueryProcessorBase <queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor >, + public detail::HasDataMode + { + using Base = base::CoreSegmentQueryProcessorBase<queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; + using CoreSegment = armem::wm::CoreSegment; + using ProviderSegment = armem::wm::ProviderSegment; + + public: + + CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); + + }; + + + class MemoryQueryProcessor : + public base::MemoryQueryProcessorBase<queryTarget, armem::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>, + public detail::HasDataMode + { + public: + + MemoryQueryProcessor(DataMode dataMode = DataMode::WithData); + + }; + +} + + +namespace armarx::armem::server::query_proc::wm_server +{ + + using EntityQueryProcessor = wm::detail::EntityQueryProcessor<server::wm::Entity>; + + + class ProviderSegmentQueryProcessor : + public base::ProviderSegmentQueryProcessorBase<wm::queryTarget, server::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor >, + public wm::detail::HasDataMode + { + public: + + ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); + + }; + + + class CoreSegmentQueryProcessor : + public base::CoreSegmentQueryProcessorBase <wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor >, + public wm::detail::HasDataMode + { + using Base = base::CoreSegmentQueryProcessorBase<wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; + using CoreSegment = server::wm::CoreSegment; + using ProviderSegment = server::wm::ProviderSegment; + + public: + + CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); + + + using Base::process; + + /// Locks the core segment, then delegates back to `CoreSegmentQueryProcessorBase`. + void process( + armem::wm::CoreSegment& result, + const armem::query::data::CoreSegmentQuery& query, + const CoreSegment& coreSegment) const override; + + }; + + + class MemoryQueryProcessor : + public base::MemoryQueryProcessorBase<wm::queryTarget, server::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>, + public wm::detail::HasDataMode + { + public: + + MemoryQueryProcessor(DataMode dataMode = DataMode::WithData); + + }; + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp deleted file mode 100644 index 68821bcd95cdf2aaccf7126d4055495d39d0393d..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "BaseQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h deleted file mode 100644 index d4875053c93dc2278cdb9f327fc0739370811fe7..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <RobotAPI/interface/armem/query.h> -#include <RobotAPI/libraries/armem/core/DataMode.h> - -#include <RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h> - - -namespace armarx::armem::wm::query_proc -{ - /** - * @brief Base class for memory query processors. - */ - template <class DataT, class QueryT> - class BaseQueryProcessor : - virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT> - { - using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>; - - public: - - BaseQueryProcessor(DataMode dataMode = DataMode::WithData) : - dataMode(dataMode) - {} - - - protected: - - query::data::QueryTarget getTargetType() const override - { - return query::data::QueryTarget::WM; - } - - DataMode dataMode; - - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp deleted file mode 100644 index deb66ad71924022ba5a4ebcf2aa582265023dcf5..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "CoreSegmentQueryProcessor.h" - -#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h> - - -namespace armarx::armem::wm::query_proc -{ - - CoreSegmentQueryProcessor::CoreSegmentQueryProcessor(DataMode dataMode) : - Base(dataMode), providerSegmentProcessor(dataMode) - {} - - - CoreSegmentQueryProcessor::~CoreSegmentQueryProcessor() = default; - - - void CoreSegmentQueryProcessor::process( - CoreSegment& result, const armem::query::data::CoreSegmentQuery& query, const CoreSegment& coreSegment) const - { - std::scoped_lock lock(coreSegment.mutex()); - CoreSegmentQueryProcessorBase::process(result, query, coreSegment); - } - - - data::CoreSegment CoreSegmentQueryProcessor::processToIce(const armem::query::data::CoreSegmentQuery& query, const wm::CoreSegment& coreSegment) const - { - data::CoreSegment data; - toIce(data, process(query, coreSegment)); - return data; - } - - - ProviderSegment CoreSegmentQueryProcessor::providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegment& s) const - { - return providerSegmentProcessor.process(q, s); - } - - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h deleted file mode 100644 index a09f5c8cef96350398e35d0448f9a3aee1f27a53..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include <mutex> - -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h> - -#include "BaseQueryProcessor.h" -#include "ProviderSegmentQueryProcessor.h" - - -namespace armarx::armem::wm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class CoreSegmentQueryProcessor : - virtual public BaseQueryProcessor<wm::CoreSegment, armem::query::data::CoreSegmentQuery>, - virtual public base::query_proc::CoreSegmentQueryProcessorBase<wm::CoreSegment> - { - using Base = BaseQueryProcessor<wm::CoreSegment, armem::query::data::CoreSegmentQuery>; - - public: - - CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); - virtual ~CoreSegmentQueryProcessor() override; - - using Base::process; - - /// Locks the core segment, then delegates back to `CoreSegmentQueryProcessorBase`. - void process(CoreSegment& result, - const armem::query::data::CoreSegmentQuery& query, - const CoreSegment& coreSegment) const override; - - data::CoreSegment processToIce(const armem::query::data::CoreSegmentQuery& query, const wm::CoreSegment& coreSegment) const; - - - protected: - - virtual ProviderSegment providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override; - - - private: - - ProviderSegmentQueryProcessor providerSegmentProcessor; - - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp deleted file mode 100644 index ec1c7640c229c551d0b8b6b1a8f2df7b771139ef..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "EntityQueryProcessor.h" - -#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h> - - -namespace armarx::armem::wm::query_proc -{ - EntityQueryProcessor::EntityQueryProcessor(DataMode dataMode) : - BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>(dataMode) - {} - - - EntityQueryProcessor::~EntityQueryProcessor() = default; - - - void EntityQueryProcessor::addResultSnapshot(wm::Entity& result, const wm::EntitySnapshot& snapshot) const - { - bool withData = (dataMode == DataMode::WithData); - if (withData) - { - result.addSnapshot(wm::EntitySnapshot{ snapshot }); - } - else - { - wm::EntitySnapshot copy = snapshot; - copy.forEachInstance([](EntityInstance & i) - { - i.data() = nullptr; - return true; - }); - result.addSnapshot(std::move(copy)); - } - } - - - data::Entity EntityQueryProcessor::processToIce(const armem::query::data::EntityQuery& query, const wm::Entity& entity) const - { - data::Entity data; - toIce(data, process(query, entity)); - return data; - } - - - void EntityQueryProcessor::addResultSnapshot(wm::Entity& result, wm::Entity::ContainerT::const_iterator it) const - { - addResultSnapshot(result, it->second); - } - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h deleted file mode 100644 index 4d0a2e02ad44a3364ee4cfd6a4e7db3b0c5fb993..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h> - -#include "BaseQueryProcessor.h" - - -namespace armarx::armem::wm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class EntityQueryProcessor : - virtual public BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>, - virtual public base::query_proc::EntityQueryProcessorBase<wm::Entity> - { - using Base = BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>; - - public: - - EntityQueryProcessor(DataMode dataMode = DataMode::WithData); - virtual ~EntityQueryProcessor() override; - - data::Entity processToIce(const armem::query::data::EntityQuery& query, const wm::Entity& entity) const; - - - private: - - void addResultSnapshot(wm::Entity& result, wm::Entity::ContainerT::const_iterator it) const override; - void addResultSnapshot(wm::Entity& result, const wm::EntitySnapshot& snapshot) const override; - - }; - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp deleted file mode 100644 index 7aa868af13bc525b42d93f230a8398c27531525d..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "MemoryQueryProcessor.h" - - -namespace armarx::armem::wm::query_proc -{ - - MemoryQueryProcessor::MemoryQueryProcessor(DataMode dataMode) : - Base(dataMode), coreSegmentProcessor(dataMode) - {} - - - MemoryQueryProcessor::~MemoryQueryProcessor() - { - } - - - CoreSegment MemoryQueryProcessor::coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegment& s) const - { - return coreSegmentProcessor.process(q, s); - } - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h deleted file mode 100644 index a442baaf38b297ab3659228e21e0a158cd00a4bb..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h> - -#include "BaseQueryProcessor.h" - -#include "CoreSegmentQueryProcessor.h" - - -namespace armarx::armem::wm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class MemoryQueryProcessor : - virtual public BaseQueryProcessor<wm::Memory, armem::query::data::MemoryQuery>, - virtual public base::query_proc::MemoryQueryProcessorBase<wm::Memory> - { - using Base = BaseQueryProcessor<wm::Memory, armem::query::data::MemoryQuery>; - - public: - - MemoryQueryProcessor(DataMode dataMode = DataMode::WithData); - virtual ~MemoryQueryProcessor() override; - - - protected: - - virtual CoreSegment coreSegmentProcessorProcess( - const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegment& s) const override; - - - private: - - CoreSegmentQueryProcessor coreSegmentProcessor; - - }; -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp deleted file mode 100644 index d50d252aacbd6460bcaa668b2e983c445b018f17..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "ProviderSegmentQueryProcessor.h" - -#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h> - - -namespace armarx::armem::wm::query_proc -{ - - ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) : - Base(dataMode), entityProcessor(dataMode) - {} - - - ProviderSegmentQueryProcessor::~ProviderSegmentQueryProcessor() = default; - - - data::ProviderSegment ProviderSegmentQueryProcessor::processToIce(const armem::query::data::ProviderSegmentQuery& query, const wm::ProviderSegment& providerSegment) const - { - data::ProviderSegment data; - toIce(data, process(query, providerSegment)); - return data; - } - - - Entity ProviderSegmentQueryProcessor::entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const Entity& s) const - { - return entityProcessor.process(q, s); - } - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h deleted file mode 100644 index ee878428d4e52d237bb0fe9c9050fa071c38953a..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h> - -#include "BaseQueryProcessor.h" -#include "EntityQueryProcessor.h" - - -namespace armarx::armem::wm::query_proc -{ - /** - * @brief Handles memory queries. - */ - class ProviderSegmentQueryProcessor : - virtual public BaseQueryProcessor<wm::ProviderSegment, armem::query::data::ProviderSegmentQuery>, - virtual public base::query_proc::ProviderSegmentQueryProcessorBase<wm::ProviderSegment> - { - using Base = BaseQueryProcessor<wm::ProviderSegment, armem::query::data::ProviderSegmentQuery>; - - public: - - ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); - virtual ~ProviderSegmentQueryProcessor() override; - - - using Base::process; - data::ProviderSegment processToIce(const armem::query::data::ProviderSegmentQuery& query, const wm::ProviderSegment& providerSegment) const; - - - protected: - - virtual Entity entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const Entity& s) const override; - - private: - - EntityQueryProcessor entityProcessor; - - }; -} diff --git a/source/RobotAPI/libraries/armem/server/segment/Segment.h b/source/RobotAPI/libraries/armem/server/segment/Segment.h index 52d12980eaf68a022ae595e7da41f3b2c03fd5a4..7808e99d31f4df3543bfbd5b882a408dda143ed5 100644 --- a/source/RobotAPI/libraries/armem/server/segment/Segment.h +++ b/source/RobotAPI/libraries/armem/server/segment/Segment.h @@ -16,11 +16,12 @@ namespace armarx::armem namespace server { class MemoryToIceAdapter; - } - namespace wm - { - class CoreSegment; - class ProviderSegment; + + namespace wm + { + class CoreSegment; + class ProviderSegment; + } } } namespace armarx::armem::server::segment @@ -67,9 +68,9 @@ namespace armarx::armem::server::segment /** * @brief A base class for core segments */ - class CoreSegmentBase : public detail::SegmentBase<armarx::armem::wm::CoreSegment> + class CoreSegmentBase : public detail::SegmentBase<server::wm::CoreSegment> { - using Base = detail::SegmentBase<armarx::armem::wm::CoreSegment>; + using Base = detail::SegmentBase<server::wm::CoreSegment>; public: @@ -107,9 +108,9 @@ namespace armarx::armem::server::segment /** * @brief A base class for provider segments */ - class ProviderSegmentBase : public detail::SegmentBase<armarx::armem::wm::ProviderSegment> + class ProviderSegmentBase : public detail::SegmentBase<server::wm::ProviderSegment> { - using Base = detail::SegmentBase<armarx::armem::wm::ProviderSegment>; + using Base = detail::SegmentBase<server::wm::ProviderSegment>; public: @@ -142,7 +143,7 @@ namespace armarx::armem::server::segment aron::typenavigator::ObjectNavigatorPtr coreSegmentAronType; aron::typenavigator::ObjectNavigatorPtr providerSegmentAronType; - armarx::armem::wm::CoreSegment* coreSegment; + server::wm::CoreSegment* coreSegment; }; diff --git a/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h b/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h index d6601c39b8076a140070db86859b38d575e52dc7..460fbf3f0f0cd4ea6c2835d499071f2e43bf2a7d 100644 --- a/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h +++ b/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h @@ -14,11 +14,11 @@ namespace armarx::armem namespace server { class MemoryToIceAdapter; - } - namespace wm - { - class CoreSegment; + namespace wm + { + class CoreSegment; + } } } @@ -59,7 +59,7 @@ namespace armarx::armem::server::segment protected: server::MemoryToIceAdapter& iceMemory; - wm::CoreSegment* coreSegment = nullptr; + server::wm::CoreSegment* coreSegment = nullptr; aron::typenavigator::ObjectNavigatorPtr aronType; struct Properties diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.cpp similarity index 85% rename from source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp rename to source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.cpp index f1a308f0764a8cb8067f3403ef5427d904fa93dc..d90756691871b6ad444a67fa76a733d0086b5b29 100644 --- a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp +++ b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.cpp @@ -1,7 +1,7 @@ #include "MaxHistorySize.h" -namespace armarx::armem::base::detail +namespace armarx::armem::server::detail { void MaxHistorySize::setMaxHistorySize(long maxSize) { diff --git a/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.h b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.h new file mode 100644 index 0000000000000000000000000000000000000000..e2f2d498c2945f4456c281abafe0f1ad66074e72 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.h @@ -0,0 +1,58 @@ +#pragma once + + +namespace armarx::armem::server::detail +{ + // TODO: Replace by ConstrainedHistorySize (not only max entries, e.g. delete oldest / delete least accessed / ...) + + class MaxHistorySize + { + public: + + /** + * @brief Set the maximum number of snapshots to be contained in an entity. + * Affected entities are to be update right away. + */ + void setMaxHistorySize(long maxSize); + + long getMaxHistorySize() const; + + + protected: + + /** + * @brief Maximum size of entity histories. + * + * If negative, the size of `history` is not limited. + * + * @see Entity::maxHstorySize + */ + long _maxHistorySize = -1; + + }; + + + + template <class DerivedT> + class MaxHistorySizeParent : public MaxHistorySize + { + public: + + /** + * @brief Sets the maximum history size of entities in this container. + * This affects all current entities as well as new ones. + * + * @see MaxHistorySize::setMaxHistorySize() + */ + void setMaxHistorySize(long maxSize) + { + MaxHistorySize::setMaxHistorySize(maxSize); + static_cast<DerivedT&>(*this).forEachChild([maxSize](auto & child) + { + child.setMaxHistorySize(maxSize); + return true; + }); + } + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/wm/ice_conversions.cpp b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ba3352d6e8bb443693ebfa5752a46cad9c24267 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.cpp @@ -0,0 +1,64 @@ +#include "ice_conversions.h" + +#include <RobotAPI/libraries/armem/core/base/ice_conversions.h> + + +namespace armarx::armem::server +{ + + void wm::toIce(data::EntityInstance& ice, const EntityInstance& data) + { + base::toIce(ice, data); + } + void wm::fromIce(const data::EntityInstance& ice, EntityInstance& data) + { + base::fromIce(ice, data); + } + + + void wm::toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot) + { + base::toIce(ice, snapshot); + } + void wm::fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot) + { + base::fromIce(ice, snapshot); + } + + void wm::toIce(data::Entity& ice, const Entity& entity) + { + base::toIce(ice, entity); + } + void wm::fromIce(const data::Entity& ice, Entity& entity) + { + base::fromIce(ice, entity); + } + + void wm::toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment) + { + base::toIce(ice, providerSegment); + } + void wm::fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment) + { + base::fromIce(ice, providerSegment); + } + + void wm::toIce(data::CoreSegment& ice, const CoreSegment& coreSegment) + { + base::toIce(ice, coreSegment); + } + void wm::fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment) + { + base::fromIce(ice, coreSegment); + } + + void wm::toIce(data::Memory& ice, const Memory& memory) + { + base::toIce(ice, memory); + } + void wm::fromIce(const data::Memory& ice, Memory& memory) + { + base::fromIce(ice, memory); + } + +} diff --git a/source/RobotAPI/libraries/armem/server/wm/ice_conversions.h b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.h new file mode 100644 index 0000000000000000000000000000000000000000..c25b16775bc577c61d0c804cf4525b23ecd5e5d1 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.h @@ -0,0 +1,30 @@ +#pragma once + +#include <RobotAPI/interface/armem/memory.h> + +#include "memory_definitions.h" + + +namespace armarx::armem::server::wm +{ + + void toIce(data::EntityInstance& ice, const EntityInstance& data); + void fromIce(const data::EntityInstance& ice, EntityInstance& data); + + + void toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot); + void fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot); + + void toIce(data::Entity& ice, const Entity& entity); + void fromIce(const data::Entity& ice, Entity& entity); + + + void toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment); + void fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment); + + void toIce(data::CoreSegment& ice, const CoreSegment& coreSegment); + void fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment); + + void toIce(data::Memory& ice, const Memory& memory); + void fromIce(const data::Memory& ice, Memory& memory); +} diff --git a/source/RobotAPI/libraries/armem/server/wm/memory_definitions.cpp b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58be8027db2561979d3510b7d481715678b61eae --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.cpp @@ -0,0 +1,202 @@ +#include "memory_definitions.h" + +#include "error.h" + +#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +#include <map> +#include <vector> + + +namespace armarx::armem::server::wm +{ + + void Entity::setMaxHistorySize(long maxSize) + { + MaxHistorySize::setMaxHistorySize(maxSize); + truncate(); + } + + + auto Entity::update(const EntityUpdate& update) -> UpdateResult + { + UpdateResult result = EntityBase::update(update); + result.removedSnapshots = this->truncate(); + return result; + } + + + std::vector<EntitySnapshot> Entity::truncate() + { + std::vector<EntitySnapshot> removedElements; + if (_maxHistorySize >= 0) + { + while (this->_container.size() > size_t(_maxHistorySize)) + { + removedElements.push_back(std::move(this->_container.begin()->second)); + this->_container.erase(this->_container.begin()); + } + ARMARX_CHECK_LESS_EQUAL(this->_container.size(), _maxHistorySize); + } + return removedElements; + } + + + + Entity& ProviderSegment::addEntity(Entity&& entity) + { + Entity& added = ProviderSegmentBase::addEntity(std::move(entity)); + added.setMaxHistorySize(this->getMaxHistorySize()); + return added; + } + + + + std::mutex& CoreSegment::mutex() const + { + return _mutex; + } + + + std::optional<wm::EntitySnapshot> CoreSegment::getLatestEntitySnapshot(const MemoryID& entityID) const + { + const wm::Entity& entity = this->getEntity(entityID); + if (entity.empty()) + { + return std::nullopt; + } + else + { + return entity.getLatestSnapshot(); + } + } + + + std::optional<wm::EntityInstance> CoreSegment::getLatestEntityInstance( + const MemoryID& entityID, int instanceIndex) const + { + auto snapshot = getLatestEntitySnapshot(entityID); + if (snapshot.has_value() + and instanceIndex >= 0 + and static_cast<size_t>(instanceIndex) < snapshot->size()) + { + return snapshot->getInstance(instanceIndex); + } + else + { + return std::nullopt; + } + } + + + armarx::aron::datanavigator::DictNavigatorPtr + CoreSegment::getLatestEntityInstanceData(const MemoryID& entityID, int instanceIndex) const + { + auto instance = getLatestEntityInstance(entityID, instanceIndex); + if (instance.has_value()) + { + return instance->data(); + } + else + { + return nullptr; + } + } + + + ProviderSegment& CoreSegment::addProviderSegment(ProviderSegment&& providerSegment) + { + ProviderSegmentT& added = CoreSegmentBase::addProviderSegment(std::move(providerSegment)); + added.setMaxHistorySize(this->getMaxHistorySize()); + return added; + } + + + std::optional<wm::EntitySnapshot> + CoreSegment::getLatestEntitySnapshotLocking(const MemoryID& entityID) const + { + std::scoped_lock lock(_mutex); + return getLatestEntitySnapshot(entityID); + } + + std::optional<wm::EntityInstance> + CoreSegment::getLatestEntityInstanceLocking(const MemoryID& entityID, int instanceIndex) const + { + std::scoped_lock lock(_mutex); + return getLatestEntityInstance(entityID, instanceIndex); + } + + armarx::aron::datanavigator::DictNavigatorPtr + CoreSegment::getLatestEntityInstanceDataLocking(const MemoryID& entityID, int instanceIndex) const + { + std::scoped_lock lock(_mutex); + return getLatestEntityInstanceData(entityID, instanceIndex); + } + + + // TODO: add core segment if param is set + std::vector<Memory::Base::UpdateResult> + Memory::updateLocking(const Commit& commit) + { + // Group updates by core segment, then update each core segment in a batch to only lock it once. + std::map<std::string, std::vector<const EntityUpdate*>> updatesPerCoreSegment; + for (const EntityUpdate& update : commit.updates) + { + updatesPerCoreSegment[update.entityID.coreSegmentName].push_back(&update); + } + + std::vector<Memory::Base::UpdateResult> result; + // To throw an exception after the commit if a core segment is missing and the memory should not create new ones + std::vector<std::string> missingCoreSegmentNames; + for (const auto& [coreSegmentName, updates] : updatesPerCoreSegment) + { + auto it = this->_container.find(coreSegmentName); + if (it != this->_container.end()) + { + CoreSegment& coreSegment = it->second; + + // Lock the core segment for the whole batch. + std::scoped_lock lock(coreSegment.mutex()); + + for (const EntityUpdate* update : updates) + { + auto r = coreSegment.update(*update); + Base::UpdateResult ret { r }; + ret.memoryUpdateType = UpdateType::UpdatedExisting; + result.push_back(ret); + } + } + else + { + // Perform the other updates first, then throw afterwards. + missingCoreSegmentNames.push_back(coreSegmentName); + } + } + // Throw an exception if something went wrong. + if (not missingCoreSegmentNames.empty()) + { + // Just throw an exception for the first entry. We can extend this exception in the future. + throw armem::error::MissingEntry::create<CoreSegment>(missingCoreSegmentNames.front(), *this); + } + return result; + } + + + // TODO: Add core segment if param is set + Memory::Base::UpdateResult + Memory::updateLocking(const EntityUpdate& update) + { + this->_checkContainerName(update.entityID.memoryName, this->name()); + + CoreSegment& segment = getCoreSegment(update.entityID.coreSegmentName); + Base::UpdateResult result; + { + std::scoped_lock lock(segment.mutex()); + result = segment.update(update); + } + result.memoryUpdateType = UpdateType::UpdatedExisting; + return result; + } + +} diff --git a/source/RobotAPI/libraries/armem/server/wm/memory_definitions.h b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.h new file mode 100644 index 0000000000000000000000000000000000000000..4eb6fdbb3105b0ae2ce3148c8457b915040a170a --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.h @@ -0,0 +1,189 @@ +#pragma once + +#include "detail/MaxHistorySize.h" + +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/core/base/EntityInstanceBase.h> +#include <RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h> +#include <RobotAPI/libraries/armem/core/base/EntityBase.h> +#include <RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h> +#include <RobotAPI/libraries/armem/core/base/CoreSegmentBase.h> +#include <RobotAPI/libraries/armem/core/base/MemoryBase.h> + +#include <mutex> +#include <optional> + + +namespace armarx::armem::server::wm +{ + using EntityInstanceMetadata = base::EntityInstanceMetadata; + using EntityInstanceData = armarx::aron::datanavigator::DictNavigator; + using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr; + + using EntityInstance = armem::wm::EntityInstance; + using EntitySnapshot = armem::wm::EntitySnapshot; + + + /// @see base::EntityBase + class Entity : + public base::EntityBase<EntitySnapshot, Entity>, + public detail::MaxHistorySize + { + public: + + using base::EntityBase<EntitySnapshot, Entity>::EntityBase; + + + /** + * @brief Sets the maximum history size. + * + * The current history is truncated if necessary. + */ + void setMaxHistorySize(long maxSize); + + UpdateResult update(const EntityUpdate& update); + + + protected: + + /// If maximum size is set, ensure `history`'s is not higher. + std::vector<EntitySnapshotT> truncate(); + + }; + + + + /// @see base::ProviderSegmentBase + class ProviderSegment : + public base::ProviderSegmentBase<Entity, ProviderSegment>, + public detail::MaxHistorySizeParent<ProviderSegment> + { + public: + + using base::ProviderSegmentBase<Entity, ProviderSegment>::ProviderSegmentBase; + + + using ProviderSegmentBase::addEntity; + EntityT& addEntity(EntityT&& entity); + + }; + + + + /// @brief base::CoreSegmentBase + class CoreSegment : + public base::CoreSegmentBase<ProviderSegment, CoreSegment>, + public detail::MaxHistorySizeParent<CoreSegment> + { + using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>; + + public: + + using Base::CoreSegmentBase; + + // ToDo: Replace by runLocked() + std::mutex& mutex() const; + + + // Non-locking interface + + std::optional<wm::EntitySnapshot> getLatestEntitySnapshot( + const MemoryID& entityID) const; + std::optional<wm::EntityInstance> getLatestEntityInstance( + const MemoryID& entityID, int instanceIndex = 0) const; + armarx::aron::datanavigator::DictNavigatorPtr getLatestEntityInstanceData( + const MemoryID& entityID, int instanceIndex = 0) const; + + + template <class AronDtoT> + std::optional<AronDtoT> getLatestEntityInstanceDataAs( + const MemoryID& entityID, int instanceIndex = 0) const + { + wm::EntityInstanceDataPtr data = getLatestEntityInstanceData(entityID, instanceIndex); + if (data) + { + AronDtoT aron; + aron.fromAron(data); + return aron; + } + else + { + return std::nullopt; + } + } + + + /// @see base::CoreSegmentBase::addProviderSegment() + using CoreSegmentBase::addProviderSegment; + ProviderSegment& addProviderSegment(ProviderSegment&& providerSegment); + + + // Locking interface + + std::optional<wm::EntitySnapshot> getLatestEntitySnapshotLocking( + const MemoryID& entityID) const; + std::optional<wm::EntityInstance> getLatestEntityInstanceLocking( + const MemoryID& entityID, int instanceIndex = 0) const; + armarx::aron::datanavigator::DictNavigatorPtr getLatestEntityInstanceDataLocking( + const MemoryID& entityID, int instanceIndex = 0) const; + + + template <class AronDtoT> + std::optional<AronDtoT> getLatestEntityInstanceDataLockingAs( + const MemoryID& entityID, int instanceIndex = 0) const + { + // Keep lock to a minimum. + wm::EntityInstanceDataPtr data = nullptr; + { + std::scoped_lock lock(_mutex); + data = getLatestEntityInstanceData(entityID, instanceIndex); + } + if (data) + { + AronDtoT aron; + aron.fromAron(data); + return aron; + } + else + { + return std::nullopt; + } + } + + + protected: + + mutable std::mutex _mutex; + + }; + + + + /// @see base::MemoryBase + class Memory : + public base::MemoryBase<CoreSegment, Memory> + { + using Base = base::MemoryBase<CoreSegment, Memory>; + + public: + + using Base::MemoryBase; + + + /** + * @brief Perform the commit, locking the core segments. + * + * Groups the commits by core segment, and updates each core segment + * in a batch, locking the core segment. + */ + std::vector<Base::UpdateResult> updateLocking(const Commit& commit); + + /** + * @brief Update the memory, locking the updated core segment. + */ + Base::UpdateResult updateLocking(const EntityUpdate& update); + + }; + +} + diff --git a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp index 0e51493955af7e917e4cd2ef533f0872b4b7488d..376f2ec680f92e64a5c72b496543749a303e8cc1 100644 --- a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp +++ b/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp @@ -27,6 +27,7 @@ #include <RobotAPI/Test.h> #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h> #include <RobotAPI/libraries/armem/core/diskmemory/Memory.h> #include <RobotAPI/libraries/armem/core/error.h> @@ -701,7 +702,7 @@ BOOST_AUTO_TEST_CASE(test_segment_setup) BOOST_AUTO_TEST_CASE(test_history_size_in_entity) { - armem::wm::Entity entity("entity"); + armem::server::wm::Entity entity("entity"); armem::EntityUpdate update; update.entityID.entityName = entity.name(); @@ -744,7 +745,7 @@ BOOST_AUTO_TEST_CASE(test_history_size_in_entity) BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment) { - armem::wm::ProviderSegment providerSegment("SomeRGBImageProvider"); + armem::server::wm::ProviderSegment providerSegment("SomeRGBImageProvider"); armem::EntityUpdate update; update.entityID.providerSegmentName = providerSegment.name(); diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp index 32795093a9c602e694a580b962279891f2062d50..656842b3dcd23d49a84a51a04fc02143c14cada2 100644 --- a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp +++ b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp @@ -26,9 +26,9 @@ #include <RobotAPI/Test.h> #include <RobotAPI/interface/armem/query.h> -#include <RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h> #include <RobotAPI/libraries/armem/core/error.h> #include <RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.h> +#include <RobotAPI/libraries/armem/server/query_proc/wm.h> #include <SimoxUtility/algorithm/get_map_keys_values.h> #include <SimoxUtility/algorithm/string.h> @@ -39,7 +39,7 @@ namespace armem = armarx::armem; namespace aron = armarx::aron; namespace query = armarx::armem::query::data; -using EntityQueryProcessor = armarx::armem::wm::query_proc::EntityQueryProcessor; +using EntityQueryProcessor = armarx::armem::server::query_proc::wm::EntityQueryProcessor; namespace ArMemQueryTest @@ -53,7 +53,7 @@ namespace ArMemQueryTest { armem::wm::Entity entity; - armem::wm::query_proc::EntityQueryProcessor processor; + armem::server::query_proc::wm::EntityQueryProcessor processor; std::vector<armem::wm::Entity> results; diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp index bc63d69b96701b226b10c83d3b28eca3a7ea154c..5e5431e41aa6a94ba8616247ec19a5529ca9927e 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp @@ -5,8 +5,8 @@ #include <RobotAPI/libraries/armem/core/diskmemory/Memory.h> -#include <RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h> -#include <RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h> +#include <RobotAPI/libraries/armem/server/query_proc/diskmemory.h> +#include <RobotAPI/libraries/armem/server/query_proc/wm.h> #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h> @@ -243,7 +243,7 @@ namespace armarx::armem::gui input.addQueryTargetToAll(armem::query::data::QueryTarget::LTM); // We use LTM as query target for the disk - armem::d_ltm::query_proc::MemoryQueryProcessor d_ltm_processor; + armem::server::query_proc::d_ltm::MemoryQueryProcessor d_ltm_processor; dMem = d_ltm_processor.process(input.toIce(), dMem); wm::Memory converted = dMem.convert(); @@ -302,7 +302,7 @@ namespace armarx::armem::gui std::stringstream ss; auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); - ss << "Last update: " << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X"); + ss << "Last update: " ;// << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X"); if (dataChanged) { diff --git a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp index 67ffed4ba2e37812dc40a31a8534f1119b384282..5860b2f48f9659c7ac631e1270425f112a0efcab 100644 --- a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp +++ b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp @@ -1,8 +1,3 @@ -// STD / STL -#include <iostream> -#include <fstream> -#include <sstream> - // BaseClass #include "Segment.h" @@ -11,10 +6,16 @@ #include <RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.h> #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h> #include <ArmarXCore/core/application/properties/ProxyPropertyDefinition.h> +// STD / STL +#include <iostream> +#include <fstream> +#include <sstream> + namespace armarx::armem::server::motions::mdb { diff --git a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp index 365958be88ce336c2404b1af157940cd27b5acf9..2ddcc827d80c0700f59cb5f9ee8638322f4e5633 100644 --- a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp @@ -3,14 +3,15 @@ #include <sstream> #include <ArmarXCore/core/time/TimeUtil.h> -#include "ArmarXCore/core/logging/Logging.h" -#include <ArmarXCore/core/application/properties/forward_declarations.h> +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h> +#include <ArmarXCore/core/application/properties/PluginAll.h> -#include "RobotAPI/libraries/armem/util/util.h" -#include "RobotAPI/libraries/aron/common/aron_conversions.h" +#include <RobotAPI/libraries/armem/util/util.h> +#include <RobotAPI/libraries/aron/common/aron_conversions.h> #include <RobotAPI/libraries/armem/core/aron_conversions.h> -#include "RobotAPI/libraries/armem/core/MemoryID.h" +#include <RobotAPI/libraries/armem/core/MemoryID.h> #include <RobotAPI/libraries/armem/client/Writer.h> #include <RobotAPI/libraries/armem/client/query/Builder.h> #include <RobotAPI/libraries/armem/client/query/query_fns.h> @@ -49,34 +50,32 @@ namespace armarx::armem::server::obj::attachments { } - std::vector<armarx::armem::attachment::ObjectAttachment> Segment::getAttachments(const armem::Time& timestamp) const + std::vector<armarx::armem::attachment::ObjectAttachment> + Segment::getAttachments(const armem::Time& timestamp) const { ARMARX_CHECK_NOT_NULL(coreSegment); std::scoped_lock(coreSegment->mutex()); std::vector<armarx::armem::attachment::ObjectAttachment> attachments; - - for (const auto& [_, provSeg] : *coreSegment) + coreSegment->forEachEntity([this, &attachments](const wm::Entity & entity) { - for (const auto& [name, entity] : provSeg.entities()) - { - const auto& entityInstance = entity.getLatestSnapshot().getInstance(0); - const auto aronAttachment = tryCast<armarx::armem::arondto::attachment::ObjectAttachment>(entityInstance); + const wm::EntityInstance& entityInstance = entity.getLatestSnapshot().getInstance(0); - if (not aronAttachment) - { - ARMARX_WARNING << "Could not convert entity instance to 'ObjectAttachment'"; - continue; - } + const auto aronAttachment = tryCast<armarx::armem::arondto::attachment::ObjectAttachment>(entityInstance); + if (not aronAttachment) + { + ARMARX_WARNING << "Could not convert entity instance to 'ObjectAttachment'"; + return true; + } - ARMARX_DEBUG << "Key is " << armem::MemoryID(entity.id()); + ARMARX_DEBUG << "Key is " << armem::MemoryID(entity.id()); - armarx::armem::attachment::ObjectAttachment attachment; - fromAron(*aronAttachment, attachment); + armarx::armem::attachment::ObjectAttachment attachment; + fromAron(*aronAttachment, attachment); - attachments.push_back(attachment); - } - } + attachments.push_back(attachment); + return true; + }); return attachments; } diff --git a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h index 0b9302d93390c473b87c67066bfe173237f3774b..4f8cd20ccd9a0ce456bb664f5f5eb8a25f1981e0 100644 --- a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h +++ b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h @@ -21,41 +21,19 @@ #pragma once -#include <string> -#include <optional> -#include <mutex> -#include <unordered_map> +#include <RobotAPI/libraries/armem/core/Time.h> +#include <RobotAPI/libraries/armem/core/forward_declarations.h> +#include <RobotAPI/libraries/armem/server/forward_declarations.h> +#include <RobotAPI/libraries/armem_objects/types.h> -#include <ArmarXCore/core/logging/Logging.h> #include <ArmarXCore/core/application/properties/forward_declarations.h> +#include <ArmarXCore/core/logging/Logging.h> -// #include "ArmarXGui/libraries/RemoteGui/Client/Widgets.h" - -#include "RobotAPI/components/ArViz/Client/Client.h" - -#include "RobotAPI/libraries/armem/core/MemoryID.h" -#include "RobotAPI/libraries/armem/core/Time.h" -#include "RobotAPI/libraries/armem_objects/types.h" - - -namespace armarx::armem -{ - namespace server - { - class MemoryToIceAdapter; - } - - namespace wm - { - class CoreSegment; - } -} // namespace armarx::armem +#include <string> namespace armarx::armem::server::obj::attachments { - class Visu; - class Segment : public armarx::Logging { diff --git a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp index 35ce3d1cf113183ea60489a522048caa8058645e..1e9957aff7b0d093d3bd1d6e16f289d6a2a04afd 100644 --- a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp @@ -1,6 +1,7 @@ #include "FloorVis.h" #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> #include <RobotAPI/libraries/armem_objects/aron/ObjectClass.aron.generated.h> #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h> @@ -13,16 +14,19 @@ namespace armarx::armem::server::obj::clazz { } + void FloorVis::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix) { properties.define(defs, prefix); } + void FloorVis::setArViz(armarx::viz::Client arviz) { this->arviz = arviz; } + void FloorVis::updateFloorObject(const wm::CoreSegment& classCoreSegment) { viz::Layer layer = arviz.layer(properties.layerName); @@ -42,6 +46,7 @@ namespace armarx::armem::server::obj::clazz arviz.commit(layer); } + armarx::viz::Object FloorVis::makeFloorObject(const wm::Entity& classEntity) { const wm::EntityInstance& instance = classEntity.getLatestSnapshot().getInstance(0); @@ -50,6 +55,7 @@ namespace armarx::armem::server::obj::clazz return makeFloorObject(classEntity.name(), data); } + armarx::viz::Object FloorVis::makeFloorObject( const std::string& name, const arondto::ObjectClass& objectClass) @@ -61,7 +67,6 @@ namespace armarx::armem::server::obj::clazz } - void FloorVis::Properties::define(armarx::PropertyDefinitionsPtr defs, const std::string& prefix) { defs->optional(show, prefix + "Show", "Whether to show the floor."); diff --git a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h index dcce63977438bdd0d646b50aa8e5dd9679354df8..49f8a6ddd71f5c24172ddfbbfd8e312dcea2fd3f 100644 --- a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h +++ b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h @@ -10,7 +10,7 @@ namespace armarx { using PropertyDefinitionsPtr = IceUtil::Handle<class PropertyDefinitionContainer>; } -namespace armarx::armem::wm +namespace armarx::armem::server::wm { class CoreSegment; class Entity; diff --git a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp index 22608257c1abcf39340643870b704c2dadfcd54d..cd10a49c91957e5fa86094597c7903f76fb04c13 100644 --- a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp @@ -285,16 +285,13 @@ namespace armarx::armem::server::obj::clazz showComboBox = {}; showOptionsIndex.clear(); - for (const auto& [_, prov] : *segment.coreSegment) + segment.coreSegment->forEachEntity([this](const wm::Entity & entity) { - for (const auto& [_, entity] : prov) - { - std::stringstream option; - option << entity.id().entityName << " (" << entity.id().providerSegmentName << ")"; - showComboBox.addOption(option.str()); - showOptionsIndex.push_back(entity.id()); - } - } + std::stringstream option; + option << entity.id().entityName << " (" << entity.id().providerSegmentName << ")"; + showComboBox.addOption(option.str()); + showOptionsIndex.push_back(entity.id()); + }); if (showOptionsIndex.empty()) { showComboBox.addOption("<none>"); diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp index e1826b2b2e3556734b3224d2cb3cc112cab755c4..d6d224fe0580e4aa73656515a671ba5753e33326 100644 --- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp @@ -25,8 +25,9 @@ #include <RobotAPI/libraries/core/FramedPose.h> #include <RobotAPI/libraries/core/remoterobot/RemoteRobot.h> -#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> #include <ArmarXCore/core/system/cmake/CMakePackageFinder.h> +#include <ArmarXCore/core/time/TimeUtil.h> #include <SimoxUtility/algorithm/get_map_keys_values.h> #include <SimoxUtility/json.h> @@ -142,7 +143,7 @@ namespace armarx::armem::server::obj::instance // Check whether we have an old snapshot for this object. std::optional<objpose::ObjectPose> previousPose; - const armem::wm::Entity* entity = findObjectEntity(armarx::fromIce(provided.objectID), providerName); + const wm::Entity* entity = findObjectEntity(armarx::fromIce(provided.objectID), providerName); if (entity) { const arondto::ObjectInstance data = getLatestInstanceData(*entity); @@ -249,21 +250,24 @@ namespace armarx::armem::server::obj::instance } - wm::CoreSegment& Segment::getCoreSegment() + wm::CoreSegment& + Segment::getCoreSegment() { ARMARX_CHECK_NOT_NULL(coreSegment); return *coreSegment; } - const wm::CoreSegment& Segment::getCoreSegment() const + const wm::CoreSegment& + Segment::getCoreSegment() const { ARMARX_CHECK_NOT_NULL(coreSegment); return *coreSegment; } - objpose::ObjectPoseMap Segment::getObjectPoses(IceUtil::Time now) + objpose::ObjectPoseMap + Segment::getObjectPoses(IceUtil::Time now) { ObjectPoseMap objectPoses = getLatestObjectPoses(); updateObjectPoses(objectPoses, now); @@ -272,7 +276,8 @@ namespace armarx::armem::server::obj::instance - objpose::ObjectPoseMap Segment::getObjectPosesByProvider( + objpose::ObjectPoseMap + Segment::getObjectPosesByProvider( const std::string& providerName, IceUtil::Time now) { @@ -283,13 +288,14 @@ namespace armarx::armem::server::obj::instance } - armem::wm::Entity* Segment::findObjectEntity(const ObjectID& objectID, const std::string& providerName) + wm::Entity* + Segment::findObjectEntity(const ObjectID& objectID, const std::string& providerName) { ARMARX_CHECK_NOT_NULL(coreSegment); armem::MemoryID entityID = armem::MemoryID().withEntityName(objectID.str()); if (providerName.empty()) { - armem::wm::Entity* result = nullptr; + wm::Entity* result = nullptr; coreSegment->forEachProviderSegment([&result, &entityID](wm::ProviderSegment & prov) { if (prov.hasEntity(entityID.entityName)) @@ -306,7 +312,7 @@ namespace armarx::armem::server::obj::instance entityID.providerSegmentName = providerName; if (coreSegment->hasProviderSegment(providerName)) { - armem::wm::ProviderSegment& prov = coreSegment->getProviderSegment(providerName); + wm::ProviderSegment& prov = coreSegment->getProviderSegment(providerName); return prov.hasEntity(entityID.entityName) ? &prov.getEntity(entityID) : nullptr; } else @@ -389,14 +395,16 @@ namespace armarx::armem::server::obj::instance } - objpose::ObjectPoseMap Segment::getLatestObjectPoses() const + objpose::ObjectPoseMap + Segment::getLatestObjectPoses() const { ARMARX_CHECK_NOT_NULL(coreSegment); return getLatestObjectPoses(*coreSegment); } - objpose::ObjectPoseMap Segment::getLatestObjectPoses(const armem::wm::CoreSegment& coreSeg) + objpose::ObjectPoseMap + Segment::getLatestObjectPoses(const wm::CoreSegment& coreSeg) { ObjectPoseMap result; getLatestObjectPoses(coreSeg, result); @@ -404,7 +412,8 @@ namespace armarx::armem::server::obj::instance } - objpose::ObjectPoseMap Segment::getLatestObjectPoses(const armem::wm::ProviderSegment& provSeg) + objpose::ObjectPoseMap + Segment::getLatestObjectPoses(const wm::ProviderSegment& provSeg) { ObjectPoseMap result; getLatestObjectPoses(provSeg, result); @@ -412,7 +421,8 @@ namespace armarx::armem::server::obj::instance } - objpose::ObjectPose Segment::getLatestObjectPose(const armem::wm::Entity& entity) + objpose::ObjectPose + Segment::getLatestObjectPose(const wm::Entity& entity) { ObjectPose result; getLatestObjectPose(entity, result); @@ -420,7 +430,7 @@ namespace armarx::armem::server::obj::instance } - void Segment::getLatestObjectPoses(const armem::wm::CoreSegment& coreSeg, ObjectPoseMap& out) + void Segment::getLatestObjectPoses(const wm::CoreSegment& coreSeg, ObjectPoseMap& out) { coreSeg.forEachProviderSegment([&out](const wm::ProviderSegment & provSegment) { @@ -429,7 +439,7 @@ namespace armarx::armem::server::obj::instance } - void Segment::getLatestObjectPoses(const armem::wm::ProviderSegment& provSegment, ObjectPoseMap& out) + void Segment::getLatestObjectPoses(const wm::ProviderSegment& provSegment, ObjectPoseMap& out) { provSegment.forEachEntity([&out](const wm::Entity & entity) { @@ -451,7 +461,7 @@ namespace armarx::armem::server::obj::instance } - void Segment::getLatestObjectPose(const armem::wm::Entity& entity, ObjectPose& out) + void Segment::getLatestObjectPose(const wm::Entity& entity, ObjectPose& out) { entity.getLatestSnapshot().forEachInstance([&out](const wm::EntityInstance & instance) { @@ -463,13 +473,13 @@ namespace armarx::armem::server::obj::instance } - arondto::ObjectInstance Segment::getLatestInstanceData(const armem::wm::Entity& entity) + arondto::ObjectInstance Segment::getLatestInstanceData(const wm::Entity& entity) { ARMARX_CHECK_GREATER_EQUAL(entity.size(), 1); - const armem::wm::EntitySnapshot& snapshot = entity.getLatestSnapshot(); + const wm::EntitySnapshot& snapshot = entity.getLatestSnapshot(); ARMARX_CHECK_EQUAL(snapshot.size(), 1); - const armem::wm::EntityInstance& instance = snapshot.getInstance(0); + const wm::EntityInstance& instance = snapshot.getInstance(0); arondto::ObjectInstance data; data.fromAron(instance.data()); @@ -478,7 +488,8 @@ namespace armarx::armem::server::obj::instance } - ::armarx::armem::articulated_object::ArticulatedObjects Segment::getArticulatedObjects() + ::armarx::armem::articulated_object::ArticulatedObjects + Segment::getArticulatedObjects() { objpose::ObjectPoseMap objectPoses = getObjectPoses(IceUtil::Time::now()); @@ -591,7 +602,7 @@ namespace armarx::armem::server::obj::instance // Find object pose (provider name can be empty). - armem::wm::Entity* objectEntity = this->findObjectEntity(objectID, input.providerName); + wm::Entity* objectEntity = this->findObjectEntity(objectID, input.providerName); if (!objectEntity || objectEntity->empty()) { ARMARX_WARNING << "Tried to attach object " << objectID << " to node '" << frameName @@ -652,7 +663,8 @@ namespace armarx::armem::server::obj::instance } - objpose::DetachObjectFromRobotNodeOutput Segment::detachObjectFromRobotNode( + objpose::DetachObjectFromRobotNodeOutput + Segment::detachObjectFromRobotNode( const objpose::DetachObjectFromRobotNodeInput& input) { const armem::Time now = armem::Time::now(); @@ -664,7 +676,7 @@ namespace armarx::armem::server::obj::instance { // Remove from latest pose (if it was cached). // Find object pose (provider name can be empty). - armem::wm::Entity* entity = this->findObjectEntity(objectID, input.providerName); + wm::Entity* entity = this->findObjectEntity(objectID, input.providerName); if (entity) { const arondto::ObjectInstance data = getLatestInstanceData(*entity); @@ -699,7 +711,8 @@ namespace armarx::armem::server::obj::instance } - objpose::DetachAllObjectsFromRobotNodesOutput Segment::detachAllObjectsFromRobotNodes( + objpose::DetachAllObjectsFromRobotNodesOutput + Segment::detachAllObjectsFromRobotNodes( const objpose::DetachAllObjectsFromRobotNodesInput& input) { ARMARX_CHECK_NOT_NULL(coreSegment); @@ -726,9 +739,9 @@ namespace armarx::armem::server::obj::instance void Segment::storeDetachedSnapshot( - armem::wm::Entity& entity, + wm::Entity& entity, const arondto::ObjectInstance& data, - armem::Time now, + Time now, bool commitAttachedPose) { armem::EntityUpdate update; @@ -760,7 +773,8 @@ namespace armarx::armem::server::obj::instance } - std::optional<wm::EntityInstance> Segment::findClassInstance(const ObjectID& objectID) const + std::optional<wm::EntityInstance> + Segment::findClassInstance(const ObjectID& objectID) const { const ObjectID classID = { objectID.dataset(), objectID.className() }; try @@ -810,7 +824,8 @@ namespace armarx::armem::server::obj::instance } - std::optional<armem::obj::SceneSnapshot> Segment::loadScene(const std::string& filename) + std::optional<armem::obj::SceneSnapshot> + Segment::loadScene(const std::string& filename) { if (const std::optional<std::filesystem::path> path = resolveSceneFilename(filename)) { @@ -823,7 +838,8 @@ namespace armarx::armem::server::obj::instance } - std::optional<armem::obj::SceneSnapshot> Segment::loadScene(const std::filesystem::path& path) + std::optional<armem::obj::SceneSnapshot> + Segment::loadScene(const std::filesystem::path& path) { ARMARX_INFO << "Loading scene snapshot from: \n" << path; nlohmann::json j; @@ -845,7 +861,8 @@ namespace armarx::armem::server::obj::instance const std::string Segment::timestampPlaceholder = "%TIMESTAMP"; - std::optional<std::filesystem::path> Segment::resolveSceneFilename(const std::string& _filename) + std::optional<std::filesystem::path> + Segment::resolveSceneFilename(const std::string& _filename) { std::string filename = _filename; diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h index f6ba671898adbae4fb84db127e17bfb6ed0fbaed..27ffbc746af05451b5fdd54f15a3afc4c7822e08 100644 --- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h +++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h @@ -8,8 +8,6 @@ #include <SimoxUtility/caching/CacheMap.h> #include <SimoxUtility/shapes/OrientedBox.h> -#include <ArmarXCore/core/logging/Logging.h> - #include <RobotAPI/interface/core/RobotState.h> #include <RobotAPI/interface/objectpose/ObjectPoseStorageInterface.h> @@ -19,7 +17,7 @@ #include <RobotAPI/libraries/ArmarXObjects/ObjectPose.h> #include <RobotAPI/libraries/ArmarXObjects/ObjectFinder.h> -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/server/segment/SpecializedSegment.h> #include "ArticulatedObjectVisu.h" diff --git a/source/RobotAPI/libraries/armem_objects/types.h b/source/RobotAPI/libraries/armem_objects/types.h index 976f438e7c39009fd5d37fb6afdf19378da488c4..5ca91ff285e5fc92d1d3523a504379d582dda8b5 100644 --- a/source/RobotAPI/libraries/armem_objects/types.h +++ b/source/RobotAPI/libraries/armem_objects/types.h @@ -21,13 +21,11 @@ #pragma once -#include "RobotAPI/libraries/armem/core/Time.h" -#include <vector> - #include <Eigen/Geometry> -#include <RobotAPI/libraries/armem_robot/types.h> #include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/Time.h> +#include <RobotAPI/libraries/armem_robot/types.h> namespace armarx::armem::attachment @@ -97,4 +95,4 @@ namespace armarx::armem::articulated_object using ArticulatedObject = armarx::armem::robot::Robot; using ArticulatedObjects = armarx::armem::robot::Robots; -} // namespace armarx::armem::articulated_object \ No newline at end of file +} // namespace armarx::armem::articulated_object diff --git a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp index 7990703b1bb8bd1c533e9d01f427d905f4b1eedd..18b84d7c665c593369b4bd15dd5505d5c5fa88d1 100644 --- a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp @@ -2,7 +2,6 @@ #include <SimoxUtility/algorithm/get_map_keys_values.h> #include <SimoxUtility/algorithm/string/string_tools.h> -#include <SimoxUtility/color/cmaps.h> #include <SimoxUtility/math/pose/interpolate.h> #include <ArmarXCore/core/exceptions/LocalException.h> @@ -10,8 +9,10 @@ #include <RobotAPI/libraries/aron/common/aron_conversions.h> +#include <RobotAPI/libraries/armem/core/Time.h> #include <RobotAPI/libraries/armem/core/error/ArMemError.h> #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> #include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron_conversions.h> @@ -20,86 +21,100 @@ namespace armarx::armem::common::robot_state::localization { - TransformChainResult TransformHelper::lookupTransformChain(const armem::wm::CoreSegment& localizationCoreSegment, - const TransformQuery& query) + template <class ...Args> + TransformResult + TransformHelper::_lookupTransform( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const TransformQuery& query) { - const std::vector<std::string> tfChain = - buildTransformChain(localizationCoreSegment, query); - + const std::vector<std::string> tfChain = _buildTransformChain(localizationCoreSegment, query); if (tfChain.empty()) { - return {.header = query.header, - .transforms = std::vector<Eigen::Affine3f>{}, - .status = TransformChainResult::Status::ErrorFrameNotAvailable, + return {.transform = {.header = query.header}, + .status = TransformResult::Status::ErrorFrameNotAvailable, .errorMessage = "Cannot create tf lookup chain '" + query.header.parentFrame + " -> " + query.header.frame + "'"}; } - const std::vector<Eigen::Affine3f> transforms = obtainTransforms( + const std::vector<Eigen::Affine3f> transforms = _obtainTransforms( localizationCoreSegment, tfChain, query.header.agent, query.header.timestamp); - if (transforms.empty()) { ARMARX_WARNING << deactivateSpam(1) << "No transform available."; - return {.header = query.header, - .transforms = {}, - .status = TransformChainResult::Status::ErrorFrameNotAvailable, + return {.transform = {.header = query.header}, + .status = TransformResult::Status::ErrorFrameNotAvailable, .errorMessage = "Error in TF loookup: '" + query.header.parentFrame + " -> " + query.header.frame + "'. No memory data in time range."}; } + const Eigen::Affine3f transform = std::accumulate(transforms.begin(), + transforms.end(), + Eigen::Affine3f::Identity(), + std::multiplies<>()); ARMARX_DEBUG << "Found valid transform"; - return {.header = query.header, - .transforms = transforms, - .status = TransformChainResult::Status::Success}; + return {.transform = {.header = query.header, .transform = transform}, + .status = TransformResult::Status::Success}; } - TransformResult TransformHelper::lookupTransform(const armem::wm::CoreSegment& localizationCoreSegment, - const TransformQuery& query) - { - const std::vector<std::string> tfChain = - buildTransformChain(localizationCoreSegment, query); + template <class ...Args> + TransformChainResult + TransformHelper::_lookupTransformChain( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const TransformQuery& query) + { + const std::vector<std::string> tfChain = _buildTransformChain(localizationCoreSegment, query); if (tfChain.empty()) { - return {.transform = {.header = query.header}, - .status = TransformResult::Status::ErrorFrameNotAvailable, - .errorMessage = "Cannot create tf lookup chain '" + - query.header.parentFrame + " -> " + query.header.frame + - "'"}; + return + { + .header = query.header, + .transforms = std::vector<Eigen::Affine3f>{}, + .status = TransformChainResult::Status::ErrorFrameNotAvailable, + .errorMessage = "Cannot create tf lookup chain '" + + query.header.parentFrame + " -> " + query.header.frame + + "'" + }; } - const std::vector<Eigen::Affine3f> transforms = obtainTransforms( + const std::vector<Eigen::Affine3f> transforms = _obtainTransforms( localizationCoreSegment, tfChain, query.header.agent, query.header.timestamp); - if (transforms.empty()) { ARMARX_WARNING << deactivateSpam(1) << "No transform available."; - return {.transform = {.header = query.header}, - .status = TransformResult::Status::ErrorFrameNotAvailable, - .errorMessage = "Error in TF loookup: '" + query.header.parentFrame + - " -> " + query.header.frame + - "'. No memory data in time range."}; + return + { + .header = query.header, + .transforms = {}, + .status = TransformChainResult::Status::ErrorFrameNotAvailable, + .errorMessage = "Error in TF loookup: '" + query.header.parentFrame + + " -> " + query.header.frame + + "'. No memory data in time range." + }; } - const Eigen::Affine3f transform = std::accumulate(transforms.begin(), - transforms.end(), - Eigen::Affine3f::Identity(), - std::multiplies<>()); ARMARX_DEBUG << "Found valid transform"; - return {.transform = {.header = query.header, .transform = transform}, - .status = TransformResult::Status::Success}; + return + { + .header = query.header, + .transforms = transforms, + .status = TransformChainResult::Status::Success + }; } + + + template <class ...Args> std::vector<std::string> - TransformHelper::buildTransformChain(const armem::wm::CoreSegment& localizationCoreSegment, - const TransformQuery& query) + TransformHelper::_buildTransformChain( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const TransformQuery& query) { ARMARX_DEBUG << "Building transform chain"; @@ -172,8 +187,100 @@ namespace armarx::armem::common::robot_state::localization return chain; } - inline ::armarx::armem::robot_state::Transform - convertEntityToTransform(const armem::wm::EntityInstance& item) + + template <class ...Args> + std::vector<Eigen::Affine3f> + TransformHelper::_obtainTransforms( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const std::vector<std::string>& tfChain, + const std::string& agent, + const armem::Time& timestamp) + { + const auto& agentProviderSegment = localizationCoreSegment.getProviderSegment(agent); + + ARMARX_DEBUG << "Provider segments" << localizationCoreSegment.getProviderSegmentNames(); + ARMARX_DEBUG << "Entities: " << agentProviderSegment.getEntityNames(); + + try + { + std::vector<Eigen::Affine3f> transforms; + transforms.reserve(tfChain.size()); + std::transform(tfChain.begin(), + tfChain.end(), + std::back_inserter(transforms), + [&](const std::string & entityName) + { + return _obtainTransform(entityName, agentProviderSegment, timestamp); + }); + return transforms; + } + catch (const armem::error::MissingEntry& missingEntryError) + { + ARMARX_WARNING << missingEntryError.what(); + } + catch (const ::armarx::exceptions::local::ExpressionException& ex) + { + ARMARX_WARNING << "local exception: " << ex.what(); + } + catch (...) + { + ARMARX_WARNING << "Error: " << GetHandledExceptionString(); + } + + return {}; + } + + + template <class ...Args> + Eigen::Affine3f + TransformHelper::_obtainTransform( + const std::string& entityName, + const armem::base::ProviderSegmentBase<Args...>& agentProviderSegment, + const armem::Time& timestamp) + { + ARMARX_DEBUG << "getEntity:" + entityName; + const auto& entity = agentProviderSegment.getEntity(entityName); + + ARMARX_DEBUG << "History (size: " << entity.size() << "): " << entity.getTimestamps(); + + // if (entity.history.empty()) + // { + // // TODO(fabian.reister): fixme boom + // ARMARX_ERROR << "No snapshots received."; + // return Eigen::Affine3f::Identity(); + // } + + std::vector<::armarx::armem::robot_state::Transform> transforms; + transforms.push_back(_convertEntityToTransform(entity.getLatestSnapshot().getInstance(0))); + + ARMARX_DEBUG << "obtaining transform"; + if (transforms.size() > 1) + { + // TODO(fabian.reister): remove + return transforms.front().transform; + + ARMARX_DEBUG << "More than one snapshots received: " << transforms.size(); + const auto p = _interpolateTransform(transforms, timestamp); + ARMARX_DEBUG << "Done interpolating transform"; + return p; + } + + // accept this to fail (will raise armem::error::MissingEntry) + if (transforms.empty()) + { + ARMARX_DEBUG << "empty transform"; + + throw armem::error::MissingEntry("foo", "bar", "foo2", "bar2", 0); + } + + ARMARX_DEBUG << "single transform"; + + return transforms.front().transform; + } + + + ::armarx::armem::robot_state::Transform + TransformHelper::_convertEntityToTransform(const armem::wm::EntityInstance& item) { arondto::Transform aronTransform; aronTransform.fromAron(item.data()); @@ -211,8 +318,9 @@ namespace armarx::armem::common::robot_state::localization } Eigen::Affine3f - interpolateTransform(const std::vector<::armarx::armem::robot_state::Transform>& queue, - armem::Time timestamp) + TransformHelper::_interpolateTransform( + const std::vector<::armarx::armem::robot_state::Transform>& queue, + armem::Time timestamp) { ARMARX_TRACE; @@ -255,109 +363,33 @@ namespace armarx::armem::common::robot_state::localization return simox::math::interpolatePose(posePreIt->transform, poseNextIt->transform, static_cast<float>(t)); } - std::vector<Eigen::Affine3f> - TransformHelper::obtainTransforms(const armem::wm::CoreSegment& localizationCoreSegment, - const std::vector<std::string>& tfChain, - const std::string& agent, - const armem::Time& timestamp) - { - const auto& agentProviderSegment = localizationCoreSegment.getProviderSegment(agent); - - ARMARX_DEBUG << "Provider segments" - << simox::alg::get_keys(localizationCoreSegment.providerSegments()); - - ARMARX_DEBUG << "Entities: " << simox::alg::get_keys(agentProviderSegment.entities()); - - try - { - std::vector<Eigen::Affine3f> transforms; - transforms.reserve(tfChain.size()); - std::transform(tfChain.begin(), - tfChain.end(), - std::back_inserter(transforms), - [&](const std::string & entityName) - { - return obtainTransform( - entityName, agentProviderSegment, timestamp); - }); - return transforms; - } - catch (const armem::error::MissingEntry& missingEntryError) - { - ARMARX_WARNING << missingEntryError.what(); - } - catch (const ::armarx::exceptions::local::ExpressionException& ex) - { - ARMARX_WARNING << "local exception: " << ex.what(); - } - catch (...) - { - ARMARX_WARNING << "Error: " << GetHandledExceptionString(); - } - - - return {}; + TransformResult TransformHelper::lookupTransform( + const armem::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query) + { + return _lookupTransform(localizationCoreSegment, query); } - - Eigen::Affine3f - TransformHelper::obtainTransform(const std::string& entityName, - const armem::wm::ProviderSegment& agentProviderSegment, - const armem::Time& timestamp) + TransformResult TransformHelper::lookupTransform( + const armem::server::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query) { + return _lookupTransform(localizationCoreSegment, query); + } - ARMARX_DEBUG << "getEntity:" + entityName; - const auto& entity = agentProviderSegment.getEntity(entityName); - - ARMARX_DEBUG << "History (size: " << entity.history().size() << ")" - << simox::alg::get_keys(entity.history()); - - // if (entity.history.empty()) - // { - // // TODO(fabian.reister): fixme boom - // ARMARX_ERROR << "No snapshots received."; - // return Eigen::Affine3f::Identity(); - // } - - std::vector<::armarx::armem::robot_state::Transform> transforms; - transforms.reserve(entity.history().size()); - - // const auto entitySnapshots = simox::alg::get_values(entity.history()); - - const std::vector<wm::EntitySnapshot> entitySnapshots = {entity.getLatestSnapshot()}; - - std::transform( - entitySnapshots.begin(), - entitySnapshots.end(), - std::back_inserter(transforms), - [](const auto & entitySnapshot) - { - return convertEntityToTransform(entitySnapshot.getInstance(0)); - }); - - ARMARX_DEBUG << "obtaining transform"; - - if (transforms.size() > 1) - { - // TODO(fabian.reister): remove - return transforms.front().transform; - - ARMARX_DEBUG << "More than one snapshots received: " << transforms.size(); - const auto p = interpolateTransform(transforms, timestamp); - ARMARX_DEBUG << "Done interpolating transform"; - return p; - } - // accept this to fail (will raise armem::error::MissingEntry) - if (transforms.empty()) - { - ARMARX_DEBUG << "empty transform"; - - throw armem::error::MissingEntry("foo", "bar", "foo2", "bar2", 0); - } + TransformChainResult TransformHelper::lookupTransformChain( + const armem::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query) + { + return _lookupTransformChain(localizationCoreSegment, query); + } + TransformChainResult TransformHelper::lookupTransformChain( + const armem::server::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query) + { + return _lookupTransformChain(localizationCoreSegment, query); + } - ARMARX_DEBUG << "single transform"; - return transforms.front().transform; - } } // namespace armarx::armem::common::robot_state::localization diff --git a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h index 0f1f20de89fa551c4e84fff8a378cc03172c52ef..9de1fbd994f5a17c00987ce70d31525db7d9d1dd 100644 --- a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h +++ b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h @@ -26,45 +26,102 @@ #include <Eigen/Core> #include <Eigen/Geometry> +#include <RobotAPI/libraries/armem/core/forward_declarations.h> #include <RobotAPI/libraries/armem_robot_state/common/localization/types.h> -namespace armarx::armem::wm -{ - class CoreSegment; - class ProviderSegment; -} // namespace armarx::armem::wm - namespace armarx::armem::common::robot_state::localization { using armarx::armem::common::robot_state::localization::TransformQuery; using armarx::armem::common::robot_state::localization::TransformResult; + + class TransformHelper { public: - static TransformResult - lookupTransform(const armem::wm::CoreSegment& localizationCoreSegment, - const TransformQuery& query); - static TransformChainResult - lookupTransformChain(const armem::wm::CoreSegment& localizationCoreSegment, - const TransformQuery& query); + static + TransformResult + lookupTransform( + const armem::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query); + + static + TransformResult + lookupTransform( + const armem::server::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query); + + + static + TransformChainResult + lookupTransformChain( + const armem::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query); + + static + TransformChainResult + lookupTransformChain( + const armem::server::wm::CoreSegment& localizationCoreSegment, + const TransformQuery& query); + private: - static std::vector<std::string> - buildTransformChain(const armem::wm::CoreSegment& localizationCoreSegment, - const TransformQuery& query); - - static std::vector<Eigen::Affine3f> - obtainTransforms(const armem::wm::CoreSegment& localizationCoreSegment, - const std::vector<std::string>& tfChain, - const std::string& agent, - const armem::Time& timestamp); - - static Eigen::Affine3f - obtainTransform(const std::string& entityName, - const armem::wm::ProviderSegment& agentProviderSegment, - const armem::Time& timestamp); + + template <class ...Args> + static + TransformResult + _lookupTransform( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const TransformQuery& query); + + + template <class ...Args> + static + TransformChainResult + _lookupTransformChain( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const TransformQuery& query); + + + template <class ...Args> + static + std::vector<std::string> + _buildTransformChain( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const TransformQuery& query); + + + template <class ...Args> + static + std::vector<Eigen::Affine3f> + _obtainTransforms( + const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment, + const std::vector<std::string>& tfChain, + const std::string& agent, + const armem::Time& timestamp); + + + template <class ...Args> + static + Eigen::Affine3f + _obtainTransform( + const std::string& entityName, + const armem::base::ProviderSegmentBase<Args...>& agentProviderSegment, + const armem::Time& timestamp); + + + static + Eigen::Affine3f + _interpolateTransform( + const std::vector<::armarx::armem::robot_state::Transform>& queue, + armem::Time timestamp); + + static + ::armarx::armem::robot_state::Transform + _convertEntityToTransform( + const armem::wm::EntityInstance& item); + }; } // namespace armarx::armem::common::robot_state::localization