diff --git a/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.cpp b/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.cpp index 144f9edcd76acbbe536084229dfe440804add7e2..accfc00fec22ef5b1f1d454b4476d3306b198747 100644 --- a/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.cpp +++ b/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.cpp @@ -9,8 +9,11 @@ #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h> #include <RobotAPI/libraries/GraspingUtility/aron/GraspCandidate.aron.generated.h> +#include <RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.h> +#include <RobotAPI/libraries/GraspingUtility/aron_conversions.h> #include <RobotAPI/libraries/armem_grasping/aron/KnownGraspCandidate.aron.generated.h> + namespace armarx::armem::server::grasp { armarx::PropertyDefinitionsPtr GraspMemory::createPropertyDefinitions() @@ -73,7 +76,7 @@ namespace armarx::armem::server::grasp { // This function is overloaded to trigger the remote gui rebuild. armem::data::CommitResult result = ReadWritePluginUser::commit(commit); - tab.rebuild = true; + gui.tab.rebuild = true; return result; } @@ -88,24 +91,422 @@ namespace armarx::armem::server::grasp void GraspMemory::createRemoteGuiTab() { - using namespace armarx::RemoteGui::Client; + //add all instances to map + workingMemory().getCoreSegment("GraspCandidate").forEachInstance([this](const auto & instance) + { + if (gui.candidatesToDraw.find(instance.id().str()) == gui.candidatesToDraw.end()){ + gui.candidatesToDraw[instance.id().str()] = false; + } + }); -// { -// -// tab.memoryGroup = armem::server::MemoryRemoteGui().makeGroupBox(workingMemory()); -// } -// -// VBoxLayout root = {tab.memoryGroup, VSpacer()}; -// RemoteGui_createTab(getName(), root, &tab); + using namespace armarx::RemoteGui::Client; + GridLayout root; + { + gui.tab.selectAll.setLabel("Select All"); + gui.tab.deselectAll.setLabel("Deselect All"); + int row = 0; + + // bimanual candidates are not available for visualization for now +// { +// root.add(Label("CoreSegment"), Pos{row, 0}); +// row++; +// std::vector<std::string> options = workingMemory().getCoreSegmentNames(); +// if (options.empty()) +// { +// options.push_back("<None>"); +// } +// gui.tab.selectCoreSegment.setOptions(options); +// if (gui.coreSegIndex >= 0 && gui.coreSegIndex < static_cast<int>(options.size())) +// { +// gui.tab.selectCoreSegment.setIndex(gui.coreSegIndex); +// gui.coreSegment = options[gui.coreSegIndex]; +// } +// root.add(gui.tab.selectCoreSegment, Pos{row,0}); +// row++; +// } + if(workingMemory().hasCoreSegment(gui.coreSegment)) + { + { + root.add(Label("Provider"), Pos{row, 0}); + row++; + std::vector<std::string> options = workingMemory().getCoreSegment(gui.coreSegment).getProviderSegmentNames(); + if (options.empty()) + { + options.push_back("<None>"); + } + else + { + options.insert(options.begin(), "<All>"); + } + + gui.tab.selectProvider.setOptions(options); + + if (gui.providerIndex >= 0 && gui.providerIndex < static_cast<int>(options.size())) + { + gui.tab.selectProvider.setIndex(gui.providerIndex); + gui.provider = options[gui.providerIndex]; + } + root.add(gui.tab.selectProvider, Pos{row, 0}); + row++; + } + + if(gui.provider == "<All>" + || workingMemory().getCoreSegment(gui.coreSegment).hasProviderSegment(gui.provider)) + { + std::vector<MemoryID> providers; + { + root.add(Label("Entity"), Pos{row,0}); + row++; + std::vector<std::string> options; + + if (gui.provider == "<All>") + { + workingMemory().getCoreSegment(gui.coreSegment).forEachProviderSegment([&providers](const auto & provider) + { + providers.push_back(provider.id()); + }); + } + else + { + providers.push_back(MemoryID(memoryName, gui.coreSegment, gui.provider)); + + } + for (MemoryID & provider : providers) + { + for(std::string & entity : workingMemory().getProviderSegment(provider).getEntityNames()) + { + options.push_back(entity); + } + } + if (options.empty()) + { + options.push_back("<None>"); + } + else + { + options.insert(options.begin(), "<All>"); + } + gui.tab.selectEntity.setOptions(options); + if (gui.entityIndex >= 0 && gui.entityIndex < static_cast<int>(options.size())) + { + gui.tab.selectEntity.setIndex(gui.entityIndex); + gui.entity = options[gui.entityIndex]; + } + root.add(gui.tab.selectEntity, Pos{row, 0}); + row++; + } + + if( gui.entity == "<All>" + || (gui.provider == "<All>" && workingMemory().getCoreSegment(gui.coreSegment).hasEntity(gui.entity)) + || workingMemory().getCoreSegment(gui.coreSegment).getProviderSegment(gui.provider).hasEntity(gui.entity)) + { + std::vector<MemoryID> entities; + { + root.add(Label("Snapshot"), Pos{row, 0}); + row++; + std::vector<std::string> options; + for (MemoryID & provider : providers) + { + if (gui.entity == "<All>") + { + workingMemory().getProviderSegment(provider).forEachEntity([&entities](auto & entity) + { + entities.push_back(entity.id()); + }); + } + else + { + if (workingMemory().getProviderSegment(provider).hasEntity(gui.entity)) + { + entities.push_back(MemoryID(memoryName, gui.coreSegment, provider.providerSegmentName, gui.entity)); + } + } + } + + for (MemoryID & entity : entities) + { + workingMemory().getEntity(entity).forEachSnapshot([this, &options](const auto & snapshot) + { + std::string time = armem::toDateTimeMilliSeconds(snapshot.time()); + gui.timeMap[time] = snapshot.time(); + options.push_back(time); + }); + } + + if (options.empty()) + { + options.push_back("<None>"); + } + else + { + options.insert(options.begin(), "<All>"); + } + gui.tab.selectSnapshot.setOptions(options); + if (gui.snapshotIndex >= 0 && gui.snapshotIndex < static_cast<int>(options.size())) + { + gui.tab.selectSnapshot.setIndex(gui.snapshotIndex); + if(options[gui.snapshotIndex] != "<None>") + { + gui.snapshot = options[gui.snapshotIndex]; + } + } + root.add(gui.tab.selectSnapshot, Pos{row, 0}); + row++; + + + } + bool comboExists; + if (gui.snapshot == "<All>") + { + comboExists = true; + } + else + { + for (MemoryID & entity : entities) + { + if (workingMemory().getEntity(entity).hasSnapshot(gui.timeMap.at(gui.snapshot))) + { + comboExists = true; + } + } + } + if(comboExists) + { + root.add(Label("Instances"), Pos{row,0}); + row++; + root.add(gui.tab.selectAll, Pos{row, 0}); + row++; + root.add(gui.tab.deselectAll, Pos{row, 0}); + row++; + gui.tab.checkInstances.clear(); + std::vector<MemoryID> snapshots; + for (MemoryID & entity : entities) + { + if(gui.snapshot == "<All>") + { + workingMemory().getEntity(entity).forEachSnapshot([&snapshots](auto & snapshot) + { + snapshots.push_back(snapshot.id()); + }); + } + else + { + if (workingMemory().getEntity(entity).hasSnapshot(gui.timeMap.at(gui.snapshot))) + { + snapshots.push_back(workingMemory().getEntity(entity).getSnapshot(gui.timeMap.at(gui.snapshot)).id()); + } + } + } + + for (MemoryID & snapshot : snapshots) + { + workingMemory().getSnapshot(snapshot).forEachInstance([this, &row, &root](const auto & instance) + { + root.add(Label(instance.id().str()) , Pos{row, 0}); + gui.tab.checkInstances[instance.id().str()] = CheckBox(); + if(gui.candidatesToDraw.at(instance.id().str())) + { + gui.tab.checkInstances.at(instance.id().str()).setValue(true); + } + root.add(gui.tab.checkInstances[instance.id().str()], Pos{row, 1}); + row++; + }); + } + } + else + { + root.add(Label("Instances"), Pos{row,0}); + row++; + root.add(gui.tab.selectAll, Pos{row, 0}); + row++; + root.add(gui.tab.deselectAll, Pos{row, 0}); + row++; + gui.tab.checkInstances.clear(); + } + } + else + { + gui.tab.checkInstances.clear(); + + std::vector<std::string> options = {"<None>"}; + + gui.tab.selectSnapshot.setOptions(options); + + root.add(Label("Snapshot"), Pos{row, 0}); + row++; + root.add(gui.tab.selectSnapshot, Pos{row, 0}); + row++; + root.add(gui.tab.selectAll, Pos{row, 0}); + row++; + root.add(gui.tab.deselectAll, Pos{row, 0}); + row++; + } + } + else + { + gui.tab.checkInstances.clear(); + + std::vector<std::string> options = {"<None>"}; + + gui.tab.selectEntity.setOptions(options); + + root.add(Label("Entity"), Pos{row,0}); + row++; + root.add(gui.tab.selectEntity, Pos{row, 0}); + row++; + + gui.tab.selectSnapshot.setOptions(options); + + root.add(Label("Snapshot"), Pos{row, 0}); + row++; + root.add(gui.tab.selectSnapshot, Pos{row, 0}); + row++; + root.add(gui.tab.selectAll, Pos{row, 0}); + row++; + root.add(gui.tab.deselectAll, Pos{row, 0}); + row++; + } + } + else { + gui.tab.checkInstances.clear(); + + std::vector<std::string> options = {"<None>"}; + gui.tab.selectProvider.setOptions(options); + + root.add(Label("Provider"), Pos{row, 0}); + row++; + root.add(gui.tab.selectProvider, Pos{row, 0}); + row++; + + gui.tab.selectEntity.setOptions(options); + + root.add(Label("Entity"), Pos{row,0}); + row++; + root.add(gui.tab.selectEntity, Pos{row, 0}); + row++; + + gui.tab.selectSnapshot.setOptions(options); + + root.add(Label("Snapshot"), Pos{row, 0}); + row++; + root.add(gui.tab.selectSnapshot, Pos{row, 0}); + row++; + root.add(gui.tab.selectAll, Pos{row, 0}); + row++; + root.add(gui.tab.deselectAll, Pos{row, 0}); + row++; + + } + } + + + RemoteGui_createTab(getName(), root, &gui.tab); + gui.tab.rebuild = false; } void GraspMemory::RemoteGui_update() { -// if (tab.rebuild.exchange(false)) + armarx::grasping::GraspCandidateVisu visu; + +// if (gui.tab.selectCoreSegment.hasValueChanged()) // { -//// createRemoteGuiTab(); +// gui.coreSegment = gui.tab.selectCoreSegment.getValue(); +// gui.coreSegIndex = gui.tab.selectCoreSegment.getIndex(); +// gui.providerIndex = 0; +// gui.entityIndex = 0; +// gui.snapshotIndex = 0; +// gui.tab.rebuild = true; // } + + if (gui.tab.selectProvider.hasValueChanged()) + { + gui.provider = gui.tab.selectProvider.getValue(); + gui.providerIndex = gui.tab.selectProvider.getIndex(); + gui.entityIndex = 0; + gui.snapshotIndex = 0; + gui.tab.rebuild = true; + } + + if (gui.tab.selectEntity.hasValueChanged()) + { + gui.entity = gui.tab.selectEntity.getValue(); + gui.entityIndex = gui.tab.selectEntity.getIndex(); + gui.snapshotIndex = 0; + gui.tab.rebuild = true; + } + + if (gui.tab.selectSnapshot.hasValueChanged()) + { + gui.snapshot = gui.tab.selectSnapshot.getValue(); + gui.snapshotIndex = gui.tab.selectSnapshot.getIndex(); + gui.tab.rebuild = true; + } + + + if(gui.tab.selectAll.wasClicked()) + { + for(auto & element : gui.tab.checkInstances) + { + element.second.setValue(true); + } + } + + if(gui.tab.deselectAll.wasClicked()) + { + for(auto & element : gui.tab.checkInstances) + { + element.second.setValue(false); + } + } + + for(auto & element : gui.tab.checkInstances) + { + gui.candidatesToDraw.at(element.first) = element.second.getValue(); + } + + std::map<std::string, viz::Layer> reachableLayers; + std::map<std::string, viz::Layer> unreachableLayers; + + for(auto & element : gui.candidatesToDraw ) + { + std::string entityName = armem::MemoryID::fromString(element.first).entityName; + + if (reachableLayers.find(entityName) == reachableLayers.end()) + { + reachableLayers[entityName] = arviz.layer(entityName + "_reachable"); + unreachableLayers[entityName] = arviz.layer(entityName + "_unreachable"); + } + + //draw candidates + if (element.second) + { + armarx::grasping::GraspCandidate candidate; + + armarx::grasping::arondto::GraspCandidate aronTransform; + + armem::wm::EntityInstance instance = workingMemory().getInstance(armem::MemoryID::fromString(element.first)); + + aronTransform.fromAron(workingMemory().getInstance(armem::MemoryID::fromString(element.first)).data()); + + fromAron(aronTransform, candidate); + + visu.visualize(element.first, candidate, reachableLayers.at(entityName), unreachableLayers.at(entityName)); + } + } + + std::vector<viz::Layer> layers; + for(auto & [entityName, layer] : reachableLayers) + { + layers.push_back(layer); + layers.push_back(unreachableLayers.at(entityName)); + } + arviz.commit(layers); + + if (gui.tab.rebuild) + { + createRemoteGuiTab(); + } } } diff --git a/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.h b/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.h index ea7dceaddd3af6671ac35b151e3bc803222d65ca..867bf0a62575f2affd51e1842d6631ceb0204e8e 100644 --- a/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.h +++ b/source/RobotAPI/components/armem/server/GraspMemory/GraspMemory.h @@ -70,9 +70,34 @@ namespace armarx::armem::server::grasp { std::atomic_bool rebuild = false; - RemoteGui::Client::GroupBox memoryGroup; + // RemoteGui::Client::ComboBox selectCoreSegment; + RemoteGui::Client::ComboBox selectProvider; + RemoteGui::Client::ComboBox selectEntity; + RemoteGui::Client::ComboBox selectSnapshot; + RemoteGui::Client::Button selectAll; + RemoteGui::Client::Button deselectAll; + std::map<std::string, RemoteGui::Client::CheckBox> checkInstances; }; - RemoteGuiTab tab; + + + struct GuiInfo + { + // int coreSegIndex = 0; + int providerIndex = 0; + int entityIndex = 0; + int snapshotIndex = 0; + + RemoteGuiTab tab; + + std::string coreSegment = "GraspCandidate"; + std::string provider = ""; + std::string entity = ""; + std::string snapshot = ""; + + std::map<std::string, bool> candidatesToDraw; + std::map<std::string, Time> timeMap; + }; + GuiInfo gui; }; } diff --git a/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice b/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice index 702e9667ab047b4144008175e9bd4a02020d34f6..6ae5638174ec0293a4a3ab73fea68e869a397cf9 100644 --- a/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice +++ b/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice @@ -144,7 +144,6 @@ module armarx StringVariantBaseMap currentConfig; }; - dictionary<string, ProviderInfo> InfoMap; diff --git a/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.cpp b/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.cpp index a534e7df3a8aec94c251a0dc7600d87c8ef76b44..11e583902b8fbb0963e8f4c1b00746de01356f1b 100644 --- a/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.cpp +++ b/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.cpp @@ -347,6 +347,31 @@ namespace armarx } return nullptr; } + + objpose::data::ObjectPose* objpose::findObjectPoseByID(data::ObjectPoseSeq& objectPoses, const armarx::data::ObjectID& id) + { + for (objpose::data::ObjectPose& pose : objectPoses) + { + if (pose.objectID == id) + { + return &pose; + } + } + return nullptr; + } + + const objpose::data::ObjectPose* objpose::findObjectPoseByID(const data::ObjectPoseSeq& objectPoses, const armarx::data::ObjectID& id) + { + for (const objpose::data::ObjectPose& pose : objectPoses) + { + if (pose.objectID == id) + { + return &pose; + } + } + return nullptr; + } + } diff --git a/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.h b/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.h index 74b1b3e6dd6632ca7c11dcc060f5934a24725262..66c87f22f5f369c154043e83a72146f0d5bbea54 100644 --- a/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.h +++ b/source/RobotAPI/libraries/ArmarXObjects/ObjectPose.h @@ -150,5 +150,7 @@ namespace armarx::objpose ObjectPose* findObjectPoseByID(ObjectPoseSeq& objectPoses, const ObjectID& id); const ObjectPose* findObjectPoseByID(const ObjectPoseSeq& objectPoses, const ObjectID& id); + data::ObjectPose* findObjectPoseByID(data::ObjectPoseSeq& objectPoses, const armarx::data::ObjectID& id); + const data::ObjectPose* findObjectPoseByID(const data::ObjectPoseSeq& objectPoses, const armarx::data::ObjectID& id); } diff --git a/source/RobotAPI/libraries/GraspingUtility/CMakeLists.txt b/source/RobotAPI/libraries/GraspingUtility/CMakeLists.txt index 7ec81af63d843443f25008f486a87880aeb05c65..1ae8862c277d13836d015473953c605db92c9349 100644 --- a/source/RobotAPI/libraries/GraspingUtility/CMakeLists.txt +++ b/source/RobotAPI/libraries/GraspingUtility/CMakeLists.txt @@ -10,6 +10,7 @@ armarx_add_library( RobotAPI::ArmarXObjects RobotAPI::ArViz RobotAPI::armem_objects + SOURCES box_to_grasp_candidates.cpp grasp_candidate_drawer.cpp GraspCandidateHelper.cpp @@ -17,14 +18,18 @@ armarx_add_library( aron_conversions.cpp GraspCandidateWriter.cpp GraspCandidateReader.cpp + GraspCandidateVisu.cpp + HEADERS box_to_grasp_candidates.h box_to_grasp_candidates.ipp grasp_candidate_drawer.h GraspCandidateHelper.h BimanualGraspCandidateHelper.h + aron_conversions.h GraspCandidateWriter.h GraspCandidateReader.h + GraspCandidateVisu.h ) armarx_enable_aron_file_generation_for_target( TARGET_NAME diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp index 4e742c96f69db5d5abeabe58f7cbc69684e740bb..8f875542bce9f7a5ed3fe91bc697eb3cd76e1edf 100644 --- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp +++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp @@ -14,14 +14,16 @@ namespace armarx::armem { } - void GraspCandidateReader::connect() + + void GraspCandidateReader::connect(bool use) { // Wait for the memory to become available and add it as dependency. ARMARX_IMPORTANT << "GraspCandidateReader: Waiting for memory '" << properties.memoryName << "' ..."; try { - memoryReader = memoryNameSystem.useReader(properties.memoryName); + memoryReader = use ? memoryNameSystem.useReader(properties.memoryName) + : memoryNameSystem.getReader(MemoryID(properties.memoryName)); ARMARX_IMPORTANT << "GraspCandidateReader: Connected to memory '" << properties.memoryName; } @@ -30,13 +32,9 @@ namespace armarx::armem ARMARX_ERROR << e.what(); return; } - - } - - armarx::grasping::GraspCandidate asGraspCandidate(const armem::wm::EntityInstance& instance) { armarx::grasping::GraspCandidate candidate; @@ -64,12 +62,26 @@ namespace armarx::armem grasping::GraspCandidatePtr GraspCandidateReader::queryGraspCandidateInstanceByID(const armem::MemoryID& id) const + { + auto dict = queryGraspCandidateInstancesByID({id}); + if (auto it = dict.find(id.str()); it != dict.end()) + { + return it->second; + } + else + { + return nullptr; + } + } + + + grasping::GraspCandidateDict GraspCandidateReader::queryGraspCandidateInstancesByID(const std::vector<MemoryID>& ids) const { armem::client::query::Builder qb; ARMARX_DEBUG << "Query for memory name: " << properties.memoryName; - qb.singleEntitySnapshot(id.getEntitySnapshotID()); + qb.multipleEntitySnapshots(ids); const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput()); @@ -80,24 +92,19 @@ namespace armarx::armem throw armem::error::QueryFailed(properties.memoryName, qResult.errorMessage); } - - armarx::grasping::GraspCandidatePtr candidate; - - armem::wm::FunctionalVisitor visitor; - visitor.instanceConstFn = [id, &candidate](armem::wm::EntityInstance const & instance) + armarx::grasping::GraspCandidateDict candidates; + for (const MemoryID& id : ids) { - if (instance.id() == id) + if (const armem::wm::EntityInstance* instance = qResult.memory.findInstance(id)) { - candidate = new grasping::GraspCandidate(asGraspCandidate(instance)); + candidates[id.str()] = new grasping::GraspCandidate(asGraspCandidate(*instance)); } - return true; - }; - - visitor.applyTo(qResult.memory); + } - return candidate; + return candidates; } + grasping::BimanualGraspCandidatePtr GraspCandidateReader::queryBimanualGraspCandidateInstanceByID( const armem::MemoryID& id) const { @@ -134,7 +141,7 @@ namespace armarx::armem return candidate; } - std::map<std::string, grasping::GraspCandidatePtr> GraspCandidateReader::queryLatestGraspCandidateEntity( + grasping::GraspCandidateDict GraspCandidateReader::queryLatestGraspCandidateEntity( const std::string& provider, const std::string& entity) const { armem::client::query::Builder qb; @@ -172,7 +179,7 @@ namespace armarx::armem return getBimanualGraspCandidatesFromResultSet(qResult); } - std::map<std::string, grasping::GraspCandidatePtr> GraspCandidateReader::queryLatestGraspCandidates( + grasping::GraspCandidateDict GraspCandidateReader::queryLatestGraspCandidates( const std::string& provider) const { @@ -249,7 +256,7 @@ namespace armarx::armem def->optional(properties.memoryName, prefix + "MemoryName"); } - std::map<std::string, grasping::GraspCandidatePtr> GraspCandidateReader::getGraspCandidatesFromResultSet( + grasping::GraspCandidateDict GraspCandidateReader::getGraspCandidatesFromResultSet( const armem::client::QueryResult& qResult) const { if (!qResult.success) diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h index 0a1604afdb9ca58c93ce52628cee61e7ee647dcc..5de5c25e335e5544170f18f838df2e5e23d213fa 100644 --- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h +++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h @@ -1,9 +1,12 @@ #pragma once +#include <vector> + #include <RobotAPI/libraries/armem/client/Reader.h> #include <RobotAPI/libraries/armem/client.h> #include <RobotAPI/interface/units/GraspCandidateProviderInterface.h> + namespace armarx::armem { @@ -12,19 +15,20 @@ namespace armarx::armem public: GraspCandidateReader(armem::client::MemoryNameSystem& memoryNameSystem); - void connect(); + void connect(bool use = true); grasping::GraspCandidatePtr queryGraspCandidateInstanceByID(armem::MemoryID const& id) const; + grasping::GraspCandidateDict queryGraspCandidateInstancesByID(std::vector<armem::MemoryID> const& ids) const; grasping::BimanualGraspCandidatePtr queryBimanualGraspCandidateInstanceByID(armem::MemoryID const& id) const; - std::map<std::string, grasping::GraspCandidatePtr> queryLatestGraspCandidateEntity( + grasping::GraspCandidateDict queryLatestGraspCandidateEntity( std::string const& provider, std::string const& entity) const; std::map<std::string, grasping::BimanualGraspCandidatePtr> queryLatestBimanualGraspCandidateEntity( std::string const& provider, std::string const& entity) const; - std::map<std::string, grasping::GraspCandidatePtr> queryLatestGraspCandidates( + grasping::GraspCandidateDict queryLatestGraspCandidates( std::string const& provider = "") const; std::map<std::string, grasping::BimanualGraspCandidatePtr> queryLatestBimanualGraspCandidates( @@ -37,7 +41,7 @@ namespace armarx::armem private: - std::map<std::string, grasping::GraspCandidatePtr> getGraspCandidatesFromResultSet( + grasping::GraspCandidateDict getGraspCandidatesFromResultSet( armem::client::QueryResult const& qResult) const; std::map<std::string, grasping::BimanualGraspCandidatePtr> getBimanualGraspCandidatesFromResultSet( diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.cpp b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1c5e3bc4781d504f8f467ce2b8584d5358b09a06 --- /dev/null +++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.cpp @@ -0,0 +1,89 @@ +#include "GraspCandidateVisu.h" + +#include <RobotAPI/libraries/core/Pose.h> +#include <RobotAPI/components/ArViz/Client/elements/RobotHand.h> + + +namespace armarx::grasping +{ + GraspCandidateVisu::GraspCandidateVisu() + { + } + + + void GraspCandidateVisu::visualize( + const grasping::GraspCandidateDict& candidates, + viz::Client& arviz) + { + viz::Layer graspsLayer = arviz.layer("Grasps"); + viz::Layer graspsNonReachableLayer = arviz.layer("Grasps Non-Reachable"); + + visualize(candidates, graspsLayer, graspsNonReachableLayer); + arviz.commit({graspsLayer, graspsNonReachableLayer}); + } + + + void GraspCandidateVisu::visualize(const std::string &id, const GraspCandidate &candidate, + viz::Layer& layerReachable, + viz::Layer& layerNonReachable) + { + int alpha = alpha_default; + if (auto it = alphasByKey.find(id); it != alphasByKey.end()) + { + alpha = it->second; + } + + viz::Robot hand = visualize("Grasp_" + id, candidate, alpha); + + if (candidate.reachabilityInfo->reachable) + { + layerReachable.add(hand); + } + else + { + layerNonReachable.add(hand); + } + } + + void GraspCandidateVisu::visualize(const grasping::GraspCandidateDict& candidates, + viz::Layer& layerReachable, + viz::Layer& layerNonReachable) + { + for (auto& [id, candidate] : candidates) + { + visualize(id, *candidate, layerReachable, layerNonReachable); + } + } + + + viz::Robot GraspCandidateVisu::visualize( + const std::string& name, + const GraspCandidate& candidate) + { + return visualize(name, candidate, alpha_default); + } + + + viz::Robot + GraspCandidateVisu::visualize( + const std::string& name, + const grasping::GraspCandidate& candidate, + int alpha) + { + bool isReachable = candidate.reachabilityInfo->reachable; + viz::Color color = isReachable ? viz::Color::green() : viz::Color::red(); + color.a = alpha; + + Eigen::Matrix4f tcp2handRoot = fromIce(candidate.tcpPoseInHandRoot).inverse(); + Eigen::Matrix4f graspPose = PosePtr::dynamicCast(candidate.graspPose)->toEigen(); + std::string modelFile = "rt/robotmodel/Armar6-SH/Armar6-" + candidate.side + "Hand-v3.xml"; + + viz::Robot hand = viz::RobotHand(name) + .file("Armar6RT", modelFile) + .pose(fromIce(candidate.robotPose) * graspPose * tcp2handRoot) + .overrideColor(color); + + return hand; + } +} + diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.h b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.h new file mode 100644 index 0000000000000000000000000000000000000000..8eb298e4183d0daef8d004d4d3fc3cacc8cd30e7 --- /dev/null +++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateVisu.h @@ -0,0 +1,48 @@ +#pragma once + +#include <RobotAPI/components/ArViz/Client/Layer.h> +#include <RobotAPI/components/ArViz/Client/Client.h> + +#include <RobotAPI/interface/units/GraspCandidateProviderInterface.h> + + +namespace armarx::grasping +{ + class GraspCandidateVisu + { + public: + GraspCandidateVisu(); + + + void visualize( + const grasping::GraspCandidateDict& candidates, + viz::Client& arviz); + + void visualize( + const grasping::GraspCandidateDict& candidates, + viz::Layer& layerReachable, + viz::Layer& layerNonReachable); + + void visualize( + const std::string& id, + const grasping::GraspCandidate& candidate, + viz::Layer& layerReachable, + viz::Layer& layerNonReachable); + + viz::Robot visualize( + const std::string& name, + const grasping::GraspCandidate& candidate); + viz::Robot visualize( + const std::string& name, + const grasping::GraspCandidate& candidate, + int alpha); + + + public: + + int alpha_default = 255; + std::map<std::string, int> alphasByKey = {}; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/client/query/Builder.cpp b/source/RobotAPI/libraries/armem/client/query/Builder.cpp index 8637055e5b850494f15c10255b29de94785cec08..2a31828717f34906875bdbb8a17c62719b675331 100644 --- a/source/RobotAPI/libraries/armem/client/query/Builder.cpp +++ b/source/RobotAPI/libraries/armem/client/query/Builder.cpp @@ -120,4 +120,12 @@ namespace armarx::armem::client::query .snapshots().atTime(snapshotID.timestamp); } + void Builder::multipleEntitySnapshots(const std::vector<MemoryID>& snapshotIDs) + { + for (const MemoryID& snapshotID : snapshotIDs) + { + singleEntitySnapshot(snapshotID); + } + } + } diff --git a/source/RobotAPI/libraries/armem/client/query/Builder.h b/source/RobotAPI/libraries/armem/client/query/Builder.h index 3b52aa4b1945d6a2bef62932403013670843f94a..90d3e211ac9e776f061695420392b765bac1aac2 100644 --- a/source/RobotAPI/libraries/armem/client/query/Builder.h +++ b/source/RobotAPI/libraries/armem/client/query/Builder.h @@ -61,6 +61,7 @@ namespace armarx::armem::client::query void latestEntitySnapshot(const MemoryID& entityID); void singleEntitySnapshot(const MemoryID& snapshotID); + void multipleEntitySnapshots(const std::vector<MemoryID>& snapshotIDs); QueryInput buildQueryInput() const; diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp index 96369565e92c7747a33f627e6b8f98ab20ff52c7..91a9196beec405f386854d9f45f02ef5cd5bf1e7 100644 --- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp @@ -630,7 +630,8 @@ namespace armarx::armem::server::obj::instance // Store attachment in new entity snapshot. { - armem::EntityUpdate update; + armem::Commit commit; + armem::EntityUpdate & update = commit.add(); update.entityID = objectEntity->id(); update.timeCreated = now; { @@ -639,7 +640,7 @@ namespace armarx::armem::server::obj::instance updated.pose.attachmentValid = true; update.instancesData = { updated.toAron() }; } - objectEntity->update(update); + iceMemory.commit(commit); } ARMARX_INFO << "Attached object " << objectID << " by provider '" << data.pose.providerName << "' " @@ -737,7 +738,8 @@ namespace armarx::armem::server::obj::instance Time now, bool commitAttachedPose) { - armem::EntityUpdate update; + armem::Commit commit; + armem::EntityUpdate & update = commit.add(); update.entityID = entity.id(); update.timeCreated = now; { @@ -762,7 +764,7 @@ namespace armarx::armem::server::obj::instance update.instancesData = { updated.toAron() }; } - entity.update(update); + iceMemory.commit(commit); }