diff --git a/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt b/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt index a2587dc0c09e5329484dceb1838ea097e016283f..b49a31287eea44fc18ce7dc397efd05cd18d7000 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt +++ b/source/RobotAPI/components/ObjectPoseObserver/CMakeLists.txt @@ -15,7 +15,6 @@ set(SOURCES plugins/ObjectPoseProviderPlugin.cpp plugins/ObjectPoseClientPlugin.cpp - ObjectFinder.cpp ice_conversions.cpp ObjectPose.cpp ) @@ -25,7 +24,6 @@ set(HEADERS plugins/ObjectPoseProviderPlugin.h plugins/ObjectPoseClientPlugin.h - ObjectFinder.h ice_conversions.h ObjectPose.h ) diff --git a/source/RobotAPI/libraries/ArmarXObjects/ArmarXObjects.h b/source/RobotAPI/libraries/ArmarXObjects/ArmarXObjects.h index a1ebfe2e2679719eb58aa9cca8388394f5dd14e8..54315bcc8ebc727fdf55a6595a0683d6ccd1fea0 100644 --- a/source/RobotAPI/libraries/ArmarXObjects/ArmarXObjects.h +++ b/source/RobotAPI/libraries/ArmarXObjects/ArmarXObjects.h @@ -22,6 +22,8 @@ #pragma once +#include "ObjectFinder.h" +#include "ObjectInfo.h" namespace armarx { diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp b/source/RobotAPI/libraries/ArmarXObjects/ObjectFinder.cpp similarity index 55% rename from source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp rename to source/RobotAPI/libraries/ArmarXObjects/ObjectFinder.cpp index d24b27e90b9b123e5ed70ed4bcd1cbf6ac7e604d..f4e7b492421b31d5de6fe99243c76cd5fb55c5cd 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.cpp +++ b/source/RobotAPI/libraries/ArmarXObjects/ObjectFinder.cpp @@ -1,14 +1,13 @@ #include "ObjectFinder.h" #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> #include <ArmarXCore/core/util/StringHelpers.h> +#include "ObjectInfo.h" + namespace armarx { @@ -179,136 +178,5 @@ namespace armarx return packageName; } - - ObjectInfo::ObjectInfo(const std::string& packageName, const ObjectInfo::path& packageDataDir, - const std::string& dataset, const std::string& name) : - _packageName(packageName), _packageDataDir(packageDataDir), _dataset(dataset), _name(name) - { - } - - std::string ObjectInfo::package() const - { - return _packageName; - } - - std::string ObjectInfo::dataset() const - { - return _dataset; - } - - std::string ObjectInfo::name() const - { - return _name; - } - - std::string ObjectInfo::id() const - { - return _dataset + "/" + _name; - } - - ObjectInfo::path ObjectInfo::objectDirectory() const - { - return path(_packageName) / _dataset / _name; - } - - PackageFileLocation ObjectInfo::file(const std::string& _extension, const std::string& suffix) const - { - std::string extension = _extension; - if (extension.at(0) != '.') - { - extension = "." + extension; - } - std::string filename = _name + suffix + extension; - - PackageFileLocation loc; - loc.package = _packageName; - loc.relativePath = objectDirectory() / filename; - loc.absolutePath = _packageDataDir / loc.relativePath; - return loc; - } - - PackageFileLocation ObjectInfo::simoxXML() const - { - return file(".xml"); - } - - PackageFileLocation ObjectInfo::wavefrontObj() const - { - return file(".obj"); - } - - PackageFileLocation ObjectInfo::boundingBoxJson() const - { - return file(".json", "_bb"); - } - - simox::AxisAlignedBoundingBox ObjectInfo::aabb() const - { - nlohmann::json j = nlohmann::read_json(boundingBoxJson().absolutePath); - nlohmann::json jaabb = j.at("aabb"); - - auto center = jaabb.at("center").get<Eigen::Vector3f>(); - auto extents = jaabb.at("extents").get<Eigen::Vector3f>(); - auto min = jaabb.at("min").get<Eigen::Vector3f>(); - auto max = jaabb.at("max").get<Eigen::Vector3f>(); - - simox::AxisAlignedBoundingBox aabb(min, max); - - ARMARX_CHECK(aabb.center().isApprox(center)) << aabb.center().transpose() << "\n" << center.transpose(); - ARMARX_CHECK(aabb.extents().isApprox(extents)) << aabb.extents().transpose() << "\n" << extents.transpose(); - ARMARX_CHECK(aabb.min().isApprox(min)) << aabb.min().transpose() << "\n" << min.transpose(); - ARMARX_CHECK(aabb.max().isApprox(max)) << aabb.max().transpose() << "\n" << max.transpose(); - - return aabb; - } - - simox::OrientedBox<float> ObjectInfo::oobb() const - { - nlohmann::json j = nlohmann::read_json(boundingBoxJson().absolutePath); - nlohmann::json joobb = j.at("oobb"); - auto pos = joobb.at("pos").get<Eigen::Vector3f>(); - auto ori = joobb.at("ori").get<Eigen::Quaternionf>().toRotationMatrix(); - auto extents = joobb.at("extents").get<Eigen::Vector3f>(); - - Eigen::Vector3f corner = pos - ori * extents / 2; - - simox::OrientedBox<float> oobb(corner, - ori.col(0) * extents(0), - ori.col(1) * extents(1), - ori.col(2) * extents(2)); - - ARMARX_CHECK(oobb.center().isApprox(pos)) << oobb.center().transpose() << "\n" << pos.transpose(); - ARMARX_CHECK(oobb.rotation().isApprox(ori)) << oobb.rotation() << "\n" << ori; - ARMARX_CHECK(oobb.dimensions().isApprox(extents)) << oobb.dimensions().transpose() << "\n" << extents.transpose(); - return oobb; - } - - bool ObjectInfo::checkPaths() const - { - namespace fs = std::filesystem; - bool result = true; - - if (!fs::is_regular_file(simoxXML().absolutePath)) - { - ARMARX_WARNING << "Expected simox object file for object '" << *this << "': " << simoxXML().absolutePath; - result = false; - } - if (!fs::is_regular_file(wavefrontObj().absolutePath)) - { - ARMARX_WARNING << "Expected wavefront object file (.obj) for object '" << *this << "': " << wavefrontObj().absolutePath; - result = false; - } - - return result; - } - -} - -namespace armarx -{ - std::ostream& operator<<(std::ostream& os, const ObjectInfo& rhs) - { - return os << "'" << rhs.id() << "'"; - } } diff --git a/source/RobotAPI/libraries/ArmarXObjects/ObjectFinder.h b/source/RobotAPI/libraries/ArmarXObjects/ObjectFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..5e3a31f546c76a92d16e9a8bc87bba1dfcaef971 --- /dev/null +++ b/source/RobotAPI/libraries/ArmarXObjects/ObjectFinder.h @@ -0,0 +1,58 @@ +#pragma once + +#include <filesystem> + +#include <ArmarXCore/core/logging/Logging.h> + + +namespace armarx +{ + // #include <RobotAPI/libraries/ArmarXObjects/ObjectInfo.h> + class ObjectInfo; + + + /** + * @brief Used to find objects in the ArmarX objects repository [1]. + * + * @see [1] https://gitlab.com/ArmarX/ArmarXObjects + */ + class ObjectFinder : Logging + { + public: + using path = std::filesystem::path; + + public: + + ObjectFinder(const std::string& objectsPackageName = "ArmarXObjects"); + + std::optional<ObjectInfo> findObject(const std::string& dataset, const std::string& name) const; + std::optional<ObjectInfo> findObject(const std::string& nameOrID) const; + + + std::vector<std::string> getDatasets() const; + 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; + + + private: + + void init() const; + + path _rootDirAbs() const; + path _rootDirRel() const; + + + private: + + /// Name of package containing the object models (ArmarXObjects by default). + mutable std::string packageName; + + /// Absolute path to data directory (e.g. "/.../repos/ArmarXObjects/data"). + mutable path packageDataDir; + + }; + +} diff --git a/source/RobotAPI/libraries/ArmarXObjects/ObjectInfo.cpp b/source/RobotAPI/libraries/ArmarXObjects/ObjectInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..feaf2f203aca7445081f2f91e3d511a7b5bbdbd5 --- /dev/null +++ b/source/RobotAPI/libraries/ArmarXObjects/ObjectInfo.cpp @@ -0,0 +1,146 @@ +#include "ObjectInfo.h" + +#include <SimoxUtility/json.h> +#include <SimoxUtility/shapes/AxisAlignedBoundingBox.h> +#include <SimoxUtility/shapes/OrientedBox.h> + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx +{ + namespace fs = std::filesystem; + + + ObjectInfo::ObjectInfo(const std::string& packageName, const ObjectInfo::path& packageDataDir, + const std::string& dataset, const std::string& name) : + _packageName(packageName), _packageDataDir(packageDataDir), _dataset(dataset), _name(name) + { + } + + std::string ObjectInfo::package() const + { + return _packageName; + } + + std::string ObjectInfo::dataset() const + { + return _dataset; + } + + std::string ObjectInfo::name() const + { + return _name; + } + + std::string ObjectInfo::id() const + { + return _dataset + "/" + _name; + } + + ObjectInfo::path ObjectInfo::objectDirectory() const + { + return path(_packageName) / _dataset / _name; + } + + PackageFileLocation ObjectInfo::file(const std::string& _extension, const std::string& suffix) const + { + std::string extension = _extension; + if (extension.at(0) != '.') + { + extension = "." + extension; + } + std::string filename = _name + suffix + extension; + + PackageFileLocation loc; + loc.package = _packageName; + loc.relativePath = objectDirectory() / filename; + loc.absolutePath = _packageDataDir / loc.relativePath; + return loc; + } + + PackageFileLocation ObjectInfo::simoxXML() const + { + return file(".xml"); + } + + PackageFileLocation ObjectInfo::wavefrontObj() const + { + return file(".obj"); + } + + PackageFileLocation ObjectInfo::boundingBoxJson() const + { + return file(".json", "_bb"); + } + + simox::AxisAlignedBoundingBox ObjectInfo::aabb() const + { + nlohmann::json j = nlohmann::read_json(boundingBoxJson().absolutePath); + nlohmann::json jaabb = j.at("aabb"); + + auto center = jaabb.at("center").get<Eigen::Vector3f>(); + auto extents = jaabb.at("extents").get<Eigen::Vector3f>(); + auto min = jaabb.at("min").get<Eigen::Vector3f>(); + auto max = jaabb.at("max").get<Eigen::Vector3f>(); + + simox::AxisAlignedBoundingBox aabb(min, max); + + ARMARX_CHECK(aabb.center().isApprox(center)) << aabb.center().transpose() << "\n" << center.transpose(); + ARMARX_CHECK(aabb.extents().isApprox(extents)) << aabb.extents().transpose() << "\n" << extents.transpose(); + ARMARX_CHECK(aabb.min().isApprox(min)) << aabb.min().transpose() << "\n" << min.transpose(); + ARMARX_CHECK(aabb.max().isApprox(max)) << aabb.max().transpose() << "\n" << max.transpose(); + + return aabb; + } + + simox::OrientedBox<float> ObjectInfo::oobb() const + { + nlohmann::json j = nlohmann::read_json(boundingBoxJson().absolutePath); + nlohmann::json joobb = j.at("oobb"); + auto pos = joobb.at("pos").get<Eigen::Vector3f>(); + auto ori = joobb.at("ori").get<Eigen::Quaternionf>().toRotationMatrix(); + auto extents = joobb.at("extents").get<Eigen::Vector3f>(); + + Eigen::Vector3f corner = pos - ori * extents / 2; + + simox::OrientedBox<float> oobb(corner, + ori.col(0) * extents(0), + ori.col(1) * extents(1), + ori.col(2) * extents(2)); + + ARMARX_CHECK(oobb.center().isApprox(pos)) << oobb.center().transpose() << "\n" << pos.transpose(); + ARMARX_CHECK(oobb.rotation().isApprox(ori)) << oobb.rotation() << "\n" << ori; + ARMARX_CHECK(oobb.dimensions().isApprox(extents)) << oobb.dimensions().transpose() << "\n" << extents.transpose(); + return oobb; + } + + bool ObjectInfo::checkPaths() const + { + namespace fs = std::filesystem; + bool result = true; + + if (!fs::is_regular_file(simoxXML().absolutePath)) + { + ARMARX_WARNING << "Expected simox object file for object '" << *this << "': " << simoxXML().absolutePath; + result = false; + } + if (!fs::is_regular_file(wavefrontObj().absolutePath)) + { + ARMARX_WARNING << "Expected wavefront object file (.obj) for object '" << *this << "': " << wavefrontObj().absolutePath; + result = false; + } + + return result; + } + +} + +namespace armarx +{ + std::ostream& operator<<(std::ostream& os, const ObjectInfo& rhs) + { + return os << "'" << rhs.id() << "'"; + } +} + diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h b/source/RobotAPI/libraries/ArmarXObjects/ObjectInfo.h similarity index 57% rename from source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h rename to source/RobotAPI/libraries/ArmarXObjects/ObjectInfo.h index 7bbaa7c2282029ed78399027154f392f84ccad8a..260b3c15c66922eb2026817278f8d71ac2f14c75 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectFinder.h +++ b/source/RobotAPI/libraries/ArmarXObjects/ObjectInfo.h @@ -1,8 +1,8 @@ #pragma once #include <filesystem> +#include <string> -#include <ArmarXCore/core/logging/Logging.h> namespace simox { @@ -13,54 +13,6 @@ namespace simox namespace armarx { - class ObjectInfo; - - - /** - * @brief Used to find objects in the ArmarX objects repository [1]. - * - * @see [1] https://gitlab.com/ArmarX/ArmarXObjects - */ - class ObjectFinder : Logging - { - public: - using path = std::filesystem::path; - - public: - - ObjectFinder(const std::string& objectsPackageName = "ArmarXObjects"); - - std::optional<ObjectInfo> findObject(const std::string& dataset, const std::string& name) const; - std::optional<ObjectInfo> findObject(const std::string& nameOrID) const; - - - std::vector<std::string> getDatasets() const; - 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; - - - private: - - void init() const; - - path _rootDirAbs() const; - path _rootDirRel() const; - - private: - - - /// Name of package containing the object models (ArmarXObjects by default). - mutable std::string packageName; - - /// Absolute path to data directory (e.g. "/.../repos/ArmarXObjects/data"). - mutable path packageDataDir; - - }; - - struct PackageFileLocation { /// Name of the ArmarX package. @@ -86,6 +38,9 @@ namespace armarx ObjectInfo(const std::string& packageName, const path& packageDataDir, const std::string& dataset, const std::string& name); + virtual ~ObjectInfo() = default; + + std::string package() const; std::string dataset() const;