技术 - iPhone用于发送Device Motion更新的内容

时间:2013-11-15 07:45:32

标签: ios iphone core-motion

我没有CODE的问题,我想知道iPhone用于CoreMotions的内容(因为我想修复它/得到修复)。

我不确定这是否应该在这里张贴。

我想知道iPhone使用什么来发送动态更新。它有什么用来处理它们。

我的问题是,我的iPhone存在一些问题,因为它没有发送动态更新。我写了一个小项目来测试我收到的内容。在工作设备上,我输出如下:

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

但是在我的设备上(有问题的)我得到了:

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

这是我的示例项目:

- (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);
}

1 个答案:

答案 0 :(得分: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);
}