From b380e7171169fa761a4cafea372484640869d17f Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@kit.edu> Date: Mon, 26 Apr 2021 11:20:35 +0200 Subject: [PATCH] Allow to view object classes via remote gui --- .../server/ObjectMemory/ObjectMemory.cpp | 3 + .../armem_objects/server/class/Segment.cpp | 156 ++++++++++++++++-- .../armem_objects/server/class/Segment.h | 38 ++++- 3 files changed, 183 insertions(+), 14 deletions(-) diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp index 8df7556a9..ed3937cb2 100644 --- a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp +++ b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp @@ -109,6 +109,9 @@ namespace armarx::armem::server::obj ArVizComponentPluginUser::arviz, debugObserver ); + classSegment.connect( + ArVizComponentPluginUser::arviz + ); createRemoteGuiTab(); RemoteGui_startRunningTask(); diff --git a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp index 1a42f6968..eb460d47f 100644 --- a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp @@ -1,5 +1,6 @@ #include "Segment.h" +#include <RobotAPI/libraries/aron/core/Exception.h> #include <RobotAPI/libraries/aron/common/aron_conversions.h> #include <RobotAPI/libraries/ArmarXObjects/aron_conversions.h> #include <RobotAPI/libraries/armem_objects/aron_conversions.h> @@ -7,6 +8,8 @@ #include <ArmarXCore/core/Component.h> #include <ArmarXCore/core/time/TimeUtil.h> +#include <SimoxUtility/color/Color.h> +#include <SimoxUtility/math/pose/pose.h> #include <SimoxUtility/shapes/AxisAlignedBoundingBox.h> #include <SimoxUtility/shapes/OrientedBox.h> @@ -46,6 +49,11 @@ namespace armarx::armem::server::obj::clazz } } + void Segment::connect(viz::Client arviz) + { + this->arviz = arviz; + } + void Segment::loadByObjectFinder(const std::string& objectsPackage) { @@ -90,6 +98,64 @@ namespace armarx::armem::server::obj::clazz iceMemory.commit(commit); } + void Segment::visualizeClass(const MemoryID& entityID, bool showAABB, bool showOOBB) + { + const Eigen::Matrix4f pose = Eigen::Matrix4f::Identity(); + + viz::Layer layerOrigin = arviz.layer("Origin"); + layerOrigin.add(viz::Pose("Origin")); + + viz::Layer layerObject = arviz.layer("Class Model"); + viz::Layer layerAABB = arviz.layer("Class AABB"); + viz::Layer layerOOBB = arviz.layer("Class OOBB"); + + if (coreSegment) + { + try + { + armem::Entity& entity = coreSegment->getEntity(entityID); + armem::EntityInstance& instance = entity.getLatestSnapshot().getInstance(0); + + arondto::ObjectClass aron; + aron.fromAron(instance.data()); + + if (!aron.simoxXmlPath.package.empty()) + { + layerObject.add(viz::Object(entityID.str()) + .file(aron.simoxXmlPath.package, aron.simoxXmlPath.path) + .pose(pose)); + } + + if (showAABB) + { + layerAABB.add(viz::Box("AABB") + .pose(pose * simox::math::pose(aron.aabb.center)) + .size(aron.aabb.extents) + .color(simox::Color::cyan(255, 64))); + } + if (showOOBB) + { + layerOOBB.add(viz::Box("OOBB") + .pose(pose * simox::math::pose(aron.oobb.center, aron.oobb.orientation)) + .size(aron.oobb.extents) + .color(simox::Color::lime(255, 64))); + } + } + catch (const armem::error::ArMemError& e) + { + ARMARX_INFO << "Failed to visualize object class " << entityID << "." + << "\nReason: " << e.what(); + } + catch (const aron::error::AronException& e) + { + ARMARX_INFO << "Failed to visualize object class " << entityID << "." + << "\nReason: " << e.what(); + } + } + + arviz.commit(layerObject, layerOrigin, layerAABB, layerOOBB); + } + arondto::ObjectClass Segment::objectClassFromInfo(const ObjectInfo& info) { namespace fs = std::filesystem; @@ -129,13 +195,34 @@ namespace armarx::armem::server::obj::clazz } - void Segment::RemoteGui::setup(const Segment& data) + void Segment::RemoteGui::setup(const Segment& segment) + { + using namespace armarx::RemoteGui::Client; + + data.setup(segment); + visu.setup(segment); + + VBoxLayout layout; + layout.addChildren({data.group, visu.group}); + + group = {}; + group.setLabel("Class"); + group.addChildren({layout, VSpacer()}); + } + + void Segment::RemoteGui::update(Segment& segment) + { + data.update(segment); + visu.update(segment); + } + + void Segment::RemoteGui::Data::setup(const Segment& segment) { using namespace armarx::RemoteGui::Client; - maxHistorySize.setValue(std::max(1, int(data.p.maxHistorySize))); + maxHistorySize.setValue(std::max(1, int(segment.p.maxHistorySize))); maxHistorySize.setRange(1, 1e6); - infiniteHistory.setValue(data.p.maxHistorySize == -1); + infiniteHistory.setValue(segment.p.maxHistorySize == -1); GridLayout grid; int row = 0; @@ -145,19 +232,68 @@ namespace armarx::armem::server::obj::clazz row++; group = {}; - group.setLabel("Class"); - group.addChildren({grid, VSpacer()}); + group.setLabel("Data"); + group.addChild(grid); } - void Segment::RemoteGui::update(Segment& data) + void Segment::RemoteGui::Data::update(Segment& segment) { if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged()) { - std::scoped_lock lock(data.memoryMutex); - data.p.maxHistorySize = infiniteHistory.getValue() ? -1 : maxHistorySize.getValue(); - if (data.coreSegment) + std::scoped_lock lock(segment.memoryMutex); + segment.p.maxHistorySize = infiniteHistory.getValue() ? -1 : maxHistorySize.getValue(); + if (segment.coreSegment) + { + segment.coreSegment->setMaxHistorySize(long(segment.p.maxHistorySize)); + } + } + } + + + + void Segment::RemoteGui::Visu::setup(const Segment& segment) + { + using namespace armarx::RemoteGui::Client; + + showComboBox = {}; + showOptionsIndex.clear(); + for (const auto& [_, prov] : *segment.coreSegment) + { + for (const auto& [_, entity] : prov) + { + std::stringstream option; + option << entity.id().entityName << " (" << entity.id().providerSegmentName << ")"; + showComboBox.addOption(option.str()); + showOptionsIndex.push_back(entity.id()); + } + } + if (showOptionsIndex.empty()) + { + showComboBox.addOption("<none>"); + } + showButton.setLabel("Visualize Object Class"); + + GridLayout grid; + int row = 0; + grid.add(showComboBox, {row, 0}, {1, 2}); + row++; + grid.add(showButton, {row, 0}, {1, 2}); + row++; + + group = {}; + group.setLabel("Visualization"); + group.addChild(grid); + } + + void Segment::RemoteGui::Visu::update(Segment& segment) + { + if (showButton.wasClicked()) + { + const size_t index = static_cast<size_t>(showComboBox.getIndex()); + if (/*index >= 0 &&*/ index < showOptionsIndex.size()) { - data.coreSegment->setMaxHistorySize(long(data.p.maxHistorySize)); + std::scoped_lock lock(segment.memoryMutex); + segment.visualizeClass(showOptionsIndex.at(index)); } } } diff --git a/source/RobotAPI/libraries/armem_objects/server/class/Segment.h b/source/RobotAPI/libraries/armem_objects/server/class/Segment.h index 6ba5409cd..97c0af8d6 100644 --- a/source/RobotAPI/libraries/armem_objects/server/class/Segment.h +++ b/source/RobotAPI/libraries/armem_objects/server/class/Segment.h @@ -8,6 +8,7 @@ #include <ArmarXGui/libraries/RemoteGui/Client/Widgets.h> +#include <RobotAPI/components/ArViz/Client/Client.h> #include <RobotAPI/libraries/ArmarXObjects/ObjectID.h> #include <RobotAPI/libraries/ArmarXObjects/ObjectFinder.h> @@ -29,11 +30,15 @@ namespace armarx::armem::server::obj::clazz void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = ""); void init(); + void connect(viz::Client arviz); void loadByObjectFinder(const std::string& objectsPackage); void loadByObjectFinder(const ObjectFinder& finder); void loadByObjectFinder(); + void visualizeClass(const MemoryID& entityID, bool showAABB = true, bool showOOBB = true); + + static arondto::ObjectClass objectClassFromInfo(const ObjectInfo& info); @@ -45,6 +50,8 @@ namespace armarx::armem::server::obj::clazz ObjectFinder objectFinder; + viz::Client arviz; + struct Properties { @@ -63,11 +70,34 @@ namespace armarx::armem::server::obj::clazz { armarx::RemoteGui::Client::GroupBox group; - armarx::RemoteGui::Client::IntSpinBox maxHistorySize; - armarx::RemoteGui::Client::CheckBox infiniteHistory; + struct Data + { + armarx::RemoteGui::Client::GroupBox group; + + armarx::RemoteGui::Client::IntSpinBox maxHistorySize; + armarx::RemoteGui::Client::CheckBox infiniteHistory; + + void setup(const Segment& segment); + void update(Segment& segment); + }; + Data data; + + struct Visu + { + armarx::RemoteGui::Client::GroupBox group; + + std::vector<MemoryID> showOptionsIndex; + armarx::RemoteGui::Client::ComboBox showComboBox; + armarx::RemoteGui::Client::Button showButton; + + void setup(const Segment& segment); + void update(Segment& segment); + }; + Visu visu; + + void setup(const Segment& segment); + void update(Segment& segment); - void setup(const Segment& data); - void update(Segment& data); }; }; -- GitLab