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

A question regarding Euler angles from quaternion #6

Open
neilyoung opened this issue Nov 11, 2019 · 3 comments
Open

A question regarding Euler angles from quaternion #6

neilyoung opened this issue Nov 11, 2019 · 3 comments

Comments

@neilyoung
Copy link

neilyoung commented Nov 11, 2019

I'm having this quaternion (x,y,z,w):

-0.299166,-0.106895,-0.0551278,0.946591

My (C++ based) conversion gives a rotation matrix, which is pretty much identical to the R given in your page https://www.andre-gaschler.com/rotationconverter/ for the given quaternion:

R: 0.971, 0.168,-0.169,-0.040, 0.815, 0.578, 0.235,-0.555, 0.798

I'm having a doubt regarding the 'yaw' value. The coordinate system, which generates this quaternion, has the following axis convention: X is getting larger towards right, Y is getting larger towards the sky and Z is getting negative, if moving forward. Hence my code adapts to Euler Angles by sorting the values Euler like (NED, x forward/north, y right/east, z down):

float calculateRotation(const rs2_quaternion &quaternion)
{
    // http://www.chrobotics.com/library/understanding-euler-angles
    // The original axis naming is different from Euler. Align
    float w = quaternion.w;
    float x = -quaternion.z;
    float z = -quaternion.y;
    float y = quaternion.x;

    float pitch = -asin(2.0 * (x * z - w * y)) * 180.0 / M_PI;
    float roll = atan2(2.0 * (w * x + y * z), w * w - x * x - y * y + z * z) * 180.0 / M_PI;
    float yaw = atan2(2.0 * (w * z + x * y), w * w + x * x - y * y - z * z) * 180.0 / M_PI;

    return yaw;
}

The values returned for 'yaw' exactly reflect the rotation of my device around the y axis (Euler's z).

I'm now having a little doubt regarding the Euler Angle conversion of your page https://www.andre-gaschler.com/rotationconverter/: Whereas my calculation for the given quaternion gives 11.9819 degrees, which is ok for me, since I rotated right a bit, the only matching value is the Y value, if I choose "YXZ", but the sign is inverted, so -11.9818413 instead.

The same for these two examples:

Q: 0.27421,-0.359027,-0.139633,0.881142
R: 0.703, 0.049,-0.709,-0.443, 0.811,-0.383, 0.556, 0.583, 0.592
Yaw: 50.1589

Your value for yaw: Y=-50.1588726, if YXZ is selected.

Or:

Q: 0.961622,0.00379452,-0.274343,-0.00216471
R: 0.849, 0.006,-0.528, 0.008,-1.000, 0.002,-0.528,-0.006,-0.849
Yaw: 148.153

Your value for yaw: Y=-148.1534521, if YXZ is selected.

In all cases your and my conversion of Q to R or R to Q give identical results. Just the yaw sign is different...

Any idea, why this might be the case?

@neilyoung
Copy link
Author

neilyoung commented Nov 11, 2019

Hmm. Your sign just makes sense to me, if all rotations are mathematical positive (counter clockwise). Can this be the reason? The I would just need an explanation, why I have to choose "YXZ" in order to find my yaw at y. If I follow the Euler wiki, then there is this equivalency:

y-x'-z'' (intrinsic) is z-x-y (extrinsic)

The last statement reflects my axis configuration... (z is Euler x, x is Euler y, y is Euler z).

Does this make sense?

I would have to change my algorithm to

float calculateRotation(const rs2_quaternion &quaternion)
{
    // http://www.chrobotics.com/library/understanding-euler-angles
    // The original axis naming is different from Euler. Align
    float w = quaternion.w;
    float x = quaternion.z;
    float z = quaternion.y;
    float y = quaternion.x;

    float pitch = -asin(2.0 * (x * z - w * y)) * 180.0 / M_PI;
    float roll = atan2(2.0 * (w * x + y * z), w * w - x * x - y * y + z * z) * 180.0 / M_PI;
    float yaw = atan2(2.0 * (w * z + x * y), w * w + x * x - y * y - z * z) * 180.0 / M_PI;

    return yaw;
}


Note: Only the negation of the quaternion.z and .y values has been removed. I don't really understand this, but it works and aligns yours and mine...

@emilio-cartoni
Copy link

I confirm having the same problem with Y value after conversion to Euler XYZ from quaternion.

Using scipy I get positive Y rotation (0.71383966):

In [6]: R.from_quat([-0.34923958 , 0.01531289 , 0.93682159 , 0.01274906]).as_euler(
   ...: 'xyz')
Out[6]: array([0.02617994, 0.71383966, 3.12413937])

In [7]: R.from_quat([-0.34923958 , 0.01531289 , 0.93682159 , 0.01274906]).as_matrix
   ...: ()
Out[7]: 
array([[-0.75573835, -0.03458292, -0.65395991],
       [ 0.01319145, -0.99920595,  0.03759584],
       [-0.65474081,  0.01978594,  0.75559446]])

Using the online calculator at https://www.andre-gaschler.com/rotationconverter/ I get the same matrix but in the conversion to Euler XYZ the result is:
[ x: -0.0482988, y: -0.7129951, z: 3.0979631 ]

@minhlenhat21
Copy link

minhlenhat21 commented Oct 31, 2023

I have an issue when converting my quaternion sample to Euler Angle.
My quaternion q = [-0.603699,- 0.60275 ,- 0.327831 ,- 0.405948] (w,x,y,z form), and when I use my code (python), I get the result [ 1.51204108, -0.0936848 , 1.09562941] (Matlab function has the same result as me) but your calculator is [ x: 1.4448072, y: 1.0868569, z: 0.2054925 ].
Any idea ?

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

No branches or pull requests

3 participants