[search] Add support for nanoflann (faster alternative to pcl::search::KdTree) #6250
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Design considerations
The new
KdTreeNanoflann
should be usable in all situations where currently the FLANN-based kd-tree is used and all parameters etc of the new class should be configurable. At the same time, the existing classes should be changed as little as possible.The feature classes accept a
pcl::search::Search
object, while the registration classes use apcl::search::KdTree<PointTarget>
object, which is actuallypcl::search::KdTree<PointTarget, pcl::KdTreeFLANN<PointTarget>>
(default for second template parameter).I decided to make
KdTreeNanoflann
inherit frompcl::search::KdTree<PointT, pcl::KdTreeFLANN<PointT>>
, that way it can be used almost everywhere, and existing classes do not have to be changed.Limitation
There is one minor limitation which is, I believe, not solvable without breaking the ABI.
pcl::search::KdTree
has a few methods, most notablysetPointRepresentation
, which should be overridden byKdTreeNanoflann
, but these methods are not markedvirtual
. So the dynamic (runtime) dispatch does not work. Adding thevirtual
keyword would break ABI. For example, the following would not work:There is however an easy workaround:
Since it would be great to merge this PR as soon as possible and have the new KdTreeNanoflann class included in the PCL 1.15.1 release (no ABI break possible), I would suggest to accept this limitation for now, and after the PCL 1.15.1 release when breaking ABI is acceptable, we can remove this limitation by adding
virtual
to the functions inpcl::search::KdTree
andoverride
to the corresponding functions inpcl::search::KdTreeNanoflann
.Notes
-DCMAKE_BUILD_TYPE=RelWithDebInfo
or-DCMAKE_BUILD_TYPE=Release
, or choosing the "Release" config in Visual Studio.How to use
Example 1: using KdTreeNanoflann in NormalEstimation:
Example 2: using KdTreeNanoflann in ICP:
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp; icp.setSearchMethodSource(pcl::make_shared<pcl::search::KdTreeNanoflann<pcl::PointXYZ>>()); icp.setSearchMethodTarget(pcl::make_shared<pcl::search::KdTreeNanoflann<pcl::PointXYZ>>()); // rest as usual
Example 3: using a L1 distance norm:
Example 4: using KdTreeNanoflann with features instead of 3D points:
Benchmarks
I did some benchmarks to get an idea how the new
KdTreeNanoflann
compares to the FLANN basedKdTree
. Of course, these depend a lot on the processor, the point clouds used, and other factors. Switching toKdTreeNanoflann
reduces the time spent to:NormalEstimation (small radius): 75-78%
NormalEstimation (large radius): 76-78%
EuclideanClusterExtraction: 75-80%
RadiusOutlierRemoval: 25-40%
ICP (does nearestKSearch with k=1): 30-50%
NormalEstimation (small k): 85-90%
NormalEstimation (large k): 91-97%
1nn search (tree building not included): 29-32%
5nn search (tree building not included): 48-49%
50nn search (tree building not included): 83-85%
radius (small radius, sorted, tree building not included): 49-53%
radius (small radius, unsorted, tree building not included): 39-42%
radius (large radius, sorted, tree building not included): 77-81%
radius (large radius, unsorted, tree building not included): 63-65%
Where 100% refers to the time taken with
pcl::search::KdTree
, so e.g. 50% would be twice as fast as before.To discuss for the future
pcl::search::KdTree
orpcl::KdtreeFLANN
for searching and do not offer a way to change this. We could consider adding the option to pass in another search method (e.g. KdTreeNanoflann)pcl::search::KdTree
for unorganized clouds)