36 #include <VirtualRobot/MathTools.h>
37 #include <SimoxUtility/algorithm/string/string_tools.h>
39 #include <pcl/point_types.h>
40 #include <pcl/common/colors.h>
49 #define PRIMITIVE_LAYER_NAME(n) (std::string("primitivesLayer") + std::string(((n)%2 == 0)? "" : "_2"))
50 #define PRIMITIVE_LABELS_LAYER_NAME(n) (std::string("primitiveLabelsLayer") + std::string(((n)%2 == 0)? "" : "_2"))
51 #define PRIMITIVE_FRAMES_LAYER_NAME(n) (std::string("primitiveFramesLayer") + std::string(((n)%2 == 0)? "" : "_2"))
52 #define PRIMITIVE_GRASP_POINTS_LAYER_NAME(n) (std::string("graspPointLayer") + std::string(((n)%2 == 0)? "" : "_2"))
53 #define AFFORDANCES_LAYER_NAME(n) (std::string("affordancesLayer") + std::string(((n)%2 == 0)? "" : "_2"))
62 affordanceLabelSize(18),
63 primitiveVisualizationEnabled(true),
64 affordanceVisualizationEnabled(true),
65 debugVisualizationEnabled(false),
66 visualizationStyle(AffordanceVisualizationStyle::eAffordanceLabels)
72 offeringTopic(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
73 offeringTopic(getProperty<std::string>(
"VisualizationUpdateTopicName").getValue());
74 usingProxy(getProperty<std::string>(
"WorkingMemoryName").getValue());
86 std::string beliefFunction = getProperty<std::string>(
"VisualizeAffordanceBeliefFunction").getValue();
88 if (beliefFunction !=
"")
90 std::vector<std::string> primitives;
92 std::vector<std::string> affordances;
93 affordances.push_back(beliefFunction);
103 debugDrawerTopicPrx = getTopic<DebugDrawerInterfacePrx>(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
110 affordanceVisualizationTopicPrx = getTopic<AffordancePipelineVisualizationListenerPrx>(getProperty<std::string>(
"VisualizationUpdateTopicName").getValue());
113 ARMARX_ERROR <<
"Failed to obtain affordance visualization topic proxy";
117 usingTopic(getProperty<std::string>(
"DebugDrawerSelectionsTopicName").getValue());
118 offeringTopic(getProperty<std::string>(
"VisualizationUpdateTopicName").getValue());
120 std::string fileName = getProperty<std::string>(
"FileName").getValue();
121 if(!fileName.empty())
125 scene->load(fileName);
131 workingMemoryPrx = getProxy<memoryx::WorkingMemoryInterfacePrx>(getProperty<std::string>(
"WorkingMemoryName").getValue());
134 ARMARX_ERROR <<
"Failed to obtain working memory proxy";
141 ARMARX_ERROR <<
"Failed to obtain affordance segment pointer";
148 ARMARX_ERROR <<
"Failed to obtain environmental primitive segment pointer";
170 if (getProperty<bool>(
"NoAffordanceExtractionConfigured").getValue())
184 if (!getProperty<bool>(
"NoAffordanceExtractionConfigured").getValue())
198 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
208 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
218 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
226 ARMARX_INFO <<
"Visualization configuration changed: primitives=" << (enablePrimitives ?
"enabled" :
"disabled")
227 <<
", affordances=" << (enableAffordances ?
"enabled" :
"disabled")
228 <<
", debug=" << (enableDebugInformation ?
"enabled" :
"disabled");
238 visualize(updatePrimitives, updateAffordances, updateDebugInfo);
276 for (
auto& primitive : *primitives)
284 if (
auto plane = std::dynamic_pointer_cast<AffordanceKit::Plane>(primitive))
288 else if (
auto cyl = std::dynamic_pointer_cast<AffordanceKit::Cylinder>(primitive))
292 else if (
auto sphere = std::dynamic_pointer_cast<AffordanceKit::Sphere>(primitive))
296 else if (
auto box = std::dynamic_pointer_cast<AffordanceKit::Box>(primitive))
302 ARMARX_WARNING <<
"Attempt to visualize primitive of unknown type";
309 AffordanceKit::PrimitiveSetPtr primitives =
scene->getPrimitives();
310 const std::vector<AffordanceKit::AffordancePtr>& affordances =
scene->getAffordances();
312 for (
auto& primitive : *primitives)
320 std::vector<std::string> labels;
323 for (
auto& affordance : affordances)
331 if (
visualizationStyle == AffordanceVisualizationStyle::eAffordanceLabels && affordance->existsForPrimitive(primitive))
333 labels.push_back(affordance->getName());
335 else if (
visualizationStyle == AffordanceVisualizationStyle::eAffordanceBeliefFunctions)
350 std::string
id =
"affordance_" + affordance->getName() +
"_" +
std::to_string(
index) +
"_" + primitive->getId();
352 if (affordance->getTimestamp() != primitive->getTimestamp())
354 IceUtil::Time affordanceTimestamp = IceUtil::Time::microSeconds(affordance->getTimestamp());
355 IceUtil::Time primitiveTimestamp = IceUtil::Time::microSeconds(primitive->getTimestamp());
357 std::string t1 = affordanceTimestamp.toDateTime().substr(affordanceTimestamp.toDateTime().find(
' ') + 1);
358 std::string t2 = primitiveTimestamp.toDateTime().substr(primitiveTimestamp.toDateTime().find(
' ') + 1);
360 ARMARX_WARNING <<
"Timestamp of visualized affordance does not match the primitive timestamp (Affordance: " << t1 <<
", Primitive: " << t2 <<
")";
365 if (
auto unimanualA = std::dynamic_pointer_cast<AffordanceKit::UnimanualAffordance>(affordance))
370 else if (
auto bimanualA = std::dynamic_pointer_cast<AffordanceKit::BimanualAffordance>(affordance))
386 for (
unsigned int i = 0; i < labels.size(); i++)
388 label += labels[i] + ((i == labels.size() - 1) ?
"" :
", ");
391 Eigen::Vector3f
c = primitive->getCenter();
401 const std::vector<Eigen::Vector3f>& hull = plane->getConvexHull();
403 std::vector<Vector3BasePtr> polygon;
420 float radius = cylinder->getRadius();
421 float length = cylinder->getLength();
433 Eigen::Vector3f dim = box->getDimensions();
435 std::vector<std::vector<Eigen::Vector3f>> sides;
438 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
439 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
440 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
441 sides[0].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
443 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
444 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
445 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
446 sides[1].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
448 sides[2].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
449 sides[2].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
450 sides[2].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
451 sides[2].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
453 sides[3].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
454 sides[3].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
455 sides[3].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
456 sides[3].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
458 sides[4].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
459 sides[4].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
460 sides[4].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
461 sides[4].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) + (dim.z() / 2) * pose.block<3, 1>(0, 2));
463 sides[5].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
464 sides[5].push_back(pose.block<3, 1>(0, 3) + (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
465 sides[5].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) - (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
466 sides[5].push_back(pose.block<3, 1>(0, 3) - (dim.x() / 2) * pose.block<3, 1>(0, 0) + (dim.y() / 2) * pose.block<3, 1>(0, 1) - (dim.z() / 2) * pose.block<3, 1>(0, 2));
468 for (
unsigned int i = 0; i < sides.size(); i++)
487 ARMARX_INFO <<
"Current scene contains: " <<
scene->getPrimitives()->size() <<
" primitives";
488 ARMARX_INFO <<
"Current scene contains: " <<
scene->getUnimanualAffordances().size() <<
" unimanual affordances";
489 ARMARX_INFO <<
"Current scene contains: " <<
scene->getBimanualAffordances().size() <<
" bimanual affordances";
490 ARMARX_INFO <<
"Current scene contains: " <<
scene->getAffordances().size() <<
" affordances in total";
492 if (updatePrimitives)
500 if (updateAffordances)
523 if (getProperty<bool>(
"EnableDebugDrawerSelections").getValue())
525 std::set<std::string> previousSelections =
selections;
532 for (
auto& primitive : previousSelections)
555 for (
auto& primitive : primitives)
559 if (primitive->ice_isA(memoryx::PlanePrimitiveBase::ice_staticId()))
561 memoryx::PlanePrimitiveBasePtr::dynamicCast(primitive)->serialize(
s);
563 else if (primitive->ice_isA(memoryx::SpherePrimitiveBase::ice_staticId()))
565 memoryx::SpherePrimitiveBasePtr::dynamicCast(primitive)->serialize(
s);
567 else if (primitive->ice_isA(memoryx::CylinderPrimitiveBase::ice_staticId()))
569 memoryx::CylinderPrimitiveBasePtr::dynamicCast(primitive)->serialize(
s);
576 serializer->append(
s);
580 out.open(
filename, std::ios_base::trunc);
584 out << serializer->toString();
616 std::vector<std::string> tmpSelections;
621 for (
auto&
object : selectedObjects)
625 ARMARX_INFO <<
"Object " <<
object.elementName <<
" selected";
628 tmpSelections.push_back(
object.elementName);