Skip to content

Geometry/EulerAngles: make sure that returned solution has canonical ranges

NB: this is possibly a breaking change because, compared to legacy code, it may return a different dual solution, which is equally valid, but mapped to the respective canonical (standard) Euler angle ranges.

Reference issue

#2617 (initially started out describing an unrelated issue in unsupported/EulerAngles; this issue does not close #2617)

What does this implement/fix?

Per detailed discussion in #2617, this is an initial implementation of the formulas derived by @evbernardes given in this comment for Tait-Bryan angle sequences and in this comment for proper Euler sequences.

Prior to this fix, Eigen was returning a set of angles in a non-standard set of angle ranges, [0, pi] × [-pi, pi] × [-pi, pi], which is inappropriate for e.g. yaw-pitch-roll computations which is probably the most common application of .eulerAngles().

Without an angle range restriction, for any given rotation (matrix) and Euler sequence, there are two valid solution sets of Euler angles in the general, non-degenerate (non-gymbal lock) case. This MR applies solution-flipping formulas derived by @evbernardes to flip the solution to the one inside the canonical range for the respective kind of Euler angles:

  • [-pi, pi] × [-pi/2, pi/2] × [-pi, pi] for Tait-Bryan angles (a0 != a2, e.g. ZXY)
  • [-pi, pi] × [0, pi] × [-pi, pi] for proper Euler angles (a0 == a2, e.g. XYX)

This MR introduces a default-parameter bool canonical = true which defaults all clients to the new (more correct) behaviour. The existing code for computing angles which has seen long time battle-testing and seems to be robust to degenerate cases has deliberately not been touched; instead we apply at the very end a single solution-flip step when needed, which brings the solution angles into the respective canonical ranges.

If a client wants to keep using legacy Eigen behaviour, they can pass canonical = false to .eulerAngles().

Edited by Juraj Oršulić

Merge request reports

Loading