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

add failing unit test on axisAngle for Rot3 in c++ #887

Merged
merged 11 commits into from
Oct 13, 2021

Conversation

johnwlambert
Copy link
Contributor

@johnwlambert johnwlambert commented Oct 7, 2021

Adds tests to expose broken axis-angle for edge cases. See #886 for more details.

@ProfFan
Copy link
Collaborator

ProfFan commented Oct 7, 2021

Wait, why CI is successful if the unit tests fail?

@johnwlambert
Copy link
Contributor Author

@ProfFan I'm pleased to say the new python unit test now successfully fails : - )

For some reason, I don't see the output of any c++ unit tests in the CI. Are we still running those in CI?

======================================================================
FAIL: test_axisangle (test_Rot3.TestRot3)
Test .axisAngle() method.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/gtsam/gtsam/python/gtsam/tests/test_Rot3.py", line 37, in test_axisangle
    np.testing.assert_almost_equal(actual_angle, expected_angle, 1e-7)
  File "/usr/local/lib/python3.6/dist-packages/numpy/testing/_private/utils.py", line 595, in assert_almost_equal
    raise AssertionError(_build_err_msg())
AssertionError: 
Arrays are not almost equal to 0 decimals
 ACTUAL: 6.075185318083525
 DESIRED: 3.1396582

----------------------------------------------------------------------
Ran 126 tests in 1.843s

FAILED (failures=1, skipped=3)

@ProfFan
Copy link
Collaborator

ProfFan commented Oct 8, 2021

Oh dang. It seems that we accidentally disabled all C++ tests? @varunagrawal

@varunagrawal
Copy link
Collaborator

I am seeing the C++ CI no problem. Am I missing something?

@johnwlambert
Copy link
Contributor Author

I am seeing the C++ CI no problem. Am I missing something?

@varunagrawal could you share a screenshot of the c++ unit test summary you see being run in the CI (from the logs)?

@varunagrawal
Copy link
Collaborator

I misunderstood what the issue is. This is my fault, I updated the CI to be faster and made a small mistake...

@ProfFan
Copy link
Collaborator

ProfFan commented Oct 8, 2021

@johnwlambert Could you merge develop?

@dellaert
Copy link
Member

dellaert commented Oct 8, 2021

I think Fan means merge develop into this branch. We can’t merge TO develop until issue is fixed.

@ProfFan ProfFan self-assigned this Oct 12, 2021
@ProfFan
Copy link
Collaborator

ProfFan commented Oct 13, 2021

Robust Conversion from Matrix to Axis Angle Form

1 Introduction

Robust conversion from matrix to axis-angle form is not trivial because the
transform is plagued with numeric instabilities. In this document we will
review the normal form of such a conversion, and provide detailed instructions
on how to properly do it.

1.1 Basic Conversion

It is known that the conversion from a matrix can be
written as

Theorem 1: The rotation angle $\theta$ can be calculated as

where is the trace of the rotation matrix.

As such, the normalized rotation axis is:

Theorem 2: The normalized rotation axis for a rotation matrix $R$ is

where are the elements in the matrix.

2 Problem

sin(x)02*piCannot process embedded image

Figure 1.$\sin (x)$

It's pretty straightforward that when ,
(undefined label: 'eq-orig-axis') will not work because $\sin
(\theta)$ will be 0. From (undefined label: 'eq-orig-angle')
we know that, since ,

Thus we know that there are two singular points, $- 1$ and $3$, for the
axis-angle conversion. Next thing is how to deal with these two points.

3 Properties of the $\operatorname{SO} (3)$ transform at the singular points

3.1

For the solution is simple: We simply
take the Taylor expansion of

\[ \frac{\theta}{2 \sin (\theta)} \]

at . Note this is not a simple Taylor expansion, but a
limit. We can do this in Maxima:

maximadefault

Maxima 5.45.1 https://maxima.sourceforge.io

using Lisp SBCL 2.1.9

Distributed under the GNU Public License. See the file COPYING.

Dedicated to the memory of William Schelter.

The function bug_report() provides bug reporting information.

(%i1)θ:acos(t-12)

(%i2)mag:θ2*sin(θ)

(%i3)taylor(mag,t,3,3)

Thus the solution around is

3.2 $\theta \rightarrow \pi$

The solution becomes a lot more complicated when at .
This is because at this extreme point you have two solutions: you can go from
both left and right of the unit circle!

Note 3: The trace is negative.

In this case we can first convert $R$ to quaternion, which is done by

where , , .

Normally we want the angle , thus we need to make sure
that ,

and now we can easily get the angle $\theta$ as

and now the magnitude of the vector is

However, in GTSAM, we do the following simplification to avoid doing the atan2
(expensive).

First note that . Thus we have
(around $w = 0$) this Taylor expansion:

maximadefault

Maxima 5.45.1 https://maxima.sourceforge.io

using Lisp SBCL 2.1.9

Distributed under the GNU Public License. See the file COPYING.

Dedicated to the memory of William Schelter.

The function bug_report() provides bug reporting information.

(%i1)θ:2*atan2(1-w,w)

(%i2)scale:θ/sin(θ/2)

(%i3)taylor(scale,w,0,3)

which indicates that we only need a correction term of to get the
true magnitude near $\pi$.

@ProfFan
Copy link
Collaborator

ProfFan commented Oct 13, 2021

AxisAngleConversion.pdf

@varunagrawal varunagrawal linked an issue Oct 13, 2021 that may be closed by this pull request
Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

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

Fan, John, i think we should merge even in absence of the revised PDF from Fan (which I asked for in a meeting) because this is a bug that needs to be squashed. However, I’m asking Fan to fix the logic for argmax, after which I will take another look. email me when it’s done.

if (tr + 1.0 < 1e-4) {
std::vector<double> diags = {R11, R22, R33};
size_t max_elem = std::distance(diags.begin(), std::max_element(diags.begin(), diags.end()));
if (max_elem == 2) {
Copy link
Member

Choose a reason for hiding this comment

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

I’d prefer if we do

If (R11>R22 && R11>R33)
Else if (R22>R33)
Else

Copy link
Collaborator

Choose a reason for hiding this comment

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

done

Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

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

@johnwlambert could you merge after running your python tests again and pasting the results in the conversation? I remember you had a script that did a statistical analysis as to how many times it failed in 100K calls or so?

@johnwlambert
Copy link
Contributor Author

@dellaert @ProfFan just ran some analysis. The results are definitely much better than before now. We still get several dozen cases where the angle exceeds 180 degrees from those 165 previous failures. The failures are now on the order of 180.1 to 180.5 degrees, vs. expected 179.x.

Do we want to continue to try to get the last decimal place? I can add these test cases to the unit tests, if so.

@ProfFan
Copy link
Collaborator

ProfFan commented Oct 13, 2021

@johnwlambert Let's land this first. Could you put up another PR that includes the case that fails?

@ProfFan ProfFan merged commit d314fda into develop Oct 13, 2021
@ProfFan ProfFan deleted the add-failing-axis-angle-test-c++ branch October 13, 2021 23:22
@johnwlambert
Copy link
Contributor Author

@johnwlambert Let's land this first. Could you put up another PR that includes the case that fails?

Sure, thanks for merging

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.

Buggy axis-angle computation in GTSAM
4 participants