34

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

Duck
  • 34,902
  • 47
  • 248
  • 470
  • 7
    1 up for the nice presentation :-) – Kay Mar 02 '11 at 16:32
  • 1
    thanks! now I have to have a nice solution" :D – Duck Mar 02 '11 at 16:42
  • Do you need to interprete the quaternion for determining absolute position or can you deal with delta movements? – Kay Mar 02 '11 at 19:35
  • 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 Mar 02 '11 at 19:41
  • OK new idea. I start a new answer to avoid messing up the question. – Kay Mar 02 '11 at 19:45

5 Answers5

9

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.

Kay
  • 12,918
  • 4
  • 55
  • 77
  • Ah, OK, but have a look at my last edit because of the different readings. Good luck. It's late here, read from you tomorrow. – Kay Mar 02 '11 at 22:42
  • @kay Can i know...., is it possible to use the same concept to determine the angular displacement if i rotate iphone through y-axis back and forth?(around y axis). Please reply me. :) – sam Jul 23 '12 at 15:59
  • @sam Basically yes. But if you just want the angular displacement in one direction, you might be better off using [CMAttitude.roll](http://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMAttitude_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40009943-CH1-SW4) – Kay Jul 23 '12 at 16:20
  • @kay Thank you. Well if i rotate my phone around y axis so that it depicts a sinusoidal movement back and forth, Is it possible to find the angle it rotated from original position to new position and back again(it's true the angle is same)? Is that i need to store roll reading on two occasions and do what? And is it better if i use quaternion to calculate angular displacement in term of accuracy by using a logic to call quaternion when it passes zero axis(going up as a sinusoidal ) and then again call quaternion back when it passes zero axis(down), in the case of a sinusoidal? – sam Jul 23 '12 at 17:18
  • @Kay I use CMAttitude.roll to find angular displacement on one axis, but it's subjected to drifts and errors. Can i know whether i can achieve better reading from rotational matrix? – sam Sep 06 '12 at 16:12
  • @sam rotation matrix is just a different representation of the same values, so you won't get any benefit – Kay Sep 09 '12 at 13:38
  • @kay I think, You can provide me a answer to this question, One way that we could calculate the rate of change of angle is by integrating the gyroscope data with an reference, But we observe a drift in the rate of change of angle signal as the gyroscope data is subjected to drifts,But if we high pass this signal to remove drift, Signal characteristics changes. So what is the solution to this problem? – sam Sep 09 '12 at 16:07
3

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.

Kay
  • 12,918
  • 4
  • 55
  • 77
  • I had all rotations converted using quaternions and the problem continues to show. Exactly the same problem – Duck Mar 02 '11 at 16:18
  • 1
    Do you have a practical example of how this should be done? Meta code would be fine, just to give me an idea of how to solve that. Thanks – Duck Mar 02 '11 at 16:21
  • I struggled with this just 3 weeks ago and finally I got it almost working but it turned out to be to complicated as game controller and thus we threw it away :-( In that case we used 2 axes for control and the pitch's 90 degree limit was quite painful. – Kay Mar 02 '11 at 16:24
  • Basically it depends on your needs. Do you have to use all 3 rotation axes or just 1 or 2 of them? – Kay Mar 02 '11 at 16:25
  • yes, I know that. For that reason I decided to use quaternions to calculate the angles. It works fine... except for this "little" problem. – Duck Mar 02 '11 at 16:26
  • @kay, I have to use all 3 angles... and I need this as angles, not as rotation matrices, quaternions or whatever. Thanks – Duck Mar 02 '11 at 16:26
1

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.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Thanks. I understand that. What I don't see is how I can solve that. At this exact time all I do is to calculate the angles from the quaternion representation and list it on screen. How can that be adding up and provoking a gimbal lock? I suppose this is what is happening but I don't see how. – Duck Mar 02 '11 at 16:32
  • I am using this code for the calculation: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/ what the guy call bank is the one that is giving me problems. – Duck Mar 02 '11 at 16:35
  • I have to admit, I assumed you'd be using the pitch, roll and yaw values returned directly by CoreMotion, as the 'attitude' property of CMDeviceMotion, as passed to a CMDeviceMotionHandler. That seems to be free of any peculiar discontinuities, all you see is yaw and roll looping around when pitch is close to 90 (when the device is in normal, portrait orientation). I'm not immediately able to comment on the quaternion to Euler conversion code linked. – Tommy Mar 02 '11 at 17:44
  • the problem with that pitch, row and yaw stuff is exactly that limitation. The problem is that I am seeing that with quaternions... ????!!!!! – Duck Mar 02 '11 at 19:26
  • 1
    The problem is inevitable, however you end up at Euler angles. It's just a result of the maths involved. Keeping an intermediate quaternion doesn't make a difference. That's why that page has the long exposition on singularities and the suggestion that you might need to consider alternative Euler angle sequences. – Tommy Mar 02 '11 at 19:58
0

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

Community
  • 1
  • 1
iHS
  • 5,372
  • 4
  • 31
  • 49
0

This question looks relevant:

iphone - core motion range of yaw, pitch and roll

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76