From 527ec329612adba70b7ae51b73a518402e0866f0 Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@kit.edu> Date: Thu, 5 Aug 2021 16:38:55 +0200 Subject: [PATCH] Merge files into memory_definitions, rename directory to match namespace --- .../RobotAPI/libraries/armem/CMakeLists.txt | 41 ++-- source/RobotAPI/libraries/armem/core/wm.h | 10 + .../aron_conversions.cpp} | 0 .../aron_conversions.h} | 3 +- .../{workingmemory => wm}/ice_conversions.cpp | 4 +- .../{workingmemory => wm}/ice_conversions.h | 2 +- .../json_conversions.cpp | 0 .../{workingmemory => wm}/json_conversions.h | 2 +- .../armem/core/wm/memory_definitions.cpp | 214 ++++++++++++++++ .../armem/core/wm/memory_definitions.h | 230 ++++++++++++++++++ .../core/{workingmemory => wm}/visitor.h | 0 .../visitor/FunctionalVisitor.cpp | 4 +- .../visitor/FunctionalVisitor.h | 0 .../{workingmemory => wm}/visitor/Visitor.cpp | 2 +- .../{workingmemory => wm}/visitor/Visitor.h | 0 .../armem/core/workingmemory/CoreSegment.cpp | 115 --------- .../armem/core/workingmemory/CoreSegment.h | 107 -------- .../armem/core/workingmemory/Entity.cpp | 8 - .../armem/core/workingmemory/Entity.h | 38 --- .../core/workingmemory/EntityInstance.cpp | 40 --- .../armem/core/workingmemory/EntityInstance.h | 37 --- .../core/workingmemory/EntitySnapshot.cpp | 7 - .../armem/core/workingmemory/EntitySnapshot.h | 22 -- .../armem/core/workingmemory/Memory.cpp | 74 ------ .../armem/core/workingmemory/Memory.h | 38 --- .../core/workingmemory/ProviderSegment.cpp | 8 - .../core/workingmemory/ProviderSegment.h | 23 -- 27 files changed, 478 insertions(+), 551 deletions(-) create mode 100644 source/RobotAPI/libraries/armem/core/wm.h rename source/RobotAPI/libraries/armem/core/{workingmemory/entityInstance_conversions.cpp => wm/aron_conversions.cpp} (100%) rename source/RobotAPI/libraries/armem/core/{workingmemory/entityInstance_conversions.h => wm/aron_conversions.h} (76%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/ice_conversions.cpp (95%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/ice_conversions.h (97%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/json_conversions.cpp (100%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/json_conversions.h (94%) create mode 100644 source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp create mode 100644 source/RobotAPI/libraries/armem/core/wm/memory_definitions.h rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor.h (100%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/FunctionalVisitor.cpp (82%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/FunctionalVisitor.h (100%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/Visitor.cpp (98%) rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/Visitor.h (100%) delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Entity.h delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Memory.h delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index 475bfbcf1..972d51e11 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -28,8 +28,8 @@ set(LIB_FILES core/operations.cpp core/SuccessHeader.cpp core/Time.cpp - core/ice_conversions.cpp core/aron_conversions.cpp + core/ice_conversions.cpp core/json_conversions.cpp core/base/detail/MemoryItem.cpp @@ -47,18 +47,13 @@ set(LIB_FILES # core/base/MemoryBase.cpp # core/base/ProviderSegmentBase.cpp - core/workingmemory/ice_conversions.cpp - core/workingmemory/CoreSegment.cpp - core/workingmemory/Entity.cpp - core/workingmemory/EntityInstance.cpp - core/workingmemory/EntitySnapshot.cpp - core/workingmemory/Memory.cpp - core/workingmemory/ProviderSegment.cpp - core/workingmemory/ice_conversions.cpp - core/workingmemory/json_conversions.cpp - core/workingmemory/entityInstance_conversions.cpp - core/workingmemory/visitor/Visitor.cpp - core/workingmemory/visitor/FunctionalVisitor.cpp + core/wm/memory_definitions.cpp + core/wm/ice_conversions.cpp + core/wm/ice_conversions.cpp + core/wm/json_conversions.cpp + core/wm/aron_conversions.cpp + core/wm/visitor/Visitor.cpp + core/wm/visitor/FunctionalVisitor.cpp core/longtermmemory/CoreSegment.cpp core/longtermmemory/Entity.cpp @@ -167,18 +162,14 @@ set(LIB_HEADERS core/base/MemoryBase.h core/base/ProviderSegmentBase.h - core/workingmemory/CoreSegment.h - core/workingmemory/Entity.h - core/workingmemory/EntityInstance.h - core/workingmemory/EntitySnapshot.h - core/workingmemory/Memory.h - core/workingmemory/ProviderSegment.h - core/workingmemory/ice_conversions.h - core/workingmemory/json_conversions.h - core/workingmemory/entityInstance_conversions.h - core/workingmemory/visitor.h - core/workingmemory/visitor/Visitor.h - core/workingmemory/visitor/FunctionalVisitor.h + core/wm.h + core/wm/memory_definitions.h + core/wm/aron_conversions.h + core/wm/ice_conversions.h + core/wm/json_conversions.h + core/wm/visitor.h + core/wm/visitor/Visitor.h + core/wm/visitor/FunctionalVisitor.h core/longtermmemory/CoreSegment.h core/longtermmemory/Entity.h diff --git a/source/RobotAPI/libraries/armem/core/wm.h b/source/RobotAPI/libraries/armem/core/wm.h new file mode 100644 index 000000000..83776ed70 --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/wm.h @@ -0,0 +1,10 @@ +#pragma once + +#include "wm/memory_definitions.h" + + +namespace armarx::armem::wm +{ + +} + diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp similarity index 100% rename from source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.cpp rename to source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.h b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h similarity index 76% rename from source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.h rename to source/RobotAPI/libraries/armem/core/wm/aron_conversions.h index ab9ab27c4..f40d1d757 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.h +++ b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h @@ -1,6 +1,7 @@ #pragma once -#include "EntityInstance.h" +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> + namespace armarx::armem { diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp similarity index 95% rename from source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp rename to source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp index 8509ed5ea..a1fc88f19 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp +++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp @@ -6,14 +6,14 @@ namespace armarx::armem { - void toIce(armarx::armem::data::EntityInstanceMetadata& ice, const armarx::armem::wm::EntityInstanceMetadata& metadata) + 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 armarx::armem::data::EntityInstanceMetadata& ice, armarx::armem::wm::EntityInstanceMetadata& metadata) + void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata) { metadata.confidence = ice.confidence; fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived); diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h similarity index 97% rename from source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h rename to source/RobotAPI/libraries/armem/core/wm/ice_conversions.h index 4d14e6b0d..d2f7ef01f 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h +++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h @@ -3,7 +3,7 @@ #include <RobotAPI/interface/armem/commit.h> #include <RobotAPI/interface/armem/memory.h> -#include "Memory.h" +#include "memory_definitions.h" namespace armarx::armem diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/json_conversions.cpp similarity index 100% rename from source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.cpp rename to source/RobotAPI/libraries/armem/core/wm/json_conversions.cpp diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.h b/source/RobotAPI/libraries/armem/core/wm/json_conversions.h similarity index 94% rename from source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.h rename to source/RobotAPI/libraries/armem/core/wm/json_conversions.h index d132d88f7..daea55b95 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.h +++ b/source/RobotAPI/libraries/armem/core/wm/json_conversions.h @@ -1,6 +1,6 @@ #pragma once -#include "Memory.h" +#include "memory_definitions.h" #include <RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h> #include <RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h> diff --git a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp new file mode 100644 index 000000000..c200e6f68 --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp @@ -0,0 +1,214 @@ +#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::wm +{ + + bool EntityInstance::equalsDeep(const EntityInstance& other) const + { + if (_data and other.data()) + { + return id() == other.id() + && _metadata == other.metadata() + && *_data == *other.data(); + } + if (_data or other.data()) + { + return false; + } + return id() == other.id() && _metadata == other.metadata(); + } + + + void EntityInstance::update(const EntityUpdate& update) + { + ARMARX_CHECK_FITS_SIZE(this->index(), update.instancesData.size()); + + this->data() = update.instancesData.at(size_t(this->index())); + + this->_metadata.confidence = update.confidence; + + this->_metadata.timeCreated = update.timeCreated; + this->_metadata.timeSent = update.timeSent; + this->_metadata.timeArrived = update.timeArrived; + } + + + 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 + { + 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; + } + } + + + 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 new file mode 100644 index 000000000..4763944c8 --- /dev/null +++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h @@ -0,0 +1,230 @@ +#pragma once + +#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::wm +{ + + using EntityInstanceMetadata = base::EntityInstanceMetadata; + using EntityInstanceData = armarx::aron::datanavigator::DictNavigator; + using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr; + + + /** + * @brief Data of a single entity instance. + */ + class EntityInstance : + public base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata> + { + using Base = base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>; + + public: + + using Base::EntityInstanceBase; + + + /** + * @brief Fill `*this` with the update's values. + * @param update The update. + * @param index The instances index. + */ + void update(const EntityUpdate& update); + + bool equalsDeep(const EntityInstance& other) const; + + }; + + + + /** + * @brief Data of an entity at one point in time. + */ + class EntitySnapshot : + public base::EntitySnapshotBase<EntityInstance, EntitySnapshot> + { + public: + + using base::EntitySnapshotBase<EntityInstance, EntitySnapshot>::EntitySnapshotBase; + + }; + + + + /** + * @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`. + */ + class Entity : + public base::EntityBase<EntitySnapshot, Entity> + { + public: + + using base::EntityBase<EntitySnapshot, Entity>::EntityBase; + + }; + + + + /** + * @brief Data of a provider segment containing multiple entities. + */ + class ProviderSegment : + public base::ProviderSegmentBase<Entity, ProviderSegment> + { + public: + + using base::ProviderSegmentBase<Entity, ProviderSegment>::ProviderSegmentBase; + + }; + + + + /** + * @brief Data of a core segment containing multiple provider segments. + */ + class CoreSegment : + public base::CoreSegmentBase<ProviderSegment, CoreSegment> + { + using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>; + + public: + + using Base::CoreSegmentBase; + + CoreSegment(const CoreSegment& other); + CoreSegment(CoreSegment&& other); + CoreSegment& operator=(const CoreSegment& other); + CoreSegment& operator=(CoreSegment&& other); + + /** + * @brief Convert the content of this segmnet into a commit + * @return The resulting commit + */ + Commit toCommit() const; + + 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; + } + } + + + // 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. + */ + 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/core/workingmemory/visitor.h b/source/RobotAPI/libraries/armem/core/wm/visitor.h similarity index 100% rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor.h rename to source/RobotAPI/libraries/armem/core/wm/visitor.h diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.cpp b/source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.cpp similarity index 82% rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.cpp rename to source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.cpp index 53016fc6c..f72b37c1a 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.cpp +++ b/source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.cpp @@ -2,7 +2,7 @@ #include <ArmarXCore/core/exceptions/local/ExpressionException.h> -#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/core/error.h> @@ -18,6 +18,4 @@ namespace armarx::armem::wm { } - - } diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.h b/source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.h similarity index 100% rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.h rename to source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.h diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp b/source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.cpp similarity index 98% rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp rename to source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.cpp index 125ca569d..1140bc11b 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp +++ b/source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.cpp @@ -2,7 +2,7 @@ #include <ArmarXCore/core/exceptions/local/ExpressionException.h> -#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/core/error.h> diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.h b/source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.h similarity index 100% rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.h rename to source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.h diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp deleted file mode 100644 index eb437eb16..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "CoreSegment.h" - -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> - -#include "error.h" - - -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 - { - 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; - } - } - - - 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); - } - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h deleted file mode 100644 index 341c065a0..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include <mutex> -#include <optional> - -#include <RobotAPI/libraries/armem/core/base/CoreSegmentBase.h> - -#include "ProviderSegment.h" - - -namespace armarx::armem::wm -{ - - /** - * @brief Data of a core segment containing multiple provider segments. - */ - class CoreSegment : - public base::CoreSegmentBase<ProviderSegment, CoreSegment> - { - using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>; - - public: - - using Base::CoreSegmentBase; - - CoreSegment(const CoreSegment& other); - CoreSegment(CoreSegment&& other); - CoreSegment& operator=(const CoreSegment& other); - CoreSegment& operator=(CoreSegment&& other); - - /** - * @brief Convert the content of this segmnet into a commit - * @return The resulting commit - */ - Commit toCommit() const; - - 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; - } - } - - - // 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; - - }; - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp deleted file mode 100644 index e212c0d36..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Entity.h" - - -namespace armarx::armem::wm -{ - - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h deleted file mode 100644 index 34e9b2abd..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/base/EntityBase.h> - -#include "EntitySnapshot.h" - - -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`. - */ - class Entity : - public base::EntityBase<EntitySnapshot, Entity> - { - public: - - using base::EntityBase<EntitySnapshot, Entity>::EntityBase; - - }; - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp deleted file mode 100644 index 8cda21f29..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "EntityInstance.h" - -#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h> - -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> - - -namespace armarx::armem::wm -{ - - bool EntityInstance::equalsDeep(const EntityInstance& other) const - { - if (_data and other.data()) - { - return id() == other.id() - && _metadata == other.metadata() - && *_data == *other.data(); - } - if (_data or other.data()) - { - return false; - } - return id() == other.id() && _metadata == other.metadata(); - } - - - void EntityInstance::update(const EntityUpdate& update) - { - ARMARX_CHECK_FITS_SIZE(this->index(), update.instancesData.size()); - - this->data() = update.instancesData.at(size_t(this->index())); - - this->_metadata.confidence = update.confidence; - - this->_metadata.timeCreated = update.timeCreated; - this->_metadata.timeSent = update.timeSent; - this->_metadata.timeArrived = update.timeArrived; - } - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h deleted file mode 100644 index 158b1c0f8..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/base/EntityInstanceBase.h> - - -namespace armarx::armem::wm -{ - - using EntityInstanceMetadata = base::EntityInstanceMetadata; - using EntityInstanceData = armarx::aron::datanavigator::DictNavigator; - using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr; - - - /** - * @brief Data of a single entity instance. - */ - class EntityInstance : - public base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata> - { - using Base = base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>; - - public: - - using Base::EntityInstanceBase; - - - /** - * @brief Fill `*this` with the update's values. - * @param update The update. - * @param index The instances index. - */ - void update(const EntityUpdate& update); - - bool equalsDeep(const EntityInstance& other) const; - - }; -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp deleted file mode 100644 index b5daa3192..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "EntitySnapshot.h" - - -namespace armarx::armem::wm -{ - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h deleted file mode 100644 index c19a2f830..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h> - -#include "EntityInstance.h" - - -namespace armarx::armem::wm -{ - - /** - * @brief Data of an entity at one point in time. - */ - class EntitySnapshot : - public base::EntitySnapshotBase<EntityInstance, EntitySnapshot> - { - public: - - using base::EntitySnapshotBase<EntityInstance, EntitySnapshot>::EntitySnapshotBase; - - }; -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp deleted file mode 100644 index 7bff4f19e..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "Memory.h" - -#include <map> -#include <vector> - - -namespace armarx::armem::wm -{ - - // 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/workingmemory/Memory.h b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h deleted file mode 100644 index e3684b3b6..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/base/MemoryBase.h> - -#include "CoreSegment.h" - - -namespace armarx::armem::wm -{ - - /** - * @brief Data of a memory consisting of multiple core segments. - */ - 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/core/workingmemory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp deleted file mode 100644 index 01aa4e39b..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "ProviderSegment.h" - - -namespace armarx::armem::wm -{ - - -} diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h deleted file mode 100644 index 75b5d3b36..000000000 --- a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h> - -#include "Entity.h" - - -namespace armarx::armem::wm -{ - - /** - * @brief Data of a provider segment containing multiple entities. - */ - class ProviderSegment : - public base::ProviderSegmentBase<Entity, ProviderSegment> - { - public: - - using base::ProviderSegmentBase<Entity, ProviderSegment>::ProviderSegmentBase; - - }; - -} -- GitLab