EulerAngles gives wrong result on a gymbal lock configuration
Summary
Eigen::EulerAngles gives a wrong result on a gymbal lock configuration
Environment
Godbolt x86-64 Eigen 3.4.0 gcc 12.2
Eigen versions prior to 3.4.0 don't seem to have the problem.
Minimal Example
https://godbolt.org/z/YWex16oWE
#include <iostream>
#include <unsupported/Eigen/EulerAngles>
int main() {
Eigen::Quaterniond q(0.5, 0.5, 0.5, -0.5);
std::cout << q.coeffs();
std::cout << std::endl << std::endl;
puts("eulerAngles gives correct XYZ angles:");
Eigen::Vector3d ea = Eigen::Matrix3d(q).eulerAngles(1,0,2) / M_PI * 180.;
std::cout << ea(0) << " " << ea(1) << " " << ea(2) << std::endl << std::endl;
puts("Eigen::EulerAngles: (also correct in this case)");
Eigen::Vector3d ea2 = Eigen::EulerAnglesYXZd(q).angles() / M_PI * 180.;
std::cout << ea2(0) << " " << ea2(1) << " " << ea2(2) << std::endl << std::endl;
puts ("The linear subspace of correct solutions satisfies \n"
"first angle - third angle = 90\n");
// Cursed quaternion for Eigen::EulerAnglesYXZ
// Arch is x86-64
Eigen::Quaterniond q2;
auto& coeffs = q2.coeffs();
*(uint64_t*)&coeffs(0) = 0x3FDFFFFFC0000000;
*(uint64_t*)&coeffs(1) = 0x3FE0000000000001;
*(uint64_t*)&coeffs(2) = 0xBFE0000000000000;
*(uint64_t*)&coeffs(3) = 0x3FDFFFFFBFFFFFFE;
puts("Almost the same quaternion, -0.000000059604645 diff in x and w \n"
"due to floating point garbage. Printing it gives impression it is identical ");
std::cout << q2.coeffs();
std::cout << std::endl << std::endl;
puts("eulerAngles method still works:");
Eigen::Vector3d ea3 = Eigen::Matrix3d(q2).eulerAngles(1,0,2) / M_PI * 180.;
std::cout << ea3(0) << " " << ea3(1) << " " << ea3(2) << std::endl << std::endl;
Eigen::Vector3d ea4 = Eigen::EulerAnglesYXZd(q2).angles() / M_PI * 180.;
puts("Eigen::EulerAngles on Eigen >= 3.4.0 now gives a wrong result, 0 90 0!");
std::cout << ea4(0) << " " << ea4(1) << " " << ea4(2) << std::endl << std::endl;
}
Steps to reproduce
Open Godbolt
What is the current bug behavior?
Incorrect angles computed
What is the expected correct behavior?
Correct angles computed
Relevant logs
Eigen 3.4.0:
0.5
0.5
-0.5
0.5
eulerAngles gives correct XYZ angles:
0 90 -90
Eigen::EulerAngles: (also correct in this case)
90 90 0
The linear subspace of correct solutions satisfies
first angle - third angle = 90
Almost the same quaternion, -0.000000059604645 diff in x and w
due to floating point garbage. Printing it gives impression it is identical
0.5
0.5
-0.5
0.5
eulerAngles method still works:
0 90 -90
Eigen::EulerAngles on Eigen >= 3.4.0 now gives a wrong result, 0 90 0!
0 90 1.06722e-07
On Godbolt, with Eigen 3.3.9 and prior it seems to work correctly:
0.5
0.5
-0.5
0.5
eulerAngles gives correct XYZ angles:
0 90 -90
Eigen::EulerAngles: (also correct in this case)
0 90 -90
The linear subspace of correct solutions satisfies
first angle - third angle = 90
Almost the same quaternion, -0.000000059604645 diff in x and w
due to floating point garbage. Printing it gives impression it is identical
0.5
0.5
-0.5
0.5
eulerAngles method still works:
0 90 -90
Eigen::EulerAngles on Eigen >= 3.4.0 now gives a wrong result, 0 90 0!
0 90 -90
Edited by Juraj Oršulić