diff --git a/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice b/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice index e102426c44a33acb156a10203e77193689a97f92..85a862f4cd815168d6163d2d085426d71b298068 100644 --- a/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice +++ b/source/RobotAPI/interface/armem/mns/MemoryNameSystemInterface.ice @@ -33,6 +33,15 @@ module armarx string errorMessage; }; + dictionary<string, server::MemoryInterface*> MemoryInterfaces; + struct GetAllRegisteredMemoriesResult + { + bool success; + string errorMessage; + + MemoryInterfaces proxies; + }; + struct ResolveMemoryNameInput { string name; @@ -69,6 +78,8 @@ module armarx data::RegisterMemoryResult registerMemory(data::RegisterMemoryInput input); data::RemoveMemoryResult removeMemory(data::RemoveMemoryInput input); + data::GetAllRegisteredMemoriesResult getAllRegisteredMemories(); + data::ResolveMemoryNameResult resolveMemoryName(data::ResolveMemoryNameInput input); data::WaitForMemoryResult waitForMemory(data::WaitForMemoryInput input); }; diff --git a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp index 0e5c206b636e6504975736d7c6c81a0ff40255d8..79e58300a6968dfda3f60d89ff0511f9ec72f267 100644 --- a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp +++ b/source/RobotAPI/libraries/armem/mns/ComponentPlugin.cpp @@ -37,6 +37,15 @@ namespace armarx::armem::mns } + armem::data::GetAllRegisteredMemoriesResult + ComponentPluginUser::getAllRegisteredMemories(const Ice::Current&) + { + std::scoped_lock lock(mnsMutex); + armem::data::GetAllRegisteredMemoriesResult result = mns.getAllRegisteredMemories(); + return result; + } + + armem::data::ResolveMemoryNameResult ComponentPluginUser::resolveMemoryName(const armem::data::ResolveMemoryNameInput& input, const Ice::Current&) { std::scoped_lock lock(mnsMutex); diff --git a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h b/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h index ade1351d7f24c5315b55056d822fb7b26ef4eec8..1347c197e6d4f560b5773abfed30b92e8f8a7604 100644 --- a/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h +++ b/source/RobotAPI/libraries/armem/mns/ComponentPlugin.h @@ -40,6 +40,7 @@ namespace armarx::armem::mns public: armem::data::RegisterMemoryResult registerMemory(const armem::data::RegisterMemoryInput& input, const Ice::Current& = Ice::emptyCurrent) override; armem::data::RemoveMemoryResult removeMemory(const armem::data::RemoveMemoryInput& input, const Ice::Current& = Ice::emptyCurrent) override; + armem::data::GetAllRegisteredMemoriesResult getAllRegisteredMemories(const Ice::Current&) override; armem::data::ResolveMemoryNameResult resolveMemoryName(const armem::data::ResolveMemoryNameInput& input, const Ice::Current& = Ice::emptyCurrent) override; armem::data::WaitForMemoryResult waitForMemory(const armem::data::WaitForMemoryInput& input, const Ice::Current& = Ice::emptyCurrent) override; diff --git a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp index c3cff5bb45c2dfbfa793a32d1ff432a51c740203..ece0fa74306ed77465ce0bb0c643b781ec704178 100644 --- a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp +++ b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.cpp @@ -82,6 +82,30 @@ namespace armarx::armem::mns } + data::GetAllRegisteredMemoriesResult + MemoryNameSystem::getAllRegisteredMemories() + { + data::GetAllRegisteredMemoriesResult result; + result.success = true; + result.errorMessage = ""; + + for (const auto& [name, info] : memoryMap) + { + try + { + info.proxy->ice_ping(); + result.proxies[name] = info.proxy; + } + catch (const Ice::Exception&) + { + ; + } + } + + return result; + } + + armem::data::ResolveMemoryNameResult MemoryNameSystem::resolveMemoryName(const armem::data::ResolveMemoryNameInput& input) { armem::data::ResolveMemoryNameResult result; diff --git a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h index 891e78f4acf072e49670336b3d95afb4b766695a..7372246d7e8059787f97f117931830d12c9dc082 100644 --- a/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h +++ b/source/RobotAPI/libraries/armem/mns/MemoryNameSystem.h @@ -35,6 +35,8 @@ namespace armarx::armem::mns */ data::RemoveMemoryResult removeMemory(const data::RemoveMemoryInput& input); + data::GetAllRegisteredMemoriesResult getAllRegisteredMemories(); + /** * @brief Gets a memory entry, if it is available. */ diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp index 2cff7aa28476ba530a8b72febb11d563e5101b0b..78097af1a7a40ca0e8c46f1e75d8ce72783e06ab 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp @@ -9,6 +9,8 @@ #include <ArmarXCore/core/time/TimeUtil.h> #include <ArmarXCore/observers/variant/Variant.h> +#include <SimoxUtility/algorithm/get_map_keys_values.h> + #include <QBoxLayout> #include <QDialog> #include <QCheckBox> @@ -47,8 +49,8 @@ namespace armarx::armem::gui ARMARX_CHECK_NULL(_instanceGroupBox); - connect(this, &This::connected, this, &This::updateMemory); - connect(updateWidget, &armem::gui::PeriodicUpdateWidget::update, this, &This::updateMemory); + connect(this, &This::connected, this, &This::updateMemories); + connect(updateWidget, &armem::gui::PeriodicUpdateWidget::update, this, &This::updateMemories); connect(this, &This::memoryDataChanged, this, &This::updateMemoryTree); connect(memoryGroup->tree(), &armem::gui::MemoryTreeWidget::selectedItemChanged, this, &This::updateInstanceTree); @@ -64,9 +66,9 @@ namespace armarx::armem::gui void MemoryViewer::onInit(ManagedIceObject& component) { - if (memoryName.size() > 0) + if (mnsName.size() > 0) { - component.usingProxy(memoryName); + component.usingProxy(mnsName); } if (debugObserverName.size() > 0) { @@ -78,10 +80,15 @@ namespace armarx::armem::gui void MemoryViewer::onConnect(ManagedIceObject& component) { - if (!memoryName.empty()) + if (!mnsName.empty()) { - component.getProxy(memory, memoryName); - memoryReader = armem::client::Reader(memory); + component.getProxy(mns, mnsName); + auto res = mns->getAllRegisteredMemories(); + for (auto& [name, proxy] : res.proxies) + { + armem::client::Reader memoryReader{proxy}; + memoryReaders[name] = memoryReader; + } } // DebugObserver is optional (check for null on every call) if (!debugObserverName.empty()) @@ -101,52 +108,78 @@ namespace armarx::armem::gui } - void MemoryViewer::updateMemory() + void MemoryViewer::updateMemories() { - if (!memoryReader) + memoryReaders.clear(); + memoryData.clear(); + + for (auto& [name, proxy] : mns->getAllRegisteredMemories().proxies) { - return; + armem::client::Reader memoryReader{proxy}; + memoryReaders[name] = memoryReader; } - TIMING_START(MemoryQuery); + bool dataChanged = false; + + for (auto& [name, reader] : memoryReaders) { - armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); - armem::client::QueryResult result = memoryReader.query(input); - if (result) + TIMING_START(MemoryQuery); + { + armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); + armem::client::QueryResult result = reader.query(input); + if (result) + { + memoryData[name] = std::move(result.memory); + } + else + { + if (statusLabel) + { + statusLabel->setText(QString::fromStdString(result.errorMessage)); + } + } + } + TIMING_END_STREAM(MemoryQuery, ARMARX_VERBOSE); + + if (debugObserver) { - this->memoryData = std::move(result.memory); + debugObserver->setDebugDatafield(Logging::tag.tagName, "Memory Query [ms]", new Variant(MemoryQuery.toMilliSecondsDouble())); + } + + if (memoryData[name]) + { + dataChanged = true; } else { if (statusLabel) { - statusLabel->setText(QString::fromStdString(result.errorMessage)); + statusLabel->setText("No query result."); } } } - TIMING_END_STREAM(MemoryQuery, ARMARX_VERBOSE); - - if (debugObserver) - { - debugObserver->setDebugDatafield(Logging::tag.tagName, "Memory Query [ms]", new Variant(MemoryQuery.toMilliSecondsDouble())); - } - if (this->memoryData) + if (dataChanged) { emit memoryDataChanged(); } - else - { - if (statusLabel) - { - statusLabel->setText("No query result."); - } - } } + void MemoryViewer::updateInstanceTree(const armem::MemoryID& selectedID) { - if (memoryData) + if (memoryData.find(selectedID.memoryName) == memoryData.end()) + { + std::stringstream ss; + ss << "Memory name '" << selectedID.memoryName << "' is unknown. Known are: " + << simox::alg::get_keys(memoryData); + statusLabel->setText(QString::fromStdString(ss.str())); + return; + } + + const std::optional<armem::Memory>& data = memoryData.at(selectedID.memoryName); + + if (data) { if (!selectedID.hasEntityName()) { @@ -156,7 +189,7 @@ namespace armarx::armem::gui const armem::EntitySnapshot* snapshot = nullptr; if (!id.hasTimestamp()) { - const armem::Entity& entity = memoryData->getEntity(id); + const armem::Entity& entity = data->getEntity(id); if (entity.empty()) { return; @@ -170,7 +203,7 @@ namespace armarx::armem::gui { try { - snapshot = &memoryData->getEntitySnapshot(id); + snapshot = &data->getEntitySnapshot(id); } catch (const armem::error::ArMemError& e) { @@ -187,19 +220,29 @@ namespace armarx::armem::gui } if (id.hasInstanceIndex()) { - instanceGroup->view->update(id, *memoryData); + instanceGroup->view->update(id, *data); } } } void MemoryViewer::updateMemoryTree() { - if (!memoryData) + std::map<std::string, const armem::Memory*> convMap; + for (auto& [name, data] : memoryData) + { + if (data.has_value()) + { + convMap[name] = &data.value(); + } + } + + if (convMap.empty()) { return; } + TIMING_START(GuiUpdate); - memoryGroup->tree()->update(*memoryData); + memoryGroup->tree()->update(convMap); TIMING_END_STREAM(GuiUpdate, ARMARX_VERBOSE); if (debugObserver) @@ -209,34 +252,29 @@ namespace armarx::armem::gui } - const static std::string CONFIG_KEY_MEMORY = "MemoryViewer.MemoryName"; + const static std::string CONFIG_KEY_MEMORY = "MemoryViewer.MemoryNameSystem"; const static std::string CONFIG_KEY_DEBUG_OBSERVER = "MemoryViewer.DebugObserverName"; void MemoryViewer::loadSettings(QSettings* settings) { - memoryName = settings->value(QString::fromStdString(CONFIG_KEY_MEMORY), "Memory").toString().toStdString(); + mnsName = settings->value(QString::fromStdString(CONFIG_KEY_MEMORY), "ArMemMemoryNameSystem").toString().toStdString(); debugObserverName = settings->value(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER), "DebugObserver").toString().toStdString(); } void MemoryViewer::saveSettings(QSettings* settings) { - settings->setValue(QString::fromStdString(CONFIG_KEY_MEMORY), QString::fromStdString(memoryName)); + settings->setValue(QString::fromStdString(CONFIG_KEY_MEMORY), QString::fromStdString(mnsName)); settings->setValue(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER), QString::fromStdString(debugObserverName)); } void MemoryViewer::writeConfigDialog(SimpleConfigDialog* dialog) { - dialog->addProxyFinder<armem::server::MemoryInterfacePrx>({CONFIG_KEY_MEMORY, "Memory", "*Memory"}); + dialog->addProxyFinder<armarx::armem::mns::MemoryNameSystemInterfacePrx>({CONFIG_KEY_MEMORY, "ArMemMemoryNameSystem", "*"}); dialog->addProxyFinder<armarx::DebugObserverInterfacePrx>({CONFIG_KEY_DEBUG_OBSERVER, "Debug Observer", "DebugObserver"}); } void MemoryViewer::readConfigDialog(SimpleConfigDialog* dialog) { - memoryName = dialog->getProxyName(CONFIG_KEY_MEMORY); + mnsName = dialog->getProxyName(CONFIG_KEY_MEMORY); debugObserverName = dialog->getProxyName(CONFIG_KEY_DEBUG_OBSERVER); } } - - - - - diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h index df66ad86fa603443119744d0ee152f5f126e805a..5c8f4b2f182f798a3c076a89e6a30ff24d10050c 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h @@ -7,7 +7,7 @@ #include <ArmarXCore/interface/observers/ObserverInterface.h> #include <ArmarXCore/core/logging/Logging.h> -#include <RobotAPI/interface/armem/server/MemoryInterface.h> +#include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> #include <RobotAPI/libraries/armem/client/Reader.h> #include <RobotAPI/libraries/armem_gui/lifecycle.h> #include <RobotAPI/libraries/armem_gui/instance/GroupBox.h> @@ -15,7 +15,6 @@ #include <RobotAPI/libraries/armem_gui/PeriodicUpdateWidget.h> - class QBoxLayout; class QDialog; class QGroupBox; @@ -63,7 +62,7 @@ namespace armarx::armem::gui public slots: - void updateMemory(); + void updateMemories(); void updateInstanceTree(const armem::MemoryID& selectedID); @@ -95,11 +94,11 @@ namespace armarx::armem::gui public: - std::string memoryName; - armem::server::MemoryInterfacePrx memory; - armem::client::Reader memoryReader; + std::string mnsName; + armem::mns::MemoryNameSystemInterfacePrx mns; - std::optional<armem::Memory> memoryData; + std::map<std::string, armem::client::Reader> memoryReaders; + std::map<std::string, std::optional<armem::Memory>> memoryData; QLayout* updateWidgetLayout; @@ -121,5 +120,3 @@ namespace armarx::armem::gui }; } - -