conversion quaternion <--->euler angles goes wrong

Started by
6 comments, last by apatriarca 11 years ago

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;

}

Advertisement

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.

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

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.

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.

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

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.

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?

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

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

This topic is closed to new replies.

Advertisement