I have been working on an app that uses a side-to-side tilt motion gesture. I have it working using the CMDeviceMotion data via the CMQuaternion values to get "roll" via Using quaternion instead of roll, pitch and yaw to track device motion but I have one weird bit of behaviour where the output will sometimes work perfectly and others not.
The app is locked to landscape orientation (both ways) but I have noticed that if I start the app held in portrait orientation my roll code works perfectly with a pi/2 modifier. If I open the app with the device held in landscape it works on pitch with no modifier.
The problem is that I have no way of knowing which to use! Is there some way of detecting or reseting the frame of reference?
UPDATE:
I tell a lie, if I start in landscape orientation it seems to just pick a random axes :( I assume this is again a Gimbal Lock thing but the original question still applies - how do I get this to be consistent when I start the device in a landscape orientation?
UPDATE 2:
Some token code (coming from a NSNotification) for people who can't read and feel the need to downvote without.
CMDeviceMotion *data = [[note userInfo] valueForKey:@"data"];
CMQuaternion quat = data.attitude.quaternion;
CGFloat roll = atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z);
CGFloat pitch = atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z);
CGFloat yaw = 2*(quat.x*quat.y + quat.w*quat.z);
NSLog(@" - - ");
NSLog(@"raw roll: %f",roll);
NSLog(@"raw pitch: %f",pitch);
NSLog(@"raw yaw: %f",yaw);
NSLog(@"q.x: %f",quat.x);
NSLog(@"q.y: %f",quat.y);
NSLog(@"q.z: %f",quat.z);
NSLog(@"q.w: %f",quat.w);
Launched from startDeviceMotionUpdatesToQueue
in AppDelegate.
This is irrelevant however as the issue is that the quaternion data is stable when the device is in a portrait orientation at launch but not with a landscape orientation. What I choose to do with the device data is a totally separate issue.
This is a similar issue without a satisfactory answer (or any code in the question :|) CMDeviceMotion yaw values unstable when iPhone is vertical