Question

I am having my first play around with Core Motion and have struck an issue and I can't work out what is going on. I am sure it is going to be a simple issue. Here is some code:

.h file

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

@interface TempVC : UIViewController {
CMMotionManager *motionManager;
CMAttitude *referenceAttitude;
CMAttitude *attitude;
}
- (void)updateData;
@end

.m file

#import "TempVC.h"
#define DEGREES(radians) (radians / M_PI * 180.0)
@implementation TempVC

- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor brownColor];

motionManager = [[CMMotionManager alloc] init]; 
referenceAttitude = nil;

CMDeviceMotion *dm = motionManager.deviceMotion;
attitude = dm.attitude;
referenceAttitude = [attitude retain];

motionManager.deviceMotionUpdateInterval = 0.1;
[motionManager startDeviceMotionUpdates];

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateData) userInfo:nil repeats:YES];

}

- (void)updateData
{
attitude = motionManager.deviceMotion.attitude;
[attitude multiplyByInverseOfAttitude:referenceAttitude];
NSLog(@"\n Roll: %.0f\n Pitch: %.0f\n Yaw: %.0f",DEGREES(attitude.roll), DEGREES(attitude.pitch), DEGREES(attitude.yaw));
}

This code will crash with no real indication of what goes wrong. If I comment out

[attitude multiplyByInverseOfAttitude:referenceAttitude];

Everything works fine??? Have I implemented the reference wrong?

Was it helpful?

Solution

You access CMMotionManager's deviceMotion property before starting updates. There you store your referenceAttitude which will still be nil at that time. When updateData is called a few millis later [attitude multiplyByInverseOfAttitude:referenceAttitude]; will fail.

Try instead to set the referenceAttitude on the first call of updateData and it should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top