25 #include <VirtualRobot/VirtualRobot.h>
32 #include <SemanticObjectRelations/Hooks/VisualizerInterface.h>
33 #include <SemanticObjectRelations/Shapes.h>
44 defineOptionalProperty<std::string>(
"ice.DebugObserverName",
46 "Name of the topic the DebugObserver listens to.");
48 defineOptionalProperty<std::string>(
"ice.ShapesTopicName",
50 "Name of the topic on which shapes are reported.");
51 defineOptionalProperty<std::string>(
"ice.ShapesName",
52 "SegmentRansacShapes",
53 "Name to use when reporting the extracted shapes.");
58 defineOptionalProperty<bool>(
61 "Extract shapes on each new point cloud and publish them to the shapes topic.");
63 defineOptionalProperty<std::string>(
64 "ransac.TargetShapes",
65 "box, cylinder, sphere",
66 "Shapes to be extracted (any combination of: box, cylinder, sphere).");
68 defineOptionalProperty<float>(
69 "ransac.maxModelError", 1000.,
"Discard a model if its error is above this threshold.")
72 defineOptionalProperty<int>(
73 "ransac.maxIterations", 100,
"Maximal number of iterations of each RANSAC run.")
76 defineOptionalProperty<float>(
77 "ransac.distanceThresholdBox",
79 "A point with a distance below this threshold is considererd an inlier. (Box)")
81 defineOptionalProperty<float>(
82 "ransac.distanceThresholdPCL",
84 "A point with a distance below this threshold is considererd an inlier. "
85 "(PCL, i.e. cylinder and sphere)")
87 defineOptionalProperty<float>(
90 "The percentage of points that may be considered as outliers and may be ignored for "
92 "This affects box extents, cylinder height, and error computation.")
95 defineOptionalProperty<float>(
96 "ransac.minInlierRate",
98 "A model is considered a good fit, if this fraction of all points are "
99 "inliers for that model. (0.0 ... 1.0)")
102 defineOptionalProperty<float>(
103 "ransac.sizePenaltyFactor",
105 "Weight of the size penalty (relative to distance error). "
106 "Size penalty inhibits shapes with huge radius (cyl, sph) or extents (box)."
107 "Set to 0 to disable size penalty.")
109 defineOptionalProperty<float>(
110 "ransac.sizePenaltyExponent",
112 "Exponent of the of the size penalty (as in s^x, with size measure s and exponent x). "
113 "Size penalty inhibits shapes with huge radius (cyl, sph) or extents (box).")
122 semrel::VisuLevel::RESULT);
136 shapeExtraction.setMaxModelError(getProperty<float>(
"ransac.maxModelError"));
137 shapeExtraction.setMaxIterations(getProperty<int>(
"ransac.maxIterations"));
139 shapeExtraction.setDistanceThresholdBox(getProperty<float>(
"ransac.distanceThresholdBox"));
140 shapeExtraction.setDistanceThresholdPCL(getProperty<float>(
"ransac.distanceThresholdPCL"));
142 shapeExtraction.setOutlierRate(getProperty<float>(
"ransac.outlierRate"));
144 shapeExtraction.setMinInlierRate(getProperty<float>(
"ransac.minInlierRate"));
146 shapeExtraction.setSizePenaltyFactor(getProperty<float>(
"ransac.sizePenaltyFactor"));
147 shapeExtraction.setSizePenaltyExponent(getProperty<float>(
"ransac.sizePenaltyExponent"));
151 std::string targetShapes = getProperty<std::string>(
"ransac.TargetShapes");
155 targetShapes.begin(), targetShapes.end(), targetShapes.begin(), ::tolower);
158 shapeExtraction.setBoxExtractionEnabled(targetShapes.find(
"box") != std::string::npos);
159 shapeExtraction.setCylinderExtractionEnabled(targetShapes.find(
"cylinder") !=
161 shapeExtraction.setSphereExtractionEnabled(targetShapes.find(
"sphere") !=
192 pcl::PointCloud<PointT>::Ptr receivedPointCloud(
new pcl::PointCloud<PointT>());
203 ARMARX_VERBOSE <<
"Timeout or error while waiting for pointclouds.";
209 debugObserver->setDebugChannel(
215 new armarx::Variant(
static_cast<int>(receivedPointCloud->header.stamp))},
221 std::scoped_lock lock(inputPointCloudMutex);
222 this->inputPointCloud = receivedPointCloud;
225 if (getProperty<bool>(
"mode.AsPipeline"))
227 armarx::semantic::data::ShapeList
shapes;
229 std::scoped_lock lockInputPointCloud(inputPointCloudMutex, extractionMutex);
231 ARMARX_INFO <<
"Running shape extraction (" << inputPointCloud->size()
233 const semrel::ShapeExtractionResult extractionResult =
234 shapeExtraction.extract(*inputPointCloud);
239 debugObserver->setDebugChannel(
242 {
"Num Extracted Shapes",
246 shapesTopic->reportShapes(shapesName,
shapes);
250 armarx::semantic::data::ShapeList
253 if (!inputPointCloud)
255 ARMARX_WARNING <<
"No point cloud received. Not running shape extraction.";
260 std::scoped_lock lockInputPointCloud(inputPointCloudMutex, extractionMutex);
262 ARMARX_INFO <<
"Running shape extraction (" << inputPointCloud->size() <<
" points) ...";
263 semrel::ShapeExtractionResult extractionResult = shapeExtraction.extract(*inputPointCloud);
265 armarx::semantic::data::ShapeList result;
268 std::scoped_lock lock(extractedShapes.mutex);
270 extractedShapes.shapes = std::move(extractionResult.objects);
273 ARMARX_INFO <<
"Extracted " << extractedShapes.shapes.size() <<
" shapes. \n"
274 << extractedShapes.shapes;
276 result = extractedShapes.shapesIce;
280 debugObserver->setDebugChannel(
283 {
"Num Extracted Shapes",
new armarx::Variant(
static_cast<int>(result.size()))},
289 armarx::semantic::data::ShapeList
292 std::lock_guard<std::mutex> lock(extractedShapes.mutex);
293 return extractedShapes.shapesIce;
299 return "SegmentRansacShapeExtractor";