I need some help using gyroscope on iPhone. I can't understand readings from CMAttitude regarding pitch, roll and yaw in a particular situation.
This is my code
- (void)handleDeviceMotion:(CMDeviceMotion*)motion {
NSLog(@"Yaw %f ",attitude.yaw * 180 / M_PI);
NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI);
NSLog(@"Roll %f ",attitude.roll * 180 / M_PI);
}
Let's suppose that iPhone is laying down on a plane as in the following figure:
pitch, roll and yaw are (almost) 0 degrees and any turn around an axis returns understandable readings. For example, turning the device right, the Yaw decreases and Pitch and Roll remains at 0.
Now the iPhone is in the following position:
and measurement is started again.
Readings are: Yaw = 0, Pitch = 90, Roll = 0
Since the devices rotated around this axis, Pitch increases.
Moving the iPhone into this position:
readings are: Yaw = 30, Pitch = 90, Roll = 0
Once again, since the device rotates around the Yaw axis, this value changes and the others not.
Moving the device around the Roll axis:
readings are: Yaw = 0, Pitch = 90, Roll = -20.
Now what I can't understand. Moving the iPhone around a circle of radius R (R > 0), like in this figure:
Yaw changes meanwhile Pitch and Roll don't.
I would have expected Yaw had remained unchanged and Roll had changed.
How can compensate this since I am interested exclusively to rotations around Yaw axis made by the user ?
Another problem I have is drifting. The iPhone is in the position described in the second figure, taken in my hand at rest for a long time (1 minute or more). The Yaw constantly increase. Any idea how to compensate the drifting ?
Thank you in advance
UPDATE I have followed Kay suggestions but nothing changes. Some more detail on my code. I would like to use Yaw to rotated an UIImage only when user rotate the device around the Yaw axis. This works, but when the user rotates around its own vertical axis the Yaw changes. I suppose that is not correct since when the user moves around its vertical axis, the devices doesn't rotate around its own Yaw axis. May be I am wrong. This is my original code:
- (void)handleDeviceMotion:(CMDeviceMotion*)motion {
CMAttitude *attitude = motion.attitude;
NSLog(@"Yaw %f ",attitude.yaw * 180 / M_PI);
NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI);
NSLog(@"Roll %f ",attitude.roll * 180 / M_PI);
image.transform = CGAffineTransformMakeRotation(-attitude.yaw);
}
This is the code after Kay suggestion:
- (void)handleDeviceMotion:(CMDeviceMotion*)motion {
CMAttitude *attitude = motion.attitude;
if (startAttitude == 0) {
startAttitude = attitude;
}
[attitude multiplyByInverseOfAttitude:startAttitude];
NSLog(@"Yaw %f ",attitude.yaw * 180 / M_PI);
NSLog(@"Pitch %f ",attitude.pitch * 180 / M_PI);
NSLog(@"Roll %f ",attitude.roll * 180 / M_PI);
image.transform = CGAffineTransformMakeRotation(-attitude.yaw);
}
I start device motion monitoring with
[motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical toQueue:[NSOperationQueue currentQueue]
withHandler: ^(CMDeviceMotion *motion, NSError *error){
[self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];
}];