30 #include <pcl/common/colors.h>
31 #include <pcl/point_types.h>
33 #include <SimoxUtility/algorithm/string/string_tools.h>
34 #include <VirtualRobot/MathTools.h>
48 #define PRIMITIVE_LAYER_NAME(n) \
49 (std::string("primitivesLayer") + std::string(((n) % 2 == 0) ? "" : "_2"))
50 #define PRIMITIVE_LABELS_LAYER_NAME(n) \
51 (std::string("primitiveLabelsLayer") + std::string(((n) % 2 == 0) ? "" : "_2"))
52 #define PRIMITIVE_FRAMES_LAYER_NAME(n) \
53 (std::string("primitiveFramesLayer") + std::string(((n) % 2 == 0) ? "" : "_2"))
54 #define PRIMITIVE_GRASP_POINTS_LAYER_NAME(n) \
55 (std::string("graspPointLayer") + std::string(((n) % 2 == 0) ? "" : "_2"))
56 #define AFFORDANCES_LAYER_NAME(n) \
57 (std::string("affordancesLayer") + std::string(((n) % 2 == 0) ? "" : "_2"))
66 affordanceLabelSize(18),
67 primitiveVisualizationEnabled(true),
68 affordanceVisualizationEnabled(true),
69 debugVisualizationEnabled(false),
70 visualizationStyle(AffordanceVisualizationStyle::eAffordanceLabels)
77 offeringTopic(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
78 offeringTopic(getProperty<std::string>(
"VisualizationUpdateTopicName").getValue());
79 usingProxy(getProperty<std::string>(
"WorkingMemoryName").getValue());
91 std::string beliefFunction =
92 getProperty<std::string>(
"VisualizeAffordanceBeliefFunction").getValue();
94 if (beliefFunction !=
"")
96 std::vector<std::string> primitives;
98 std::vector<std::string> affordances;
99 affordances.push_back(beliefFunction);
104 getProperty<float>(
"MinExpectedProbability").getValue());
114 getProperty<std::string>(
"DebugDrawerTopicName").getValue());
122 getProperty<std::string>(
"VisualizationUpdateTopicName").getValue());
125 ARMARX_ERROR <<
"Failed to obtain affordance visualization topic proxy";
129 usingTopic(getProperty<std::string>(
"DebugDrawerSelectionsTopicName").getValue());
130 offeringTopic(getProperty<std::string>(
"VisualizationUpdateTopicName").getValue());
132 std::string fileName = getProperty<std::string>(
"FileName").getValue();
133 if (!fileName.empty())
137 scene->load(fileName);
144 getProperty<std::string>(
"WorkingMemoryName").getValue());
147 ARMARX_ERROR <<
"Failed to obtain working memory proxy";
154 ARMARX_ERROR <<
"Failed to obtain affordance segment pointer";
161 ARMARX_ERROR <<
"Failed to obtain environmental primitive segment pointer";
188 if (getProperty<bool>(
"NoAffordanceExtractionConfigured").getValue())
204 if (!getProperty<bool>(
"NoAffordanceExtractionConfigured").getValue())
220 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
232 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
244 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
253 bool enableAffordances,
254 bool enableDebugInformation,
255 const Ice::Current&
c)
257 ARMARX_INFO <<
"Visualization configuration changed: primitives="
258 << (enablePrimitives ?
"enabled" :
"disabled")
259 <<
", affordances=" << (enableAffordances ?
"enabled" :
"disabled")
260 <<
", debug=" << (enableDebugInformation ?
"enabled" :
"disabled");
270 visualize(updatePrimitives, updateAffordances, updateDebugInfo);
275 AffordanceVisualizationStyle style,
276 const std::vector<std::string>& primitives,
277 const std::vector<std::string>& affordances,
278 float minExpectedProbability,
279 const Ice::Current&
c)
297 bool updatePrimitives,
298 bool updateAffordances,
299 bool updateDebugInfo)
319 const AffordanceKit::PrimitiveSetPtr& primitives)
321 for (
auto& primitive : *primitives)
330 if (
auto plane = std::dynamic_pointer_cast<AffordanceKit::Plane>(primitive))
334 else if (
auto cyl = std::dynamic_pointer_cast<AffordanceKit::Cylinder>(primitive))
338 else if (
auto sphere = std::dynamic_pointer_cast<AffordanceKit::Sphere>(primitive))
342 else if (
auto box = std::dynamic_pointer_cast<AffordanceKit::Box>(primitive))
348 ARMARX_WARNING <<
"Attempt to visualize primitive of unknown type";
356 AffordanceKit::PrimitiveSetPtr primitives =
scene->getPrimitives();
357 const std::vector<AffordanceKit::AffordancePtr>& affordances =
scene->getAffordances();
359 for (
auto& primitive : *primitives)
370 std::vector<std::string> labels;
373 for (
auto& affordance : affordances)
385 affordance->existsForPrimitive(primitive))
387 labels.push_back(affordance->getName());
389 else if (
visualizationStyle == AffordanceVisualizationStyle::eAffordanceBeliefFunctions)
404 const AffordanceKit::PrimitivePtr& primitive,
407 std::string
id =
"affordance_" + affordance->getName() +
"_" +
std::to_string(
index) +
"_" +
410 if (affordance->getTimestamp() != primitive->getTimestamp())
412 IceUtil::Time affordanceTimestamp = IceUtil::Time::microSeconds(affordance->getTimestamp());
413 IceUtil::Time primitiveTimestamp = IceUtil::Time::microSeconds(primitive->getTimestamp());
416 affordanceTimestamp.toDateTime().substr(affordanceTimestamp.toDateTime().find(
' ') + 1);
418 primitiveTimestamp.toDateTime().substr(primitiveTimestamp.toDateTime().find(
' ') + 1);
420 ARMARX_WARNING <<
"Timestamp of visualized affordance does not match the primitive "
421 "timestamp (Affordance: "
422 << t1 <<
", Primitive: " << t2 <<
")";
427 if (
auto unimanualA =
428 std::dynamic_pointer_cast<AffordanceKit::UnimanualAffordance>(affordance))
437 else if (
auto bimanualA =
438 std::dynamic_pointer_cast<AffordanceKit::BimanualAffordance>(affordance))
456 const AffordanceKit::PrimitivePtr& primitive,
457 const std::vector<std::string>& labels)
461 for (
unsigned int i = 0; i < labels.size(); i++)
463 label += labels[i] + ((i == labels.size() - 1) ?
"" :
", ");
466 Eigen::Vector3f
c = primitive->getCenter();
469 primitive->getId() +
"_labels",
484 const std::vector<Eigen::Vector3f>& hull = plane->getConvexHull();
486 std::vector<Vector3BasePtr> polygon;
509 sphere->getRadius());
515 float radius = cylinder->getRadius();
516 float length = cylinder->getLength();
536 Eigen::Vector3f dim = box->getDimensions();
538 std::vector<std::vector<Eigen::Vector3f>> sides;
541 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) +
542 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
543 (dim.z() / 2) * pose.block<3, 1>(0, 2));
544 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) +
545 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
546 (dim.z() / 2) * pose.block<3, 1>(0, 2));
547 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) -
548 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
549 (dim.z() / 2) * pose.block<3, 1>(0, 2));
550 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) -
551 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
552 (dim.z() / 2) * pose.block<3, 1>(0, 2));
554 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) +
555 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
556 (dim.z() / 2) * pose.block<3, 1>(0, 2));
557 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) +
558 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
559 (dim.z() / 2) * pose.block<3, 1>(0, 2));
560 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) -
561 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
562 (dim.z() / 2) * pose.block<3, 1>(0, 2));
563 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) -
564 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
565 (dim.z() / 2) * pose.block<3, 1>(0, 2));
567 sides[2].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) +
568 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
569 (dim.z() / 2) * pose.block<3, 1>(0, 2));
570 sides[2].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) +
571 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
572 (dim.z() / 2) * pose.block<3, 1>(0, 2));
573 sides[2].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) +
574 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
575 (dim.z() / 2) * pose.block<3, 1>(0, 2));
576 sides[2].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) +
577 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
578 (dim.z() / 2) * pose.block<3, 1>(0, 2));
580 sides[3].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) -
581 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
582 (dim.z() / 2) * pose.block<3, 1>(0, 2));
583 sides[3].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) -
584 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
585 (dim.z() / 2) * pose.block<3, 1>(0, 2));
586 sides[3].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) -
587 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
588 (dim.z() / 2) * pose.block<3, 1>(0, 2));
589 sides[3].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) -
590 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
591 (dim.z() / 2) * pose.block<3, 1>(0, 2));
593 sides[4].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) +
594 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
595 (dim.z() / 2) * pose.block<3, 1>(0, 2));
596 sides[4].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) -
597 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
598 (dim.z() / 2) * pose.block<3, 1>(0, 2));
599 sides[4].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) -
600 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
601 (dim.z() / 2) * pose.block<3, 1>(0, 2));
602 sides[4].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) +
603 (dim.y() / 2) * pose.block<3, 1>(0, 1) +
604 (dim.z() / 2) * pose.block<3, 1>(0, 2));
606 sides[5].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) +
607 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
608 (dim.z() / 2) * pose.block<3, 1>(0, 2));
609 sides[5].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) -
610 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
611 (dim.z() / 2) * pose.block<3, 1>(0, 2));
612 sides[5].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) -
613 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
614 (dim.z() / 2) * pose.block<3, 1>(0, 2));
615 sides[5].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) +
616 (dim.y() / 2) * pose.block<3, 1>(0, 1) -
617 (dim.z() / 2) * pose.block<3, 1>(0, 2));
619 for (
unsigned int i = 0; i < sides.size(); i++)
654 bool updateAffordances,
655 bool updateDebugInfo)
665 ARMARX_INFO <<
"Current scene contains: " <<
scene->getPrimitives()->size() <<
" primitives";
666 ARMARX_INFO <<
"Current scene contains: " <<
scene->getUnimanualAffordances().size()
667 <<
" unimanual affordances";
668 ARMARX_INFO <<
"Current scene contains: " <<
scene->getBimanualAffordances().size()
669 <<
" bimanual affordances";
671 <<
" affordances in total";
673 if (updatePrimitives)
682 if (updateAffordances)
709 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
711 std::set<std::string> previousSelections =
selections;
721 for (
auto& primitive : previousSelections)
734 const Ice::Current&
c)
743 const Ice::Current&
c)
747 memoryx::EnvironmentalPrimitiveBaseList primitives =
750 for (
auto& primitive : primitives)
754 if (primitive->ice_isA(memoryx::PlanePrimitiveBase::ice_staticId()))
756 memoryx::PlanePrimitiveBasePtr::dynamicCast(primitive)->serialize(
s);
758 else if (primitive->ice_isA(memoryx::SpherePrimitiveBase::ice_staticId()))
760 memoryx::SpherePrimitiveBasePtr::dynamicCast(primitive)->serialize(
s);
762 else if (primitive->ice_isA(memoryx::CylinderPrimitiveBase::ice_staticId()))
764 memoryx::CylinderPrimitiveBasePtr::dynamicCast(primitive)->serialize(
s);
771 serializer->append(
s);
775 out.open(
filename, std::ios_base::trunc);
779 out << serializer->toString();
812 const DebugDrawerSelectionList& selectedObjects,
815 std::vector<std::string> tmpSelections;
820 for (
auto&
object : selectedObjects)
824 ARMARX_INFO <<
"Object " <<
object.elementName <<
" selected";
827 tmpSelections.push_back(
object.elementName);