41 std::scoped_lock lock(pointCloudMutex);
43 pcl::console::setVerbosityLevel(pcl::console::L_ALWAYS);
55 icp.setMaximumIterations(100);
56 icp.setMaxCorrespondenceDistance(500.0);
58 modelKeypoints.reset(
new pcl::PointCloud<PointT>);
63 pcl::PointCloud<PointT>::Ptr cloudPtr(
new pcl::PointCloud<PointT>());
66 ARMARX_FATAL <<
"Could not find point cloud file in ArmarXDataPath: " << modelFileName;
69 else if (pcl::io::loadPCDFile<PointT>(modelFileName.c_str(), *cloudPtr) == -1)
71 ARMARX_FATAL <<
"unable to load point cloud from file " << modelFileName;
76 grid.setLeafSize(Eigen::Vector3f(leafSize, leafSize, leafSize));
78 grid.setInputCloud(cloudPtr);
79 grid.filter(*modelKeypoints);
84 modelDescriptors.reset(
new pcl::PointCloud<PointD>());
86 pcl::PointCloud<pcl::Normal>::Ptr pointCloudModelNormals(
87 new pcl::PointCloud<pcl::Normal>);
89 normalEstimation.setInputCloud(cloudPtr);
90 normalEstimation.setRadiusSearch(10.0);
91 normalEstimation.compute(*pointCloudModelNormals);
94 featureEstimation.setInputCloud(modelKeypoints);
95 featureEstimation.setInputNormals(pointCloudModelNormals);
96 featureEstimation.setSearchSurface(cloudPtr);
97 featureEstimation.setRadiusSearch(20.0);
98 featureEstimation.compute(*modelDescriptors);
100 matchSearchTree.setInputCloud(modelDescriptors);
104 clusterer.setInputCloud(modelKeypoints);
141 std::scoped_lock lock(pointCloudMutex);
143 pcl::PointCloud<PointL>::Ptr cloudPtr(
new pcl::PointCloud<PointL>());
147 ARMARX_WARNING <<
"Timeout or error while waiting for point cloud data"
156 float bestFitnessScore = std::numeric_limits<float>::max();
157 Eigen::Matrix4f bestTransform = Eigen::Matrix4f::Identity();
159 pcl::PointCloud<PointT>::Ptr afterICPResultPointCloud(
new pcl::PointCloud<PointT>());
160 pcl::PointCloud<PointT>::Ptr beforeICPResultPointCloud(
new pcl::PointCloud<PointT>());
162 std::map<uint32_t, pcl::PointIndices> labeledPointMap;
165 for (
auto& it : labeledPointMap)
170 pcl::PointCloud<PointT>::Ptr segment(
new pcl::PointCloud<PointT>());
171 copyPointCloud(*cloudPtr, it.second, *segment);
173 pcl::PointCloud<PointT>::Ptr transformedCloudPtr(
new pcl::PointCloud<PointT>());
174 pcl::PointCloud<PointT>::Ptr cloudDownsampledPtr(
new pcl::PointCloud<PointT>());
175 pcl::PointCloud<pcl::Normal>::Ptr normalPtr(
new pcl::PointCloud<pcl::Normal>());
176 pcl::PointCloud<PointD>::Ptr descriptorPtr(
new pcl::PointCloud<PointD>());
177 pcl::CorrespondencesPtr correspondencesPtr(
new pcl::Correspondences());
179 pcl::copyPointCloud(*segment, *transformedCloudPtr);
181 grid.setInputCloud(transformedCloudPtr);
182 grid.filter(*cloudDownsampledPtr);
186 std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f>> transformations;
190 Eigen::Vector4f centroid;
191 pcl::compute3DCentroid(*cloudDownsampledPtr, centroid);
193 for (
float i = 0.0; i < 360.0; i += 45.0)
196 Eigen::AngleAxisf(i * 180.0 /
M_PI, Eigen::Vector3f::UnitZ()));
198 Eigen::Matrix4f transform2 =
transform.matrix();
199 transform2.col(3) = centroid;
200 transformations.push_back(transform2);
206 normalEstimation.setInputCloud(transformedCloudPtr);
207 normalEstimation.compute(*normalPtr);
210 featureEstimation.setInputCloud(cloudDownsampledPtr);
211 featureEstimation.setInputNormals(normalPtr);
212 featureEstimation.setSearchSurface(transformedCloudPtr);
213 featureEstimation.compute(*descriptorPtr);
214 ARMARX_LOG <<
"found " << descriptorPtr->size() <<
" features";
218 for (
PointD& d : descriptorPtr->points)
225 std::vector<int> k_indices(k);
226 std::vector<float> k_sqr_distances(k);
227 int numNeighborsFound =
228 matchSearchTree.nearestKSearch(d, k, k_indices, k_sqr_distances);
230 if (numNeighborsFound == 1)
232 pcl::Correspondence corr(k_indices[0], i, k_sqr_distances[0]);
233 correspondencesPtr->push_back(corr);
238 std::vector<pcl::Correspondences> clusteredCorrespondences;
240 clusterer.setSceneCloud(cloudDownsampledPtr);
241 clusterer.setModelSceneCorrespondences(correspondencesPtr);
242 clusterer.recognize(transformations, clusteredCorrespondences);
244 ARMARX_LOG <<
" found " << transformations.size() <<
" transformations";
248 for (Eigen::Matrix4f& t : transformations)
250 pcl::PointCloud<PointT>::Ptr transformedModelPtr3(
new pcl::PointCloud<PointT>());
251 pcl::transformPointCloud(*modelKeypoints, *transformedModelPtr3, t);
253 *beforeICPResultPointCloud += *transformedModelPtr3;
255 icp.setInputTarget(cloudDownsampledPtr);
256 icp.setInputSource(modelKeypoints);
257 pcl::PointCloud<PointT>::Ptr registered(
new pcl::PointCloud<PointT>);
258 icp.align(*registered, t);
260 if (icp.hasConverged())
262 float fitnessScore = icp.getFitnessScore();
263 Eigen::Matrix4f
transform = icp.getFinalTransformation();
266 ARMARX_LOG <<
"fitness score " << fitnessScore;
268 pcl::PointCloud<PointT>::Ptr transformedModelPtr2(
269 new pcl::PointCloud<PointT>());
270 pcl::transformPointCloud(*modelKeypoints, *transformedModelPtr2,
transform);
272 *afterICPResultPointCloud += *transformedModelPtr2;
274 if (fitnessScore <= bestFitnessScore)
276 bestFitnessScore = fitnessScore;
279 std::scoped_lock lock(localizeMutex);
286 debugDrawerPrx->setPoseVisu(
287 "PointCloudLocalizer",
"label " + it.first, pose);
296 if (bestFitnessScore < 2000.0)
298 ARMARX_LOG <<
"best transformation " << bestTransform;
299 pcl::PointCloud<PointT>::Ptr BestResultPointCloud(
new pcl::PointCloud<PointT>());
300 pcl::transformPointCloud(*modelKeypoints, *BestResultPointCloud, bestTransform);