Motion Events Part 2: Core Motion

Motion information for iOS apps is made available through the use of motion events. Part 2 of this tutorial explains how it works.

Part one of this motion events series touched on the history of various motion sensing technologies and uses in current iOS devices. Between the cluster of accelerometers and the gyroscope contained within all fourth-generation iOS devices, no motion goes undetected. It is up to the developer, of course, to determine the frequency and level of information required for use within an iOS app. A basic business app, for example, may only be concerned with the device's orientation, while a gaming app could take full advantage of detecting acceleration across three spatial axes.

Tracking device motion

The Core Motion framework consists of three data objects and several classes for capturing and retrieving low-level motion events. The CMAccelerometerData object captures information from the three accelerometers. The CMGyroData object captures rotation information from the iOS device's gyroscope. The CMDeviceMotion object encapsulates data from the accelerometer and gyroscope. The information is used to populate attitude, gravity, userAcceleration, and rotationRate member properties of the CMDeviceMotion class. For iOS devices with a magnetometer, the magneticField property contains the magnetic field vector. Detailed information of an iOS device's symmetry axes (yaw, pitch, and roll) can be retrieved in real-time by implementing the CMDeviceMotion class (Figure A).
Figure A

The symmetry axes of an iOS device consist of the vertical axis, lateral axis, and longitudinal axis. All three axes remain perpendicular to one another regardless the device orientation. The symmetry axes allow developers to track device motion in three dimensions. The vertical axis (yaw) is responsible for side-to-side movement. The lateral axis (pitch) crosses left to right, and responsible for any tilting movement. The longitudinal axis (roll) extends from the top to the bottom of the device. Referencing the attitude property of the CMDeviceMotion class allows access to motion data within each of the symmetry axes. The yaw, pitch, and roll properties are returned as Euler angles (Listing 1).

Listing 1

[CMMotionManagerObject startDeviceMotionUpdatesToQueue:[NSOperationQueue       currentQueue] withHandler:^ (CMDeviceMotion *devMotion, NSError *error)
CMAttitude *currentAttitude = devMotion.attitude;
verticalAxis = currentAttitude.roll*180/M_PI;
lateralAxis = currentAttitude.pitch*180/M_PI;
longitudinalAxis = currentAttitude.yaw*180/M_PI;
The values of the CMAttitude roll, pitch, and yaw properties are returned in radians. While mathematicians prefer radians, many developers prefer working with degrees. The math constant M_PI can be used in a formula to convert radians to degrees and vice-versa. As shown in Listing 1, the properties are multiplied by the quotient of 180 divided by M_PI. You could write stand-alone methods to handle the conversion of degrees and radians (Listing 2). Remember to include the header file math.h in your project.

Listing 2

CGFloat DegreesToRadians(CGFloat degrees)
return degrees*M_PI/180;
CGFloat RadiansToDegrees(CGFloat radians)
return radians*180/M_PI;
With real-time access to motion tracking data, you can call methods to do everything from moving objects on the screen to displaying navigation information in a heads-up-display (HUD). The Core Motion framework is easy to implement and very powerful. As with all of Apple's iOS frameworks, you begin by adding the framework references to your project (Figure B). Be sure to add #import <CoreMotion/CoreMotion.h> to the appropriate files.
Figure B

Using Core Motion to trigger movement of an object

The basics of using Core Motion to control direction and movement of an object on the screen - such as a character within a game - consists of the following steps:

  • Add Core Motion to the project.
  • Include references to the Core Motion header file(s).
  • Add an instance of the CMMotionManager class.
  • Create methods for using Core Motion data to move objects.
Considering that only one instance of the CMMotionManager object is required, you would typically declare the object in the AppDelegate.h file (Listing 3). With the object declared in the AppDelegate.h file, we will need to instantiate the object in the corresponding AppDelegate.m file (Listing 4).

Listing 3

#import <CoreMotion/CoreMotion.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
CMMotionManager *motionManager;
@property (readonly) CMMotionManager *motionManager;

Listing 4

-(CMMotionManager *) motionManager
if(!motionManager) motionManager = [[CMMotionManager alloc] init];
return motionManager;
You can now reference the CMMotionManager object in the AppDelegate implementation from within the ViewController.m file. From this point, your app is ready to start collecting motion data. There are two approaches for retrieving motion data - push and pull. The pull approach requires less code and processor overhead. The concept is that you would query (or pull) the information whenever you need it. Pulling motion data begins with a request from the iOS app to start an instance of the manager class and request information at certain times. The developer is responsible for starting and stopping the updates (Listing 5).

Listing 5

// Start capturing motion data
[motionManager startDeviceMotionUpdates];
// Stop capturing motion data
[motionManager stopDeviceMotionUpdates];
The push approach calls a custom handler, or block object, generating a steady stream of continuous data. The code within the block is called each time a motion event happens. This is achieved by using the NSOperationsQueue (Listing 6). The developer can set the update interval to any value between 10 and 100 times per second.

Listing 6

// Set the update frequency
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
// Setup the update queue
[motionManager startDeviceMotionUpdatesToQueue : queue withHandler: handler];

Where to go from here

The Core Motion framework allows instant access data generated by the iOS device's accelerometer, magnetometer, and gyroscope. The CMDeviceMotion class provides methods for retrieving information pertaining to the yaw, pitch, and roll movement of a device. Core Motion framework provides an iOS app with highly accurate information regarding the motion and positioning attributes of a device. App developers can easily leverage this technology to create a unique, interactive experience. There are plenty of code examples on the Apple iOS Developer site. The free Gyroscope app - available on the App Store - shows the Core Motion framework in action.

Also read: