norlab-ulaval / libpointmatcher

An Iterative Closest Point (ICP) library for 2D and 3D mapping in Robotics
BSD 3-Clause "New" or "Revised" License
1.63k stars 549 forks source link

Singular Matrix ConvergenceError #158

Closed Ellon closed 8 years ago

Ellon commented 8 years ago

Hello,

I'm using libpointmatcher to perform ICP on the KITTI dataset, more or less the way it is done in ethzasl_icp_mapping. At some point the ICP fails with the following ConvergenceError exception: encountered singular while minimizing point to plane distance and the current workaround wasn't successful.

I've been trying to understand why I'm having this problem. I do understand the matrix used in the optimization is rank deficient, but I don't understand what are the factors that cause this rank deficient matrix, how to avoid it, and why the current workaround don't work. Does anyone know how to solve this kind of issue?

I put the data that is causing the error in the attached file here (issue's file attachment didn't work).

Best,

HannesSommer commented 8 years ago

Thanks for providing the data. As a quick fix you can change https://github.com/ethz-asl/libpointmatcher/blob/master/pointmatcher/ErrorMinimizersImpl.cpp#L310 into if(!b.isApprox(ax, 1e-1)) or just disable the entire check. It should be fine for your point clouds.

I hope to push a more proper solution soon.

Ellon commented 8 years ago

Thanks for the quick reply and for the quick fix.

I noticed that using libpointmatcher with doubles also solved the problem, but seems to be slower and I cannot visualize the clouds with rviz anymore (using PointMatcher_ros::pointMatcherCloudToRosMsg from ethzasl_icp_mapping).

HannesSommer commented 8 years ago

Pr #159 should provide a better solution. It is now trying much harder to get it right :). Tthanks for the double - idea. Does it work for you this way, too?

Ellon commented 8 years ago

Unfortunately not. :(

terminate called after throwing an instance of 'PointMatcher<float>::ConvergenceError'
  what():  PointMatcher::icp - encountered numerically singular matrix while minimizing point to plane distance and the current workaround wasn't very successful :  b=-46.5462  -66.308 -51.1576  16.2807 -6.15575  1.32696 !~ A * x=-46.5464 -66.3086 -51.1565  16.2807 -6.15575  1.32697: ||b- ax||=0.00118009, ||b||=97.3916, ||ax||=97.3915

Again, the data that created the problem can be found here. Maybe the tolerance value should be increased? Or maybe user-defined?

And thanks for taking the time to solve this issue. :)

HannesSommer commented 8 years ago

Strangely this time I could not reproduce the exception based on your data, running

pmicp --config configAtConvergenceError.yaml --initTranslation $(<initTranslationAtConvergenceError.txt) --initRotation $(<initRotationAtConvergenceError.txt) mapAtConvergenceError.vtk readingAtConvergenceError.vtk

Nevertheless I've tried to improve the condition for detecting a dangerous inaccuracy further and turned the consequence into a pure warning (no exception any more). It seems doing a reliable and meaningful check here is quite hard. And me failing at that task should no longer disturb users :).

With that commit in PR #159 it should work for you just fine. For me it would still be interesting if the warning still gets triggered. See PR #160 for how to turn on the warnings.

Ellon commented 8 years ago

Indeed the exception was not being produced by the data. I just uploaded another file with the correct data.

I'll check your commits now.

pomerlef commented 8 years ago

Where are we with that issue?

HannesSommer commented 8 years ago

As far as I know this was settled with PR #159 .

pomerlef commented 8 years ago

Alright, thanks a lot for working on this!

Ellon commented 8 years ago

Sorry I forgot to reply on this issue.

Yes, the PR #159 solved the issue by warning about the numerically singular matrix instead of throwing an exception. Thanks!