25 #include <pcl/common/transforms.h>
26 #include <pcl/filters/approximate_voxel_grid.h>
32 #include <VisionX/interface/components/Calibration.h>
33 #include <VisionX/interface/core/PointCloudProcessorInterface.h>
35 #define call_template_function(F) \
36 switch (_pointCloudProviderInfo.pointCloudFormat->type) \
38 case visionx::PointContentType::ePoints: \
41 case visionx::PointContentType::eColoredPoints: \
42 F<pcl::PointXYZRGBA>(); \
44 case visionx::PointContentType::eColoredOrientedPoints: \
45 F<pcl::PointXYZRGBNormal>(); \
47 case visionx::PointContentType::eLabeledPoints: \
48 F<pcl::PointXYZL>(); \
50 case visionx::PointContentType::eColoredLabeledPoints: \
51 F<pcl::PointXYZRGBL>(); \
53 case visionx::PointContentType::eIntensity: \
54 F<pcl::PointXYZI>(); \
56 case visionx::PointContentType::eOrientedPoints: \
57 ARMARX_ERROR << "eOrientedPoints NOT HANDLED IN VISIONX"; \
60 ARMARX_ERROR << "Could not call " #F ", because format '" \
61 << _pointCloudProviderInfo.pointCloudFormat->type << "' is unknown"; \
73 return "MultiViewPointCloudProcessor";
81 prop->defineOptionalProperty<std::string>(
82 "ProviderReferenceFrame",
84 "Name of the point cloud refence frame (empty = autodetect)");
85 std::lock_guard guard{_cfgBufWriteMutex};
97 std::lock_guard guard{_cfgBufWriteMutex};
111 std::lock_guard guard{_cfgBufWriteMutex};
137 _pointCloudProviderName = getProperty<std::string>(
"ProviderName");
147 _pointCloudProvider = _pointCloudProviderInfo.
proxy;
148 _pointCloudProviderRefFrame = getProperty<std::string>(
"ProviderReferenceFrame");
149 if (_pointCloudProviderRefFrame.empty())
151 _pointCloudProviderRefFrame =
"root";
153 visionx::ReferenceFrameInterfacePrx::checkedCast(_pointCloudProvider);
156 _pointCloudProviderRefFrame = frameprov->getReferenceFrame();
161 if (!_providerThread.joinable())
170 _robot =
addRobot(
"_robot", VirtualRobot::RobotIO::eStructure);
180 _stopProviding =
true;
181 _providerThread.join();
210 std::lock_guard guard{_cfgBufWriteMutex};
218 std::lock_guard guard{_cfgBufWriteMutex};
226 std::lock_guard guard{_cfgBufWriteMutex};
241 template <
class Po
intType>
249 const auto doRecord = _doRecord.load();
252 std::lock_guard guard{_viewPointsMutex};
254 _currentViewpoint = doRecord ? 0 : -1;
261 const auto currentViewpoint = _currentViewpoint.load();
263 using cloud_t = pcl::PointCloud<PointType>;
264 using cloud_ptr_t =
typename cloud_t::Ptr;
266 std::unique_lock lock{_cfgBufReadMutex};
274 cloud_ptr_t transformedCloud;
279 <<
"Timeout or error while waiting for point cloud data of provider "
280 << _pointCloudProviderName;
283 cloud_ptr_t inputCloud(
new cloud_t);
291 fp.changeFrame(_robot,
"Global");
295 transformedCloud = cloud_ptr_t(
new cloud_t);
296 pcl::transformPointCloud(*inputCloud, *transformedCloud, providerInRootFrame);
299 std::lock_guard guard{_viewPointsMutex};
300 const auto p =
static_cast<std::size_t
>(currentViewpoint);
301 if (p + 1 > _viewPoints.size())
303 _viewPoints.resize(p + 1);
305 _viewPoints.at(p).clouds.emplace_back(transformedCloud);
306 if (buf.maxNumberOfFramesPerViewPoint > 0)
308 while (_viewPoints.at(p).clouds.size() >
309 static_cast<std::size_t
>(buf.maxNumberOfFramesPerViewPoint))
311 _viewPoints.at(p).clouds.pop_front();
317 template <
class Po
intType>
321 using cloud_t = pcl::PointCloud<PointType>;
322 using cloud_ptr_t =
typename cloud_t::Ptr;
323 std::deque<std::uint64_t> idxVec;
324 while (!_stopProviding)
326 const auto timeBeg = std::chrono::high_resolution_clock::now();
328 std::unique_lock lock{_cfgBufReadMutex};
332 cloud_ptr_t cloud(
new cloud_t);
334 std::lock_guard guard{_viewPointsMutex};
335 if (idxVec.size() < _viewPoints.size())
337 idxVec.resize(_viewPoints.size());
339 for (std::size_t i = 0; i < idxVec.size(); ++i)
341 const auto& inVec = _viewPoints.at(i).clouds;
342 const auto idx = (idxVec.at(i)++) % inVec.size();
343 const auto& in = *std::any_cast<cloud_ptr_t>(inVec.at(idx));
344 auto& out = cloud->points;
345 out.insert(out.end(), in.begin(), in.end());
349 if (buf.gridSize > 0)
351 pcl::ApproximateVoxelGrid<PointType> grid;
352 grid.setLeafSize(Eigen::Vector3f::Constant(buf.gridSize));
353 grid.setInputCloud(cloud);
354 cloud_ptr_t tempCloud(
new cloud_t);
355 grid.filter(*tempCloud);
356 tempCloud.swap(cloud);
365 std::this_thread::sleep_until(timeBeg + std::chrono::milliseconds{dtms});