34
votes

I am banging my head on the wall trying to understand this. See the next picture.

Suppose I have an iPhone resting on a table. At this time the rotation readings thru core motion are 0,0,0 for yaw, roll and pitch (picture A).

Then I roll it 90 degrees. Now it is sitting on the table with its left side, home button on the right. Now it reads 0,0,0 (picture B).

Now I yaw it 180 degrees. It is now sitting with its right side on the table. Home button on the left. It now reads 180,0,0 (picture C).

The problem comes if I roll it now. Suppose I roll it -45 degrees. I should be reading 180,-45,0 but instead I am reading 180,-45,180???? (picture D).

Why is that? Why is it giving me a value for pitch if I never changed that? How can be pitch influenced by a rotation in other angles? thanks.

enter image description here

5
1 up for the nice presentation :-)Kay
thanks! now I have to have a nice solution" :DDuck
Do you need to interprete the quaternion for determining absolute position or can you deal with delta movements?Kay
If I could obtain delta movements I would be a happy man, because I am using absolute angles to calculate exactly delta movements! I have tried to obtain that reseting the attitude reference after reading a value, so the movement would be relative to the previous read. The problem I had was that if I rotated X degrees to one direction then back the same amount, I would get different readings. For example: 0,0,0 for iphone at rest, then I rotate to some angle and back to rest and I will not read 0,0,0 anymore.Duck
OK new idea. I start a new answer to avoid messing up the question.Kay

5 Answers

9
votes

Given the case that you can live with delta movements, you can use "quaternion difference" operation. Let's say you have a previous rotation as quaternion called q1 and the current one q2. Then you can calculate the delta dQ between them so that q2 = q1*dQ is valid. All you have to do is build the inverse of q1 (q1^(-1)) and then you get:

dQ = q1^(-1) * q2

If deviceMotionInterval is high enough, you always have handy small Euler angles without any 90° singularities or other beasty stuff. The possible drawback of this solution might be a slight drift because of error propagation and the lack of feedback from your virtual space. Example: if you have your iPhone on a table showing a cube and then do a sequence of rotations, you might find a angular displacment of the cube when you put the phone back in starting position.

[EDIT:Forgot some part] To get rid of the drifting effect, you "only" need a way to express your last object's real position (q1) as a quaternion i.e. coordinates in your app as displayed on the screen. If you use tools like Unity it might be just reading the appropriate property of an the object. If you don't have easy access to it, you may have the possibility to track this position manually.

If you want to read more about this take a look at 3D math primer for graphics and game development, by Fletcher Dunn,Ian Parberry page 168.

3
votes

Euler angles are not that precise for decribing arbitrary rotation like quaternions or rotation matrices. There is often more than one set of angles to decribe a rotation and thus it's not unique.

[Edit:] As stated by Harinder core motion converts the angles into canonical representation i.e. there are some constraints - I am not sure but think the pitch angle is limited to [-90;90].

Have a look at Gimbal Lock or some similar articles about the phenomenon.

1
votes

I was unable to replicate the same results. Using the (free) Gyroscope app, reporting as roll, pitch, yaw I get (0, 0, 0) for position A, then (-90, 0, 0) for B, (-90, 0, 180) for C (which actually causes the device to face away from me, unlike in your diagram), then (-45, 0, 180) for D.

Even flipping that because you seem to be listing as yaw, roll, pitch, that's still (0, 0, 0) -> (0, -90, 0) -> (180, -90, 0) -> (180, -45, 0). Adding a roll by -90 before reporting would make the pitch and yaw axes parallel, creating gimbal lock as mentioned by faster typers than I.

The basic problem is that any attempt to describe rotation in three axes gives an implicit order of rotations — it's "rotate this much around x, then this much around y, then this much about z". Whatever order you pick, there's always a possibility for the rotation around the first axis to align the other two axes. Orientation is three dimensional, so can be described with three numbers (eg, by using unit quaternions but leaving the fourth term implicit), but not by Euler angles.

EDIT: in reference to your comment above, you can obtain delta movements by registering a handler with -startDeviceMotionUpdatesToQueue:withHandler:. That'll receive a series of CMDeviceMotions, from which you can look at the rotationRate member.

0
votes

The accelerometer measures the sum of two acceleration vectors: gravity and user acceleration. User acceleration is the acceleration that the user imparts to the device. Because Core Motion is able to track a device’s attitude using both the gyroscope and the accelerometer, it can differentiate between gravity and user acceleration

This might be helpful for you:

an-absolute-degree-measurement