GICPAlignment.cpp
Go to the documentation of this file.
1 
18 #include <GICPAlignment.h>
19 #include <Filter.h>
20 #include <pcl/features/from_meshes.h>
21 #include <pcl/filters/filter.h>
22 
23 GICPAlignment::GICPAlignment(PointCloudRGB::Ptr target_cloud, PointCloudRGB::Ptr source_cloud, bool use_covariances)
24  : aligned_cloud_(new PointCloudRGB), backup_cloud_(new PointCloudRGB)
25 {
26  target_cloud_ = target_cloud;
27  source_cloud_ = source_cloud;
28  covariances_ = use_covariances;
29  tf_epsilon_ = 4e-3;
30  max_iter_ = 100;
31  max_corresp_distance_ = 4e-2;
32  ransac_outlier_th_ = 1.0;
33  transform_exists_ = false;
34  fine_tf_ = Eigen::Matrix4f::Identity();
35 }
36 
38 {
40 
41  if(covariances_)
43 
44  fineAlignment();
46 }
47 
49 {
50  gicp_.setMaximumIterations(max_iter_);
51  gicp_.setMaxCorrespondenceDistance(max_corresp_distance_);
52  gicp_.setTransformationEpsilon(tf_epsilon_);
53  gicp_.setRANSACOutlierRejectionThreshold(ransac_outlier_th_);
54 }
55 
57 {
58  double target_res = Utils::computeCloudResolution(target_cloud_);
59  double source_res = Utils::computeCloudResolution(source_cloud_);
60  double normal_radius = (target_res + source_res) * 2.0; // doubled
61 
62  PointCloudNormal::Ptr normals(new PointCloudNormal);
63  Utils::getNormals(cloud, normal_radius, normals);
64 
65  pcl::IndicesPtr nan_indices(new std::vector<int>);
66  pcl::removeNaNNormalsFromPointCloud(*normals, *normals, *nan_indices);
67  Filter::extractIndices(cloud, cloud, nan_indices);
68 
69  // get covariances
70  pcl::features::computeApproximateCovariances(*cloud, *normals, *covs);
71 }
72 
74 {
77 
78  ROS_INFO("Extract covariances from clouds");
79  getCovariances(source_cloud_, source_covariances);
80  getCovariances(target_cloud_, target_covariances);
81 
82  gicp_.setSourceCovariances(source_covariances);
83  gicp_.setTargetCovariances(target_covariances);
84 }
85 
87 {
88  ROS_INFO("Perform GICP with %d iterations", gicp_.getMaximumIterations());
89  gicp_.setInputSource(source_cloud_);
90  gicp_.setInputTarget(target_cloud_);
91 
92  ros::Time begin = ros::Time::now();
93 
94  PointCloudRGB::Ptr aligned_cloud(new PointCloudRGB);
95  ROS_INFO("This step may take a while ...");
96  gicp_.align(*aligned_cloud);
97 
98  ros::Duration exec_time = ros::Time::now() - begin;
99  ROS_INFO("GICP time: %lf s", exec_time.toSec());
100 
101  if (gicp_.hasConverged())
102  {
103  ROS_INFO("Converged in %f FitnessScore", gicp_.getFitnessScore());
104  fine_tf_ = gicp_.getFinalTransformation();
106  }
107  else
108  ROS_ERROR("GICP no converge");
109 }
110 
111 void GICPAlignment::iterateFineAlignment(PointCloudRGB::Ptr cloud)
112 {
113  backUp(cloud); // save a copy to restore in case iteration give wrong results
114 
115  ROS_INFO("Computing iteration...");
116  gicp_.align(*cloud);
117 
118  if (gicp_.hasConverged())
119  {
120  Eigen::Matrix4f temp_tf = gicp_.getFinalTransformation();
121  fine_tf_ = temp_tf * fine_tf_;
122  Utils::printTransform(fine_tf_);
123  ROS_INFO("Converged in %f FitnessScore", gicp_.getFitnessScore());
124  }
125  else
126  ROS_ERROR("GICP no converge");
127 }
128 
130 {
132 }
133 
134 void GICPAlignment::backUp(PointCloudRGB::Ptr cloud)
135 {
136  pcl::copyPointCloud(*cloud, *backup_cloud_);
137 }
138 
140 {
141  pcl::copyPointCloud(*backup_cloud_, *aligned_cloud_);
142 }
143 
144 void GICPAlignment::applyTFtoCloud(PointCloudRGB::Ptr cloud)
145 {
146  pcl::transformPointCloud(*cloud, *aligned_cloud_, fine_tf_);
147 }
148 
150 {
151  if (!transform_exists_)
152  ROS_ERROR("No transform yet. Please run algorithm");
153  return fine_tf_;
154 }
155 
156 void GICPAlignment::getAlignedCloud(PointCloudRGB::Ptr aligned_cloud)
157 {
158  pcl::copyPointCloud(*aligned_cloud_, *aligned_cloud);
159 }
160 
161 void GICPAlignment::getAlignedCloudROSMsg(sensor_msgs::PointCloud2& aligned_cloud_msg)
162 {
163  Utils::cloudToROSMsg(aligned_cloud_, aligned_cloud_msg);
164 }
165 
166 void GICPAlignment::setSourceCloud(PointCloudRGB::Ptr source_cloud)
167 {
168  source_cloud_ = source_cloud;
169 }
170 
171 void GICPAlignment::setTargetCloud(PointCloudRGB::Ptr target_cloud)
172 {
173  target_cloud_ = target_cloud;
174 }
175 
177 {
178  max_iter_ = iterations;
180 }
181 
182 void GICPAlignment::setTfEpsilon(double tf_epsilon)
183 {
184  tf_epsilon_ = tf_epsilon;
186 }
187 
188 void GICPAlignment::setMaxCorrespondenceDistance(int max_corresp_distance)
189 {
190  max_corresp_distance_ = max_corresp_distance;
192 }
193 
194 void GICPAlignment::setRANSACOutlierTh(int ransac_threshold)
195 {
196  ransac_outlier_th_ = ransac_threshold;
198 }
static void printTransform(const Eigen::Matrix4f &transform)
Print on console transform values with matrix format.
Definition: Utils.cpp:176
double tf_epsilon_
Value for TFEpsilon for GICP. Define the convergence criterion.
static bool getNormals(PointCloudRGB::Ptr &cloud, double normal_radius, PointCloudNormal::Ptr &normals)
Get the normals for input cloud with specified normal&#39;s radius.
Definition: Utils.cpp:27
void undo()
Undo last iteration and back up results.
void getCovariances(PointCloudRGB::Ptr cloud, boost::shared_ptr< CovariancesVector > covs)
Get the covariances from cloud.
static bool isValidTransform(Eigen::Matrix4f transform)
Check whether transform contains valid data and is not NaN.
Definition: Utils.cpp:71
double ransac_outlier_th_
Value for RANSAC outlier threshold.
std::vector< Eigen::Matrix3d, Eigen::aligned_allocator< Eigen::Matrix3d > > CovariancesVector
Definition: GICPAlignment.h:37
PointCloudRGB::Ptr backup_cloud_
Save aligned pointcloud to restore if undo.
void run()
Perform GICP alignment.
bool covariances_
If true, perform GICP with convariances.
void setTargetCloud(PointCloudRGB::Ptr target_cloud)
Set the Target Cloud object.
void configParameters()
Set parameters to compute GICP alignment.
void iterate()
Do more iterations of GICP alignment.
void applyTFtoCloud(PointCloudRGB::Ptr cloud)
Once GICP is finished, apply fine transformation to source cloud.
void setTfEpsilon(double tf_epsilon)
Set the Tf Epsilon object.
static void cloudToROSMsg(PointCloudRGB::Ptr cloud, sensor_msgs::PointCloud2 &cloud_msg, const std::string &frameid="world")
Convert XYZRGB cloud to PointCloud2.
Definition: Utils.cpp:100
#define ROS_INFO(...)
pcl::PointCloud< pcl::Normal > PointCloudNormal
Definition: GICPAlignment.h:36
GICPAlignment(PointCloudRGB::Ptr target_cloud, PointCloudRGB::Ptr source_cloud, bool use_covariances)
Construct a new GICPAlignment object.
void getAlignedCloud(PointCloudRGB::Ptr aligned_cloud)
Get the aligned cloud object.
void setSourceCloud(PointCloudRGB::Ptr source_cloud)
Set the Source Cloud object.
PointCloudRGB::Ptr source_cloud_
Source pointcloud.
bool transform_exists_
If true, fine transformation is finished.
Definition: GICPAlignment.h:53
pcl::PointCloud< pcl::PointXYZRGB > PointCloudRGB
Definition: GICPAlignment.h:35
static double computeCloudResolution(PointCloudXYZ::Ptr cloud)
Obtain the resolution of the cloud.
Definition: Utils.cpp:114
void setRANSACOutlierTh(int ransac_threshold)
Set the RANSAC Outlier threshold.
void fineAlignment()
Apply GICP to perform fine alignment.
double max_corresp_distance_
Value for Max CorrespondenceDistance for GICP.
void setMaxCorrespondenceDistance(int max_corresp_distance)
Set the Max Correspondence Distance object.
void iterateFineAlignment(PointCloudRGB::Ptr cloud)
Re-iterate GICP and save new aligned cloud.
void setMaxIterations(int iterations)
Set the Max Iterations object.
void applyCovariances()
Apply the covariances before running GICP.
pcl::GeneralizedIterativeClosestPoint< pcl::PointXYZRGB, pcl::PointXYZRGB > gicp_
GICP object.
void getAlignedCloudROSMsg(sensor_msgs::PointCloud2 &aligned_cloud_msg)
Get the aligned cloud msg in PointCloud2 format.
PointCloudRGB::Ptr aligned_cloud_
Source pointcloud aligned with target cloud.
static Time now()
Eigen::Matrix4f fine_tf_
Transformation matrix as result of GICP alignment.
Eigen::Matrix4f getFineTransform()
Get the fine transform object.
PointCloudRGB::Ptr target_cloud_
Target pointcloud.
void backUp(PointCloudRGB::Ptr cloud)
Store cloud as backup cloud.
#define ROS_ERROR(...)
int max_iter_
Maximum number of GICP iterations.


leica_point_cloud_processing
Author(s): Ines Lara Sicilia
autogenerated on Fri Feb 5 2021 03:20:30