This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 609 - Euler Angles not Angle reversible, documentation example lacking, possible gimble lock issue resolveable
Euler Angles not Angle reversible, documentation example lacking, possible gi...
 Status: RESOLVED FIXED None Eigen Unclassified Geometry (show other bugs) 3.2 All All Normal Unknown Nobody 3.3 Show dependency tree / graph

 Reported: 2013-06-05 17:47 UTC by johnmichael.fischer 2019-12-04 12:22 UTC (History) 5 users (show) chtz gael.guennebaud hauke.heibel jacob.benoit.1 johnmichael.fischer

Attachments
Avoid if statement and improve consistency of eulerAngles method (6.80 KB, patch)
2013-06-06 22:44 UTC, Gael Guennebaud
no flags Details | Diff
self-contained test case (2.94 KB, application/octet-stream)
2013-06-27 18:44 UTC, Gael Guennebaud
no flags Details

 johnmichael.fischer 2013-06-05 17:47:45 UTC ```In testing the Eigen/EulerAngles implementation I have shown that I create a matrix and go Matrix > Angles > Matrix but I cannot successfully go Angles > Matrix > Angles for any matrix other than the identity matrix. Example code // Hand-Craft, ANG > MAT > ANG // first quad inputAngles << 0, 0, M_PI/4; outputMatrix.block<3,3>(0, 0) = (Eigen::AngleAxisf(inputAngles, Eigen::Vector3f::UnitZ()) * Eigen::AngleAxisf(inputAngles, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(inputAngles, Eigen::Vector3f::UnitZ())).toRotationMatrix(); outputAngles = inputMat.block<3,3>(0,0).eulerAngles(2, 0, 2); // follows Z-X-Z with output inputAngles == [0.78539819, 0.78539819, 0.78539819] pi/4, pi/4, pi/4 outputAngles == [-2.3561945, -0.78539824, -2.3561945] -3pi/4, -pi/4, -3pi/4 See this thread for more (http://forum.kde.org/viewtopic.php?f=74&t=111436&p=266230#p266230) Obviously Euler angles have lots of different conventions -- if the Eigen documentation gave a very thorough walk through for one convention it would be very helpful. Also what the expected domain/range of the three euler angles is would be handy without having to dig through the source code. Finally it is posited here (https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2012/07/euler-angles.pdf) that according to the Graphics Gems IV method (which, according to the Eigen source code is in use) it is possible to avoid floating point instability by slightly modifying the generation method of the third coefficient``` johnmichael.fischer 2013-06-05 17:51:53 UTC ```Here is an updated code example including variable definitions. The original code example got a little mushed in copy and paste. Eigen::Matrix4f inputMat; Eigen::Matrix4f outputMat; Eigen::Array3d inputAngles; Eigen::Array3d outputAngles; inputMat = outputMat = Eigen::Matrix4f::Identity(); // Hand-Craft, ANG > MAT > ANG // first quad inputAngles << M_PI/4, M_PI/4, M_PI/4; outputMatrix.block<3,3>(0, 0) = (Eigen::AngleAxisf(inputAngles, Eigen::Vector3f::UnitZ()) * Eigen::AngleAxisf(inputAngles, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(inputAngles, Eigen::Vector3f::UnitZ())).toRotationMatrix(); outputAngles = outputMatrix.block<3,3>(0,0).eulerAngles(2, 0, 2); // follows Z-X-Z``` Gael Guennebaud 2013-06-06 22:44:15 UTC ```Created attachment 342 [details] Avoid if statement and improve consistency of eulerAngles method Here is a patch implementing the approach of linked pdf. The return angles are guaranteed to be in the range [0:pi]x[0:pi]x[-pi:pi]. Implementation-wise this is much simpler and faster this way than starting with a wider [-pi:pi] range.``` johnmichael.fischer 2013-06-09 19:46:48 UTC `This looks great. Thanks a lot for your time on this wonderful project.` Gael Guennebaud 2013-06-09 23:16:45 UTC ```https://bitbucket.org/eigen/eigen/commits/b12526cb05c9/ Changeset: b12526cb05c9 User: ggael Date: 2013-06-09 23:14:45 Summary: Fix bug 609: avoid if statement and improve consistency of eulerAngles method``` johnmichael.fischer 2013-06-27 17:36:02 UTC ```I need to re-open this. Not having success with all test cases. All of the hand constructed matricies are checked with the following code (written here for brevity). Matricies are hand crafted for a right-hand system, although the determinant is still checked for safety. The following test cases do not work and I've follow-copies the input/output for inspection. Eigen::Matrix4f inputMat, outputMat; Eigen::Array3d inputAngles; inputMat = Eigen::Matrix4f::Identity(); outputMat = inputMat; // MAT > ANG > MAT inputMat.block<3,1>(0,0) << 0,1,0; inputMat.block<3,1>(0,1) << -1,0,0; inputMat.block<3,1>(0,2) << 0,0,1; if( inputMat.determinant() != 1 ) { // flip from LH to RH inputMat.block<3,1>(0,2) *= -1; } outputMat = inputMat; inputAngles = inputMat.block<3,3>(0,0).cast().eulerAngles(2, 0, 2); // follows Z-X-Z outputMat.block<3,3>(0, 0) = (Eigen::AngleAxisd(inputAngles, Eigen::Vector3d::UnitZ()) * Eigen::AngleAxisd(inputAngles, Eigen::Vector3d::UnitX()) * Eigen::AngleAxisd(inputAngles, Eigen::Vector3d::UnitZ())).toRotationMatrix().cast(); // Gives 0 -1 0 0 1 0 0 0 0 0 1 0 0 0 0 1 -0.846852 -0.531829 0 0 0.107965 -0.171917 0.979177 0 -0.520755 0.829218 0.203007 0 0 0 0 1 // Hand-Craft, MAT > ANG > MAT inputMat.block<3,1>(0,0) << 0,-1,0; inputMat.block<3,1>(0,1) << 1,0,0; inputMat.block<3,1>(0,2) << 0,0,1; // Gives 0 1 0 0 -1 0 0 0 0 0 1 0 0 0 0 1 2.22045e-016 1.57009e-016 -1 0 1.57009e-016 1 1.57009e-016 0 1 -1.57009e-016 2.22045e-016 0 0 0 0 1 // Hand-Craft, MAT > ANG > MAT inputMat.block<3,1>(0,0) << 0,-1,0; inputMat.block<3,1>(0,1) << -1,0,0; inputMat.block<3,1>(0,2) << 0,0,-1; // Gives 0 -1 0 0 -1 0 0 0 0 0 -1 0 0 0 0 1 -2.22045e-016 -1.57009e-016 1 0 1.57009e-016 -1 -1.57009e-016 0 1 1.57009e-016 2.22045e-016 0 0 0 0 1 Here are two examples in reverse, checked with the following code, which also aren't working inputMat = outputMat = Eigen::Matrix4f::Identity(); // Hand-Craft, ANG > MAT > ANG // first quad inputAngles << 0, 0, 0; outputMat.block<3,3>(0, 0) = (Eigen::AngleAxisd(inputAngles, Eigen::Vector3d::UnitZ()) * Eigen::AngleAxisd(inputAngles, Eigen::Vector3d::UnitX()) * Eigen::AngleAxisd(inputAngles, Eigen::Vector3d::UnitZ())).toRotationMatrix().cast(); outputAngles = outputMat.block<3,3>(0,0).cast().eulerAngles(2, 0, 2); // follows Z-X-Z // Gives 0 0 0 1.5708 1.5708 1.5708 // Hand-Craft, ANG > MAT > ANG inputAngles << M_PI/4, 0, 0; // Gives 0.785398 0 0 1.5708 1.5708 1.5708``` Gael Guennebaud 2013-06-27 18:44:02 UTC ```Created attachment 360 [details] self-contained test case Works for me with the attached self-contained example. It works both with double and float. Remark that with the Z-X-Z convention, if the second angle (around X) is zero then the Euler angles are not uniquely defined. As I already explained, we always pick the one with the first angle equal to zero.``` johnmichael.fischer 2013-07-03 18:03:54 UTC `I got everything working. Thanks again.` johnmichael.fischer 2013-11-29 18:07:17 UTC ```(In reply to comment #2) > Created attachment 342 [details] [review] > Avoid if statement and improve consistency of eulerAngles method > > Here is a patch implementing the approach of linked pdf. The return angles are > guaranteed to be in the range [0:pi]x[0:pi]x[-pi:pi]. Implementation-wise this > is much simpler and faster this way than starting with a wider [-pi:pi] range. Based on a specific example and studying the math again, it appears the second angle can be -pi:pi, not 0:pi as listed now in the docs. EulerAngle.h lines 60 and 65 seem to allow for values 0:-pi and 0:pi respectively. For example, this matrix evaluates to a second angle which is slightly less than -pi/2 (using Z-X-Z convention) -0.0619354 -0.018203 -0.997914 0 -0.99757 -0.0308364 0.0624764 0 -0.0319091 0.999359 -0.0162488 0 0 0 0 1 Is this a bug in the docs or the angle code? Thanks``` Christoph Hertzberg 2013-11-29 19:48:38 UTC ```This seems to have been a bug in the docs. I fixed the doc and extended the unit test (in default and 3.2): http://bitbucket.org/eigen/eigen/commits/42e0115 http://bitbucket.org/eigen/eigen/commits/4a867dd``` Nobody 2019-12-04 12:22:02 UTC ```-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/609.```

 Note You need to log in before you can comment on or make changes to this bug.