I am trying to convert quaternions provided by a MPU6050 to heading attitude and bank values but at least one of the three calculations is broken, for example in the third calculation (the uncommented one) the yaw and pitch are in the same axis and the other two almost do not change, do you know which specific formula should apply here, or at least some theory on different ways of quaternions representation that helps me figure out the maths behind this?
float heading;
float attitude;
float bank;
double test = q.x * q.y + q.z * q.w;
if (test > 0.499) { // singularity at north pole
heading = 2 * atan2(q.x, q.w);
attitude = M_PI / 2;
bank = 0;
return;
}
if (test < -0.499) { // singularity at south pole
heading = -2 * atan2(q.x, q.w);
attitude = - M_PI / 2;
bank = 0;
return;
}
double sqw = q.w * q.w;
double sqx = q.x * q.x;
double sqy = q.y * q.y;
double sqz = q.z * q.z;
/*
//http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
heading = atan2(2 * q.y * q.w - 2 * q.x * q.z , 1 - 2 * sqy - 2 * sqz);
attitude = asin(2 * test);
bank = atan2(2 * q.x * q.w - 2 * q.y * q.z , 1 - 2 * sqx - 2 * sqz);
*/
/*
// https://www.i2cdevlib.com/forums/topic/24-roll-and-pitch-angles-ranges/
heading = atan2(2 * q.x * q.y - 2 * q.w * q.z , 2* sqw + 2 * sqx - 1);
attitude = asin(2 * test);
bank = atan2(2 * q.x * q.w - 2 * q.y * q.z , 1 - 2 * sqx - 2 * sqz);
*/
//https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/indexLocal.htm
heading = atan2(2.0 * (q.x*q.y + q.z*q.w),(sqx - sqy - sqz + sqw));
bank = atan2(2.0 * (q.y*q.z + q.x*q.w),(-sqx - sqy + sqz + sqw));
attitude = asin(-2.0 * (q.x*q.z - q.y*q.w));
Serial.print("conversion\t");
Serial.print(heading * 180 / M_PI);
Serial.print("\t");
Serial.print(attitude * 180 / M_PI);
Serial.print("\t");
Serial.println(bank);
testdoesn't match Wikipedia or the SE answer linked (even after ignoring the sign). However Wiki and SE linked answer matches theattitudevariable for the third set (ignoring sign). – AJN Jul 17 '20 at 18:52