0

I'm not having problem with the CODE, I want to know what does the iPhone use for CoreMotions (because I'd like to repair it / get it repaired).

I'm not sure if this should be posted here or not.

I would like to know what does the iPhone use to send motion updates. And what does it use to process them.

My problem is, there's some problem with my iPhone, since it's not sending motion updates. I wrote a small project, to test what I'm receiving. On a working device I got output like this:

2013-11-15 09:39:44.415 GyroTest[12165:60b] QuaternionX -0.508156 QuaternionY -0.515390 QuaternionZ 0.487396 QuaternionW 0.488463 
    UserAccelX 0.002124 UserAccelY 0.007351 UserAccelZ 0.006973 
    RotationRateX -0.051634 RotationRateY 0.080035 RotationRateZ 0.025516 
    MagneticFieldX 0.000000 MagneticFieldY 0.000000 MagneticFieldZ 0.000000 MagneticFieldAccuracy -1 @ 386510.678629
2013-11-15 09:39:44.418 GyroTest[12165:60b] -1.395383
2013-11-15 09:39:44.419 GyroTest[12165:60b] -1.522387
2013-11-15 09:39:44.420 GyroTest[12165:60b] -2.972348

But on my device (the faulty one) I get:

2013-11-15 09:39:18.191 GyroTest[12165:60b] (null)
2013-11-15 09:39:18.192 GyroTest[12165:60b] 0.000000
2013-11-15 09:39:18.193 GyroTest[12165:60b] 0.000000
2013-11-15 09:39:18.194 GyroTest[12165:60b] 0.000000

Here's my sample project:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.motionManager = [[CMMotionManager alloc] init];
    self.referenceAttitude = nil;
    [self enableGyro];
    for (int i = 0 ; i < 100 ; ++i) {
        [self getDeviceGLRotationMatrix];
    }
}

-(void) enableGyro{
    CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion;
    CMAttitude *attitude = deviceMotion.attitude;
    self.referenceAttitude = attitude;
    [self.motionManager startGyroUpdates];
    [self.motionManager startAccelerometerUpdates];
    [self.motionManager startDeviceMotionUpdates];
    [self.motionManager startMagnetometerUpdates];
}

-(void) getDeviceGLRotationMatrix
{
    CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion;
    CMAttitude *attitude = deviceMotion.attitude;

    if (self.referenceAttitude != nil)
        [attitude multiplyByInverseOfAttitude:self.referenceAttitude];
    NSLog(@"------------------");
    NSLog(@"%@",self.motionManager.deviceMotion);
    NSLog(@"%f",attitude.yaw);
    NSLog(@"%f",attitude.pitch);
    NSLog(@"%f",attitude.roll);
    sleep(1);
}
4

1 回答 1

1
#include <CoreMotion/CoreMotion.h>
#import "ViewController.h"

@interface ViewController () {

}

@property (strong, nonatomic) CMMotionManager * motionManager;
@property (strong, nonatomic) NSOperationQueue * queue;

- (void) startMotionDetection;
- (void) doSomeThingWithTheMotionValues: (NSDictionary *) motionValues;

@end

@implementation ViewController
@synthesize motionManager = _motionManager;
@synthesize queue = _queue;

- (void)viewDidLoad {
     [super viewDidLoad];
     if (!_motionManager) _motionManager = [[CMMotionManager alloc] init];
     if (!_queue) _queue = [[NSOperationQueue alloc] init];

     [self startMotionDetection];
}


- (void) startMotionDetection {
     // Setting up the handler first.
     CMDeviceMotionHandler dmHandler = ^(CMDeviceMotion * aMotion, NSError * error) {
     CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion;
     CMAttitude * anAttitude = deviceMotion.attitude;
     CMQuaternion quaternion = anAttitude.quaternion;
     NSNumber * yaw = [NSNumber numberWithFloat:anAttitude.yaw*kRadiansToDegrees];
     NSNumber * roll = [NSNumber numberWithFloat:anAttitude.roll*kRadiansToDegrees];
     NSNumber * pitch = [NSNumber numberWithFloat:anAttitude.pitch*kRadiansToDegrees];

     NSNumber * x = [NSNumber numberWithFloat:quaternion.x];
     NSNumber * y = [NSNumber numberWithFloat:quaternion.y];
     NSNumber * z = [NSNumber numberWithFloat:quaternion.z];
     NSNumber * w = [NSNumber numberWithFloat:quaternion.w];

     // Creating the NSDictionary to hold the key/value pairs with the NSNumber objects
     NSDictionary * sensorValues = [NSDictionary dictionaryWithObjectsAndKeys:
                                                           yaw,      @"Yaw",
                                                           roll,     @"Roll",
                                                           pitch,    @"Pitch",
                                                           x,      @"x",
                                                           y,     @"y",
                                                           z,    @"z",
                                                           w,    @"w",
                                                           nil];

     // Sending the dictionary to the processing method
     [self performSelectorOnMainThread: @selector(doSomeThingWithTheMotionValues:)
                                                   withObject: sensorValues
                                                waitUntilDone: YES];
     // Checking if some errors occured
     if (error) {
           NSLog(@"Could not start/continue Device Motion Updates with error:\n%@",error);
           // Restart the motion manager in case of error
           [self.motionManager stopDeviceMotionUpdates];
           [self setMotionManager:nil];
           [self setQueue:nil];
           if (!_motionManager) _motionManager = [[CMMotionManager alloc] init];
           if (!_queue) _queue = [[NSOperationQueue alloc] init];
           [self startMotionDetection];
           return;
      }
    }; // End of handler block

      if (self.motionManager.deviceMotionAvailable) {
           self.motionManager.deviceMotionUpdateInterval = kMotionUpdateInterval;
           [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical
                                                                                    toQueue:self.queue
                                                                                withHandler:dmHandler];
      } else {
           ALERT(nil, @"Motion sensors not available");
      }
}

- (void) doSomeThingWithTheMotionValues: (NSDictionary *) motionValues {
      UIInterfaceOrientation orient = [CommonSessionData currentOrientation];
      float value = -1000.0;

      NSNumber * roll = (NSNumber *)[motionValues valueForKey:@"Roll"];
      float attitudeRoll = roll.floatValue;
      NSNumber * x = (NSNumber *)[motionValues valueForKey:@"x"];
      NSNumber * y = (NSNumber *)[motionValues valueForKey:@"y"];
      NSNumber * z = (NSNumber *)[motionValues valueForKey:@"z"];
      NSNumber * w = (NSNumber *)[motionValues valueForKey:@"w"];
      double quaternionPitch = pitch(x.doubleValue, y.doubleValue, z.doubleValue, w.doubleValue)*kRadiansToDegrees;

      value = UIInterfaceOrientationIsPortrait(orient) ? quaternionPitch : (orient == UIInterfaceOrientationLandscapeLeft ? attitudeRoll : -attitudeRoll);
}

和辅助方法:

double pitch(double x, double y, double z, double w) {
    return atan2(2*(y*z + w*x), w*w - x*x - y*y + z*z);
}

double yaw(double x, double y, double z, double w) {
    return asin(-2*(x*z - w*y));
}

double roll(double x, double y, double z, double w) {
    return atan2(2*(x*y + w*z), w*w + x*x - y*y - z*z);
}
于 2013-11-15T07:48:14.660 回答