iOS Motion

iOS Motion Manager Setup

Add CoreMotion Library Framework to a Xcode project

  • Select the project folder in the navigator
  • Select the target object in the editor
  • Select the Build Phases tag
  • Expand Link Binary with Libraries
  • Click on the plus sign
  • Add the CoreMotion library

Initialize Core Motion manager

MyAppDelegate.h
#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
  CMMotionManager *motionManager;
}

@property (readonly) CMMotionManager *motionManager;

@end
MyAppDelegate.m
- (CMMotionManager *)motionManager
{
  if (!motionManager) motionManager = [[CMMotionManager alloc] init];
  return motionManager;
}

Access the Motion Manager from a View Controller

MyViewController.m
- (CMMotionManager *)motionManager
{
   CMMotionManager *motionManager = nil;
   id appDelegate = [UIApplication sharedApplication].delegate;
   if ([appDelegate respondsToSelector:@selector(motionManager)]) {
     motionManager = [appDelegate motionManager];
   }
   return motionManager;
}

CMMotionManager's Property indicated hardware capabilities

@property (readonly) BOOL accelerometerAvailable;
@property (readonly) BOOL gyroAvailable;
@property (readonly) BOOL deviceMotionAvailable;

Start collecting motion data

  • For example, when the view just appear
    MyViewController.m
    - (void)viewDidAppear:(BOOL)animated
    {
    	[super viewDidAppear:animated];
    	[self startMyMotionDetect];
            ...
    

After the view disappear, ensure the motion manager stop collecting updates

MyViewController.m
- (void)viewDidDisappear:(BOOL)animated
{
  [super viewDidDisappear:animated];
  [self.motionManager stopAccelerometerUpdates];
  ...
}

iOS Motion Data Collecting

Collecting motion data

MyViewController.m
#define MOTION_SCALE 5.0

- (void)startMyMotionDetect
{
  [self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
      withHandler:^(CMAccelerometerData *data, NSError *error) {
         dispatch_async(dispatch_get_main_queue(), ^{
           // Collecting data
	   data.acceleration.x * MOTION_SCALE;
	   data.acceleration.y * MOTION_SCALE;
           ...
	 });
      }
  ];
}
  • Use a code block in the main dispatching thread to read motion data

Handling Accelerometer Updates

- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue
                             withHandler:(CMAccelerometerHandler)handler;

Handling Gyro Updates

- (void)startGyroUpdatesToQueue:(NSOperationQueue *)queue
                    withHandler:(CMGyroHandler)handler;

Handling both Accelerometer & Gyro Updates

- (void)startDeviceMotionUpdatesToQueue:(NSOperationQueue *)queue
                            withHandler:(CMDeviceMotionHandler)handler;

Properties controlling frequency of updates

@property NSTimeInterval accelerometerUpdateInterval;
@property NSTimeInterval gyroUpdateInterval;
@property NSTimeInterval deviceMotionUpdateInterval;

Accelerometer Motion Data

@property (readonly) CMAccelerometerData *accelerometerData;

CMAccelerometerData provides

@property (readonly) CMAcceleration acceleration;
typedef struct { double x; double y; double z; } CMAcceleration; // In g

Gyro Motion Data

@property (readonly) CMGyroData *gyroData;

CMGyroData provides

@property (readonly) CMRotationRate rotationRate;
typedef struct { double x; double y; double z; } CMRotationRate; // In radians/second 

Both Accelerometer & Gyro Motion Data

@property (readonly) CMDeviceMotion *deviceMotion;

CMDeviceMotion provides

@property (readonly) CMAcceleration gravity;
@property(readonly) CMAcceleration userAcceleration;
typedef struct { double x; double y; double z; } CMAcceleration; // In "g"

@property CMRotationRate rotationRate;
typedef struct { double x; double y; double z; } CMRotationRate; // In radians/second
@propertyCMAttitude *attitude;
@interface CMAttitude : NSObject
@property (readonly) double roll;
@property (readonly) double pitch;
@property (readonly) double yaw;