diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.cpp b/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.cpp index 4f2d0c35fa4c95375cf67d09e332c1ecec5b77fa..cf5eb9b333563c0850e9e4fa5f7b618041958f63 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.cpp +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.cpp @@ -250,6 +250,12 @@ namespace armarx return select("HandControllerName"); } + std::string Arm::getHandUnitName() const + { + ARMARX_TRACE; + return select("HandUnitName"); + } + std::string Arm::getHandRootNode() const { ARMARX_TRACE; diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.h b/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.h index 76c9b283f5d915e54d1f240c94d01aa9774d8e08..c1fa9b4d74194e7fd4b8c2a5748d81ef4ccfdcbd 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.h +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.h @@ -64,6 +64,8 @@ namespace armarx std::string getHandRootNode() const; + std::string getHandUnitName() const; + std::string getHandModelPath() const; std::string getAbsoluteHandModelPath() const; diff --git a/source/RobotAPI/libraries/armem_robot_state/aron/RobotDescription.xml b/source/RobotAPI/libraries/armem_robot_state/aron/RobotDescription.xml index aae0bba8efb2b42d6b426698911b36e6331ade27..3fb008da6919db746fd335735c6c2aa094e58a12 100644 --- a/source/RobotAPI/libraries/armem_robot_state/aron/RobotDescription.xml +++ b/source/RobotAPI/libraries/armem_robot_state/aron/RobotDescription.xml @@ -27,6 +27,9 @@ <ObjectChild key='end_effector'> <string /> </ObjectChild> + <ObjectChild key='hand_unit'> + <string /> + </ObjectChild> <!-- Legacy old memory --> <!-- <ObjectChild key='memory_hand_name'> <string /> @@ -50,6 +53,21 @@ </Object> + <Object name='armarx::armem::arondto::ManipulationCapability'> + <ObjectChild key="affordance"> + <string /> + </ObjectChild> + <ObjectChild key="tcp"> + <string optional="true"/> + </ObjectChild> + <ObjectChild key="shape"> + <string optional="true"/> + </ObjectChild> + <ObjectChild key="type"> + <string optional="true"/> + </ObjectChild> + </Object> + <Object name='armarx::armem::arondto::RobotInfo'> <ObjectChild key="parts"> <Dict> @@ -121,6 +139,14 @@ <armarx::armem::arondto::RobotInfo /> </ObjectChild> + <ObjectChild key='manipulationCapabilities'> + <Dict optional="true"> + <List> + <armarx::armem::arondto::ManipulationCapability /> + </List> + </Dict> + </ObjectChild> + <!-- <ObjectChild key='scaling'> <float32 /> </ObjectChild> --> diff --git a/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp b/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp index 9d03afe51e81fa99cf707eaf09ad517825d245f6..41f86a758d9ee8137d54351162ef42ac23a83bbf 100644 --- a/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp @@ -117,6 +117,7 @@ namespace armarx::armem::robot_state::description fromAron(dto.xml, bo.xml); aron::fromAron(dto.visualization, bo.visualization); aron::fromAron(dto.info, bo.info); + aron::fromAron(dto.manipulationCapabilities, bo.manipulationCapabilities); } void @@ -126,6 +127,7 @@ namespace armarx::armem::robot_state::description toAron(dto.xml, bo.xml); aron::toAron(dto.visualization, bo.visualization); aron::toAron(dto.info, bo.info); + aron::toAron(dto.manipulationCapabilities, bo.manipulationCapabilities); } } // namespace armarx::armem::robot_state::description diff --git a/source/RobotAPI/libraries/armem_robot_state/server/description/Segment.cpp b/source/RobotAPI/libraries/armem_robot_state/server/description/Segment.cpp index 0fdb753ba78f100ed62681da36dc5673a3bb1af8..ef4c89379d9f243e1c7b22699b93c983370f5614 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/description/Segment.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/server/description/Segment.cpp @@ -3,6 +3,7 @@ #include <filesystem> #include <SimoxUtility/algorithm/string/string_tools.h> +#include <VirtualRobot/XML/RobotIO.h> #include <ArmarXCore/core/PackagePath.h> #include <ArmarXCore/core/application/properties/PluginAll.h> @@ -20,6 +21,7 @@ #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h> #include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron/Robot.aron.generated.h> +#include <RobotAPI/libraries/armem_robot_state/aron/RobotDescription.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron_conversions.h> #include <RobotAPI/libraries/armem_robot_state/memory_ids.h> #include <RobotAPI/libraries/armem_robot_state/robot_conversions.h> @@ -187,6 +189,10 @@ namespace armarx::armem::server::robot_state::description e.torso_kinematic_chain = tryGet([&]() { return arm.getTorsoKinematicChain(); }); + e.hand_unit = + tryGet([&]() { return arm.getHandUnitName(); }); + + info.parts.emplace(side + "Arm", e); } } @@ -208,11 +214,51 @@ namespace armarx::armem::server::robot_state::description } } + std::optional< + std::map<std::string, std::vector<armarx::armem::arondto::ManipulationCapability>>> + allManipulationCapabilities; + { + const auto robot = VirtualRobot::RobotIO::loadRobot(robotPath.toSystemPath()); + ARMARX_CHECK_NOT_NULL(robot) << robotPath.toSystemPath(); + + for (const auto& eef : robot->getEndEffectors()) + { + const auto& capabilities = eef->getManipulationCapabilities(); + if (capabilities.has_value()) + { + std::vector<armarx::armem::arondto::ManipulationCapability> + manipulationCapabilities; + + for (const auto& vrCap : capabilities->capabilities) + { + arondto::ManipulationCapability dto; + + dto.affordance = vrCap.affordance; + dto.tcp = vrCap.tcp; + dto.shape = vrCap.shape; + dto.type = vrCap.type; + + manipulationCapabilities.push_back(dto); + } + + // initialize on demand + if (not allManipulationCapabilities) + { + allManipulationCapabilities.emplace(); + } + + allManipulationCapabilities->emplace(eef->getName(), + manipulationCapabilities); + } + } + } + const armem::robot_state::description::RobotDescription robotDescription{ .name = kinematicUnit->getRobotName(), .xml = {robotPath.serialize().package, robotPath.serialize().path}, .visualization = visualization, - .info = info}; + .info = info, + .manipulationCapabilities = allManipulationCapabilities}; // make sure that the package path is valid ARMARX_CHECK(std::filesystem::exists(robotDescription.xml.toSystemPath())); diff --git a/source/RobotAPI/libraries/armem_robot_state/types.h b/source/RobotAPI/libraries/armem_robot_state/types.h index 80d11cc4f556da58b9489b4fd452f12e632b093e..aa30157a5bf548f7cbcad4c63650e089d1a3730d 100644 --- a/source/RobotAPI/libraries/armem_robot_state/types.h +++ b/source/RobotAPI/libraries/armem_robot_state/types.h @@ -23,6 +23,7 @@ #include <filesystem> #include <map> +#include <optional> #include <vector> #include <Eigen/Geometry> @@ -49,6 +50,9 @@ namespace armarx::armem::robot_state arondto::RobotDescriptionVisualization visualization; arondto::RobotInfo info; + std::optional< + std::map<std::string, std::vector<armarx::armem::arondto::ManipulationCapability>>> + manipulationCapabilities = std::nullopt; }; using RobotDescriptions = std::vector<RobotDescription>;