A
CMMotionManager
object can give you readings from the accelerometer
and gyroscope.
But you won’t want to get the speed of rotation,
either
biased
or
unbiased.
(Were you planning to put your iPhone on a phonograph turntable?)
The purpose of the gyroscope is to give us the device’s attitude,
as we mentioned
here.
List of Core motion classes.
main.m
AttitudeAppDelegate
View
Attitude-Info.plist
Project → Edit Active Target Attitude" → General → Linked Libraries
Add
CoreMotion.framework
.
Add the
Required
Device Capabilities
key to
Attitude-Inf.plist
,accelerometer
and
gyroscope
.
The three Euler angles give the current attitude of the device
in the form of three rotations from a starting attitude called the
reference frame.
The quaternion gives the current attitude of the device in the form
of a single rotation of θ degrees from the reference frame.
Which would you rather use?
The range of the function
acos
is 0 to &pi,
so the θ displayed by the app will range from 0° to 360°.
Wikipedia
article
on rotations.
view.font = [UIFont fontWithName: @"Courier" size: 12];
draw
method of class
View
checks the device’s
attitude
whenever it feels like it.
This is called
pulling
the attitude from the motion manager.
The other approach is to call the
startGyroUpdatesToQueue:withHandler:
of class
CMMotionManager
instead of using an
NSTimer
.
This will make the motion manager
push
out the attitude to us,
allowing us to receive every single attitude update.
We have to write a
block
of code
(with a caret)
which will be executed every time an update arrives.
The following variable
handler
is like a pointer to a function in C++.
(An Objective-C selector does not know what class its method belongs to.)
See
Core
Motion.
manager.deviceMotionUpdateInterval = 1.0 / hertz; CMDeviceMotionHandler handler = ^ (CMDeviceMotion *motion, NSError *error) { [self draw: motion]; //add an argument to the draw method of class View }; //Shouldn't use the main queue, but probably okay for only 10 hertz. [manager startDeviceMotionUpdatesToQueue: [NSOperationQueue mainQueue] withHandler: handler];
attitude
is measured with respect to the attitude in which the device was when we
called the
startDeviceMotionUpdates
method of class
CMMotionManager
.
We can change the reference frame with the
multiplyByInverseOfAttitude:
method of class
CMAttitude:
.
//a is the attitude with respect to the original attitude. CMAttitude *a = manager.deviceMotion.attitude; CMAttitude *other = //whatever; [a multiplyByInverseOfAttitude: other]; //a is not the attitude with respect to the other attitude.