/* * This file is part of ArmarX. * * ArmarX is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * ArmarX is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * @author Fabian Reister ( fabian dot reister at kit dot edu ) * @date 2024 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt * GNU General Public License */ #include "FamiliarObjectDetectionExample.h" #include <Eigen/Geometry> #include <pcl/point_types.h> #include <opencv2/core/mat.hpp> #include <IceUtil/Time.h> #include <SimoxUtility/math/pose/pose.h> #include <VirtualRobot/Robot.h> #include <VirtualRobot/VirtualRobot.h> #include <VirtualRobot/XML/RobotIO.h> #include "ArmarXCore/core/time/Clock.h" #include <ArmarXCore/core/PackagePath.h> #include <ArmarXCore/core/exceptions/local/ExpressionException.h> #include <ArmarXCore/core/logging/Logging.h> #include <ArmarXCore/core/services/tasks/PeriodicTask.h> #include <ArmarXCore/core/time/CycleUtil.h> #include "RobotAPI/libraries/ArmarXObjects/ObjectID.h" #include <RobotAPI/libraries/armem/core/Time.h> #include <RobotAPI/libraries/armem_objects/aron/FamiliarObjectInstance.aron.generated.h> #include <RobotAPI/libraries/armem_objects/types.h> // #include <RobotAPI/libraries/armem_objects/aron_conversions.h> // #include <RobotAPI/libraries/armem/core/aron_conversions.h> #include <RobotAPI/libraries/ArmarXObjects/aron_conversions.h> namespace armarx::familiar_objects { FamiliarObjectDetectionExample::FamiliarObjectDetectionExample() { addPlugin(familiarObjectInstanceReaderPlugin); p.exemplaryFamiliarObjectID.dataset = "myDataset"; p.exemplaryFamiliarObjectID.className = "sphere"; p.exemplaryFamiliarObjectID.instanceName = "0"; } armarx::PropertyDefinitionsPtr FamiliarObjectDetectionExample::createPropertyDefinitions() { armarx::PropertyDefinitionsPtr defs = new ComponentPropertyDefinitions(getConfigIdentifier()); defs->required(p.robotName, "p.robotName"); defs->optional(p.exemplaryFamiliarObjectID.dataset, "p.objectId.dataset"); defs->optional(p.exemplaryFamiliarObjectID.className, "p.objectId.className"); defs->optional(p.exemplaryFamiliarObjectID.instanceName, "p.objectId.instanceName"); defs->component(familiarObjectPoseStoragePrx, "ObjectMemory"); return defs; } std::string FamiliarObjectDetectionExample::getDefaultName() const { return "FamiliarObjectDetectionExample"; } void FamiliarObjectDetectionExample::onInitComponent() { } void FamiliarObjectDetectionExample::onConnectComponent() { // // First, we create a familiar object and send it to the memory. // ARMARX_IMPORTANT << "Storing exemplary familiar object in memory"; storeExemplaryFamiliarObjectInMemory(); // // Then, we read the familiar object from the memory. // ARMARX_IMPORTANT << "Reading familiar object from memory"; readExemplaryFamiliarObjectFromMemory(); } void FamiliarObjectDetectionExample::storeExemplaryFamiliarObjectInMemory() const { ::armarx::objpose::ProvidedFamiliarObjectPoseSeq data; armem::arondto::FamiliarObjectInstance familiarObject; familiarObject.timestamp = armarx::Clock::Now(); familiarObject.poseSensFrame.pose = Eigen::Isometry3f{Eigen::Translation3f{0, 0, 1000}}.matrix(); familiarObject.poseSensFrame.header.frame = "DepthCameraSim"; familiarObject.poseSensFrame.header.agent = p.robotName; // familiarObject.poseSensFrame.header.frame = "AzureKinect_RGB"; familiarObject.objectID = p.exemplaryFamiliarObjectID; familiarObject.confidence = 1.0; // familiarObject.bounding_box = // familiarObject.depth_image_patch = cv::Mat1f(cv::Size(20, 20)); // familiarObject.rgb_image_patch = cv::Mat3b(cv::Size(20, 20)); const int numPoints = 100; // x in red for (int i = 0; i < numPoints; i++) { pcl::PointXYZRGBA point; point.x = static_cast<float>(i) - numPoints / 2; point.y = 0; point.z = 0; point.r = 255; point.g = 0; point.b = 0; familiarObject.points.points.push_back(point); } // y in green for (int i = 0; i < numPoints; i++) { pcl::PointXYZRGBA point; point.x = 0; point.y = static_cast<float>(i) - numPoints / 2; point.z = 0; point.r = 0; point.g = 255; point.b = 0; familiarObject.points.points.push_back(point); } // z in blue for (int i = 0; i < numPoints; i++) { pcl::PointXYZRGBA point; point.y = 0; point.y = 0; point.z = static_cast<float>(i) - numPoints / 2; point.r = 0; point.g = 0; point.b = 255; familiarObject.points.points.push_back(point); } familiarObject.points.header.frame_id = "DepthCameraSim"; familiarObject.points.is_dense = true; familiarObject.points.width = familiarObject.points.points.size(); familiarObject.points.height = 1; familiarObject.bounding_box.center.setZero(); familiarObject.bounding_box.extents.setConstant(numPoints); data.push_back(familiarObject.toAronDTO()); ARMARX_INFO << "Sending " << data.size() << " familiar object to the memory"; familiarObjectPoseStoragePrx->reportFamiliarObjectPoses(getName(), data); } void FamiliarObjectDetectionExample::readExemplaryFamiliarObjectFromMemory() const { ARMARX_CHECK_NOT_NULL(familiarObjectInstanceReaderPlugin); const armem::obj::familiar_object_instance::Reader& familiarObjectInstanceReader = familiarObjectInstanceReaderPlugin->get(); // // 1. Read from all providers // ARMARX_IMPORTANT << "Reading from all providers"; { const auto allFamiliarObjectInstances = familiarObjectInstanceReader.queryAllLatestFamiliarObjectInstances(); // print for (const auto& [providerName, instances] : allFamiliarObjectInstances) { ARMARX_INFO << "Provider name: " << providerName; for (const auto& instance : instances) { ARMARX_INFO << "- Instance: " << instance.objectID.dataset << "/" << instance.objectID.className << "/" << instance.objectID.instanceName; } } } // // 2. Read from a specific provider // ARMARX_IMPORTANT << "Reading from a specific provider"; { const std::map<std::string, std::vector<armem::arondto::FamiliarObjectInstance>> familiarObjectInstances = familiarObjectInstanceReader.queryAllLatestFamiliarObjectInstances(getName()); ARMARX_INFO << "Provider name: " << getName(); ARMARX_CHECK_EQUAL(familiarObjectInstances.size(), 1); ARMARX_CHECK_EQUAL(familiarObjectInstances.begin()->first, getName()); const auto& thisFamiliarObjectInstances = familiarObjectInstances.begin()->second; // print for (const auto& instance : thisFamiliarObjectInstances) { ARMARX_INFO << "- Instance: " << instance.objectID.dataset << "/" << instance.objectID.className << "/" << instance.objectID.instanceName; } } // // 3. Read all instances of a specific class // ARMARX_IMPORTANT << "Reading all instances of a specific class"; { armarx::ObjectID objectId; fromAron(p.exemplaryFamiliarObjectID, objectId); const auto instances = familiarObjectInstanceReader.queryLatestFamiliarObjectInstancesFromClass( objectId.getClassID()); for (const auto& [instanceName, instancesForProvider] : instances) { for (const auto& instance : instancesForProvider) { ARMARX_INFO << "- Instance: " << instance.objectID.dataset << "/" << instance.objectID.className << "/" << instance.objectID.instanceName; } } } // // 4. Read a specific instance // ARMARX_IMPORTANT << "Reading a specific instance"; { armarx::ObjectID objectId; fromAron(p.exemplaryFamiliarObjectID, objectId); const std::optional<std::map<std::string, armem::arondto::FamiliarObjectInstance>> instances = familiarObjectInstanceReader.queryLatestFamiliarObjectInstance(objectId); ARMARX_CHECK(instances.has_value()); for (const auto& [instanceName, instance] : instances.value()) { ARMARX_INFO << "- Instance: " << instance.objectID.dataset << "/" << instance.objectID.className << "/" << instance.objectID.instanceName; } } } void FamiliarObjectDetectionExample::onDisconnectComponent() { // task->stop(); } void FamiliarObjectDetectionExample::onExitComponent() { } } // namespace armarx::familiar_objects