Point Cloud Library (PCL) 1.15.1-dev
Loading...
Searching...
No Matches
ndt.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2010-2012, Willow Garage, Inc.
6 * Copyright (c) 2012-, Open Perception, Inc.
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * * Neither the name of the copyright holder(s) nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 *
39 */
40
41#pragma once
42
43#include <pcl/common/utils.h>
44#include <pcl/filters/voxel_grid_covariance.h>
45#include <pcl/registration/registration.h>
46#include <pcl/memory.h>
47#include <pcl/pcl_macros.h>
48
49#include <unsupported/Eigen/NonLinearOptimization>
50
51namespace pcl {
52
54 RADIUS, // Original
55 DIRECT27, // VoxelGridCovariance::getAllNeighborsAtPoint
56 DIRECT26, // VoxelGridCovariance::getNeighborhoodAtPoint
57 DIRECT7, // VoxelGridCovariance::getFaceNeighborsAtPoint
58 DIRECT1 // VoxelGridCovariance::getVoxelAtPoint
59};
60
61/** \brief A 3D Normal Distribution Transform registration implementation for
62 * point cloud data.
63 * \note For more information please see <b>Magnusson, M. (2009). The
64 * Three-Dimensional Normal-Distributions Transform — an Efficient Representation
65 * for Registration, Surface Analysis, and Loop Detection. PhD thesis, Orebro
66 * University. Orebro Studies in Technology 36.</b>, <b>More, J., and Thuente,
67 * D. (1994). Line Search Algorithm with Guaranteed Sufficient Decrease In ACM
68 * Transactions on Mathematical Software.</b> and Sun, W. and Yuan, Y, (2006)
69 * Optimization Theory and Methods: Nonlinear Programming. 89-100
70 * \note Math refactored by Todor Stoyanov.
71 * \author Brian Okorn (Space and Naval Warfare Systems Center Pacific)
72 * \ingroup registration
73 */
74template <typename PointSource, typename PointTarget, typename Scalar = float>
76: public Registration<PointSource, PointTarget, Scalar> {
77protected:
80 using PointCloudSourcePtr = typename PointCloudSource::Ptr;
81 using PointCloudSourceConstPtr = typename PointCloudSource::ConstPtr;
82
85 using PointCloudTargetPtr = typename PointCloudTarget::Ptr;
86 using PointCloudTargetConstPtr = typename PointCloudTarget::ConstPtr;
87
90
91 /** \brief Typename of searchable voxel grid containing mean and
92 * covariance. */
94 /** \brief Typename of pointer to searchable voxel grid. */
96 /** \brief Typename of const pointer to searchable voxel grid. */
98 /** \brief Typename of const pointer to searchable voxel grid leaf. */
100
101public:
102 using Ptr =
103 shared_ptr<NormalDistributionsTransform<PointSource, PointTarget, Scalar>>;
104 using ConstPtr =
105 shared_ptr<const NormalDistributionsTransform<PointSource, PointTarget, Scalar>>;
106 using Vector3 = typename Eigen::Matrix<Scalar, 3, 1>;
108 using Affine3 = typename Eigen::Transform<Scalar, 3, Eigen::Affine>;
109
110 /** \brief Constructor. Sets \ref outlier_ratio_ to 0.55, \ref step_size_ to
111 * 0.1 and \ref resolution_ to 1.0
112 */
114
115 /** \brief Empty destructor */
116 ~NormalDistributionsTransform() override = default;
117
118 /** \brief Provide a pointer to the input target (e.g., the point cloud that
119 * we want to align the input source to).
120 * \param[in] cloud the input point cloud target
121 */
122 inline void
128
129 /** \brief Set/change the voxel grid resolution.
130 * \param[in] resolution side length of voxels
131 */
132 inline void
133 setResolution(float resolution)
134 {
135 // Prevents unnecessary voxel initiations
136 if (resolution_ != resolution) {
137 resolution_ = resolution;
138 if (target_) { // init() needs target_
139 init();
140 }
141 }
142 }
143
144 /** \brief Set the minimum number of points required for a cell to be used (must be 3
145 * or greater for covariance calculation). Calls the function of the underlying
146 * VoxelGridCovariance. This function must be called before `setInputTarget` and
147 * `setResolution`. \param[in] min_points_per_voxel the minimum number of points
148 * required for a voxel to be used
149 */
150 inline void
151 setMinPointPerVoxel(unsigned int min_points_per_voxel)
152 {
153 target_cells_.setMinPointPerVoxel(min_points_per_voxel);
154 }
155
156 /** \brief Get voxel grid resolution.
157 * \return side length of voxels
158 */
159 inline float
161 {
162 return resolution_;
163 }
164
165 /** \brief Get the newton line search maximum step length.
166 * \return maximum step length
167 */
168 inline double
170 {
171 return step_size_;
172 }
173
174 /** \brief Set/change the newton line search maximum step length.
175 * \param[in] step_size maximum step length
176 */
177 inline void
178 setStepSize(double step_size)
179 {
180 step_size_ = step_size;
181 }
182
183 /** \brief Initialize the scheduler and set the number of threads to use.
184 * \param[in] nr_threads the number of hardware threads to use (0 sets the value back
185 * to automatic)
186 */
187 inline void
188 setNumberOfThreads(unsigned int nr_threads = 0);
189
190 /** \brief Set neighborhood search method.
191 * \param[in] method neighborhood search method
192 */
193 inline void
195 {
196 search_method_ = method;
197 }
198
199 /** \brief Get the point cloud outlier ratio.
200 * \return outlier ratio
201 */
202 inline double
204 {
205 return outlier_ratio_;
206 }
207
208 /** \brief Get the point cloud outlier ratio.
209 * \return outlier ratio
210 */
212 18,
213 "The method `getOulierRatio` has been renamed to "
214 "`getOutlierRatio`.")
215 inline double
217 {
218 return outlier_ratio_;
219 }
220
221 /** \brief Set/change the point cloud outlier ratio.
222 * \param[in] outlier_ratio outlier ratio
223 */
224 inline void
225 setOutlierRatio(double outlier_ratio)
226 {
227 outlier_ratio_ = outlier_ratio;
228 }
229
231 18,
232 "The method `setOulierRatio` has been renamed to "
233 "`setOutlierRatio`.")
234 /** \brief Set/change the point cloud outlier ratio.
235 * \param[in] outlier_ratio outlier ratio
236 */
237 inline void
238 setOulierRatio(double outlier_ratio)
239 {
240 outlier_ratio_ = outlier_ratio;
241 }
242
243 /** \brief Get the registration alignment likelihood.
244 * \return transformation likelihood
245 */
246 inline double
248 {
249 return trans_likelihood_;
250 }
251
252 /** \brief Get the registration alignment probability.
253 * \return transformation probability
254 */
256 16,
257 "The method `getTransformationProbability` has been renamed to "
258 "`getTransformationLikelihood`.")
259 inline double
261 {
262 return trans_likelihood_;
263 }
264
265 /** \brief Get the number of iterations required to calculate alignment.
266 * \return final number of iterations
267 */
268 inline int
270 {
271 return nr_iterations_;
272 }
273
274 /** \brief Get access to the `VoxelGridCovariance` generated from target cloud
275 * containing point means and covariances. Set the input target cloud before calling
276 * this. Useful for debugging, e.g.
277 * \code
278 * pcl::PointCloud<PointXYZ> visualize_cloud;
279 * ndt.getTargetCells().getDisplayCloud(visualize_cloud);
280 * \endcode
281 */
282 inline const TargetGrid&
284 {
285 return target_cells_;
286 }
287
288 /** \brief Convert 6 element transformation vector to affine transformation.
289 * \param[in] x transformation vector of the form [x, y, z, roll, pitch, yaw]
290 * \param[out] trans affine transform corresponding to given transformation
291 * vector
292 */
293 static void
294 convertTransform(const Eigen::Matrix<double, 6, 1>& x, Affine3& trans)
295 {
296 trans = Eigen::Translation<Scalar, 3>(x.head<3>().cast<Scalar>()) *
297 Eigen::AngleAxis<Scalar>(static_cast<Scalar>(x(3)), Vector3::UnitX()) *
298 Eigen::AngleAxis<Scalar>(static_cast<Scalar>(x(4)), Vector3::UnitY()) *
299 Eigen::AngleAxis<Scalar>(static_cast<Scalar>(x(5)), Vector3::UnitZ());
300 }
301
302 /** \brief Convert 6 element transformation vector to transformation matrix.
303 * \param[in] x transformation vector of the form [x, y, z, roll, pitch, yaw]
304 * \param[out] trans 4x4 transformation matrix corresponding to given
305 * transformation vector
306 */
307 static void
308 convertTransform(const Eigen::Matrix<double, 6, 1>& x, Matrix4& trans)
309 {
310 Affine3 _affine;
311 convertTransform(x, _affine);
312 trans = _affine.matrix();
313 }
314
315protected:
316 using Registration<PointSource, PointTarget, Scalar>::reg_name_;
317 using Registration<PointSource, PointTarget, Scalar>::getClassName;
318 using Registration<PointSource, PointTarget, Scalar>::input_;
319 using Registration<PointSource, PointTarget, Scalar>::indices_;
320 using Registration<PointSource, PointTarget, Scalar>::target_;
321 using Registration<PointSource, PointTarget, Scalar>::nr_iterations_;
322 using Registration<PointSource, PointTarget, Scalar>::max_iterations_;
323 using Registration<PointSource, PointTarget, Scalar>::previous_transformation_;
324 using Registration<PointSource, PointTarget, Scalar>::final_transformation_;
325 using Registration<PointSource, PointTarget, Scalar>::transformation_;
326 using Registration<PointSource, PointTarget, Scalar>::transformation_epsilon_;
327 using Registration<PointSource, PointTarget, Scalar>::
329 using Registration<PointSource, PointTarget, Scalar>::converged_;
330 using Registration<PointSource, PointTarget, Scalar>::corr_dist_threshold_;
331 using Registration<PointSource, PointTarget, Scalar>::inlier_threshold_;
332
333 using Registration<PointSource, PointTarget, Scalar>::update_visualizer_;
334
335 /** \brief Estimate the transformation and returns the transformed source
336 * (input) as output.
337 * \param[out] output the resultant input transformed point cloud dataset
338 */
339 virtual void
341 {
342 computeTransformation(output, Matrix4::Identity());
343 }
344
345 /** \brief Estimate the transformation and returns the transformed source
346 * (input) as output.
347 * \param[out] output the resultant input transformed point cloud dataset
348 * \param[in] guess the initial gross estimation of the transformation
349 */
350 void
351 computeTransformation(PointCloudSource& output, const Matrix4& guess) override;
352
353 /** \brief Initiate covariance voxel structure. */
354 void inline init()
355 {
358 // Initiate voxel structure.
359 target_cells_.filter(true);
360 PCL_DEBUG("[pcl::%s::init] Computed voxel structure, got %zu voxels with valid "
361 "normal distributions.\n",
362 getClassName().c_str(),
363 target_cells_.getCentroids()->size());
364 }
365
366 /** \brief Compute derivatives of likelihood function w.r.t. the
367 * transformation vector.
368 * \note Equation 6.10, 6.12 and 6.13 [Magnusson 2009].
369 * \param[out] score_gradient the gradient vector of the likelihood function
370 * w.r.t. the transformation vector
371 * \param[out] hessian the hessian matrix of the likelihood function
372 * w.r.t. the transformation vector
373 * \param[in] trans_cloud transformed point cloud
374 * \param[in] transform the current transform vector
375 * \param[in] compute_hessian flag to calculate hessian, unnecessary for step
376 * calculation.
377 */
378 double
379 computeDerivatives(Eigen::Matrix<double, 6, 1>& score_gradient,
380 Eigen::Matrix<double, 6, 6>& hessian,
381 const PointCloudSource& trans_cloud,
382 const Eigen::Matrix<double, 6, 1>& transform,
383 bool compute_hessian = true);
384
385 /** \brief Compute individual point contributions to derivatives of
386 * likelihood function w.r.t. the transformation vector.
387 * \note Equation 6.10, 6.12 and 6.13 [Magnusson 2009].
388 * \param[in,out] score_gradient the gradient vector of the likelihood
389 * function w.r.t. the transformation vector
390 * \param[in,out] hessian the hessian matrix of the likelihood function
391 * w.r.t. the transformation vector
392 * \param[in] x_trans transformed point minus mean of occupied covariance
393 * voxel
394 * \param[in] c_inv covariance of occupied covariance voxel
395 * \param[in] point_jacobian The first order derivative of the transformation of a
396 * point w.r.t. the transform vector, \f$ J_E \f$ in Equation 6.18 [Magnusson 2009]
397 * \param[in] point_hessian The second order derivative of the transformation of a
398 * point w.r.t. the transform vector, \f$ H_E \f$ in Equation 6.20 [Magnusson 2009].
399 * If this is a nullptr, the hessian is not calculated (unnecessary for step
400 * calculation)
401 */
402 double
403 updateDerivatives(Eigen::Matrix<double, 6, 1>& score_gradient,
404 Eigen::Matrix<double, 6, 6>& hessian,
405 const Eigen::Vector3d& x_trans,
406 const Eigen::Matrix3d& c_inv,
407 const Eigen::Matrix<double, 3, 6>& point_jacobian,
408 const Eigen::Matrix<double, 18, 6>* point_hessian) const;
409
410 /** \brief Compute individual point contributions to derivatives of
411 * likelihood function w.r.t. the transformation vector.
412 * \note Equation 6.10, 6.12 and 6.13 [Magnusson 2009].
413 * \param[in,out] score_gradient the gradient vector of the likelihood
414 * function w.r.t. the transformation vector
415 * \param[in,out] hessian the hessian matrix of the likelihood function
416 * w.r.t. the transformation vector
417 * \param[in] x_trans transformed point minus mean of occupied covariance
418 * voxel
419 * \param[in] c_inv covariance of occupied covariance voxel
420 * \param[in] compute_hessian flag to calculate hessian, unnecessary for step
421 * calculation.
422 * \warning This overload uses the global variables point_jacobian_, point_hessian_
423 */
424 double
425 updateDerivatives(Eigen::Matrix<double, 6, 1>& score_gradient,
426 Eigen::Matrix<double, 6, 6>& hessian,
427 const Eigen::Vector3d& x_trans,
428 const Eigen::Matrix3d& c_inv,
429 bool compute_hessian = true) const;
430
431 /** \brief Precompute angular components of derivatives.
432 * \note Equation 6.19 and 6.21 [Magnusson 2009].
433 * \param[in] transform the current transform vector
434 * \param[in] compute_hessian flag to calculate hessian, unnecessary for step
435 * calculation.
436 */
437 void
438 computeAngleDerivatives(const Eigen::Matrix<double, 6, 1>& transform,
439 bool compute_hessian = true);
440
441 /** \brief Compute point derivatives.
442 * \note Equation 6.18-21 [Magnusson 2009].
443 * \param[in] x point from the input cloud
444 * \param[out] point_jacobian The first order derivative of the transformation of a
445 * point w.r.t. the transform vector, \f$ J_E \f$ in Equation 6.18 [Magnusson 2009]
446 * \param[out] point_hessian The second order derivative of the transformation of a
447 * point w.r.t. the transform vector, \f$ H_E \f$ in Equation 6.20 [Magnusson 2009].
448 * If this is a nullptr, the hessian is not calculated (unnecessary for step
449 * calculation)
450 */
451 void
452 computePointDerivatives(const Eigen::Vector3d& x,
453 Eigen::Matrix<double, 3, 6>& point_jacobian,
454 Eigen::Matrix<double, 18, 6>* point_hessian) const;
455
456 /** \brief Compute point derivatives.
457 * \note Equation 6.18-21 [Magnusson 2009].
458 * \param[in] x point from the input cloud
459 * \param[in] compute_hessian flag to calculate hessian, unnecessary for step
460 * calculation.
461 * \warning This overload uses the global variables angular_jacobian_,
462 * angular_hessian_, point_jacobian_, point_hessian_
463 */
464 void
465 computePointDerivatives(const Eigen::Vector3d& x, bool compute_hessian = true);
466
467 /** \brief Compute hessian of likelihood function w.r.t. the transformation
468 * vector.
469 * \note Equation 6.13 [Magnusson 2009].
470 * \param[out] hessian the hessian matrix of the likelihood function
471 * w.r.t. the transformation vector
472 * \param[in] trans_cloud transformed point cloud
473 */
474 void
475 computeHessian(Eigen::Matrix<double, 6, 6>& hessian,
476 const PointCloudSource& trans_cloud);
477
478 /** \brief Compute individual point contributions to hessian of likelihood
479 * function w.r.t. the transformation vector.
480 * \note Equation 6.13 [Magnusson 2009].
481 * \param[in,out] hessian the hessian matrix of the likelihood function
482 * w.r.t. the transformation vector
483 * \param[in] x_trans transformed point minus mean of occupied covariance
484 * voxel
485 * \param[in] c_inv covariance of occupied covariance voxel
486 * \param[in] point_jacobian The first order derivative of the transformation of a
487 * point w.r.t. the transform vector, \f$ J_E \f$ in Equation 6.18 [Magnusson 2009]
488 * \param[in] point_hessian The second order derivative of the transformation of a
489 * point w.r.t. the transform vector, \f$ H_E \f$ in Equation 6.20 [Magnusson 2009]
490 */
491 void
492 updateHessian(Eigen::Matrix<double, 6, 6>& hessian,
493 const Eigen::Vector3d& x_trans,
494 const Eigen::Matrix3d& c_inv,
495 const Eigen::Matrix<double, 3, 6>& point_jacobian,
496 const Eigen::Matrix<double, 18, 6>& point_hessian) const;
497
498 /** \brief Compute individual point contributions to hessian of likelihood
499 * function w.r.t. the transformation vector.
500 * \note Equation 6.13 [Magnusson 2009].
501 * \param[in,out] hessian the hessian matrix of the likelihood function
502 * w.r.t. the transformation vector
503 * \param[in] x_trans transformed point minus mean of occupied covariance
504 * voxel
505 * \param[in] c_inv covariance of occupied covariance voxel
506 * \warning This overload uses the global variables point_jacobian_ and point_hessian_
507 */
508 void
509 updateHessian(Eigen::Matrix<double, 6, 6>& hessian,
510 const Eigen::Vector3d& x_trans,
511 const Eigen::Matrix3d& c_inv) const;
512
513 /** \brief Compute line search step length and update transform and
514 * likelihood derivatives using More-Thuente method.
515 * \note Search Algorithm [More, Thuente 1994]
516 * \param[in] transform initial transformation vector, \f$ x \f$ in Equation
517 * 1.3 (Moore, Thuente 1994) and \f$ \vec{p} \f$ in Algorithm 2 [Magnusson
518 * 2009]
519 * \param[in] step_dir descent direction, \f$ p \f$ in Equation 1.3 (Moore,
520 * Thuente 1994) and \f$ \delta \vec{p} \f$ normalized in Algorithm 2
521 * [Magnusson 2009]
522 * \param[in] step_init initial step length estimate, \f$ \alpha_0 \f$ in
523 * Moore-Thuente (1994) and the normal of \f$ \delta \vec{p} \f$ in Algorithm
524 * 2 [Magnusson 2009]
525 * \param[in] step_max maximum step length, \f$ \alpha_max \f$ in
526 * Moore-Thuente (1994)
527 * \param[in] step_min minimum step length, \f$ \alpha_min \f$ in
528 * Moore-Thuente (1994)
529 * \param[out] score final score function value, \f$ f(x + \alpha p) \f$ in
530 * Equation 1.3 (Moore, Thuente 1994) and \f$ score \f$ in Algorithm 2
531 * [Magnusson 2009]
532 * \param[in,out] score_gradient gradient of score function w.r.t.
533 * transformation vector, \f$ f'(x + \alpha p) \f$ in Moore-Thuente (1994) and
534 * \f$ \vec{g} \f$ in Algorithm 2 [Magnusson 2009]
535 * \param[out] hessian hessian of score function w.r.t. transformation vector,
536 * \f$ f''(x + \alpha p) \f$ in Moore-Thuente (1994) and \f$ H \f$ in
537 * Algorithm 2 [Magnusson 2009]
538 * \param[in,out] trans_cloud transformed point cloud, \f$ X \f$ transformed
539 * by \f$ T(\vec{p},\vec{x}) \f$ in Algorithm 2 [Magnusson 2009]
540 * \return final step length
541 */
542 double
543 computeStepLengthMT(const Eigen::Matrix<double, 6, 1>& transform,
544 Eigen::Matrix<double, 6, 1>& step_dir,
545 double step_init,
546 double step_max,
547 double step_min,
548 double& score,
549 Eigen::Matrix<double, 6, 1>& score_gradient,
550 Eigen::Matrix<double, 6, 6>& hessian,
551 PointCloudSource& trans_cloud);
552
553 /** \brief Update interval of possible step lengths for More-Thuente method,
554 * \f$ I \f$ in More-Thuente (1994)
555 * \note Updating Algorithm until some value satisfies \f$ \psi(\alpha_k) \leq
556 * 0 \f$ and \f$ \phi'(\alpha_k) \geq 0 \f$ and Modified Updating Algorithm
557 * from then on [More, Thuente 1994].
558 * \param[in,out] a_l first endpoint of interval \f$ I \f$, \f$ \alpha_l \f$
559 * in Moore-Thuente (1994)
560 * \param[in,out] f_l value at first endpoint, \f$ f_l \f$ in Moore-Thuente
561 * (1994), \f$ \psi(\alpha_l) \f$ for Update Algorithm and \f$ \phi(\alpha_l)
562 * \f$ for Modified Update Algorithm
563 * \param[in,out] g_l derivative at first endpoint, \f$ g_l \f$ in
564 * Moore-Thuente (1994), \f$ \psi'(\alpha_l) \f$ for Update Algorithm and \f$
565 * \phi'(\alpha_l) \f$ for Modified Update Algorithm
566 * \param[in,out] a_u second endpoint of interval \f$ I \f$, \f$ \alpha_u \f$
567 * in Moore-Thuente (1994)
568 * \param[in,out] f_u value at second endpoint, \f$ f_u \f$ in Moore-Thuente
569 * (1994), \f$ \psi(\alpha_u) \f$ for Update Algorithm and \f$ \phi(\alpha_u)
570 * \f$ for Modified Update Algorithm
571 * \param[in,out] g_u derivative at second endpoint, \f$ g_u \f$ in
572 * Moore-Thuente (1994), \f$ \psi'(\alpha_u) \f$ for Update Algorithm and \f$
573 * \phi'(\alpha_u) \f$ for Modified Update Algorithm
574 * \param[in] a_t trial value, \f$ \alpha_t \f$ in Moore-Thuente (1994)
575 * \param[in] f_t value at trial value, \f$ f_t \f$ in Moore-Thuente (1994),
576 * \f$ \psi(\alpha_t) \f$ for Update Algorithm and \f$ \phi(\alpha_t) \f$ for
577 * Modified Update Algorithm
578 * \param[in] g_t derivative at trial value, \f$ g_t \f$ in Moore-Thuente
579 * (1994), \f$ \psi'(\alpha_t) \f$ for Update Algorithm and \f$
580 * \phi'(\alpha_t) \f$ for Modified Update Algorithm
581 * \return if interval converges
582 */
583 bool
584 updateIntervalMT(double& a_l,
585 double& f_l,
586 double& g_l,
587 double& a_u,
588 double& f_u,
589 double& g_u,
590 double a_t,
591 double f_t,
592 double g_t) const;
593
594 /** \brief Select new trial value for More-Thuente method.
595 * \note Trial Value Selection [More, Thuente 1994], \f$ \psi(\alpha_k) \f$ is
596 * used for \f$ f_k \f$ and \f$ g_k \f$ until some value satisfies the test
597 * \f$ \psi(\alpha_k) \leq 0 \f$ and \f$ \phi'(\alpha_k) \geq 0 \f$ then \f$
598 * \phi(\alpha_k) \f$ is used from then on.
599 * \note Interpolation Minimizer equations from Optimization Theory and
600 * Methods: Nonlinear Programming By Wenyu Sun, Ya-xiang Yuan (89-100).
601 * \param[in] a_l first endpoint of interval \f$ I \f$, \f$ \alpha_l \f$ in
602 * Moore-Thuente (1994)
603 * \param[in] f_l value at first endpoint, \f$ f_l \f$ in Moore-Thuente (1994)
604 * \param[in] g_l derivative at first endpoint, \f$ g_l \f$ in Moore-Thuente
605 * (1994)
606 * \param[in] a_u second endpoint of interval \f$ I \f$, \f$ \alpha_u \f$ in
607 * Moore-Thuente (1994)
608 * \param[in] f_u value at second endpoint, \f$ f_u \f$ in Moore-Thuente
609 * (1994)
610 * \param[in] g_u derivative at second endpoint, \f$ g_u \f$ in Moore-Thuente
611 * (1994)
612 * \param[in] a_t previous trial value, \f$ \alpha_t \f$ in Moore-Thuente
613 * (1994)
614 * \param[in] f_t value at previous trial value, \f$ f_t \f$ in Moore-Thuente
615 * (1994)
616 * \param[in] g_t derivative at previous trial value, \f$ g_t \f$ in
617 * Moore-Thuente (1994)
618 * \return new trial value
619 */
620 double
621 trialValueSelectionMT(double a_l,
622 double f_l,
623 double g_l,
624 double a_u,
625 double f_u,
626 double g_u,
627 double a_t,
628 double f_t,
629 double g_t) const;
630
631 /** \brief Auxiliary function used to determine endpoints of More-Thuente
632 * interval.
633 * \note \f$ \psi(\alpha) \f$ in Equation 1.6 (Moore, Thuente 1994)
634 * \param[in] a the step length, \f$ \alpha \f$ in More-Thuente (1994)
635 * \param[in] f_a function value at step length a, \f$ \phi(\alpha) \f$ in
636 * More-Thuente (1994)
637 * \param[in] f_0 initial function value, \f$ \phi(0) \f$ in Moore-Thuente
638 * (1994)
639 * \param[in] g_0 initial function gradient, \f$ \phi'(0) \f$ in More-Thuente
640 * (1994)
641 * \param[in] mu the step length, constant \f$ \mu \f$ in Equation 1.1 [More,
642 * Thuente 1994]
643 * \return sufficient decrease value
644 */
645 inline double
647 double a, double f_a, double f_0, double g_0, double mu = 1.e-4) const
648 {
649 return f_a - f_0 - mu * g_0 * a;
650 }
651
652 /** \brief Auxiliary function derivative used to determine endpoints of
653 * More-Thuente interval.
654 * \note \f$ \psi'(\alpha) \f$, derivative of Equation 1.6 (Moore, Thuente
655 * 1994)
656 * \param[in] g_a function gradient at step length a, \f$ \phi'(\alpha) \f$ in
657 * More-Thuente (1994)
658 * \param[in] g_0 initial function gradient, \f$ \phi'(0) \f$ in More-Thuente
659 * (1994)
660 * \param[in] mu the step length, constant \f$ \mu \f$ in Equation 1.1 [More,
661 * Thuente 1994]
662 * \return sufficient decrease derivative
663 */
664 inline double
665 auxilaryFunction_dPsiMT(double g_a, double g_0, double mu = 1.e-4) const
666 {
667 return g_a - mu * g_0;
668 }
669
670 /** \brief The voxel grid generated from target cloud containing point means
671 * and covariances. */
673
674 /** \brief The side length of voxels. */
675 float resolution_{1.0f};
676
677 /** \brief The maximum step length. */
678 double step_size_{0.1};
679
680 /** \brief The ratio of outliers of points w.r.t. a normal distribution,
681 * Equation 6.7 [Magnusson 2009]. */
682 double outlier_ratio_{0.55};
683
684 /** \brief The normalization constants used fit the point distribution to a
685 * normal distribution, Equation 6.8 [Magnusson 2009]. */
686 double gauss_d1_{0.0}, gauss_d2_{0.0};
687
688 /** \brief The likelihood score of the transform applied to the input cloud,
689 * Equation 6.9 and 6.10 [Magnusson 2009]. */
690 union {
692 16,
693 "`trans_probability_` has been renamed to `trans_likelihood_`.")
695 double trans_likelihood_{0.0};
696 };
697
698 /** \brief Precomputed Angular Gradient
699 *
700 * The precomputed angular derivatives for the jacobian of a transformation
701 * vector, Equation 6.19 [Magnusson 2009].
702 */
703 Eigen::Matrix<double, 8, 4> angular_jacobian_;
704
705 /** \brief Precomputed Angular Hessian
706 *
707 * The precomputed angular derivatives for the hessian of a transformation
708 * vector, Equation 6.19 [Magnusson 2009].
709 */
710 Eigen::Matrix<double, 15, 4> angular_hessian_;
711
712 /** \brief The first order derivative of the transformation of a point
713 * w.r.t. the transform vector, \f$ J_E \f$ in Equation 6.18 [Magnusson
714 * 2009]. */
715 Eigen::Matrix<double, 3, 6> point_jacobian_;
716
717 /** \brief The second order derivative of the transformation of a point
718 * w.r.t. the transform vector, \f$ H_E \f$ in Equation 6.20 [Magnusson
719 * 2009]. */
720 Eigen::Matrix<double, 18, 6> point_hessian_;
721
722private:
723 /** \brief The number of threads the scheduler should use. */
724 unsigned int threads_{1};
725
726 /** \brief The method used for nearest neighbor search. */
728
729public:
731};
732} // namespace pcl
733
734#include <pcl/registration/impl/ndt.hpp>
A 3D Normal Distribution Transform registration implementation for point cloud data.
Definition ndt.h:76
float getResolution() const
Get voxel grid resolution.
Definition ndt.h:160
shared_ptr< const NormalDistributionsTransform< PointSource, PointTarget, Scalar > > ConstPtr
Definition ndt.h:105
typename PointCloudTarget::Ptr PointCloudTargetPtr
Definition ndt.h:85
const TargetGrid & getTargetCells() const
Get access to the VoxelGridCovariance generated from target cloud containing point means and covarian...
Definition ndt.h:283
PointIndices::ConstPtr PointIndicesConstPtr
Definition ndt.h:89
double getStepSize() const
Get the newton line search maximum step length.
Definition ndt.h:169
Eigen::Matrix< double, 18, 6 > point_hessian_
The second order derivative of the transformation of a point w.r.t.
Definition ndt.h:720
void setNumberOfThreads(unsigned int nr_threads=0)
Initialize the scheduler and set the number of threads to use.
Definition ndt.hpp:48
virtual void computeTransformation(PointCloudSource &output)
Estimate the transformation and returns the transformed source (input) as output.
Definition ndt.h:340
typename TargetGrid::LeafConstPtr TargetGridLeafConstPtr
Typename of const pointer to searchable voxel grid leaf.
Definition ndt.h:99
int getFinalNumIteration() const
Get the number of iterations required to calculate alignment.
Definition ndt.h:269
typename Registration< PointSource, PointTarget, Scalar >::PointCloudTarget PointCloudTarget
Definition ndt.h:84
void computePointDerivatives(const Eigen::Vector3d &x, Eigen::Matrix< double, 3, 6 > &point_jacobian, Eigen::Matrix< double, 18, 6 > *point_hessian) const
Compute point derivatives.
Definition ndt.hpp:393
double computeDerivatives(Eigen::Matrix< double, 6, 1 > &score_gradient, Eigen::Matrix< double, 6, 6 > &hessian, const PointCloudSource &trans_cloud, const Eigen::Matrix< double, 6, 1 > &transform, bool compute_hessian=true)
Compute derivatives of likelihood function w.r.t.
Definition ndt.hpp:211
typename PointCloudTarget::ConstPtr PointCloudTargetConstPtr
Definition ndt.h:86
void computeAngleDerivatives(const Eigen::Matrix< double, 6, 1 > &transform, bool compute_hessian=true)
Precompute angular components of derivatives.
Definition ndt.hpp:308
typename PointCloudSource::ConstPtr PointCloudSourceConstPtr
Definition ndt.h:81
typename Registration< PointSource, PointTarget, Scalar >::PointCloudSource PointCloudSource
Definition ndt.h:79
void setOutlierRatio(double outlier_ratio)
Set/change the point cloud outlier ratio.
Definition ndt.h:225
NormalDistributionsTransform()
Constructor.
Definition ndt.hpp:70
bool updateIntervalMT(double &a_l, double &f_l, double &g_l, double &a_u, double &f_u, double &g_u, double a_t, double f_t, double g_t) const
Update interval of possible step lengths for More-Thuente method, in More-Thuente (1994)
Definition ndt.hpp:622
void computeHessian(Eigen::Matrix< double, 6, 6 > &hessian, const PointCloudSource &trans_cloud)
Compute hessian of likelihood function w.r.t.
Definition ndt.hpp:516
void init()
Initiate covariance voxel structure.
Definition ndt.h:354
typename Eigen::Matrix< Scalar, 3, 1 > Vector3
Definition ndt.h:106
double auxilaryFunction_dPsiMT(double g_a, double g_0, double mu=1.e-4) const
Auxiliary function derivative used to determine endpoints of More-Thuente interval.
Definition ndt.h:665
float resolution_
The side length of voxels.
Definition ndt.h:675
typename Registration< PointSource, PointTarget, Scalar >::Matrix4 Matrix4
Definition ndt.h:107
~NormalDistributionsTransform() override=default
Empty destructor.
double outlier_ratio_
The ratio of outliers of points w.r.t.
Definition ndt.h:682
VoxelGridCovariance< PointTarget > TargetGrid
Typename of searchable voxel grid containing mean and covariance.
Definition ndt.h:93
void setInputTarget(const PointCloudTargetConstPtr &cloud) override
Provide a pointer to the input target (e.g., the point cloud that we want to align the input source t...
Definition ndt.h:123
double getTransformationProbability() const
Get the registration alignment probability.
Definition ndt.h:260
TargetGrid target_cells_
The voxel grid generated from target cloud containing point means and covariances.
Definition ndt.h:672
typename PointCloudSource::Ptr PointCloudSourcePtr
Definition ndt.h:80
Eigen::Matrix< double, 8, 4 > angular_jacobian_
Precomputed Angular Gradient.
Definition ndt.h:703
void setMinPointPerVoxel(unsigned int min_points_per_voxel)
Set the minimum number of points required for a cell to be used (must be 3 or greater for covariance ...
Definition ndt.h:151
void setOulierRatio(double outlier_ratio)
Set/change the point cloud outlier ratio.
Definition ndt.h:238
double getOulierRatio() const
Get the point cloud outlier ratio.
Definition ndt.h:216
Eigen::Matrix< double, 15, 4 > angular_hessian_
Precomputed Angular Hessian.
Definition ndt.h:710
shared_ptr< NormalDistributionsTransform< PointSource, PointTarget, Scalar > > Ptr
Definition ndt.h:103
static void convertTransform(const Eigen::Matrix< double, 6, 1 > &x, Matrix4 &trans)
Convert 6 element transformation vector to transformation matrix.
Definition ndt.h:308
void setResolution(float resolution)
Set/change the voxel grid resolution.
Definition ndt.h:133
double step_size_
The maximum step length.
Definition ndt.h:678
void updateHessian(Eigen::Matrix< double, 6, 6 > &hessian, const Eigen::Vector3d &x_trans, const Eigen::Matrix3d &c_inv, const Eigen::Matrix< double, 3, 6 > &point_jacobian, const Eigen::Matrix< double, 18, 6 > &point_hessian) const
Compute individual point contributions to hessian of likelihood function w.r.t.
Definition ndt.hpp:575
double gauss_d1_
The normalization constants used fit the point distribution to a normal distribution,...
Definition ndt.h:686
void setStepSize(double step_size)
Set/change the newton line search maximum step length.
Definition ndt.h:178
double trialValueSelectionMT(double a_l, double f_l, double g_l, double a_u, double f_u, double g_u, double a_t, double f_t, double g_t) const
Select new trial value for More-Thuente method.
Definition ndt.hpp:667
PointIndices::Ptr PointIndicesPtr
Definition ndt.h:88
void setNeighborhoodSearchMethod(const NeighborSearchMethod &method)
Set neighborhood search method.
Definition ndt.h:194
Eigen::Matrix< double, 3, 6 > point_jacobian_
The first order derivative of the transformation of a point w.r.t.
Definition ndt.h:715
double auxilaryFunction_PsiMT(double a, double f_a, double f_0, double g_0, double mu=1.e-4) const
Auxiliary function used to determine endpoints of More-Thuente interval.
Definition ndt.h:646
double computeStepLengthMT(const Eigen::Matrix< double, 6, 1 > &transform, Eigen::Matrix< double, 6, 1 > &step_dir, double step_init, double step_max, double step_min, double &score, Eigen::Matrix< double, 6, 1 > &score_gradient, Eigen::Matrix< double, 6, 6 > &hessian, PointCloudSource &trans_cloud)
Compute line search step length and update transform and likelihood derivatives using More-Thuente me...
Definition ndt.hpp:780
static void convertTransform(const Eigen::Matrix< double, 6, 1 > &x, Affine3 &trans)
Convert 6 element transformation vector to affine transformation.
Definition ndt.h:294
double updateDerivatives(Eigen::Matrix< double, 6, 1 > &score_gradient, Eigen::Matrix< double, 6, 6 > &hessian, const Eigen::Vector3d &x_trans, const Eigen::Matrix3d &c_inv, const Eigen::Matrix< double, 3, 6 > &point_jacobian, const Eigen::Matrix< double, 18, 6 > *point_hessian) const
Compute individual point contributions to derivatives of likelihood function w.r.t.
Definition ndt.hpp:450
typename Eigen::Transform< Scalar, 3, Eigen::Affine > Affine3
Definition ndt.h:108
double getOutlierRatio() const
Get the point cloud outlier ratio.
Definition ndt.h:203
double getTransformationLikelihood() const
Get the registration alignment likelihood.
Definition ndt.h:247
PointCloudConstPtr input_
The input point cloud dataset.
Definition pcl_base.h:147
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Provide a pointer to the input dataset.
Definition pcl_base.hpp:65
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition pcl_base.h:150
Registration represents the base registration class for general purpose, ICP-like methods.
Matrix4 final_transformation_
The final transformation matrix estimated by the registration method after N iterations.
std::function< UpdateVisualizerCallbackSignature > update_visualizer_
Callback function to update intermediate source point cloud position during it's registration to the ...
double corr_dist_threshold_
The maximum distance threshold between two correspondent points in source <-> target.
std::string reg_name_
The registration method name.
Matrix4 transformation_
The transformation matrix estimated by the registration method.
virtual void setInputTarget(const PointCloudTargetConstPtr &cloud)
Provide a pointer to the input target (e.g., the point cloud that we want to align the input source t...
int nr_iterations_
The number of iterations the internal optimization ran for (used internally).
Matrix4 previous_transformation_
The previous transformation matrix estimated by the registration method (used internally).
bool converged_
Holds internal convergence state, given user parameters.
Eigen::Matrix< Scalar, 4, 4 > Matrix4
int max_iterations_
The maximum number of iterations the internal optimization should run for.
double transformation_rotation_epsilon_
The maximum rotation difference between two consecutive transformations in order to consider converge...
double inlier_threshold_
The inlier distance threshold for the internal RANSAC outlier rejection loop.
double transformation_epsilon_
The maximum difference between two consecutive transformations in order to consider convergence (user...
PointCloudTargetConstPtr target_
The input point cloud dataset target.
const std::string & getClassName() const
Abstract class get name method.
void setMinPointPerVoxel(int min_points_per_voxel)
Set the minimum number of points required for a cell to be used (must be 3 or greater for covariance ...
void filter(PointCloud &output, bool searchable=false)
Filter cloud and initializes voxel structure.
const Leaf * LeafConstPtr
Const pointer to VoxelGridCovariance leaf structure.
PointCloudPtr getCentroids()
Get a pointcloud containing the voxel centroids.
void setLeafSize(const Eigen::Vector4f &leaf_size)
Set the voxel grid leaf size.
Definition voxel_grid.h:259
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition memory.h:86
Defines functions, macros and traits for allocating and using memory.
NeighborSearchMethod
Definition ndt.h:53
Defines all the PCL and non-PCL macros used.
#define PCL_DEPRECATED(Major, Minor, Message)
macro for compatibility across compilers and help remove old deprecated items for the Major....
Definition pcl_macros.h:156
shared_ptr< ::pcl::PointIndices > Ptr
shared_ptr< const ::pcl::PointIndices > ConstPtr