-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
DefaultConvergenceCriteria::setFailureAfterMaximumIterations() appears broken #1598
Comments
Thanks for looking into it. Given the in-depth analysis you already did, it would be great if you could submit a pull request addressing the issue. For additional info on how to contribute, please check this. |
I had a problem with this issue too. And I think the major problem is It returns a boolean state of convergence, but also asign the detail reason to Therefore, this issue becomes "will be First, Second, Third, Why Finally, as issue author said, there is no further test when This is all of my analysis, and sorry for uncleaned. Anyway, I just share my answers.
to
and add state This is not work well, if user try to check the failure using And the solution for next major version(if PCL API will have huge change.) This is only my idea, so may be I am wrong. So please let me know if you have another idea or further discussion about this issue. Thanks. |
I certainly agree with you about the misleading name of
Just to clarify, we are talking about different function here, pcl/registration/include/pcl/registration/impl/icp.hpp Lines 236 to 238 in b535651
Now with your proposal we will get out of the loop by setting What do you think? |
You are right, user checks failure using Yes, you can check So I agree with your solution but this upcomming problem should be concerned. Because If they are an inheritance, this makes sense. But they are a component. That makes further expansion of code tricky, and software design will be bad. Anyway, I agree with your idea and I would like you fix it as you said. but what do you think about the upcomming problem I explained above? I just ask to you because I have no idea of that problem. If you too, just leave it as remained problem. If you think it doesn't make concerns, just ignore it. To solve that problem, I got a different idea: ICP has
But this idea maybe not compatible with original |
I think you are totally right with your concerns. The The problem with your idea is that I have some half-baked ideas how to improve the situation. I haven't thought them through yet, but I'll share them already so we can start a discussion. First, we add an explicit state for the failure after max iterations (as you already proposed): enum ConvergenceState
{
CONVERGENCE_CRITERIA_NOT_CONVERGED, // group 1: no convergence, no failure
CONVERGENCE_CRITERIA_ITERATIONS, // group 2: convergence
CONVERGENCE_CRITERIA_TRANSFORM, // group 2: convergence
CONVERGENCE_CRITERIA_ABS_MSE, // group 2: convergence
CONVERGENCE_CRITERIA_REL_MSE, // group 2: convergence
CONVERGENCE_CRITERIA_NO_CORRESPONDENCES, // group 3: failure
CONVERGENCE_CRITERIA_FAILURE_AFTER_MAX_ITERATIONS // group 3: failure
}; Then in if (failure_after_max_iter_)
{
convergence_state_ = CONVERGENCE_CRITERIA_FAILURE_AFTER_MAX_ITERATIONS;
return (false);
} Note the comments in the first snippet. The ...
}
while (convergence_criteria_->getConvergenceState() == CONVERGENCE_CRITERIA_NOT_CONVERGED) So for the purposes of controlling the loop we will ignore what What do you think? |
That's brilliant! I agree with your idea. Also thank you for your kind explanations. I think there is no more consideration about infinite ICP loop. But I missed one thing that Chungzuwalla(the issue opener) said. At the beginning, I thought just move failure test after all pass tests. But this is not a good idea. Because, after that, other contributers consider about this order every times they append new failure state and its test. Instead, I found another idea that remove all To implement this idea, there is one more thing to do. Even though pcl/registration/include/pcl/registration/impl/default_convergence_criteria.hpp Lines 71 to 76 in 09c124a
Therefore, there needs a boolean variable which stores whether The code below is what I said. I omitted detail code.
Is there anything wrong? Feel free to tell me. Additionally, I thought about showing multiple convergence state using std::bitset. But it needs many changes. And test every criteria is slower than just return at any convergence met. So I didn't think about it further. |
Good points, agree with your proposal. There are a few things that I suspect are currently wrong with
Regarding |
Yes, About I don't understand well your second consideration. But I think you talk about I have two options to solve it. Manual reset or automatic reset, but both are not quite good ideas. Manual reset means doing reset by ICP, and automatic reset means doing reset by Manual reset is just make a public reset method, so let ICP deal with it. When ICP starts new alignment, ICP call My automatic reset is doing in
So, ICP doesn't care about But this has a flaw. We start this discussion with that Anyway, I recommend the latter than the former. But if you have better idea, let me know please. |
For the "automatic reset" approach we may use the fact that
Then in the loop it is first incremented and then pcl/registration/include/pcl/registration/impl/icp.hpp Lines 230 to 238 in 49c168a
So in the very beginning of As for my second point, I meant the following hypothetical situation:
|
Yes, you right. Only consecutive similar transforms is allowed. There needs a reset when the transform becomes large. |
Unfortunately I'm quite busy with other things and don't have an estimate on when I would have time (if ever) to implement the discussed fixes myself. So if you want this to be fixed, prepare a pull request! |
- Exit loop with convergence state instead of `converged_` in icp - Add new convergence state `CONVERGENCE_CRITERIA_FAILURE_AFTER_MAX_ ITERATIONS` - When `failure_after_max_iter_` is set true, `hasConverged()` checks all similarity before returning a failure. - Even though one iteration has several similar conditions, counts `iterations_similar_transforms_` up only 1. - If transform becomes large, `iterations_similar_transforms_` reset to 0. Only consecutive similar iterations are allowed to converge. - Edit a description about the change above in API docs. - When new alignment restarts after a convergence or a failure, `iterations_similar_transforms_` also reset to 0.
Fix misbehavior in the "failure after maximum iterations" mode This updates `ICP` and `DefaultConvergenceCriteria` classes to fix misbehavior in the "failure after maximum iterations" mode. (Prior to this change the registration loop would hang in an infinite loop #1598). It also refines "maximum iterations similar transforms" option to mean **consequtive** transforms. A new convergence state `CONVERGENCE_CRITERIA_FAILURE_AFTER_MAX_ ITERATIONS` is added.
Code to reproduce:
Expected result: after 1 iteration, alignment should be abandoned and icp.align() should return, and icp.hasConverged() should be false.
Actual result: icp.align() enters an endless loop and will never return.
The enclosing loop in icp.hpp is:
which loops until pcl::registration::DefaultConvergenceCriteria::hasConverged() returns true. However, pcl::registration::DefaultConvergenceCriteria::hasConverged() starts with:
Once iterations_ >= max_iterations_, hasConverged () immediately returns false, without testing other convergence criteria, causing an endless loop.
The text was updated successfully, but these errors were encountered: