25 #include <pcl/common/transforms.h>
26 #include <pcl/filters/statistical_outlier_removal.h>
28 #include <SimoxUtility/meta/type_name.h>
36 #include <VisionX/interface/components/Calibration.h>
55 .
value(buf.outlierStddevMulThresh)
64 .
value(buf.ransacEpsilon)
70 .
value(buf.ransacBitmapEpsilon)
76 .
value(buf.ransacNormalThresh)
83 .
value(buf.ransacProbability)
90 .
value(buf.ransacMinSupport)
96 .
value(buf.ransacMaxruntimeMs)
108 prx.
getValue(buf.outlierMeanK,
"outlierMeanK");
109 prx.
getValue(buf.outlierStddevMulThresh,
"outlierStddevMulThresh");
111 prx.
getValue(buf.ransacEpsilon,
"ransacEpsilon");
112 prx.
getValue(buf.ransacNormalThresh,
"ransacNormalThresh");
113 prx.
getValue(buf.ransacMinSupport,
"ransacMinSupport");
114 prx.
getValue(buf.ransacBitmapEpsilon,
"ransacBitmapEpsilon");
115 prx.
getValue(buf.ransacProbability,
"ransacProbability");
116 prx.
getValue(buf.ransacMaxruntimeMs,
"ransacMaxruntimeMs");
122 #define result_name_transformed getName() + "_Transformed"
123 #define result_name_filtered getName() + "_Filtered"
129 visionx::PointCloudProcessorPropertyDefinitions(prefix)
131 defineOptionalProperty<std::string>(
132 "ProviderReferenceFrame",
134 "Name of the point cloud refence frame (empty = autodetect)");
140 return "EfficientRANSACPrimitiveExtractor";
146 _pointCloudProviderName = getProperty<std::string>(
"ProviderName");
159 _pointCloudProvider = _pointCloudProviderInfo.
proxy;
160 _pointCloudProviderRefFrame = getProperty<std::string>(
"ProviderReferenceFrame");
161 if (_pointCloudProviderRefFrame.empty())
163 _pointCloudProviderRefFrame =
"root";
165 visionx::ReferenceFrameInterfacePrx::checkedCast(_pointCloudProvider);
168 _pointCloudProviderRefFrame = frameprov->getReferenceFrame();
175 addRobot(
"_localRobot", VirtualRobot::RobotIO::eStructure);
198 #define call_template_function(F) \
199 switch (_pointCloudProviderInfo.pointCloudFormat->type) \
201 case visionx::PointContentType::ePoints: \
202 F<pcl::PointXYZ>(); \
204 case visionx::PointContentType::eColoredPoints: \
205 F<pcl::PointXYZRGBA>(); \
207 case visionx::PointContentType::eColoredOrientedPoints: \
208 F<pcl::PointXYZRGBNormal>(); \
210 case visionx::PointContentType::eLabeledPoints: \
211 F<pcl::PointXYZL>(); \
213 case visionx::PointContentType::eColoredLabeledPoints: \
214 F<pcl::PointXYZRGBL>(); \
216 case visionx::PointContentType::eIntensity: \
217 F<pcl::PointXYZI>(); \
219 case visionx::PointContentType::eOrientedPoints: \
220 ARMARX_ERROR << "eOrientedPoints NOT HANDLED IN VISIONX"; \
223 ARMARX_ERROR << "Could not process point cloud, because format '" \
224 << _pointCloudProviderInfo.pointCloudFormat->type << "' is unknown"; \
256 template <
class Po
intType>
261 using cloud_t = pcl::PointCloud<PointType>;
262 using cloud_ptr_t =
typename cloud_t::Ptr;
263 const auto now = [] {
return std::chrono::high_resolution_clock::now(); };
264 const auto timeBeg = now();
267 const auto dt = now() - timeBeg;
268 const int us = std::chrono::duration_cast<std::chrono::microseconds>(
dt).count();
273 cloud_ptr_t transformedCloud;
278 <<
"Timeout or error while waiting for point cloud data of provider "
279 << _pointCloudProviderName;
282 cloud_ptr_t inputCloud(
new cloud_t);
290 _pointCloudProviderRefFrame,
291 _localRobot.
robot->getName()};
293 fp.changeFrame(_localRobot.
robot,
"Global");
297 transformedCloud = cloud_ptr_t(
new cloud_t);
298 pcl::transformPointCloud(*inputCloud, *transformedCloud, providerInRootFrame);
305 cloud_ptr_t filtered(
new cloud_t);
306 pcl::StatisticalOutlierRemoval<PointType> sor;
307 sor.setInputCloud(transformedCloud);
308 sor.setMeanK(buf.outlierMeanK);
309 sor.setStddevMulThresh(buf.outlierStddevMulThresh);
310 sor.filter(*filtered);
319 std::vector<Point> points;
320 points.reserve(transformedCloud->size());
321 static constexpr
float inf = std::numeric_limits<float>::infinity();
328 for (
const auto& p : *transformedCloud)
330 points.emplace_back(
Vec3f(p.x, p.y, p.z));
331 std::tie(minX, maxX) = std::minmax({minX, maxX, p.x});
332 std::tie(minY, maxY) = std::minmax({minY, maxY, p.y});
333 std::tie(minZ, maxZ) = std::minmax({minZ, maxZ, p.z});
337 pc.setBBox({minX, minY, minZ}, {maxX, maxY, maxZ});
349 buf.ransacBitmapEpsilon;
352 buf.ransacNormalThresh;
354 buf.ransacMinSupport;
356 buf.ransacProbability;
392 .position(Eigen::Vector3f::Zero())
394 .pointSizeInPixels(8)
395 .pointCloud(*transformedCloud));
399 std::size_t numCyl = 0;
400 std::size_t numSph = 0;
401 std::size_t numPla = 0;
402 std::size_t numUnk = 0;
404 static int maxnum = 0;
408 const auto draw_cloud = [&](std::size_t num, std::string desc)
412 cloud.
position(Eigen::Vector3f::Zero());
416 for (std::size_t i2 = 0; i2 < num; ++i2, ++idx)
418 const auto& pt =
pc.at(
pc.size() - 1 - idx);
420 pt.pos.getValue()[0], pt.pos.getValue()[1], pt.pos.getValue()[2], i);
423 cloudLayer.
add(cloud);
427 for (; i <
shapes.size(); ++i)
433 const auto& [
s, sz] =
shapes.at(i);
436 if (plane_t* ptr =
dynamic_cast<plane_t*
>(
s.Ptr()); ptr)
440 ptr->Internal().getPosition().getValue(
c.x(),
c.y(),
c.z());
443 ptr->Internal().getNormal().getValue(
n.x(),
n.y(),
n.z());
447 .lineColorGlasbeyLUT(i)
449 .circle(
c,
n, 200, 64));
451 else if (sphere_t* ptr =
dynamic_cast<sphere_t*
>(
s.Ptr()); ptr)
455 ptr->Internal().Center().getValue(
c.x(),
c.y(),
c.z());
457 ransacLayer.
add(
viz::Sphere(name).colorGlasbeyLUT(i).position(
c).radius(
458 ptr->Internal().Radius()));
460 else if (cylinder_t* ptr =
dynamic_cast<cylinder_t*
>(
s.Ptr()); ptr)
464 ptr->Internal().AxisPosition().getValue(
c.x(),
c.y(),
c.z());
470 .radius(ptr->Internal().Radius())
476 ARMARX_WARNING <<
"UNKNOWN shape " << simox::meta::get_type_name(
s.Ptr());
480 draw_cloud(sz,
"dummy");
483 for (; i < maxnum; ++i)
485 draw_cloud(0,
"dummy");