8

I have a CMRotationMatrix *rot and i would like to get the pitch, yaw, roll from the matrix. Any ideas how i could do that?

Thanks

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Jonas Schnelli
  • 9,965
  • 3
  • 48
  • 60

3 Answers3

29

Its better to use the Quaternion than Euler angles.... The roll, pitch and yaw values can be derived from quaternion using these formulae:

roll  = atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z)
pitch = atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z)
yaw   =  asin(2*x*y + 2*z*w)

It can be implemented as:

CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
myRoll = radiansToDegrees(atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z)) ;
myPitch = radiansToDegrees(atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z));
myYaw = radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));

where the radianstoDegrees is a preprocessor directive implemented as:

#define radiansToDegrees(x) (180/M_PI)*x

This is done to convert the radian values given by the formulae, to degrees.

More information about the conversion can be found here: tinkerforge and here:Conversion between Quaternions and Euler angles.

Andrei Marincas
  • 446
  • 5
  • 13
iSeeker
  • 776
  • 1
  • 8
  • 24
  • 2
    I'm curious, what's the reason behind "it's better to use Quaternion than Euler Angles" ? – Jacksonkr Jun 21 '16 at 23:13
  • 2
    Thanks. It works well. motionManager.deviceMotion.attitude.pitch/roll/yaw are really unstable.I am wondering why Apple does not fix them. – Vince Yuan Dec 01 '17 at 14:31
  • 2
    It's because Euler angles can fall into [Gimbal lock](https://en.wikipedia.org/wiki/Gimbal_lock) and you lost one degree of freedom which you cannot successfuly get back. There are workarounds (such as detecting near gimbal lock state) but better and more efficient solution is to use other representation (quaternions or rotation matrices). Still euler angles are easy to use (and understand) and is OK for many use cases. – Palli Nov 23 '18 at 08:50
  • 1
    how would you convert these values to 0:360 degrees range? – Ilker Baltaci May 28 '19 at 13:13
  • 3
    I agree with the other comments here; the roll / pitch / yaw values from Apple seem unstable / vulnerable to the Gimbal lock condition. Specifically, when I alter the pitch of my device drastically, the roll value often becomes erratic, even when I don't actually "roll" the device. – Brian Sachetta Sep 09 '19 at 14:58
1

pitch, yaw, roll from the matrix. Any ideas how i could do that?

In which order? Pitch, yaw and roll, commonly called Euler angles, don't represent rotations unambigously. Depending on the order you carry out the individual sub-rotations you end up with completely different rotation matrices.

My personal recommendation: Don't use Euler angles at all, they just call for (numerical) trouble. Use a matrix (you already do) or a quaternion.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
-2

Found it out myself:

CMAttitude *currentAttitude = motionManager.deviceMotion.attitude;    

        if (currentAttitude == nil)
        {
            NSLog(@"Could not get device orientation.");
            return;
        }
        else {
            float PI = 3.14159265;
            float yaw = currentAttitude.yaw * 180/PI;
            float pitch = currentAttitude.pitch * 180/PI;
            float roll = currentAttitude.roll * 180/PI;

        }
Jonas Schnelli
  • 9,965
  • 3
  • 48
  • 60