Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Euler angles to rotation matrix manual transformation for iOS devices

This is a small background and introduction to the problem:

I have some functionality in my motion- and location-based iOS app, which needs a rotation matrix as an input. Some graphical output is dependent on this matrix. With every movement of the device, graphical output is changed. This is a part of the code which makes that:

[motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical
                                                   toQueue:motionQueue
                                               withHandler:
 ^(CMDeviceMotion* motion, NSError* error){
  //get and process matrix data
 }

In this structure only 4 frames are available:

XArbitraryZVertical

XArbitraryCorrectedZVertical

XMagneticNorthZVertical

XTrueNorthZVertical

I need to have another reference, f.e. gyroscope value instead of North and these frames can not offer me exactly what I want.

In order to reach my goal, I use next structure:

[motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical
                                                   toQueue:motionQueue
                                               withHandler:
 ^(CMDeviceMotion* motion, NSError* error){
  //get Euler angles and transform it to rotation matrix
 }

You may ask me, why I do not use built in rotation matrix? The answer is simple. I need to make some kind of own reference frame and I can make this via putting inside modified values of angles.

The problem:

In order to get rotation matrix from Euler angles we need to make matrix for each angle and after that multiply them. For 3D case we will have matrix for each axis (3 of them). After that we multiply matrixes. The problem is that the output is dependent on the order of multiplication. XYZ is not equal to ZYX. Wikipedia tells me, that there are 12 variants and I do not know which one is the right one for iOS implementation. I need to know in which order I need to multiply them. In addition, I need to know which angles represents X, Y, Z. For example, X - roll, Y - pitch, Z - yaw.

Actually, this problem was solved by Apple years ago, but I do not have access to .m-files and I do not know which order of multiplication is the right one for iOS device.

Similar question was published here, but order from that math example in the solution does not work for me.

like image 216
Oleksandr Tomashchuk Avatar asked Oct 30 '22 18:10

Oleksandr Tomashchuk


1 Answers

Regarding: Which angles relate to which axis.

See this: link:https://developer.apple.com/documentation/coremotion/getting_processed_device-motion_data/understanding_reference_frames_and_device_attitude

enter image description here

Regarding rotation order for calculating rotation matrix & Euler angles (Pitch, Roll, Yaw)

Short Answer: ZXY is the rotation order on iOS.

I kept searching for this answer too. Got tired. Not sure why this is not documented somewhere easy to lookup. I decided to collect empirical data and test out which rotation order best matches the values. My values are below.


Methodology:

  1. Wrote a small iPhone App to return quaternion values & corresponding pitch, roll, yaw angles

  2. Computed pitch, roll, yaw values from the quaternions for various rotation orders (XYZ, XZY, YZX, YXZ, ZYX, ZXY)

  3. Calculated RMS error with respect to the pitch, yaw, roll values reported by iOS device motion. Identified the orientation with the least error.

Results:

Rotation orders: ZYX & ZXY both returned values very close to the iOS reported values. However, the Error on ZXY was ~46-597X lower than ZXY for every case. Hence I believe ZXY is the rotation order.

enter image description here

like image 101
Ravindhran Sankar Avatar answered Nov 15 '22 05:11

Ravindhran Sankar