32 #include <VirtualRobot/Visualization/TriMeshModel.h>
33 #include <VirtualRobot/CollisionDetection/CollisionChecker.h>
34 #include <VirtualRobot/CollisionDetection/CollisionCheckerImplementation.h>
35 #include <VirtualRobot/ManipulationObject.h>
36 #include <SemanticObjectRelations/Visualization/SupportAnalysisVisualizer.h>
37 #include <SemanticObjectRelations/Visualization/ContactDetectionVisualizer.h>
38 #include <SemanticObjectRelations/SupportAnalysis/json.h>
39 #include <SemanticObjectRelations/Shapes/json/ShapeSerializers.h>
47 defineOptionalProperty<std::string>(
"WorkingMemoryName",
"WorkingMemory",
"Name of WorkingMemory component");
48 defineOptionalProperty<std::string>(
"PriorKnowledgeName",
"PriorKnowledge",
"Name of PriorKnowledge component");
49 defineOptionalProperty<std::string>(
"RobotStateComponentName",
"RobotStateComponent",
"Name of RobotStateComponent component");
50 defineOptionalProperty<std::string>(
"DebugDrawerTopicName",
"DebugDrawerUpdates",
"The name of the debug drawer topic");
51 defineOptionalProperty<int>(
"UpdatePeriodInMS", 10,
"Update period in ms");
53 defineOptionalProperty<semrel::VisuLevel>(
"VisuLevel", semrel::VisuLevel::RESULT,
54 "Visualization level: Determines what is shown in the debug drawer\n"
55 "Possible values: live, verbose, result, user, disabled")
56 .map(
"live", semrel::VisuLevel::LIVE_VISU)
57 .map(
"verbose", semrel::VisuLevel::VERBOSE)
58 .map(
"result", semrel::VisuLevel::RESULT)
59 .map(
"user", semrel::VisuLevel::USER)
60 .map(
"disabled", semrel::VisuLevel::DISABLED);
62 defineOptionalProperty<float>(
"ContactMarginInMM", 5.0f,
"Margin (mm) used during contact detection between objects");
65 static semrel::ContactPointList calculateContactPoints(semrel::ShapeList
const& objects)
67 semrel::ContactPointList result;
69 VirtualRobot::CollisionCheckerPtr collisionChecker = VirtualRobot::CollisionChecker::getGlobalCollisionChecker();
70 for (std::size_t i = 0; i < objects.size(); ++i)
73 for (std::size_t j = i + 1; j < objects.size(); ++j)
76 Eigen::Affine3f poseB(shapeB.
object->getGlobalPose());
78 VirtualRobot::CollisionModelPtr collModelA = shapeA.
object->getCollisionModel();
79 VirtualRobot::CollisionModelPtr collModelB = shapeB.
object->getCollisionModel();
80 VirtualRobot::MultiCollisionResult collisions = collisionChecker->checkMultipleCollisions(collModelA, collModelB);
83 auto& facesB = collModelB->getTriMeshModel()->faces;
84 auto& normalsB = collModelB->getTriMeshModel()->normals;
85 for (VirtualRobot::SingleCollisionPair
const& collision : collisions.pairs)
88 VirtualRobot::MathTools::TriangleFace
const& faceOnB = facesB.at(collision.id2);
90 Eigen::Vector3f globalPointOnB = collision.contact2;
92 Eigen::Vector3f localNormalOnB;
93 if (faceOnB.idNormal1 == UINT_MAX)
95 localNormalOnB = poseB.linear() * faceOnB.normal;
99 Eigen::Vector3f n1B = normalsB[faceOnB.idNormal1];
100 Eigen::Vector3f n2B = normalsB[faceOnB.idNormal2];
101 Eigen::Vector3f n3B = normalsB[faceOnB.idNormal3];
103 localNormalOnB = (n1B + n2B + n3B).normalized();
105 Eigen::Vector3f globalNormalOnB = poseB.linear() * localNormalOnB;
107 result.emplace_back(&shapeA, &shapeB, globalPointOnB, globalNormalOnB);
115 static void filterObjectsWithoutCollisionModel(std::vector<memoryx::ObjectInstanceWrapper>& objects)
118 auto removeIter = std::remove_if(objects.begin(), objects.end(),
122 if (object.manipulationObject->getCollisionModel())
124 if (object.manipulationObject->getCollisionModel()->getTriMeshModel())
130 ARMARX_WARNING_S <<
"No tri-mesh model in '" << object.instanceInMemory->getMostProbableClass() <<
"'";
135 ARMARX_WARNING_S <<
"No collision model in '" << object.instanceInMemory->getMostProbableClass() <<
"'";
139 objects.erase(removeIter, objects.end());
144 std::lock_guard<std::mutex> lock(componentMutex);
146 std::vector<memoryx::ObjectInstanceWrapper> objectInstances = objectInstancesSegment_.queryObjects();
147 filterObjectsWithoutCollisionModel(objectInstances);
150 std::set<semrel::ShapeID> safeShapes;
151 std::set<std::string> safeObjectClassNames = {
"workbench",
"booth"};
153 std::vector<std::string>
names;
155 for (
auto&
object : objectInstances)
157 std::string objectClass =
object.instanceInMemory->getMostProbableClass();
159 if (safeObjectClassNames.count(objectClass) > 0)
161 ARMARX_IMPORTANT <<
"Adding safe object: " <<
object.instanceInMemory->getName();
162 safeShapes.insert(semrel::ShapeID{uniqueID});
164 object.manipulationObject->getCollisionModel()->inflateModel(prop_ContactMarginInMM);
165 std::unique_ptr<semantic::SimoxObjectShape> shape = std::make_unique<semantic::SimoxObjectShape>(
object.manipulationObject, objectClass);
166 shape->entityId =
object.instanceInMemory->getId();
168 shape->setID(semrel::ShapeID{uniqueID});
170 shapes.push_back(std::move(shape));
176 semrel::ContactPointList contactPoints = calculateContactPoints(
shapes);
177 semrel::ContactGraph contactGraph = semrel::buildContactGraph(contactPoints,
shapes);
179 semrel::ContactDetectionVisualizer& visu = semrel::ContactDetectionVisualizer::get();
180 visu.drawContactPoints(contactPoints);
182 semrel::SupportGraph supportGraph = supportAnalysis.performSupportAnalysis(
shapes, safeShapes, &contactGraph);
186 semrel::AttributedGraph attributedGraph = semrel::toAttributedGraph(supportGraph);
187 attributedGraph.serializeObjects(semrel::toShapeMap(
shapes));
189 getGraphStorageTopic()->begin_reportGraph(
"Support", iceGraph);
192 relationSegment->replaceRelations(relations);
197 #define GET_PROP(name) \
198 prop_ ## name = getProperty<decltype(prop_ ## name )>(#name).getValue()
200 void SemanticRelationAnalyzer::onInitComponent()
211 offeringTopic(prop_DebugDrawerTopicName);
213 semantic::ArmarXLog::setAsImplementation(getName());
217 void SemanticRelationAnalyzer::onConnectComponent()
219 workingMemory = getProxy<memoryx::WorkingMemoryInterfacePrx>(prop_WorkingMemoryName);
220 priorKnowledge = getProxy<memoryx::PriorKnowledgeInterfacePrx>(prop_PriorKnowledgeName);
221 robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(prop_RobotStateComponentName);
222 debugDrawer = getTopic<DebugDrawerInterfacePrx>(prop_DebugDrawerTopicName);
224 semantic::ArmarXVisualizer::setAsImplementation(debugDrawer);
225 semrel::VisuLevel visuLevel = getProperty<semrel::VisuLevel>(
"VisuLevel").getValue();
226 semrel::VisualizerInterface::get().setMinimumVisuLevel(visuLevel);
228 relationSegment = workingMemory->getRelationsSegment();
229 objectInstancesSegment_.initFromProxies(priorKnowledge, workingMemory, robotStateComponent);
231 jsonSerializer.reset(
new semantic::JsonSimoxShapeSerializer(&objectInstancesSegment_.objectClassSegment));
232 semantic::JsonSimoxShapeSerializer::registerSerializer(jsonSerializer,
true);
235 extractSupportGraphFromWorkingMemory(Ice::Current());
242 void SemanticRelationAnalyzer::onDisconnectComponent()
245 updateTask =
nullptr;
249 void SemanticRelationAnalyzer::onExitComponent()
256 getConfigIdentifier()));
259 static std::string
const LAYER_NAME =
"SemanticRelationAnalyzer";