diff --git a/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt b/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt index d5760158331a6f3dc664f3116a9f571e6830d37d..a2587dc0c09e5329484dceb1838ea097e016283f 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt +++ b/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt @@ -11,17 +11,23 @@ set(COMPONENT_LIBS set(SOURCES ObjectPoseObserver.cpp - ObjectPoseProviderPlugin.cpp + + plugins/ObjectPoseProviderPlugin.cpp + plugins/ObjectPoseClientPlugin.cpp ObjectFinder.cpp ice_conversions.cpp + ObjectPose.cpp ) set(HEADERS ObjectPoseObserver.h - ObjectPoseProviderPlugin.h + + plugins/ObjectPoseProviderPlugin.h + plugins/ObjectPoseClientPlugin.h ObjectFinder.h ice_conversions.h + ObjectPose.h ) diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp b/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp index 4779f70a41dda97a309ed7606b37f192f142a29a..eef7faa2231ea91333ed9b4da81ff402f74a1cdc 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp @@ -3,6 +3,7 @@ #include <SimoxUtility/filesystem/list_directory.h> #include <SimoxUtility/json.h> #include <SimoxUtility/shapes/AxisAlignedBoundingBox.h> +#include <SimoxUtility/shapes/OrientedBox.h> #include <ArmarXCore/core/exceptions/local/ExpressionException.h> #include <ArmarXCore/core/system/cmake/CMakePackageFinder.h> @@ -85,17 +86,29 @@ namespace armarx std::vector<std::string> ObjectFinder::getDatasets() const { - init(); - const bool local = true; - std::vector<path> paths = simox::fs::list_directory(_rootDirAbs(), local); - return std::vector<std::string>(paths.begin(), paths.end()); + // init(); // Done by called methods. + std::vector<std::string> datasets; + for (const auto& dir : getDatasetDirectories()) + { + datasets.push_back(dir.filename()); + } + return datasets; } std::vector<ObjectFinder::path> ObjectFinder::getDatasetDirectories() const { init(); const bool local = false; - return simox::fs::list_directory(_rootDirAbs(), local); + std::vector<path> dirs = simox::fs::list_directory(_rootDirAbs(), local); + std::vector<path> datasetDirs; + for (const auto& p : dirs) + { + if (std::filesystem::is_directory(p)) + { + datasetDirs.push_back(p); + } + } + return datasetDirs; } std::vector<ObjectInfo> ObjectFinder::findAllObjects(bool checkPaths) const @@ -117,6 +130,18 @@ namespace armarx return objects; } + std::map<std::string, std::vector<ObjectInfo>> + ObjectFinder::findAllObjectsByDataset(bool checkPaths) const + { + // init(); // Done by called methods. + std::map<std::string, std::vector<ObjectInfo>> objects; + for (const std::string& dataset : getDatasets()) + { + objects[dataset] = findAllObjectsOfDataset(dataset, checkPaths); + } + return objects; + } + std::vector<ObjectInfo> ObjectFinder::findAllObjectsOfDataset(const std::string& dataset, bool checkPaths) const { init(); @@ -227,6 +252,23 @@ namespace armarx return simox::AxisAlignedBoundingBox(min, max); } + simox::OrientedBox<float> ObjectInfo::oobb() const + { + nlohmann::json j = nlohmann::read_json(boundingBoxJson().absolutePath); + nlohmann::json joobb = j.at("oobb"); + auto ori = joobb.at("ori").get<Eigen::Quaternionf>().toRotationMatrix(); + auto min = joobb.at("min").get<Eigen::Vector3f>(); + auto extents = joobb.at("extents").get<Eigen::Vector3f>(); + + Eigen::Vector3f corner = ori * min; + + simox::OrientedBox<float> oobb(corner, + ori.col(0) * extents(0), + ori.col(1) * extents(1), + ori.col(2) * extents(2)); + return oobb; + } + bool ObjectInfo::checkPaths() const { namespace fs = std::filesystem; diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h b/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h index e7e8fdf98b9669d2f52ac746200d53113a3c7333..7bbaa7c2282029ed78399027154f392f84ccad8a 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h @@ -7,6 +7,7 @@ namespace simox { struct AxisAlignedBoundingBox; + template<class FloatT> class OrientedBox; } namespace armarx @@ -37,6 +38,7 @@ namespace armarx std::vector<path> getDatasetDirectories() const; std::vector<ObjectInfo> findAllObjects(bool checkPaths = true) const; + std::map<std::string, std::vector<ObjectInfo>> findAllObjectsByDataset(bool checkPaths = true) const; std::vector<ObjectInfo> findAllObjectsOfDataset(const std::string& dataset, bool checkPaths = true) const; @@ -99,6 +101,7 @@ namespace armarx PackageFileLocation boundingBoxJson() const; simox::AxisAlignedBoundingBox aabb() const; + simox::OrientedBox<float> oobb() const; /** diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPose.cpp b/source/RobotAPI/components/ObjectPoseObserver/ObjectPose.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd24a1ecc8cc9cf390684902112e5ac44a49c624 --- /dev/null +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectPose.cpp @@ -0,0 +1,160 @@ +#include "ObjectPose.h" + +#include <VirtualRobot/Robot.h> +#include <VirtualRobot/RobotConfig.h> + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +#include <RobotAPI/libraries/core/Pose.h> +#include <RobotAPI/libraries/core/FramedPose.h> + + +namespace armarx::objpose +{ + + Eigen::Matrix4f toEigen(const PoseBasePtr pose) + { + auto cast = PosePtr::dynamicCast(pose); + ARMARX_CHECK_NOT_NULL(cast); + return cast->toEigen(); + } + + ObjectPose::ObjectPose() + { + } + + ObjectPose::ObjectPose(const data::ObjectPose& ice) + { + fromIce(ice); + } + + void ObjectPose::fromIce(const data::ObjectPose& ice) + { + providerName = ice.providerName; + objectType = ice.objectType; + objectID = ice.objectID; + + objectPoseRobot = toEigen(ice.objectPoseRobot); + objectPoseGlobal = toEigen(ice.objectPoseGlobal); + objectPoseOriginal = toEigen(ice.objectPoseOriginal); + objectPoseOriginalFrame = ice.objectPoseOriginalFrame; + + robotConfig = ice.robotConfig; + robotPose = toEigen(ice.robotPose); + + confidence = ice.confidence; + timestamp = IceUtil::Time::microSeconds(ice.timestampMicroSeconds); + + localOOBB = ice.localOOBB; + } + + data::ObjectPose ObjectPose::toIce() const + { + data::ObjectPose ice; + toIce(ice); + return ice; + } + + void ObjectPose::toIce(data::ObjectPose& ice) const + { + ice.providerName = providerName; + ice.objectType = objectType; + ice.objectID = objectID; + + ice.objectPoseRobot = new Pose(objectPoseRobot); + ice.objectPoseGlobal = new Pose(objectPoseGlobal); + ice.objectPoseOriginal = new Pose(objectPoseOriginal); + ice.objectPoseOriginalFrame = objectPoseOriginalFrame; + + ice.robotConfig = robotConfig; + ice.robotPose = new Pose(robotPose); + + ice.confidence = confidence; + ice.timestampMicroSeconds = timestamp.toMicroSeconds(); + + ice.localOOBB = localOOBB; + } + + void ObjectPose::fromProvidedPose(const data::ProvidedObjectPose& provided, VirtualRobot::RobotPtr robot) + { + providerName = provided.providerName; + objectType = provided.objectType; + + objectID = provided.objectID; + + objectPoseOriginal = toEigen(provided.objectPose); + objectPoseOriginalFrame = provided.objectPoseFrame; + + armarx::FramedPose framed(objectPoseOriginal, objectPoseOriginalFrame, robot->getName()); + framed.changeFrame(robot, robot->getRootNode()->getName()); + objectPoseRobot = framed.toEigen(); + framed.changeToGlobal(robot); + objectPoseGlobal = framed.toEigen(); + + robotConfig = robot->getConfig()->getRobotNodeJointValueMap(); + robotPose = robot->getGlobalPose(); + + confidence = provided.confidence; + timestamp = IceUtil::Time::microSeconds(provided.timestampMicroSeconds); + + localOOBB = provided.localOOBB; + } + +} + +namespace armarx +{ + + void objpose::fromIce(const data::ObjectPose& ice, ObjectPose& pose) + { + pose.fromIce(ice); + } + objpose::ObjectPose objpose::fromIce(const data::ObjectPose& ice) + { + return ObjectPose(ice); + } + + void objpose::fromIce(const data::ObjectPoseSeq& ice, ObjectPoseSeq& poses) + { + poses.clear(); + poses.reserve(ice.size()); + for (const auto& i : ice) + { + poses.emplace_back(i); + } + } + objpose::ObjectPoseSeq objpose::fromIce(const data::ObjectPoseSeq& ice) + { + ObjectPoseSeq poses; + fromIce(ice, poses); + return poses; + } + + + void objpose::toIce(data::ObjectPose& ice, const ObjectPose& pose) + { + pose.toIce(ice); + } + objpose::data::ObjectPose objpose::toIce(const ObjectPose& pose) + { + return pose.toIce(); + } + + void objpose::toIce(data::ObjectPoseSeq& ice, const ObjectPoseSeq& poses) + { + ice.clear(); + ice.reserve(poses.size()); + for (const auto& p : poses) + { + ice.emplace_back(p.toIce()); + } + } + objpose::data::ObjectPoseSeq objpose::toIce(const ObjectPoseSeq& poses) + { + data::ObjectPoseSeq ice; + toIce(ice, poses); + return ice; + } + +} + diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPose.h b/source/RobotAPI/components/ObjectPoseObserver/ObjectPose.h new file mode 100644 index 0000000000000000000000000000000000000000..6a237e319daaae4c6e43ff0d6cd933990d2ae2f2 --- /dev/null +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectPose.h @@ -0,0 +1,71 @@ +#pragma once + +#include <Eigen/Core> + +#include <VirtualRobot/VirtualRobot.h> + +#include <IceUtil/Time.h> + +#include <RobotAPI/interface/objectpose/types.h> + + +namespace armarx::objpose +{ + + /** + * @brief An object pose as stored by the ObjectPoseObserver. + */ + struct ObjectPose + { + ObjectPose(); + ObjectPose(const data::ObjectPose& ice); + + void fromIce(const data::ObjectPose& ice); + + data::ObjectPose toIce() const; + void toIce(data::ObjectPose& ice) const; + + void fromProvidedPose(const data::ProvidedObjectPose& provided, VirtualRobot::RobotPtr robot); + + + /// Name of the providing component. + std::string providerName; + /// Known or unknown object. + ObjectTypeEnum objectType = AnyObject; + + /// The object ID, i.e. dataset and name. + ObjectID objectID; + + Eigen::Matrix4f objectPoseRobot; + Eigen::Matrix4f objectPoseGlobal; + Eigen::Matrix4f objectPoseOriginal; + std::string objectPoseOriginalFrame; + + std::map<std::string, float> robotConfig; + Eigen::Matrix4f robotPose; + + /// Confidence in [0, 1] (1 = full, 0 = none). + float confidence = 0; + /// Source timestamp. + IceUtil::Time timestamp = IceUtil::Time::microSeconds(-1); + + /// Object bounding box in object's local coordinate frame. + Box localOOBB; + }; + using ObjectPoseSeq = std::vector<ObjectPose>; + + + void fromIce(const data::ObjectPose& ice, ObjectPose& pose); + ObjectPose fromIce(const data::ObjectPose& ice); + + void fromIce(const data::ObjectPoseSeq& ice, ObjectPoseSeq& poses); + ObjectPoseSeq fromIce(const data::ObjectPoseSeq& ice); + + + void toIce(data::ObjectPose& ice, const ObjectPose& pose); + data::ObjectPose toIce(const ObjectPose& pose); + + void toIce(data::ObjectPoseSeq& ice, const ObjectPoseSeq& poses); + data::ObjectPoseSeq toIce(const ObjectPoseSeq& poses); + +} diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp index b969a58931b1d3242a0ebbbf5176c1ccc413810e..e7202cd5ae606072e92b776949bcb5b15f2d9270 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp @@ -31,18 +31,12 @@ #include <RobotAPI/libraries/core/Pose.h> #include <RobotAPI/libraries/core/FramedPose.h> +#include "ice_conversions.h" + namespace armarx { - const simox::meta::EnumNames<objpose::ObjectTypeEnum> ObjectTypeEnumNames = - { - { objpose::ObjectTypeEnum::AnyObject, "AnyObject" }, - { objpose::ObjectTypeEnum::KnownObject, "KnownObject" }, - { objpose::ObjectTypeEnum::UnknownObject, "UnknownObject" } - }; - - ObjectPoseObserverPropertyDefinitions::ObjectPoseObserverPropertyDefinitions(std::string prefix) : armarx::ObserverPropertyDefinitions(prefix) { @@ -121,11 +115,11 @@ namespace armarx { offerChannel(providerName, "Channel of provider '" + providerName + "'."); } - offerOrUpdateDataField(providerName, "objectType", ObjectTypeEnumNames.to_name(info.objectType), ""); + offerOrUpdateDataField(providerName, "objectType", objpose::ObjectTypeEnumNames.to_name(info.objectType), ""); } void ObjectPoseObserver::reportObjectPoses( - const std::string& providerName, const objpose::ProvidedObjectPoseSeq& providedPoses, const Ice::Current&) + const std::string& providerName, const objpose::data::ProvidedObjectPoseSeq& providedPoses, const Ice::Current&) { ARMARX_VERBOSE << "Received object poses from '" << providerName << "'."; @@ -137,28 +131,7 @@ namespace armarx for (const auto& provided : providedPoses) { objpose::ObjectPose& pose = objectPoses.emplace_back(); - pose.objectType = provided.objectType; - pose.objectID = provided.objectID; - - pose.objectPoseOriginal = provided.objectPose; - pose.objectPoseOriginalFrame = provided.objectPoseFrame; - - armarx::PosePtr p = armarx::PosePtr::dynamicCast(provided.objectPose); - ARMARX_CHECK_NOT_NULL(p); - { - armarx::FramedPose framed(p->toEigen(), provided.objectPoseFrame, robot->getName()); - framed.changeFrame(robot, robot->getRootNode()->getName()); - pose.objectPoseRobot = new Pose(framed.toEigen()); - framed.changeToGlobal(robot); - pose.objectPoseGlobal = new Pose(framed.toEigen()); - - pose.robotConfig = robot->getConfig()->getRobotNodeJointValueMap(); - pose.robotPose = new Pose(robot->getGlobalPose()); - } - - pose.confidence = provided.confidence; - pose.timestampMicroSeconds = provided.timestampMicroSeconds; - pose.providerName = provided.providerName; + pose.fromProvidedPose(provided, robot); } } @@ -170,24 +143,24 @@ namespace armarx } - objpose::ObjectPoseSeq ObjectPoseObserver::getObjectPoses(const Ice::Current&) + objpose::data::ObjectPoseSeq ObjectPoseObserver::getObjectPoses(const Ice::Current&) { std::scoped_lock lock(dataMutex); - objpose::ObjectPoseSeq result; + objpose::data::ObjectPoseSeq result; for (const auto& [name, poses] : objectPoses) { for (const auto& pose : poses) { - result.push_back(pose); + result.push_back(pose.toIce()); } } return result; } - objpose::ObjectPoseSeq ObjectPoseObserver::getObjectPosesByProvider(const std::string& providerName, const Ice::Current&) + objpose::data::ObjectPoseSeq ObjectPoseObserver::getObjectPosesByProvider(const std::string& providerName, const Ice::Current&) { std::scoped_lock lock(dataMutex); - return objectPoses.at(providerName); + return objpose::toIce(objectPoses.at(providerName)); } @@ -325,11 +298,11 @@ namespace armarx continue; } - PoseBasePtr pose = visu.inGlobalFrame ? objectPose.objectPoseGlobal : objectPose.objectPoseRobot; + Eigen::Matrix4f pose = visu.inGlobalFrame ? objectPose.objectPoseGlobal : objectPose.objectPoseRobot; viz::Object object = viz::Object(id.dataset + "/" + id.name) .file(objectInfo->package(), objectInfo->simoxXML().relativePath) - .pose(armarx::PosePtr::dynamicCast(pose)->toEigen()); + .pose(pose); if (visu.alpha < 1) { object.overrideColor(simox::Color::white().with_alpha(visu.alpha)); diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h index d06d2e2915b1e959dce91b727b498ba1140bf059..23484b0b377b7d2fad5b56c8aab7f87f613624a3 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h @@ -33,7 +33,7 @@ #include <RobotAPI/libraries/RobotAPIComponentPlugins/RobotStateComponentPlugin.h> #include "ObjectFinder.h" -#include "ice_conversions.h" +#include "ObjectPose.h" #define ICE_CURRENT_ARG const Ice::Current& = Ice::emptyCurrent @@ -83,13 +83,13 @@ namespace armarx // ObjectPoseTopic interface public: void reportProviderAvailable(const std::string& providerName, ICE_CURRENT_ARG) override; - void reportObjectPoses(const std::string& providerName, const objpose::ProvidedObjectPoseSeq& objectPoses, ICE_CURRENT_ARG) override; + void reportObjectPoses(const std::string& providerName, const objpose::data::ProvidedObjectPoseSeq& objectPoses, ICE_CURRENT_ARG) override; // ObjectPoseObserverInterface interface public: - objpose::ObjectPoseSeq getObjectPoses(ICE_CURRENT_ARG) override; - objpose::ObjectPoseSeq getObjectPosesByProvider(const std::string& providerName, ICE_CURRENT_ARG) override; + objpose::data::ObjectPoseSeq getObjectPoses(ICE_CURRENT_ARG) override; + objpose::data::ObjectPoseSeq getObjectPosesByProvider(const std::string& providerName, ICE_CURRENT_ARG) override; void requestObjects(const objpose::ObjectIDSeq& objectIDs, Ice::Long relativeTimeoutMS, ICE_CURRENT_ARG) override; diff --git a/source/RobotAPI/components/ObjectPoseObserver/ProvidedObjectPose.cpp b/source/RobotAPI/components/ObjectPoseObserver/ProvidedObjectPose.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ecf05de2b31c102245e4fccfbf9663d43ab19f9b --- /dev/null +++ b/source/RobotAPI/components/ObjectPoseObserver/ProvidedObjectPose.cpp @@ -0,0 +1,12 @@ +#include "ProvidedObjectPose.h" + + +namespace armarx::objpose +{ + ProvidedObjectPose::ProvidedObjectPose(const data::ProvidedObjectPose& ice) + { + + } +} + + diff --git a/source/RobotAPI/components/ObjectPoseObserver/ProvidedObjectPose.h b/source/RobotAPI/components/ObjectPoseObserver/ProvidedObjectPose.h new file mode 100644 index 0000000000000000000000000000000000000000..afc47fe515c61511c1ab225df37b2c96a48eaa2f --- /dev/null +++ b/source/RobotAPI/components/ObjectPoseObserver/ProvidedObjectPose.h @@ -0,0 +1,41 @@ +#pragma once + +#include <Eigen/Core> + +#include <RobotAPI/interface/objectpose/types.h> + + +namespace armarx::objpose +{ + + struct ProvidedObjectPose + { + ProvidedObjectPose(); + ProvidedObjectPose(const data::ProvidedObjectPose& ice); + + + /// Name of the providing component. + std::string providerName; + /// Known or unknown object. + ObjectTypeEnum objectType = AnyObject; + + /// The object ID, i.e. dataset and name. + ObjectID objectID; + + /// Pose in `objectPoseFrame`. + Eigen::Matrix4f objectPose; + std::string objectPoseFrame; + + /// Confidence in [0, 1] (1 = full, 0 = none). + float confidence = 0; + /// Source timestamp. + long timestampMicroSeconds = -1; + + /// Object bounding box in object's local coordinate frame. + Box localOOBB; + }; + + + + +} diff --git a/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.cpp b/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.cpp index 0502b05d46ce9747707522052a40c1a69df0048c..e40d29d709de816fedbd44e84d54f08961542eff 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.cpp +++ b/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.cpp @@ -1,5 +1,12 @@ #include "ice_conversions.h" +#include <VirtualRobot/Robot.h> +#include <VirtualRobot/RobotConfig.h> + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +#include <RobotAPI/libraries/core/FramedPose.h> + namespace armarx { @@ -9,5 +16,13 @@ namespace armarx return os << "'" << id.dataset << "/" << id.name << "'"; } + const simox::meta::EnumNames<objpose::ObjectTypeEnum> objpose::ObjectTypeEnumNames = + { + { objpose::ObjectTypeEnum::AnyObject, "AnyObject" }, + { objpose::ObjectTypeEnum::KnownObject, "KnownObject" }, + { objpose::ObjectTypeEnum::UnknownObject, "UnknownObject" } + }; + } + diff --git a/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.h b/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.h index fc73211f96f470557795667cbc62e8405f33bdd6..e9a0da5413706e3e53eea0f4fb4fee267c5f8354 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.h +++ b/source/RobotAPI/components/ObjectPoseObserver/ice_conversions.h @@ -1,7 +1,10 @@ #pragma once +#include <SimoxUtility/meta/enum/EnumNames.hpp> + #include <RobotAPI/interface/objectpose/types.h> -#include <RobotAPI/interface/objectpose/ObjectPoseProvider.h> + +#include "ObjectPose.h" namespace armarx::objpose @@ -9,5 +12,6 @@ namespace armarx::objpose std::ostream& operator<<(std::ostream& os, const ObjectID& id); + extern const simox::meta::EnumNames<objpose::ObjectTypeEnum> ObjectTypeEnumNames; } diff --git a/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseClientPlugin.cpp b/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseClientPlugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb921e04a106971c501849d28fec3dfc18db415f --- /dev/null +++ b/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseClientPlugin.cpp @@ -0,0 +1,59 @@ +#include "ObjectPoseClientPlugin.h" + + +namespace armarx::plugins +{ + + void ObjectPoseClientPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) + { + if (!properties->hasDefinition(makePropertyName(PROPERTY_NAME))) + { + properties->defineOptionalProperty<std::string>( + makePropertyName(PROPERTY_NAME), + "ObjectPoseObserver", + "Name of the object pose observer."); + } + } + + void ObjectPoseClientPlugin::preOnInitComponent() + { + parent<Component>().usingProxyFromProperty(makePropertyName(PROPERTY_NAME)); + } + + void ObjectPoseClientPlugin::preOnConnectComponent() + { + parent<ObjectPoseClientPluginUser>().objectPoseObserver = createObjectPoseObserver(); + } + + objpose::ObjectPoseObserverInterfacePrx ObjectPoseClientPlugin::createObjectPoseObserver() + { + return parent<Component>().getTopicFromProperty<objpose::ObjectPoseObserverInterfacePrx>(makePropertyName(PROPERTY_NAME)); + } + +} + + +namespace armarx +{ + + ObjectPoseClientPluginUser::ObjectPoseClientPluginUser() + { + addPlugin(plugin); + } + + objpose::ObjectPoseObserverInterfacePrx ObjectPoseClientPluginUser::createObjectPoseObserver() + { + return plugin->createObjectPoseObserver(); + } + + objpose::ObjectPoseSeq ObjectPoseClientPluginUser::getObjectPoses() + { + if (!objectPoseObserver) + { + ARMARX_WARNING << "No object pose observer."; + return {}; + } + return objpose::fromIce(objectPoseObserver->getObjectPoses()); + } + +} diff --git a/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseClientPlugin.h b/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseClientPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..667c22b4ed44a887c9dcd453836fcb67e50d4c9f --- /dev/null +++ b/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseClientPlugin.h @@ -0,0 +1,63 @@ +#pragma once + +#include <ArmarXCore/core/Component.h> + +#include <RobotAPI/interface/objectpose/ObjectPoseObserver.h> + +#include "../ObjectPose.h" + + +namespace armarx::plugins +{ + + class ObjectPoseClientPlugin : public ComponentPlugin + { + public: + using ComponentPlugin::ComponentPlugin; + + void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override; + + void preOnInitComponent() override; + void preOnConnectComponent() override; + + objpose::ObjectPoseObserverInterfacePrx createObjectPoseObserver(); + + + private: + + static constexpr const char* PROPERTY_NAME = "ObjectPoseTopicName"; + + }; + +} + + +namespace armarx +{ + + /** + * @brief Provides an `objpose::ObjectPoseTopicPrx objectPoseTopic` as member variable. + */ + class ObjectPoseClientPluginUser : + virtual public ManagedIceObject + { + public: + + /// Allow usage like: ObjectPose::getObjects() + using ObjectPose = ObjectPoseClientPluginUser; + + ObjectPoseClientPluginUser(); + + objpose::ObjectPoseObserverInterfacePrx createObjectPoseObserver(); + objpose::ObjectPoseObserverInterfacePrx objectPoseObserver; + + + objpose::ObjectPoseSeq getObjectPoses(); + + + private: + + armarx::plugins::ObjectPoseClientPlugin* plugin = nullptr; + + }; +} diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseProviderPlugin.cpp b/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseProviderPlugin.cpp similarity index 100% rename from source/RobotAPI/components/ObjectPoseObserver/ObjectPoseProviderPlugin.cpp rename to source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseProviderPlugin.cpp diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseProviderPlugin.h b/source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseProviderPlugin.h similarity index 100% rename from source/RobotAPI/components/ObjectPoseObserver/ObjectPoseProviderPlugin.h rename to source/RobotAPI/components/ObjectPoseObserver/plugins/ObjectPoseProviderPlugin.h diff --git a/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice b/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice index 3eddae79a480fa3aee046da4572e552e052fba50..7a8060dbabbb206be75243df6f579b90a203993d 100644 --- a/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice +++ b/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice @@ -36,39 +36,10 @@ module armarx module objpose { - struct ObjectPose - { - /// Name of the providing component. - string providerName; - /// Known or unknown object. - ObjectTypeEnum objectType = AnyObject; - - /// The object ID, i.e. dataset and name. - ObjectID objectID; - - PoseBase objectPoseRobot; - PoseBase objectPoseGlobal; - PoseBase objectPoseOriginal; - string objectPoseOriginalFrame; - - StringFloatDictionary robotConfig; - PoseBase robotPose; - - /// Confidence in [0, 1] (1 = full, 0 = none). - float confidence = 0; - /// Source timestamp. - long timestampMicroSeconds = -1; - - /// Object bounding box in object's local coordinate frame. - Box localOOBB; - }; - sequence<ObjectPose> ObjectPoseSeq; - - interface ObjectPoseObserverInterface extends ObserverInterface, ObjectPoseTopic { - ObjectPoseSeq getObjectPoses(); - ObjectPoseSeq getObjectPosesByProvider(string providerName); + data::ObjectPoseSeq getObjectPoses(); + data::ObjectPoseSeq getObjectPosesByProvider(string providerName); void requestObjects(ObjectIDSeq objectIDs, long relativeTimeoutMS); diff --git a/source/RobotAPI/interface/objectpose/ObjectPoseProvider.ice b/source/RobotAPI/interface/objectpose/ObjectPoseProvider.ice index 61f9a99fb6872ba20a9cd47dd8976130914c257b..4dcfb2d2f699107a2fbf95a4cf0baf996726a33b 100644 --- a/source/RobotAPI/interface/objectpose/ObjectPoseProvider.ice +++ b/source/RobotAPI/interface/objectpose/ObjectPoseProvider.ice @@ -33,31 +33,6 @@ module armarx // A struct's name cannot cannot differ only in capitalization from its immediately enclosing module name. module objpose { - struct ProvidedObjectPose - { - /// Name of the providing component. - string providerName; - /// Known or unknown object. - ObjectTypeEnum objectType = AnyObject; - - /// The object ID, i.e. dataset and name. - ObjectID objectID; - - /// Pose in `objectPoseFrame`. - PoseBase objectPose; - string objectPoseFrame; - - /// Confidence in [0, 1] (1 = full, 0 = none). - float confidence = 0; - /// Source timestamp. - long timestampMicroSeconds = -1; - - /// Object bounding box in object's local coordinate frame. - Box localOOBB; - }; - sequence<ProvidedObjectPose> ProvidedObjectPoseSeq; - - struct ProviderInfo { ObjectTypeEnum objectType = AnyObject; @@ -70,7 +45,7 @@ module armarx { /// Signal that a new provider is now available (and ready for `getProviderInfo()`. void reportProviderAvailable(string providerName); - void reportObjectPoses(string providerName, ProvidedObjectPoseSeq candidates); + void reportObjectPoses(string providerName, data::ProvidedObjectPoseSeq candidates); }; interface ObjectPoseProvider diff --git a/source/RobotAPI/interface/objectpose/types.ice b/source/RobotAPI/interface/objectpose/types.ice index e91ac3fcf82b7a3548e44ecdc3ce6a43572f1bc9..eaf7adf779b0ac6d51c952f343f08d75bd87d93c 100644 --- a/source/RobotAPI/interface/objectpose/types.ice +++ b/source/RobotAPI/interface/objectpose/types.ice @@ -57,6 +57,65 @@ module armarx Vector3Base extents; }; + + module data + { + /// An object pose provided by an ObjectPoseProvider. + struct ProvidedObjectPose + { + /// Name of the providing component. + string providerName; + /// Known or unknown object. + ObjectTypeEnum objectType = AnyObject; + + /// The object ID, i.e. dataset and name. + ObjectID objectID; + + /// Pose in `objectPoseFrame`. + PoseBase objectPose; + string objectPoseFrame; + + /// Confidence in [0, 1] (1 = full, 0 = none). + float confidence = 0; + /// Source timestamp. + long timestampMicroSeconds = -1; + + /// Object bounding box in object's local coordinate frame. + Box localOOBB; + }; + sequence<ProvidedObjectPose> ProvidedObjectPoseSeq; + + + /// An object pose as stored by the ObjectPoseObserver. + struct ObjectPose + { + /// Name of the providing component. + string providerName; + /// Known or unknown object. + ObjectTypeEnum objectType = AnyObject; + + /// The object ID, i.e. dataset and name. + ObjectID objectID; + + PoseBase objectPoseRobot; + PoseBase objectPoseGlobal; + PoseBase objectPoseOriginal; + string objectPoseOriginalFrame; + + StringFloatDictionary robotConfig; + PoseBase robotPose; + + /// Confidence in [0, 1] (1 = full, 0 = none). + float confidence = 0; + /// Source timestamp. + long timestampMicroSeconds = -1; + + /// Object bounding box in object's local coordinate frame. + Box localOOBB; + }; + sequence<ObjectPose> ObjectPoseSeq; + } + }; };