Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for correspondence estimation with different point types #1476

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

SergioRAgostinho
Copy link
Member

Fixes #329. Credits for @aichim, @jpapon and @taketwo .
Added unit test for XYZ point types.

Still have some doubts:

  • pcl::registration::CorrespondenceEstimation seems to support with all point types. Is it supposed to work with more weird cases of source and target point types, e.g. between XYZ points types <-> Normal point types? Not sure if this is possible.
  • Should I also add a test for Normal point types? RGB? Is KDTree flexible enough for this?

@taketwo
Copy link
Member

taketwo commented Dec 13, 2015

LGTM. Can't comment on the point type use cases, never used this class in my projects. I think testing with XYZ points is enough, this verifies that the algorithm is correct.

@SergioRAgostinho
Copy link
Member Author

Seems to work with pcl::Normal to pcl::Normal, but if one of the point types has XYZ data and the other doesn't, e.g. pcl::Normal to pcl::PointNormal, it starts failing. It's probably giving priority to XYZ data.

@SergioRAgostinho
Copy link
Member Author

Gentle reminder. This is good for review and merge.

@SergioRAgostinho SergioRAgostinho added the needs: code review Specify why not closed/merged yet label Aug 22, 2016
@SergioRAgostinho SergioRAgostinho added this to the pcl-1.9.0 milestone Aug 22, 2016
@taketwo
Copy link
Member

taketwo commented Dec 13, 2017

My colleague (Thomas, actually) has recently enquired about the status of this PR. Has anything changed from your side in the last... two years? Maybe rebase, check CI results, and merge?

@SergioRAgostinho SergioRAgostinho added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Dec 13, 2017
@SergioRAgostinho
Copy link
Member Author

I'll have a new look at it later today with fresh eyes.

jpapon and others added 2 commits December 14, 2017 01:18
- Added Specialization helper to prevent unnecessary copies when
invoking nearestKSearch
- Added unit tests
@SergioRAgostinho
Copy link
Member Author

SergioRAgostinho commented Dec 14, 2017

This is all I managed to do before the weekend. I circumvented the unnecessary copy discussed in #329 with the use of a helper specialized struct. I verified that it performs no copy when the point type is the same and it invokes copyPoint (through nearestKSearchT) in the opposite case.

That helper struct might require some reorganization though. I can't enclose it inside the CorrespondenceEstimation, because I lose the ability to specialize it.

Nevertheless, the proof of concept is here. Now we need to decide how to tidy up things.

@SergioRAgostinho SergioRAgostinho added needs: code review Specify why not closed/merged yet and removed needs: author reply Specify why not closed/merged yet labels Dec 14, 2017
@taketwo
Copy link
Member

taketwo commented Dec 14, 2017

I wonder why don't we apply this same specialization trick directly to KdTree::nearestKSearchT() function?

@SergioRAgostinho
Copy link
Member Author

No doubt that it would make more sense. On C++14 migration it will require a cleanup.

Anything else you see out of place?

@taketwo
Copy link
Member

taketwo commented Dec 14, 2017

No doubt that it would make more sense. On C++14 migration it will require a cleanup.

Don't understand. Do you mean we can not implement it now?

Anything else you see out of place?

No, everything else looks good.

@SergioRAgostinho
Copy link
Member Author

Yes I can. Only mid next week though. I'm restricted to a tablet for the duration of the weekend.

I noticed I need to improve the doxygen documentation and perhaps try some obscure cases under which only the normals are the common fields.

@taketwo
Copy link
Member

taketwo commented Dec 14, 2017

Ah, OK!

@taketwo taketwo added needs: more work Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Dec 14, 2017
@SergioRAgostinho
Copy link
Member Author

Just had a quick look at things and applying this change will require to modify search/search.h for nearestKSearch(T) and radiusSearch(T), but also replicate the same approach on kdtree/kdtree.h. This will take more time than anticipated.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

I don't know how comfortable you are with template stuff, so here is a quick snippet:

template <typename PointTDiff, typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0> inline int

This is the template line for the version where point types are the same. For the opposite case just replace "enable" with "disable".

@SergioRAgostinho
Copy link
Member Author

SergioRAgostinho commented Dec 19, 2017

Included your comment regarding the enable_if, disable_if.

I also realized why the tests failed (one year ago) for anything other than point XYZ types. The KdTree's derived from Search are all for "simple" XYZ queries. For ND queries, one needs to use the KdTree from the kdtree module. Correspondence estimation uses the former.

Edit: Here's a dump with some extra verbose from the added unit test

$ test/registration/test_correspondence_estimation 
[==========] Running 19 tests from 18 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from CorrespondenceEstimation
[ RUN      ] CorrespondenceEstimation.CorrespondenceEstimationNormalShooting
[       OK ] CorrespondenceEstimation.CorrespondenceEstimationNormalShooting (3 ms)
[ RUN      ] CorrespondenceEstimation.CorrespondenceEstimationSetSearchMethod
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
[       OK ] CorrespondenceEstimation.CorrespondenceEstimationSetSearchMethod (0 ms)
[----------] 2 tests from CorrespondenceEstimation (3 ms total)

[----------] 1 test from CorrespondenceEstimationTest/0, where TypeParam = pcl::PointXYZ
[ RUN      ] CorrespondenceEstimationTest/0.DifferentPointTypes
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
[       OK ] CorrespondenceEstimationTest/0.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/0 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/1, where TypeParam = pcl::PointXYZI
[ RUN      ] CorrespondenceEstimationTest/1.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/1.DifferentPointTypes (1 ms)
[----------] 1 test from CorrespondenceEstimationTest/1 (1 ms total)

[----------] 1 test from CorrespondenceEstimationTest/2, where TypeParam = pcl::PointXYZL
[ RUN      ] CorrespondenceEstimationTest/2.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/2.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/2 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/3, where TypeParam = pcl::PointXYZRGBA
[ RUN      ] CorrespondenceEstimationTest/3.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/3.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/3 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/4, where TypeParam = pcl::PointXYZRGB
[ RUN      ] CorrespondenceEstimationTest/4.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/4.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/4 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/5, where TypeParam = pcl::PointXYZRGBL
[ RUN      ] CorrespondenceEstimationTest/5.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/5.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/5 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/6, where TypeParam = pcl::PointXYZHSV
[ RUN      ] CorrespondenceEstimationTest/6.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/6.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/6 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/7, where TypeParam = pcl::InterestPoint
[ RUN      ] CorrespondenceEstimationTest/7.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/7.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/7 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/8, where TypeParam = pcl::PointNormal
[ RUN      ] CorrespondenceEstimationTest/8.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/8.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/8 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/9, where TypeParam = pcl::PointXYZRGBNormal
[ RUN      ] CorrespondenceEstimationTest/9.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/9.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/9 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/10, where TypeParam = pcl::PointXYZINormal
[ RUN      ] CorrespondenceEstimationTest/10.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/10.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/10 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/11, where TypeParam = pcl::PointXYZLNormal
[ RUN      ] CorrespondenceEstimationTest/11.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/11.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/11 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/12, where TypeParam = pcl::PointWithRange
[ RUN      ] CorrespondenceEstimationTest/12.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/12.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/12 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/13, where TypeParam = pcl::PointWithViewpoint
[ RUN      ] CorrespondenceEstimationTest/13.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/13.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/13 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/14, where TypeParam = pcl::PointWithScale
[ RUN      ] CorrespondenceEstimationTest/14.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/14.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/14 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/15, where TypeParam = pcl::PointSurfel
[ RUN      ] CorrespondenceEstimationTest/15.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/15.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/15 (0 ms total)

[----------] 1 test from CorrespondenceEstimationTest/16, where TypeParam = pcl::PointDEM
[ RUN      ] CorrespondenceEstimationTest/16.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[       OK ] CorrespondenceEstimationTest/16.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/16 (0 ms total)

[----------] Global test environment tear-down
[==========] 19 tests from 18 test cases ran. (4 ms total)
[  PASSED  ] 19 tests.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

Sorry, I should have been more explicit. There is no need for helper classes. All we need is to replace

template <typename PointTDiff> inline int
nearestKSearchT (const PointTDiff &point, int k,
                 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const
{
  PointT p;
  copyPoint (point, p);
  return (nearestKSearch (p, k, k_indices, k_sqr_distances));
}

with

template <typename PointTDiff, typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0> inline int
nearestKSearchT (const PointTDiff &point, int k,
                 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const
{
  return (nearestKSearch (point, k, k_indices, k_sqr_distances));
}

template <typename PointTDiff, typename boost::disable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0> inline int
nearestKSearchT (const PointTDiff &point, int k,
                 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const
{
  PointT p;
  copyPoint (point, p);
  return (nearestKSearch (p, k, k_indices, k_sqr_distances));
}

@SergioRAgostinho
Copy link
Member Author

You can't specialize class methods without specializing the entire class.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

This rule does not apply here, because we are specializing not on the class template parameter, but on a method's own parameter. In other words, you can not specialize nearestKSearchT for different PointT classes, however it's absolutely alright to specialize on PointTDiff or auxiliary parameter (like in this case). Just give it a try ;)

@SergioRAgostinho
Copy link
Member Author

I'm trying to verify the what you said in cpp.sh as first step. Here's my snippet so far http://cpp.sh/2x7s4 did I miss the point behind what you described? My class is not templated on anything, just the methods.

Another thing which stands out in what you wrote is this
typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0
How is this valid? You're saying a type is 0.

@SergioRAgostinho
Copy link
Member Author

SergioRAgostinho commented Dec 19, 2017

Ok... there are some additional nuances to what boost::enable_if does. I'll just go and try what you proposed.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

Hm, perhaps I'm wrong with my last statement. However, the thing still works, because we are actually not specializing anything! This part which you are wondering about typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0, when the point types are the same, it expands to int = 0. So it becomes an integral template argument. When the types are different, it's a substitution failure and this version of the method is just not considered.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

So for the compiler only single unspecialized version of

template<PointDiffT, int = 0> inline int nearestKSearchT()

is visible, so everything is fine.

@SergioRAgostinho
Copy link
Member Author

Your approach is being killed by C++03 :/

error: default template arguments may not be used in function templates without -std=c++11 or -std=gnu++11

If I remove that default setting to = 0 then we get an ambiguous call.

In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp: In instantiation of ‘void pcl::registration::CorrespondenceEstimation<PointSource, PointTarget, Scalar>::determineCorrespondences(pcl::Correspondences&, double) [with PointSource = pcl::PointXYZRGBA; PointTarget = pcl::PointXYZRGBA; Scalar = float; pcl::Correspondences = std::vector<pcl::Correspondence, Eigen::aligned_allocator<pcl::Correspondence> >]’:
/home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:328:1:   required from here
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: error: no matching function for call to ‘pcl::search::KdTree<pcl::PointXYZRGBA, pcl::KdTreeFLANN<pcl::PointXYZRGBA, flann::L2_Simple<float> > >::nearestKSearchT(const pcl::PointXYZRGBA&, int, std::vector<int>&, std::vector<float>&)’
     tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
     ^
In file included from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac_model.h:54:0,
                 from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac.h:45,
                 from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/ransac.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:45,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:167:9: note: candidate: template<class PointTDiff, typename boost::disable_if<boost::is_same<pcl::PointXYZRGBA, T2>, int>::type <anonymous> > int pcl::search::Search<PointT>::nearestKSearchT(const PointTDiff&, int, std::vector<int>&, std::vector<float>&) const [with PointTDiff = PointTDiff; typename boost::disable_if<boost::is_same<T1, T2>, int>::type <anonymous> = <enumerator>; PointT = pcl::PointXYZRGBA]
         nearestKSearchT (const PointTDiff &point, int k,
         ^
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:167:9: note:   template argument deduction/substitution failed:
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: note:   couldn't deduce template parameter ‘<anonymous>’
     tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
     ^
In file included from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac_model.h:54:0,
                 from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac.h:45,
                 from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/ransac.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:45,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:177:9: note: candidate: template<class PointTDiff, typename boost::enable_if<boost::is_same<pcl::PointXYZRGBA, T2>, int>::type <anonymous> > int pcl::search::Search<PointT>::nearestKSearchT(const PointTDiff&, int, std::vector<int>&, std::vector<float>&) const [with PointTDiff = PointTDiff; typename boost::enable_if<boost::is_same<T1, T2>, int>::type <anonymous> = <enumerator>; PointT = pcl::PointXYZRGBA]
         nearestKSearchT (const PointTDiff &point, int k,
         ^
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:177:9: note:   template argument deduction/substitution failed:
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: note:   couldn't deduce template parameter ‘<anonymous>’
     tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
     ^
In file included from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac_model.h:54:0,
                 from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac.h:45,
                 from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/ransac.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:45,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:249:9: note: candidate: template<class PointTDiff> void pcl::search::Search<PointT>::nearestKSearchT(const pcl::PointCloud<PointTDiff>&, const std::vector<int>&, int, std::vector<std::vector<int> >&, std::vector<std::vector<float> >&) const [with PointTDiff = PointTDiff; PointT = pcl::PointXYZRGBA]
         nearestKSearchT (const pcl::PointCloud<PointTDiff> &cloud, const std::vector<int>& indices, int k, std::vector< std::vector<int> > &k_indices,
         ^
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:249:9: note:   template argument deduction/substitution failed:
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
                 from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
                 from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: note:   ‘const pcl::PointXYZRGBA’ is not derived from ‘const pcl::PointCloud<PointT>’
     tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
     ^

Still, this was definitely one of my meta lessons for this year. 👍

@SergioRAgostinho
Copy link
Member Author

SergioRAgostinho commented Dec 19, 2017

Unless you want to start invoking explicitly nearestKSearchT<PointTDiff, 0> ? Not exactly sexy but it should work in theory.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

Damn, true, this requires C++11 😞
OK, then we will use return type SFINAE (prepare for the next meta lesson). Give me a sec to prototype.

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

Just replace the template line with:

template <typename T> inline typename boost::enable_if<boost::is_same<PointT, T>, int>::type

and disable_if respectively. Should work regardless of C++ standard. It's basically the same, but it makes it harder to read the return type of the function, that's why I normally prefer the first approach.

@SergioRAgostinho
Copy link
Member Author

Quick question, just in case you know it

typename boost::enable_if<boost::is_same<PointT, T>, int>::type

expands to int in case the condition is true, and what happens in the opposite case? Is it something collision free?

Some of the methods are of void type. Should I modify to

typename boost::enable_if<boost::is_same<PointT, T>, void>::type

?

@taketwo
Copy link
Member

taketwo commented Dec 19, 2017

and what happens in the opposite case?

Nothing. It's called "substitution failure" and the function is just silently discarded by the compiler. That's why the technique is called SFINAE (substitution failure is not an error).

Some of the methods are of void type.

Yes, just put void instead of int.

@SergioRAgostinho
Copy link
Member Author

👍 works. I'll clean it up.

@SergioRAgostinho
Copy link
Member Author

SergioRAgostinho commented Dec 19, 2017

I'll squash my personal commits after review and CI validation.

@SergioRAgostinho SergioRAgostinho added needs: code review Specify why not closed/merged yet and removed needs: more work Specify why not closed/merged yet labels Dec 19, 2017
@SergioRAgostinho SergioRAgostinho removed this from the pcl-1.9.0 milestone Aug 26, 2018
@stale
Copy link

stale bot commented Feb 21, 2020

This pull request has been automatically marked as stale because it hasn't had
any activity in the past 60 days. Commenting or adding a new commit to the
pull request will revert this.

Come back whenever you have time. We look forward to your contribution.

@larshg
Copy link
Contributor

larshg commented Jun 14, 2023

This one has been superseded by #4901 ?

@stale stale bot removed the status: stale label Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs: code review Specify why not closed/merged yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CorrespondenceEstimation with different point types
4 participants