From cbd9ed12eb5248887e83d818aa2017f717b602f3 Mon Sep 17 00:00:00 2001 From: "fabian.peller-konrad@kit.edu" <fabian.peller-konrad@kit.edu> Date: Wed, 28 Jul 2021 08:39:29 +0200 Subject: [PATCH] memory can add coresegments on commit if enabled (useful for LTM) --- .../armem/core/base/CoreSegmentBase.h | 37 ++++++++----- .../libraries/armem/core/base/MemoryBase.h | 54 +++++++++++++++++-- .../armem/core/workingmemory/Memory.cpp | 28 ++-------- .../armem/core/workingmemory/Memory.h | 3 -- .../armem/server/MemoryToIceAdapter.cpp | 1 + 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h index 6dc77c576..5e22ba703 100644 --- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h +++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h @@ -150,38 +150,49 @@ namespace armarx::armem::base * * Missing entity entries are added before updating. */ - UpdateResult update(const EntityUpdate& update) + virtual UpdateResult update(const EntityUpdate& update) { this->_checkContainerName(update.entityID.coreSegmentName, this->name()); + auto [inserted, provSeg] = addProviderSegmentIfMissing(update.entityID.providerSegmentName); + + + // Update entry. + UpdateResult ret(provSeg->update(update)); + if (inserted) + { + ret.coreSegmentUpdateType = UpdateType::InsertedNew; + } + else + { + ret.coreSegmentUpdateType = UpdateType::UpdatedExisting; + } + return ret; + } + + std::pair<bool, ProviderSegmentT*> addProviderSegmentIfMissing(const std::string& providerSegmentName) + { ProviderSegmentT* provSeg; - UpdateType updateType = UpdateType::InsertedNew; - auto it = this->_container.find(update.entityID.providerSegmentName); + auto it = this->_container.find(providerSegmentName); if (it == this->_container.end()) { if (_addMissingProviderSegmentDuringUpdate) { // Insert into map. - provSeg = &addProviderSegment(update.entityID.providerSegmentName); - provSeg->setMaxHistorySize(_maxHistorySize); - updateType = UpdateType::InsertedNew; + provSeg = &addProviderSegment(providerSegmentName); + return {true, provSeg}; } else { - throw error::MissingEntry::create<EntitySnapshotT>(update.entityID.providerSegmentName, *this); + throw error::MissingEntry::create<EntitySnapshotT>(providerSegmentName, *this); } } else { provSeg = &it->second; - updateType = UpdateType::UpdatedExisting; + return {false, provSeg}; } - - // Update entry. - UpdateResult ret(provSeg->update(update)); - ret.coreSegmentUpdateType = updateType; - return ret; } void append(const _Derived& m) diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h index 73e70478f..781322b54 100644 --- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h +++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h @@ -242,16 +242,43 @@ namespace armarx::armem::base { this->_checkContainerName(update.entityID.memoryName, this->name()); - auto it = this->_container.find(update.entityID.coreSegmentName); - if (it != this->_container.end()) + auto [inserted, coreSeg] = addCoreSegmentIfMissing(update.entityID.coreSegmentName); + + // Update entry. + UpdateResult ret(coreSeg->update(update)); + if (inserted) + { + ret.memoryUpdateType = UpdateType::InsertedNew; + } + else { - UpdateResult ret(it->second.update(update)); ret.memoryUpdateType = UpdateType::UpdatedExisting; - return ret; + } + return ret; + } + + std::pair<bool, CoreSegmentT*> addCoreSegmentIfMissing(const std::string& coreSegmentName) + { + CoreSegmentT* coreSeg; + + auto it = this->_container.find(coreSegmentName); + if (it == this->_container.end()) + { + if (_addMissingCoreSegmentDuringUpdate) + { + // Insert into map. + coreSeg = &addCoreSegment(coreSegmentName); + return {true, coreSeg}; + } + else + { + throw error::MissingEntry::create<EntitySnapshotT>(coreSegmentName, *this); + } } else { - throw armem::error::MissingEntry::create<CoreSegmentT>(update.entityID.coreSegmentName, *this); + coreSeg = &it->second; + return {false, coreSeg}; } } @@ -308,5 +335,22 @@ namespace armarx::armem::base { return this->name(); } + + protected: + + virtual void _copySelf(DerivedT& other) const override + { + Base::_copySelf(other); + other._addMissingCoreSegmentDuringUpdate = _addMissingCoreSegmentDuringUpdate; + } + virtual void _copySelfEmpty(DerivedT& other) const override + { + Base::_copySelfEmpty(other); + other._addMissingCoreSegmentDuringUpdate = _addMissingCoreSegmentDuringUpdate; + } + + public: + + bool _addMissingCoreSegmentDuringUpdate = false; }; } diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp index cd6c9cc58..70fd41e7c 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp +++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp @@ -7,18 +7,7 @@ namespace armarx::armem::wm { - std::vector<Memory::Base::UpdateResult> - Memory::update(const Commit& commit) - { - std::vector<Memory::Base::UpdateResult> result; - for (const EntityUpdate& update : commit.updates) - { - result.push_back(this->update(update)); - } - return result; - } - - + // TODO: add core segment if param is set std::vector<Memory::Base::UpdateResult> Memory::updateLocking(const Commit& commit) { @@ -30,7 +19,7 @@ namespace armarx::armem::wm } std::vector<Memory::Base::UpdateResult> result; - // To throw an exception after the commit if a core segment is missing. + // 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) { @@ -66,18 +55,7 @@ namespace armarx::armem::wm } - Memory::Base::UpdateResult - Memory::update(const EntityUpdate& update) - { - this->_checkContainerName(update.entityID.memoryName, this->name()); - - CoreSegment& segment = getCoreSegment(update.entityID.coreSegmentName); - Base::UpdateResult result = segment.update(update); - result.memoryUpdateType = UpdateType::UpdatedExisting; - return result; - } - - + // TODO: Add core segment if param is set Memory::Base::UpdateResult Memory::updateLocking(const EntityUpdate& update) { diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h index 99a14dbdd..d52bce5ca 100644 --- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h +++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h @@ -27,8 +27,6 @@ namespace armarx::armem::wm Memory& operator=(const Memory& other) = default; Memory& operator=(Memory&& other) = default; - - virtual std::vector<Base::UpdateResult> update(const Commit& commit) override; /** * @brief Perform the commit, locking the core segments. * @@ -37,7 +35,6 @@ namespace armarx::armem::wm */ std::vector<Base::UpdateResult> updateLocking(const Commit& commit); - virtual Base::UpdateResult update(const EntityUpdate& update) override; /** * @brief Update the memory, locking the updated core segment. */ diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp index 0d6685c45..801536883 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp @@ -178,6 +178,7 @@ namespace armarx::armem::server if (longtermMemory->alwaysTransferSettings.enabled) { wm::Memory tmp(longtermMemory->name()); + tmp._addMissingCoreSegmentDuringUpdate = true; tmp.update(update); longtermMemory->append(tmp); } -- GitLab