260 const auto& buf = _cfgBuf.getUpToDateReadBuffer();
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);
287 const Eigen::Matrix4f providerInRootFrame = [&]() -> Eigen::Matrix4f
290 _pointCloudProviderRefFrame,
291 _localRobot.robot->getName()};
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);
313 std::swap(filtered, transformedCloud);
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;
357 ransacOptions.
m_maxruntime = std::chrono::milliseconds{buf.ransacMaxruntimeMs};
374 size_t remaining = detector.
Detect(pc, 0, pc.
size(), &shapes);
383 ARMARX_INFO <<
"remaining unassigned points " << remaining << std::endl;
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)
410 viz::Layer cloudLayer =
arviz.layer(
"Cloud " + std::to_string(i) +
" " + 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);
424 arviz.commit({cloudLayer});
427 for (; i < shapes.
size(); ++i)
433 const auto& [s, sz] = shapes.
at(i);
434 const std::string name = std::to_string(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());
469 .color(viz::Color::green())
470 .radius(ptr->Internal().Radius())
476 ARMARX_WARNING <<
"UNKNOWN shape " << simox::meta::get_type_name(s.Ptr());
480 draw_cloud(sz,
"dummy");
482 draw_cloud(remaining,
"dummy");
483 for (; i < maxnum; ++i)
485 draw_cloud(0,
"dummy");
492 arviz.commit({cloudLayer, ransacLayer});