pcl icon indicating copy to clipboard operation
pcl copied to clipboard

Support for correspondence estimation with different point types

Open SergioRAgostinho opened this issue 9 years ago • 31 comments
trafficstars

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?

SergioRAgostinho avatar Dec 13 '15 14:12 SergioRAgostinho

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.

taketwo avatar Dec 13 '15 14:12 taketwo

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 avatar Dec 13 '15 14:12 SergioRAgostinho

Gentle reminder. This is good for review and merge.

SergioRAgostinho avatar Dec 16 '15 07:12 SergioRAgostinho

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?

taketwo avatar Dec 13 '17 07:12 taketwo

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

SergioRAgostinho avatar Dec 13 '17 12:12 SergioRAgostinho

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 avatar Dec 14 '17 04:12 SergioRAgostinho

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

taketwo avatar Dec 14 '17 10:12 taketwo

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

Anything else you see out of place?

SergioRAgostinho avatar Dec 14 '17 15:12 SergioRAgostinho

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.

taketwo avatar Dec 14 '17 15:12 taketwo

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.

SergioRAgostinho avatar Dec 14 '17 15:12 SergioRAgostinho

Ah, OK!

taketwo avatar Dec 14 '17 15:12 taketwo

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.

SergioRAgostinho avatar Dec 19 '17 01:12 SergioRAgostinho

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".

taketwo avatar Dec 19 '17 08:12 taketwo

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.

SergioRAgostinho avatar Dec 19 '17 10:12 SergioRAgostinho

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));
}

taketwo avatar Dec 19 '17 10:12 taketwo

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

SergioRAgostinho avatar Dec 19 '17 10:12 SergioRAgostinho

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 ;)

taketwo avatar Dec 19 '17 10:12 taketwo

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 avatar Dec 19 '17 11:12 SergioRAgostinho

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

SergioRAgostinho avatar Dec 19 '17 11:12 SergioRAgostinho

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 avatar Dec 19 '17 11:12 taketwo

So for the compiler only single unspecialized version of

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

is visible, so everything is fine.

taketwo avatar Dec 19 '17 11:12 taketwo

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. :+1:

SergioRAgostinho avatar Dec 19 '17 11:12 SergioRAgostinho

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

SergioRAgostinho avatar Dec 19 '17 11:12 SergioRAgostinho

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

taketwo avatar Dec 19 '17 12:12 taketwo

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.

taketwo avatar Dec 19 '17 12:12 taketwo

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

?

SergioRAgostinho avatar Dec 19 '17 12:12 SergioRAgostinho

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.

taketwo avatar Dec 19 '17 12:12 taketwo

:+1: works. I'll clean it up.

SergioRAgostinho avatar Dec 19 '17 12:12 SergioRAgostinho

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

SergioRAgostinho avatar Dec 19 '17 13:12 SergioRAgostinho

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.

stale[bot] avatar Feb 21 '20 19:02 stale[bot]