Jump to content

  • Log In with Google      Sign In   
  • Create Account

conversion quaternion <--->euler angles goes wrong


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 bitinf   Members   -  Reputation: 103

Like
0Likes
Like

Posted 06 April 2013 - 01:28 PM

 

I'm trying to implement the conversion between quaternion and Euler angles. I've referred to some exsiting methods. But the results have "sign(±)" problems. That is, I first convert a quaternion q to Euler angles (pan,tilt,roll) and then computer the quaternion again from the acquired Euler angles. But the result sometimes is -q, and sometimes it's q. Below is my code. In my code, I use a coodinate system with z pointing up. Pan is rotation with respect to y-axis, tilt x-axis, roll z-axis. I apply roll first, then tilt, and last pan. Could anyone tell me what is wrong? Thanks a lot!

 

//from quaterion to pan,tilt,roll

void q2ptr(quaternion q, double &pan, double &tilt, double &roll)

{

  double sqw = q.w * q.w;

  double sqx = q.x * q.x;

  double sqy = q.y * q.y;

  double sqz = q.z * q.z;

  double n2 = sqx + sqy + sqz + sqw;

  double eps = 1.e-7;

  double test = q.x * q.y + q.z * q.w;

  if (test > (0.5-eps) * n2)

     {

       // Singularity at north pole

       roll = 2 * atan2(q.x, q.w); // Yaw

       tilt = M_PI/2; // Pitch pan = 0;

      }

   else if (test < -(0.5-eps) * n2)

   {

      // Singularity at south pole

      roll = -2*atan2(q.x, q.w); // Yaw

      tilt = -M_PI/2; // Pitch pan = 0; // Roll

    }

    else

    {

      roll = atan2(2*(q.w*q.y - q.x*q.z), sqx - sqy - sqz + sqw);

      pan = atan2(2*(q.w*q.x - q.y*q.z), -sqx + sqy - sqz + sqw);

      tilt = asin(2*test/n2);

     }

 }

 

 //from pan,tilt,roll to quaterion void

 ptr2q(double pan, double tilt, double roll, quaternion &q)

 {

   double c1, c2, c3, s1, s2, s3; c1 = cos(roll/2);

   c2 = cos(tilt/2);  c3 = cos(pan/2); s1 = sin(roll/2); s2 = sin(tilt/2); s3 = sin(pan/2);

   q.w = c1*c2*c3 - s1*s2*s3;

   q.x = s1*s2*c3 + c1*c2*s3;

   q.y = s1*c2*c3 + c1*s2*s3;

   q.z = c1*s2*c3 - s1*c2*s3;

   }



Sponsor:

#2 Paradigm Shifter   Crossbones+   -  Reputation: 5381

Like
0Likes
Like

Posted 06 April 2013 - 01:38 PM

q and -q represent the same rotation, unit quaternions are a double cover for the sphere.

 

The only issue is when interpolating/slerping quaternions, you want to go the quickest route rather than the long way round, but you can do that by checking that the quaternion dot product between the 2 quaternions is positive, if it is negative negate one of the quaternions before interpolation.

 

EDIT: If you think about the axis/rotation form of a quaternion it is easy to see that -q and q represent the same rotation; the axis is negated but so is the rotation angle => they represent the same rotation.

 

EDIT2: Euler angle representations aren't unique either, so converting Euler angles to a quaternion and then back again might not give you the same angles back either ;)

 

EDIT3: So in conclusion, there's nothing to worry about.


Edited by Paradigm Shifter, 06 April 2013 - 01:49 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#3 bitinf   Members   -  Reputation: 103

Like
0Likes
Like

Posted 06 April 2013 - 03:05 PM

Thank you so much for the timely reply. I know -q and q represent the same rotation.

You say that one quaternion may have many corresponding Euler angles. I also think so. But why common methods only return a single set of angles?   And the same, why the inverse (from angles to quaternion) returns a single quaternion?  Are there some rules in it?

Thanks!

 

q and -q represent the same rotation, unit quaternions are a double cover for the sphere.

 

The only issue is when interpolating/slerping quaternions, you want to go the quickest route rather than the long way round, but you can do that by checking that the quaternion dot product between the 2 quaternions is positive, if it is negative negate one of the quaternions before interpolation.

 

EDIT: If you think about the axis/rotation form of a quaternion it is easy to see that -q and q represent the same rotation; the axis is negated but so is the rotation angle => they represent the same rotation.

 

EDIT2: Euler angle representations aren't unique either, so converting Euler angles to a quaternion and then back again might not give you the same angles back either ;)

 

EDIT3: So in conclusion, there's nothing to worry about.



#4 Paradigm Shifter   Crossbones+   -  Reputation: 5381

Like
0Likes
Like

Posted 06 April 2013 - 03:21 PM

Any set of the angles will do (just like returning q or -q is acceptable as well). If you want the other quaternion representing the Eulers, negate it.

 

I guess the reason for ambiguity is because of the call to asin (which returns angles only in a 180 degree (or pi radian) range), not the full range (because of how inverse functions work, they can only return one value). Try adding pi on to the return from asin, you will probably get the other quaternion instead... (EDIT: asin(x + pi) != asin(x) so ignore that ;), the formula is asin(x + pi) = -asin(x), I think [too much beer])

 

(atan2 does return full 2pi radian range though).

 

I wouldn't worry about it though. Note the trig functions don't really have inverse functions (since a function can only return one value in the strict mathematical sense of the term), asin is a restirction of the "inverse" sin funtion so that it does have a unique inverse.

 

EDIT: Try thinking of it like this instead:

 

why doesn't sqrt(-1 * -1) return -1? Same deal.


Edited by Paradigm Shifter, 06 April 2013 - 03:43 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#5 bitinf   Members   -  Reputation: 103

Like
0Likes
Like

Posted 06 April 2013 - 04:18 PM

thanks a lot!

Any set of the angles will do (just like returning q or -q is acceptable as well). If you want the other quaternion representing the Eulers, negate it.

 

I guess the reason for ambiguity is because of the call to asin (which returns angles only in a 180 degree (or pi radian) range), not the full range (because of how inverse functions work, they can only return one value). Try adding pi on to the return from asin, you will probably get the other quaternion instead... (EDIT: asin(x + pi) != asin(x) so ignore that ;), the formula is asin(x + pi) = -asin(x), I think [too much beer])

 

(atan2 does return full 2pi radian range though).

 

I wouldn't worry about it though. Note the trig functions don't really have inverse functions (since a function can only return one value in the strict mathematical sense of the term), asin is a restirction of the "inverse" sin funtion so that it does have a unique inverse.

 

EDIT: Try thinking of it like this instead:

 

why doesn't sqrt(-1 * -1) return -1? Same deal.



#6 apatriarca   Crossbones+   -  Reputation: 1721

Like
0Likes
Like

Posted 18 April 2013 - 01:36 AM

May I ask why do you need such conversion? I have never found a use case for it. The Euler angle to quaternion conversion is probably useful in tools because Euler angles are sometimes more intuitive from a user perspective, but why returning Euler angles from a quaternion?



#7 Paradigm Shifter   Crossbones+   -  Reputation: 5381

Like
0Likes
Like

Posted 18 April 2013 - 03:10 AM

Yeah, it's not that useful but you could use it for an onscreen compass or something (I'm not saying that would be the best way to implement a compass though)

 

If you support one operation you may as well support the inverse, it makes a good test case and the OP discovered that the representation isn't unique anyway, so maths was done, all is well ;)


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#8 apatriarca   Crossbones+   -  Reputation: 1721

Like
0Likes
Like

Posted 18 April 2013 - 03:39 AM

If you support one operation you may as well support the inverse, it makes a good test case and the OP discovered that the representation isn't unique anyway, so maths was done, all is well ;)

Yeah, it surely helped bitinf to have a better understanding of these rotation representations. smile.png






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS