diff --git a/source/RobotAPI/components/armem/client/ArticulatedObjectExampleMemoryWriterClient/ArticulatedObjectExampleMemoryWriterClient.cpp b/source/RobotAPI/components/armem/client/ArticulatedObjectExampleMemoryWriterClient/ArticulatedObjectExampleMemoryWriterClient.cpp index 3432b49f461f373cbf66af66315c27566e20c7b2..553a24c85e79c7353c09893df04212e17c2c1fb8 100644 --- a/source/RobotAPI/components/armem/client/ArticulatedObjectExampleMemoryWriterClient/ArticulatedObjectExampleMemoryWriterClient.cpp +++ b/source/RobotAPI/components/armem/client/ArticulatedObjectExampleMemoryWriterClient/ArticulatedObjectExampleMemoryWriterClient.cpp @@ -1,15 +1,19 @@ #include "ArticulatedObjectExampleMemoryWriterClient.h" -#include "ArmarXCore/core/PackagePath.h" -#include "ArmarXCore/core/system/ArmarXDataPath.h" -#include "RobotAPI/libraries/armem/core/Time.h" -#include <Eigen/src/Geometry/Transform.h> +#include <memory> + +#include <Eigen/Geometry> + #include <IceUtil/Time.h> + +#include <VirtualRobot/Robot.h> +#include <VirtualRobot/XML/RobotIO.h> #include <VirtualRobot/VirtualRobot.h> -#include <memory> +#include <ArmarXCore/core/PackagePath.h> +#include <ArmarXCore/core/system/ArmarXDataPath.h> #include <ArmarXCore/core/exceptions/local/ExpressionException.h> #include <ArmarXCore/core/time/CycleUtil.h> @@ -17,19 +21,18 @@ #include <RobotAPI/libraries/armem/client/query/query_fns.h> #include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h> #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h> +#include <RobotAPI/libraries/armem/core/Time.h> -#include <VirtualRobot/Robot.h> -#include <VirtualRobot/XML/RobotIO.h> namespace armarx::articulated_object { ArticulatedObjectExampleMemoryWriterClient::ArticulatedObjectExampleMemoryWriterClient() : - articulatedObjectWriter(new ::armarx::armem::articulated_object::Writer(*this)){} + articulatedObjectWriter(new ::armarx::armem::articulated_object::Writer(*this)) {} armarx::PropertyDefinitionsPtr ArticulatedObjectExampleMemoryWriterClient::createPropertyDefinitions() { armarx::PropertyDefinitionsPtr defs = - new ComponentPropertyDefinitions(getConfigIdentifier()); + new ComponentPropertyDefinitions(getConfigIdentifier()); defs->topic(debugObserver); @@ -55,31 +58,29 @@ namespace armarx::articulated_object task->start(); } - void ArticulatedObjectExampleMemoryWriterClient::onDisconnectComponent() { task->stop(); } + void ArticulatedObjectExampleMemoryWriterClient::onDisconnectComponent() + { + task->stop(); + } void ArticulatedObjectExampleMemoryWriterClient::onExitComponent() {} VirtualRobot::RobotPtr createDishwasher() { const std::string xml = - "Environment/mobile-kitchen/dishwasher-only/dishwasher.xml"; + "./ArmarXObjects/Environment/mobile-kitchen/dishwasher-only/dishwasher.xml"; const std::string name = "dishwasher"; - const PackagePath packagePath(armarx::ArmarXDataPath::getProject({"ArmarXObjects"}, xml), xml); - - auto robot = VirtualRobot::RobotIO::loadRobot(packagePath.toSystemPath(), VirtualRobot::RobotIO::eStructure); - - return robot; + return VirtualRobot::RobotIO::loadRobot(ArmarXDataPath::resolvePath(xml), VirtualRobot::RobotIO::eStructure); } armem::articulated_object::ArticulatedObject convert(const VirtualRobot::Robot& obj, const armem::Time& timestamp) { - ARMARX_INFO << "filename is " << obj.getFilename(); - - + ARMARX_INFO << "Filename is " << obj.getFilename(); - return - armem::articulated_object::ArticulatedObject{ + return + armem::articulated_object::ArticulatedObject + { .description = { .name = obj.getName(), .xml = PackagePath(armarx::ArmarXDataPath::getProject({"ArmarXObjects"}, obj.getFilename()), obj.getFilename()) @@ -106,7 +107,6 @@ namespace armarx::articulated_object while (not task->isStopped()) { - ARMARX_INFO << "Reporting articulated objects"; const IceUtil::Time now = TimeUtil::GetTime(); diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp index cc296ea48e6f06437060c7e1cb41f7cd06678e8b..4b3406074588f20a9b5abd0251b6e2188078bc56 100644 --- a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp +++ b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp @@ -23,6 +23,7 @@ #include "ObjectMemory.h" #include <RobotAPI/interface/core/articulated_object/topic.h> +#include <mutex> namespace armarx::armem::server::obj @@ -120,8 +121,16 @@ namespace armarx::armem::server::obj ArVizComponentPluginUser::arviz ); + + { + std::lock_guard g(server::ComponentPluginUser::workingMemoryMutex); + server::ComponentPluginUser::workingMemory.addCoreSegment("ArticulatedObjectInstance"); // TODO , arondto::::toInitialAronType()); + server::ComponentPluginUser::workingMemory.addCoreSegment("ArticulatedObjectClass"); // TODO , arondto::::toInitialAronType()); + } + createRemoteGuiTab(); RemoteGui_startRunningTask(); + } void ObjectMemory::onDisconnectComponent() diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ed69e4c80c5bc975c1acd46ffb7b57e4418915d7 100644 --- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp +++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp @@ -0,0 +1,122 @@ +#include "Reader.h" + +#include <mutex> + +#include "ArmarXCore/core/logging/Logging.h" +#include "RobotAPI/libraries/armem/core/Time.h" +#include "RobotAPI/libraries/armem/client/query/Builder.h" +#include "RobotAPI/libraries/armem_objects/aron_conversions.h" +#include <RobotAPI/libraries/armem_objects/aron/Robot.aron.generated.h> +#include <optional> + +namespace armarx::armem::articulated_object +{ + + Reader::Reader(ManagedIceObject& component) : MemoryConnector(component) {} + + + ArticulatedObject Reader::get(const ArticulatedObjectDescription& description, + const armem::Time& timestamp) + { + ArticulatedObject obj + { + .description = description, + .config = {}, // will be populated by synchronize + .timestamp = timestamp + }; + + synchronize(obj, timestamp); + + return obj; + } + + void Reader::synchronize(ArticulatedObject& obj, const armem::Time& timestamp) + { + auto state = queryState(obj.description, timestamp); + + if (not state) /* c++20 [[unlikely]] */ + { + ARMARX_WARNING << "Could not synchronize object " << obj.description.name; + return; + } + + obj.config = std::move(*state); + } + + std::optional<RobotState> Reader::queryState(const RobotDescription& description, const armem::Time& timestamp) + { + // TODO(fabian.reister): how to deal with multiple providers? + + // Query all entities from provider. + armem::client::query::Builder qb; + + // clang-format off + qb + .coreSegments().withName(properties.memoryName) + .providerSegments().withName(properties.providerName) // agent + .entities().withName(description.name) + .snapshots().atTime(timestamp); + // clang-format on + + const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput()); + + ARMARX_DEBUG << "Lookup result in reader: " << qResult; + + if (not qResult.success) /* c++20 [[unlikely]] */ + { + return std::nullopt; + } + + return getRobotState(qResult.memory); + } + + std::optional<RobotState> convert(const armem::wm::EntityInstance& instance) + { + arondto::RobotState aronRobotState; + try + { + aronRobotState.fromAron(instance.data()); + } + catch (...) + { + return std::nullopt; + } + + RobotState robotState; + fromAron(aronRobotState, robotState); + + return robotState; + } + + std::optional<RobotState> Reader::getRobotState(const armarx::armem::wm::Memory& memory) const + { + // clang-format off + const armem::wm::ProviderSegment& providerSegment = memory + .getCoreSegment(properties.memoryName) + .getProviderSegment(properties.providerName); + // clang-format on + const auto entities = simox::alg::get_values(providerSegment.entities()); + + if (entities.empty()) + { + ARMARX_WARNING << "No entity found"; + return std::nullopt; + } + + const auto entitySnapshots = simox::alg::get_values(entities.front().history()); + + if (entitySnapshots.empty()) + { + ARMARX_WARNING << "No entity snapshots found"; + return std::nullopt; + } + + // TODO(fabian.reister): check if 0 available + const armem::wm::EntityInstance& instance = entitySnapshots.front().getInstance(0); + + return convert(instance); + } + + + +} // namespace armarx::armem::articulated_object \ No newline at end of file diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h index 556284d2cc8961c96b5545acfdd5a1855c5f2fcf..3fe33b6c6bc69f61a4721a014cb2618a5f59d905 100644 --- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h +++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h @@ -1,7 +1,12 @@ #pragma once -#include "interfaces.h" +#include <mutex> +#include <optional> + +#include "RobotAPI/libraries/armem/client/MemoryConnector.h" +#include "RobotAPI/libraries/armem/client/Reader.h" +#include "interfaces.h" namespace armarx::armem::articulated_object { @@ -10,10 +15,31 @@ namespace armarx::armem::articulated_object virtual public ::armarx::armem::MemoryConnector { public: + Reader(ManagedIceObject& component); virtual ~Reader() = default; void synchronize(ArticulatedObject& obj, const armem::Time& timestamp) override; ArticulatedObject get(const ArticulatedObjectDescription& description, const armem::Time& timestamp) override; + + std::optional<RobotState> queryState(const RobotDescription& description, const armem::Time& timestamp); + + protected: + std::optional<RobotState> getRobotState(const armarx::armem::wm::Memory& memory) const; + + private: + + struct Properties + { + std::string memoryName = "ObjectMemory"; + std::string coreSegmentName = "ArticulatedObjectInstance"; + std::string providerName; + } properties; + + const std::string propertyPrefix = "mem.obj.articulated.read."; + + armem::client::Reader memoryReader; + std::mutex memoryWriterMutex; + }; diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp index c47215d1342f8923a3de7cad5064007636ba9254..ea8545699d4dbc85a3a135ca3efb269d2a0f755c 100644 --- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp +++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp @@ -1,4 +1,5 @@ #include "Writer.h" + #include "RobotAPI/libraries/armem_objects/aron_conversions.h" #include <mutex> @@ -49,13 +50,11 @@ namespace armarx::armem::articulated_object ARMARX_DEBUG << "Trying to create core segment + provider segment"; const auto result = - memoryWriter.addSegment(properties.memoryName, properties.providerName); + memoryWriter.addSegment(properties.coreSegmentName, properties.providerName); if (not result.success) { - ARMARX_ERROR << result.errorMessage; - - // TODO(fabian.reister): message + ARMARX_ERROR << "Creating core segment failed. Reason: " << result.errorMessage; return false; }