Skip to content

Conversation

NobleBumblebee
Copy link
Contributor

Reference issue

fix #446

What does this implement/fix?

Fixes case of negative dError in ICP algorithm.

Additional information

Implementation:
When dError is negative (error is rising) exits iteration loop with values of previous iterations with lower error.
The first iteration is guaranteed by defining dError and preError as np.inf before the loop.

Shamil GEMUEV added 3 commits December 21, 2020 15:10
* added clause for negative dError

* change initiation of errors from constant value to np.inf
@AtsushiSakai
Copy link
Owner

Thank you for you PR. Your improvement make sense for me. I have some minor requests to improve the whole code. PTAL.

Copy link
Owner

@AtsushiSakai AtsushiSakai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL. Also, this is not your fault, but could you please fix indention error in line 41?

indexes, error = nearest_neighbor_association(previous_points, current_points)
Rt, Tt = svd_motion_estimation(previous_points[:, indexes], current_points)

if dError < 0: # prevent matrix H changing, exit loop
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dError is only updated in line 60. If we check the value in line 64 with "dError <= EPS", we can check the value is negative or not. So, I think this check is not needed here. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put if dError < 0 before the line 58 that changes the state of matrix H. If the error increases, we want to use matrix H from the previous iteration when error was lower. So breaking before line 58 keeps previous iteration transformation.

Copy link
Owner

@AtsushiSakai AtsushiSakai Dec 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want to use matrix H from the previous iteration

Yes. I know what you want. But, I am not sure your change achieve it.
dError is only updated in line 60, so when dError changed to negative, it always break at line 64 without you change (if dError <= EPS.).
I think this means previous code works based on what you want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. Thank you for watching. My bad, I didn't transfered the code correctly, as I did some more modifications for my project.

  1. dError should not be absolute, otherwise we cannot catch negative dError.
  2. dError assignment goes before if dError < 0 check.
  3. Also changed from Converge to Not Converge as when error is increasing it's the second case.

@NobleBumblebee
Copy link
Contributor Author

I am not sure, do you want the indention in line 41 to be the same level as "(" or "plt" + tab?

@AtsushiSakai
Copy link
Owner

I'm sorry I mean this code

plt.gcf().canvas.mpl_connect('key_release_event',
lambda event: [exit(0) if event.key == 'escape' else None])

The second line should be align the top of (`key.... of the first line.

Shamil GEMUEV added 2 commits December 31, 2020 14:28
* correct order for calculating errors

* fix indention
@NobleBumblebee
Copy link
Contributor Author

The indention we were talking about didn't passed the check, so I suggest split function arguments in two lines as I did in last commit.

Copy link
Owner

@AtsushiSakai AtsushiSakai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing. I think this code works correctly. But I think we can improve the code for readability. PTAL.

preError = error

# update current points
current_points = (Rt @ current_points) + Tt[:, np.newaxis]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please move line 61 and 62 to line 50 after svd_motion_estimation? I think this looks more easy to read the code.

preError = error
print("Residual:", error)

if dError <= EPS:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can merge these break statements to line 55 like:

if 0 <= dError <= EPS:
    print("Converge", error, dError, count)
    break
elif dError < 0:
    print("Not Converge... Error increased. ", preError, dError, count)
    break
elif MAX_ITER <= count:
     print("Not Converge... Reached max iterations", error, dError, count)
     break

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot see how we can merge break statements. Because it's important for H = update_homogeneous_matrix to be after dError < 0 (as at this break we take H status from previous iteration) and before dError <= EPS (as we need to update H before possible breaking for these 2 cases).

P.S. I thought it over, it is possible to move up 2 last break statements, but there will always be something between dError < 0 and the others. Moving them up, it is necessary to do dError = preError - error after them but before dError < 0. To my mind it becomes a mess in algorithm logic, so I suggest to keep code as is.
I share your wish to make things beautiful. But here I don't see a way to make it better.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Make sense. Thanks.

Copy link
Owner

@AtsushiSakai AtsushiSakai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for great improvement!!.

preError = error
print("Residual:", error)

if dError <= EPS:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Make sense. Thanks.

@AtsushiSakai AtsushiSakai merged commit d5ce035 into AtsushiSakai:master Jan 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ICP bug with negative delta error
2 participants