29#include <boost/lexical_cast.hpp>
33#include <pcl/common/colors.h>
41#include <AffordanceKit/PrimitiveExtractor.h>
42#include <AffordanceKit/primitives/Box.h>
43#include <AffordanceKit/primitives/Cylinder.h>
44#include <AffordanceKit/primitives/Plane.h>
45#include <AffordanceKit/primitives/Sphere.h>
54 lastProcessedTimestamp = 0;
71 euclideanClusteringTolerance =
getProperty<float>(
"euclideanClusteringTolerance").getValue();
76 numOrientationalSamplings =
getProperty<int>(
"NumOrientationalSamplings").getValue();
84 primitiveExtractor.reset(
new AffordanceKit::PrimitiveExtractor());
85 primitiveExtractor->updateParameters(verbose,
97 euclideanClusteringTolerance,
109 mappingEnabled =
true;
130 ARMARX_ERROR <<
"Failed to obtain working memory proxy";
133 environmentalPrimitiveSegment = workingMemory->getEnvironmentalPrimitiveSegment();
134 if (!environmentalPrimitiveSegment)
136 ARMARX_ERROR <<
"Failed to obtain environmental primitive segment pointer";
149 if (!robotStateComponent->getSynchronizedRobot()->hasRobotNode(sourceFrameName))
152 robotStateComponent =
nullptr;
158 debugDrawerTopicPrx->clearLayer(
"primitiveMapper");
166 debugValues[
"processingTime"] =
new Variant(0.0);
167 debugValues[
"oldPrimitives"] =
new Variant(0.0);
168 debugValues[
"visiblePrimitives"] =
new Variant(0.0);
169 debugValues[
"newPrimitives"] =
new Variant(0.0);
170 debugValues[
"modifiedPrimitives"] =
new Variant(0.0);
171 debugValues[
"unmodifiedPrimitives"] =
new Variant(0.0);
172 debugValues[
"removedPrimitives"] =
new Variant(0.0);
173 debugValues[
"numViews"] =
new Variant(0.0);
174 debugObserver->setDebugChannel(
getName(), debugValues);
190 std::unique_lock lock(enableMutex);
191 mappingEnabled =
true;
197 std::unique_lock lock(enableMutex);
198 mappingEnabled =
false;
210 std::unique_lock lock(enableMutex);
219 IceUtil::Time startTime = IceUtil::Time::now();
221 pcl::PointCloud<pcl::PointXYZRGBL>::Ptr temp(
new pcl::PointCloud<pcl::PointXYZRGBL>());
228 pcl::copyPointCloud(*temp, *labeledCloudPtr);
229 if (labeledCloudPtr->size() == 0)
240 inliersCloudPtr = primitiveExtractor->computeScenePrimitives(labeledCloudPtr);
241 graspCloudPtr = primitiveExtractor->getDetectedGraspPoints();
244 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& planeInliers =
245 primitiveExtractor->getPlaneInliers();
246 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& cylinderInliers =
247 primitiveExtractor->getCylinderInliers();
248 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& sphereInliers =
249 primitiveExtractor->getSphereInliers();
250 const std::vector<float>& circularityProbabilities =
251 primitiveExtractor->getCircularityProbabilities();
253 ARMARX_INFO <<
" ********* Detected Plane number: " << planeInliers.size();
254 ARMARX_INFO <<
" ********* Detected Cylinder number: " << cylinderInliers.size();
255 ARMARX_INFO <<
" ********* Detected Sphere number: " << sphereInliers.size();
256 ARMARX_INFO <<
" ********* Detected Circle Probabilities: " << circularityProbabilities.size();
263 << (IceUtil::Time::now() - startTime).toSecondsDouble() <<
" secs";
266 startTime = IceUtil::Time::now();
270 std::unique_lock lock(enableMutex);
271 enabled = mappingEnabled;
278 pushPrimitivesToMemoryAffordanceKit(temp->header.stamp);
282 pushPrimitivesToMemory(temp->header.stamp);
286 std::unique_lock lock(timestampMutex);
287 lastProcessedTimestamp = temp->header.stamp;
292 pointCloudSegmentationPrx->reportNewPointCloudSegmentation();
295 ARMARX_INFO <<
"Mapping took " << (IceUtil::Time::now() - startTime).toSecondsDouble()
300PrimitiveExtractor::getGraspPointInlierRatio(memoryx::EnvironmentalPrimitiveBasePtr leftPrimitive,
301 memoryx::EnvironmentalPrimitiveBasePtr rightPrimitive)
303 FramedPosePtr pose = FramedPosePtr::dynamicCast(rightPrimitive->getPose());
304 Eigen::Matrix4f worldToPrimitive = pose->toEigen().inverse();
306 Eigen::Vector3f oBBDimensions =
307 Vector3Ptr::dynamicCast(rightPrimitive->getOBBDimensions())->toEigen();
308 Eigen::Vector3f extent = 0.5 * oBBDimensions + (Eigen::Vector3f::Ones() * 50);
310 float numPoints = 0.0;
311 memoryx::PointList graspPoints = leftPrimitive->getGraspPoints();
313 for (Vector3BasePtr& p : graspPoints)
315 Eigen::Vector4f temp = Eigen::Vector4f(p->x, p->y, p->z, 1.0);
316 Eigen::Vector3f point = (worldToPrimitive * temp).head<3>();
318 if ((point.array().abs() < extent.array()).all())
324 return numPoints / graspPoints.size();
328PrimitiveExtractor::fusePrimitives(std::vector<memoryx::EntityBasePtr>& newPrimitives,
332 std::vector<EnvironmentalPrimitiveBasePtr> primitives =
333 environmentalPrimitiveSegment->getEnvironmentalPrimitives();
336 std::vector<memoryx::EnvironmentalPrimitiveBasePtr> nonVisiblePrimitives;
337 std::vector<memoryx::EnvironmentalPrimitiveBasePtr> visiblePrimitives;
339 std::vector<memoryx::EnvironmentalPrimitiveBasePtr> modifiedPrimitives;
340 std::set<std::string> processedPrimitives;
341 std::set<std::string> primitivesToRemove;
343 if (robotStateComponent)
345 Eigen::Matrix4f cameraToWorld = Eigen::Matrix4f::Identity();
348 auto snapshot = robotStateComponent->getRobotSnapshotAtTimestamp(
timestamp);
350 FramedPoseBasePtr pose = snapshot->getRobotNode(sourceFrameName)->getGlobalPose();
352 cameraToWorld = armarx::FramedPosePtr::dynamicCast(pose)->toEigen();
355 primitiveFilter.updateCameraPosition(cameraToWorld);
358 primitiveFilter.visualizeFrustum(debugDrawerTopicPrx);
360 primitiveFilter.getPrimitivesInFieldOfView(
361 primitives, visiblePrimitives, nonVisiblePrimitives);
366 ARMARX_ERROR <<
"Frustum culling not possible without RobotStateComponent assuming that "
367 "all primitives are visible";
368 visiblePrimitives = primitives;
376 for (
const EnvironmentalPrimitiveBasePtr& p : primitives)
378 if (p->ice_isA(memoryx::BoxPrimitiveBase::ice_staticId()))
380 primitivesToRemove.insert(p->getId());
385 if (nonVisiblePrimitives.size())
387 ARMARX_INFO <<
"found " << nonVisiblePrimitives.size()
388 <<
" non visible primitives in field of view.";
389 for (memoryx::EnvironmentalPrimitiveBasePtr& p : nonVisiblePrimitives)
391 p->setProbability(std::max(0.0, p->getProbability() - 0.1));
392 if (p->getProbability() <= 0.4)
394 primitivesToRemove.insert(p->getId());
398 modifiedPrimitives.push_back(p);
404 ARMARX_DEBUG <<
"total primitives " << primitives.size() <<
" visible primitives "
405 << visiblePrimitives.size() <<
"new primitives" << newPrimitives.size();
407 std::vector<memoryx::EntityBasePtr> uniqueEntities;
408 for (
const memoryx::EntityBasePtr& newEntity : newPrimitives)
410 memoryx::EnvironmentalPrimitiveBasePtr newPrimitive =
411 memoryx::EnvironmentalPrimitiveBasePtr::dynamicCast(newEntity);
413 std::vector<EnvironmentalPrimitiveBasePtr> intersectingPrimitives;
414 fusionStrategy.getIntersectingSimilarPrimitives(
415 primitives, newPrimitive, intersectingPrimitives, 50.0);
419 bool addPrimitive =
true;
420 for (EnvironmentalPrimitiveBasePtr& intersectingPrimitive : intersectingPrimitives)
422 if (primitivesToRemove.count(intersectingPrimitive->getId()))
427 int currentLabel = 0;
428 float inlierRatioLeft = getGraspPointInlierRatio(newPrimitive, intersectingPrimitive);
429 float inlierRatioRight = getGraspPointInlierRatio(intersectingPrimitive, newPrimitive);
431 if (inlierRatioLeft <= 0.1 && inlierRatioRight <= 0.1)
433 processedPrimitives.insert(intersectingPrimitive->getId());
436 if (inlierRatioLeft >= 0.9 && inlierRatioRight >= 0.9)
438 intersectingPrimitive->setTime(newPrimitive->getTime());
439 float newProbability = std::fmax(newPrimitive->getProbability(),
440 intersectingPrimitive->getProbability() + 0.15);
441 intersectingPrimitive->setProbability(std::fmin(1.0, newProbability));
442 modifiedPrimitives.push_back(intersectingPrimitive);
444 addPrimitive =
false;
447 else if (inlierRatioLeft <= 0.3 && inlierRatioRight >= 0.7)
450 primitivesToRemove.insert(intersectingPrimitive->getId());
452 else if (inlierRatioLeft >= 0.7 && inlierRatioRight <= 0.3)
455 addPrimitive =
false;
458 else if ((inlierRatioLeft + inlierRatioRight) >= 1.4)
460 if ((newPrimitive->getOBBDimensions()->x * newPrimitive->getOBBDimensions()->y) >
461 (intersectingPrimitive->getOBBDimensions()->x *
462 intersectingPrimitive->getOBBDimensions()->y))
464 primitivesToRemove.insert(intersectingPrimitive->getId());
468 addPrimitive =
false;
476 else if (intersectingPrimitive->getLabel())
478 currentLabel = intersectingPrimitive->getLabel();
481 if (currentLabel == 0 && intersectingPrimitives.size())
483 currentLabel = ++lastUsedLabel;
485 newPrimitive->setLabel(currentLabel);
487 for (EnvironmentalPrimitiveBasePtr& x : intersectingPrimitives)
489 x->setLabel(currentLabel);
490 modifiedPrimitives.push_back(x);
495 uniqueEntities.push_back(newPrimitive);
499 if (robotStateComponent)
502 for (memoryx::EnvironmentalPrimitiveBasePtr& p : visiblePrimitives)
505 if (processedPrimitives.count(p->getId()) || primitivesToRemove.count(p->getId()))
510 float probability = p->getProbability();
511 p->setProbability(std::max(0.0, p->getProbability() - 0.5));
512 ARMARX_LOG <<
"reducing probability for primitive in field of view: " << p->getId()
513 <<
" from " << probability <<
" to " << p->getProbability();
515 if (p->getProbability() <= 0.4)
517 ARMARX_LOG <<
"scheduling primitive " << p->getId() <<
" for removal";
518 primitivesToRemove.insert(p->getId());
522 modifiedPrimitives.push_back(p);
528 ARMARX_INFO <<
"removing " << primitivesToRemove.size() <<
" primitives";
530 for (
const std::string& x : primitivesToRemove)
532 environmentalPrimitiveSegment->removeEntity(x);
536 processedPrimitives.clear();
537 for (EnvironmentalPrimitiveBasePtr& x : modifiedPrimitives)
539 if (!primitivesToRemove.count(x->getId()) && !processedPrimitives.count(x->getId()))
542 environmentalPrimitiveSegment->updateEntity(x->getId(), x);
543 processedPrimitives.insert(x->getId());
547 float unmodified = primitives.size() - modified - primitivesToRemove.size();
549 ARMARX_INFO <<
"Writing segmentation (" << uniqueEntities.size() <<
" primitives) to memory";
551 environmentalPrimitiveSegment->addEntityList(uniqueEntities);
554 debugValues[
"processingTime"] =
556 debugValues[
"oldPrimitives"] =
new Variant((
float)primitives.size());
557 debugValues[
"visiblePrimitives"] =
new Variant((
float)visiblePrimitives.size());
558 debugValues[
"newPrimitives"] =
new Variant((
float)uniqueEntities.size());
559 debugValues[
"modifiedPrimitives"] =
new Variant(modified);
560 debugValues[
"unmodifiedPrimitives"] =
new Variant(unmodified);
561 debugValues[
"removedPrimitives"] =
new Variant((
float)primitivesToRemove.size());
563 debugValues[
"numViews"] =
new Variant((
int)numViews);
564 debugObserver->setDebugChannel(
getName(), debugValues);
566 pcl::PointCloud<pcl::PointXYZL>::Ptr inliers(
new pcl::PointCloud<pcl::PointXYZL>());
567 for (
const EnvironmentalPrimitiveBasePtr& x : primitives)
569 if (primitivesToRemove.count(x->getId()))
574 for (
const armarx::Vector3BasePtr& v : x->getInliers())
577 p.label = x->getLabel();
581 inliers->points.push_back(p);
585 for (
const memoryx::EntityBasePtr& e : uniqueEntities)
589 for (
const armarx::Vector3BasePtr& v : x->getInliers())
592 p.label = x->getLabel();
596 inliers->points.push_back(p);
602 inliers->width = inliers->points.size();
612PrimitiveExtractor::pushPrimitivesToMemory(IceUtil::Int64 originalTimestamp)
614 std::vector<memoryx::EntityBasePtr> newPrimitives;
616 const std::vector<pcl::ModelCoefficients::Ptr>& planeCoefficients =
617 primitiveExtractor->getPlaneCoefficients();
618 const std::vector<pcl::ModelCoefficients::Ptr>& cylinderCoefficients =
619 primitiveExtractor->getCylinderCoefficients();
620 const std::vector<pcl::ModelCoefficients::Ptr>& sphereCoefficients =
621 primitiveExtractor->getSphereCoefficients();
622 const std::vector<float>& circularityProbabilities =
623 primitiveExtractor->getCircularityProbabilities();
625 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& planeInliers =
626 primitiveExtractor->getPlaneInliers();
627 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& cylinderInliers =
628 primitiveExtractor->getCylinderInliers();
629 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& sphereInliers =
630 primitiveExtractor->getSphereInliers();
632 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& cylinderGraspPoints =
633 primitiveExtractor->getCylinderGraspPoints();
634 const std::vector<pcl::PointCloud<pcl::PointXYZL>::Ptr>& sphereGraspPoints =
635 primitiveExtractor->getSphereGraspPoints();
640 for (
size_t i = 0; i < planeCoefficients.size(); i++)
643 pcl::ModelCoefficients::Ptr coefficients = planeCoefficients[i];
644 pcl::PointCloud<pcl::PointXYZL>::Ptr inliers = planeInliers[i];
646 pcl::PointCloud<pcl::PointXYZL>::Ptr graspPoints(
new pcl::PointCloud<pcl::PointXYZL>());
648 pcl::PointCloud<pcl::PointXYZL>::Ptr temp(
new pcl::PointCloud<pcl::PointXYZL>());
649 pcl::ProjectInliers<PointL> proj;
650 proj.setModelType(pcl::SACMODEL_PLANE);
651 proj.setInputCloud(inliers);
652 proj.setModelCoefficients(coefficients);
657 pcl::ConcaveHull<PointL> concaveHull;
658 concaveHull.setInputCloud(temp);
659 concaveHull.setDimension(2);
660 concaveHull.setAlpha(69.0);
662 concaveHull.reconstruct(*graspPoints);
665 ARMARX_LOG << __LINE__ <<
" done computing hull";
668 pcl::MomentOfInertiaEstimation<pcl::PointXYZL> bb;
669 pcl::PointXYZL min_point_OBB, max_point_OBB, position_OBB;
670 Eigen::Matrix3f rotational_matrix_OBB;
672 bb.setInputCloud(graspPoints);
674 bb.getOBB(min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);
676 Eigen::Vector3f position(position_OBB.x, position_OBB.y, position_OBB.z);
678 new Vector3(max_point_OBB.x * 2, max_point_OBB.y * 2, max_point_OBB.z * 2);
683 pcl::PointXYZL pointMin, pointMax;
684 pcl::getMinMax3D<pcl::PointXYZL>(*inliers, pointMin, pointMax);
685 float length = (pointMax.getVector3fMap() - pointMin.getVector3fMap()).norm();
688 EnvironmentalPrimitiveBasePtr primitive;
690 primitive->setOBBDimensions(dimension);
691 primitive->setPose(pose);
692 primitive->setProbability(0.75);
693 primitive->setLabel(0);
694 primitive->setTime(
new TimestampVariant(originalTimestamp));
695 primitive->setLength(length);
696 primitive->setCircularityProbability(circularityProbabilities[i]);
697 primitive->setSampling(
new armarx::MatrixFloat(4, 0));
698 primitive->setName(
"environmentalPrimitive_" + boost::lexical_cast<std::string>(label++));
701 PointList graspPointList(graspPoints->points.size());
702 for (
size_t p = 0; p < graspPoints->points.size(); p++)
705 graspPoints->points[p].x, graspPoints->points[p].y, graspPoints->points[p].z);
706 graspPointList[p] = currPoint;
708 primitive->setGraspPoints(graspPointList);
710 PointList inlierList(inliers->points.size());
711 for (
size_t p = 0; p < inliers->points.size(); p++)
713 const Eigen::Vector3f& f = inliers->points[p].getVector3fMap();
714 inlierList[p] =
new Vector3(f);
716 primitive->setInliers(inlierList);
722 std::vector<Eigen::Vector3f>
convexHull(graspPointList.size());
723 for (
unsigned int i = 0; i < graspPointList.size(); i++)
725 convexHull[i] = armarx::Vector3Ptr::dynamicCast(graspPointList[i])->toEigen();
727 AffordanceKit::PlanePtr plane(
new AffordanceKit::Plane(convexHull));
728 plane->sample(spatialSamplingDistance, numOrientationalSamplings);
729 armarx::MatrixFloatBasePtr
s(
new armarx::MatrixFloat(plane->getSampling()));
730 primitive->setSampling(s);
734 newPrimitives.push_back(primitive);
740 for (
size_t i = 0; i < cylinderCoefficients.size(); i++)
743 pcl::ModelCoefficients::Ptr coefficients = cylinderCoefficients[i];
744 pcl::PointCloud<pcl::PointXYZL>::Ptr inliers = cylinderInliers[i];
745 pcl::PointCloud<pcl::PointXYZL>::Ptr graspPoints = cylinderGraspPoints[i];
747 pcl::PointCloud<pcl::PointXYZL>::Ptr temp(
new pcl::PointCloud<pcl::PointXYZL>());
748 pcl::ProjectInliers<PointL> proj;
749 proj.setModelType(pcl::SACMODEL_PLANE);
750 proj.setInputCloud(inliers);
751 proj.setModelCoefficients(coefficients);
754 pcl::ConcaveHull<PointL> concaveHull;
755 concaveHull.setInputCloud(temp);
756 concaveHull.setDimension(2);
757 concaveHull.setAlpha(69.0);
758 concaveHull.setKeepInformation(
true);
759 concaveHull.reconstruct(*graspPoints);
762 pcl::MomentOfInertiaEstimation<pcl::PointXYZL> bb;
763 pcl::PointXYZL min_point_OBB, max_point_OBB, position_OBB;
764 Eigen::Matrix3f rotational_matrix_OBB;
766 bb.setInputCloud(inliers);
768 bb.getOBB(min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);
770 Eigen::Vector3f position(position_OBB.x, position_OBB.y, position_OBB.z);
772 new Vector3(max_point_OBB.x * 2, max_point_OBB.y * 2, max_point_OBB.z * 2);
778 float min_t = std::numeric_limits<float>::infinity();
779 float max_t = -std::numeric_limits<float>::infinity();
782 coefficients->values[0], coefficients->values[1], coefficients->values[2]);
784 coefficients->values[3], coefficients->values[4], coefficients->values[5]);
787 for (
unsigned int i = 0; i < inliers->points.size(); i++)
789 Eigen::Vector3f
v(inliers->points[i].x, inliers->points[i].y, inliers->points[i].z);
791 float t = (
v - b).
dot(d) / d.dot(d);
793 min_t = std::min(min_t, t);
794 max_t = std::max(max_t, t);
797 float length = max_t - min_t;
798 Eigen::Vector3f base = b + min_t * d + 0.5 * length * d;
799 Eigen::Vector3f direction = d;
800 float radius = coefficients->values[6];
803 CylinderPrimitiveBasePtr primitive;
805 primitive->setCylinderPoint(
new Vector3(base));
806 primitive->setCylinderAxisDirection(
new Vector3(direction));
807 primitive->setCylinderRadius(radius);
808 primitive->setLength(length);
809 primitive->setOBBDimensions(dimension);
810 primitive->setPose(pose);
811 primitive->setProbability(0.75);
812 primitive->setLabel(0);
813 primitive->setTime(
new TimestampVariant(originalTimestamp));
814 primitive->setCircularityProbability(0.0);
815 primitive->setSampling(
new armarx::MatrixFloat(4, 0));
818 PointList graspPointList(graspPoints->points.size());
820 for (
size_t p = 0; p < graspPoints->points.size(); p++)
823 graspPoints->points[p].x, graspPoints->points[p].y, graspPoints->points[p].z);
824 graspPointList[p] = currPoint;
827 primitive->setName(
"environmentalPrimitive_" +
828 boost::lexical_cast<std::string>(planeCoefficients.size() + i));
829 primitive->setGraspPoints(graspPointList);
832 AffordanceKit::CylinderPtr cylinder(
833 new AffordanceKit::Cylinder(base, direction, length, radius));
834 cylinder->sample(spatialSamplingDistance, numOrientationalSamplings);
835 armarx::MatrixFloatBasePtr
s(
new armarx::MatrixFloat(cylinder->getSampling()));
836 primitive->setSampling(s);
840 newPrimitives.push_back(primitive);
846 for (
size_t i = 0; i < sphereCoefficients.size(); i++)
849 pcl::ModelCoefficients::Ptr coefficients = sphereCoefficients[i];
850 pcl::PointCloud<pcl::PointXYZL>::Ptr inliers = sphereInliers[i];
851 pcl::PointCloud<pcl::PointXYZL>::Ptr graspPoints = sphereGraspPoints[i];
858 pcl::MomentOfInertiaEstimation<pcl::PointXYZL> bb;
859 pcl::PointXYZL min_point_OBB, max_point_OBB, position_OBB;
860 Eigen::Matrix3f rotational_matrix_OBB;
862 bb.setInputCloud(inliers);
864 bb.getOBB(min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);
866 Eigen::Vector3f position(position_OBB.x, position_OBB.y, position_OBB.z);
868 new Vector3(max_point_OBB.x * 2, max_point_OBB.y * 2, max_point_OBB.z * 2);
874 pcl::PointXYZL pointMin, pointMax;
875 pcl::getMinMax3D<pcl::PointXYZL>(*inliers, pointMin, pointMax);
876 float length = (pointMax.getVector3fMap() - pointMin.getVector3fMap()).norm();
879 EnvironmentalPrimitiveBasePtr primitive = {};
881 primitive->setOBBDimensions(dimension);
882 primitive->setPose(pose);
883 primitive->setLabel(0);
884 primitive->setProbability(0.75);
885 primitive->setTime(
new TimestampVariant(originalTimestamp));
886 primitive->setLength(length);
887 primitive->setCircularityProbability(0.0);
888 primitive->setSampling(
new armarx::MatrixFloat(4, 0));
891 PointList graspPointList(graspPoints->points.size());
893 for (
size_t p = 0; p < graspPoints->points.size(); p++)
896 graspPoints->points[p].x, graspPoints->points[p].y, graspPoints->points[p].z);
897 graspPointList[p] = currPoint;
900 primitive->setName(
"environmentalPrimitive_" +
901 boost::lexical_cast<std::string>(cylinderCoefficients.size() +
902 planeCoefficients.size() + i));
903 primitive->setGraspPoints(graspPointList);
907 coefficients->values[0], coefficients->values[1], coefficients->values[2]);
908 float radius = coefficients->values[3];
909 AffordanceKit::SpherePtr sphere(
new AffordanceKit::Sphere(center, radius));
910 sphere->sample(spatialSamplingDistance, numOrientationalSamplings);
911 armarx::MatrixFloatBasePtr
s(
new armarx::MatrixFloat(sphere->getSampling()));
912 primitive->setSampling(s);
916 newPrimitives.push_back(primitive);
920 ARMARX_LOG << __LINE__ <<
" writing primitives to memory.";
922 if (enablePrimitiveFusion)
924 fusePrimitives(newPrimitives, originalTimestamp);
928 ARMARX_LOG << __LINE__ <<
" removing previous primitives from memory.";
929 environmentalPrimitiveSegment->removeAllEntities();
931 environmentalPrimitiveSegment->addEntityList(newPrimitives);
935 ARMARX_LOG << __LINE__ <<
"done writing primitives to memory.";
939 newPrimitives.clear();
941 std::vector<EnvironmentalPrimitiveBasePtr> primitives =
942 environmentalPrimitiveSegment->getEnvironmentalPrimitives();
945 unsigned int sz = newPrimitives.size();
946 fusionStrategy.findBoxPrimitives(primitives, newPrimitives, environmentalPrimitiveSegment);
949 for (
auto& primitive : newPrimitives)
957 Eigen::Matrix4f pose = PosePtr::dynamicCast(box->getPose())->toEigen();
958 Eigen::Vector3f dimensions =
959 Vector3Ptr::dynamicCast(box->getOBBDimensions())->toEigen();
960 AffordanceKit::BoxPtr b(
new AffordanceKit::Box(pose, dimensions));
963 armarx::MatrixFloatBasePtr
s(
new armarx::MatrixFloat(b->getSampling()));
967 ARMARX_INFO <<
"Found " << (newPrimitives.size() - sz) <<
" Box primitives";
969 environmentalPrimitiveSegment->addEntityList(newPrimitives);
974PrimitiveExtractor::pushPrimitivesToMemoryAffordanceKit(IceUtil::Int64 originalTimestamp)
976 AffordanceKit::PrimitiveSetPtr ps = primitiveExtractor->getPrimitiveSet(
980 AffordanceKitArmarX::PrimitiveSetArmarX primitiveSet(ps);
981 primitiveSet.writeToMemory(environmentalPrimitiveSegment);
993 std::unique_lock lock(enableMutex);
994 return mappingEnabled;
997armarx::TimestampBasePtr
1000 std::unique_lock lock(timestampMutex);
1006 const Ice::Current&
c)
1009 primitiveExtractor->updateParameters(verbose,
1010 parameters.minSegmentSize,
1011 parameters.maxSegmentSize,
1012 parameters.planeMaxIterations,
1013 parameters.planeDistanceThreshold,
1014 parameters.planeNormalDistance,
1015 parameters.cylinderMaxIterations,
1016 parameters.cylinderDistanceThreshold,
1017 parameters.cylinderRadiusLimit,
1018 parameters.sphereMaxIterations,
1019 parameters.sphereDistanceThreshold,
1020 parameters.sphereNormalDistance,
1021 parameters.euclideanClusteringTolerance,
1022 parameters.outlierThreshold,
1023 parameters.circularDistanceThreshold);
1029 std::string absolute_filename;
1032 ARMARX_INFO <<
"Loading parameter setup from " << absolute_filename;
1033 QSettings config(QString::fromStdString(absolute_filename), QSettings::IniFormat);
1035 config.beginGroup(
"PrimitiveExtraction");
1037 primitiveExtractor->updateParameters(
1043 config.value(
"PlaneMaxIterations",
getProperty<double>(
"planeMaximumIteration").getValue())
1046 .value(
"PlaneDistanceThreshold",
1049 config.value(
"PlaneNormalDistance",
getProperty<float>(
"planeNormalDistance").getValue())
1052 .value(
"CylinderMaxIterations",
1056 .value(
"CylinderDistanceThreshold",
1059 config.value(
"CylinderRadiusLimit",
getProperty<float>(
"cylinderRadiousLimit").getValue())
1065 .value(
"SphereDistanceThreshold",
1068 config.value(
"SphereNormalDistance",
getProperty<float>(
"sphereNormalDistance").getValue())
1071 .value(
"EuclideanClusteringTolerance",
1074 config.value(
"OutlierDistanceThreshold",
getProperty<float>(
"outlierThreshold").getValue())
1077 .value(
"PlaneCircularDistanceThreshold",
1084visionx::PrimitiveExtractorParameters
1087 visionx::PrimitiveExtractorParameters parameters;
1088 parameters.minSegmentSize = primitiveExtractor->minSegmentSize;
1089 parameters.maxSegmentSize = primitiveExtractor->maxSegmentSize;
1090 parameters.planeMaxIterations = primitiveExtractor->planeMaxIteration;
1091 parameters.planeDistanceThreshold = primitiveExtractor->planeMaxIteration;
1092 parameters.planeNormalDistance = primitiveExtractor->planeNormalDistanceWeight;
1093 parameters.cylinderMaxIterations = primitiveExtractor->cylinderMaxIteration;
1094 parameters.cylinderDistanceThreshold = primitiveExtractor->cylinderDistanceThreshold;
1095 parameters.cylinderRadiusLimit = primitiveExtractor->cylinderRadiusLimit;
1097 parameters.sphereMaxIterations = primitiveExtractor->sphereMaxIteration;
1098 parameters.sphereDistanceThreshold = primitiveExtractor->sphereDistanceThreshold;
1099 parameters.sphereNormalDistance = primitiveExtractor->sphereNormalDistanceWeight;
1100 parameters.euclideanClusteringTolerance = primitiveExtractor->euclideanClusteringTolerance;
1101 parameters.outlierThreshold = primitiveExtractor->outlierThreshold;
1102 parameters.circularDistanceThreshold = primitiveExtractor->circleDistanceThreshold;
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Implements a Variant type for timestamps.
The Variant class is described here: Variants.
void enableResultPointClouds(std::string resultProviderName="")
Enables visualization.
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
void usingPointCloudProvider(std::string providerName)
Registers a delayed topic subscription and a delayed provider proxy retrieval which will be available...
bool waitForPointClouds(int milliseconds=1000)
Wait for new PointClouds.
void provideResultPointClouds(const PointCloudPtrT &pointClouds, std::string providerName="")
sends result PointClouds for visualization
#define ARMARX_INFO
The normal logging level.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
std::string const GlobalFrame
Variable of the global coordinate system.
ConvexHull< Point >::type convexHull(const std::vector< Point > &points)
const VariantTypeId FramedPose
T getValue(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName)
double s(double t, double s0, double v0, double a0, double j)
double v(double t, double v0, double a0, double j)
state::Type center(state::Type previous)
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Vector3 > Vector3Ptr
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< FramedPose > FramedPosePtr
const armarx::VariantTypeId PlanePrimitive
const armarx::VariantTypeId SpherePrimitive
const armarx::VariantTypeId CylinderPrimitive
IceInternal::Handle< EnvironmentalPrimitive > EnvironmentalPrimitivePtr
IceInternal::Handle< BoxPrimitive > BoxPrimitivePtr
double dot(const Point &x, const Point &y)