IOS 特定於裝置的開發:Core Motion基礎

haibo wang發表於2014-12-23

    Core Motion框架集中了運動資料處理。該框架是在IOS 4 SDK中引入的,用於取代accelerometer加速計訪問。它提供了對3個關鍵的機載感測器的集中式監測。這些感測器有陀螺儀、磁力計和加速計組成,其中陀螺儀用於測量裝置的旋轉,磁力計提供了一種測量羅盤方位的方式,加速計用於監測沿著3根軸的重力變化。第四個入口點稱為裝置移動(device motion),他把全部3中感測器都結合進單個監測系統中。

   Core Motion使用來自這些感測器原始值建立可度的測量結果,主要表現為力向量的形式。可測量的項包括以下屬性:

     》裝置姿勢(attitude):裝置相對於某個參照畫面的方向。姿勢被表示為搖晃,前傾和左右搖擺的角度,他們都以弧度為單位。

     》旋轉速率(rotationRate):裝置圍繞它的三根軸中的每一根軸旋轉的速率。旋轉包括x、y和z角速度值,他們以弧度/秒為單位。

     》重力(gravity):裝置當前的加速度向量,由正常的重力場提供。重力的單位是g's,分別沿著x、y和z軸來測量。每個單位代表由地球提供的標準重力加速度(9.8米/秒的平方)

     》使用者加速度(userAcceleration):使用者提供的加度素向量。像重力一樣,使用者加速度的單位也是g's,分別沿著x、y和z軸來測量。當把它們加到一起時,使用者向量和重力向量代表給裝置提供的總加速度。

     》磁場(magneticField):代表裝置臨近區域的總磁場的向量。磁場是沿著x,y和z軸以為特斯拉(microtesla)為單位測量的。還提供了校準精度,通知應用程式有關磁場測量的質量。

 

1.測試感測器

你可以使用在Info.plist中設定使用或排除機載感測器,也可以在程式中來測試每種可能的Core Motion支援:

@property (nonatomic , strong)CMMotionManager *motionManager;


 _motionManager = [[CMMotionManager alloc]init];
    //監測陀螺儀
    if(_motionManager.gyroAvailable)
    {
        [_motionManager startGyroUpdates];
    }
    
    //監測磁力計
    if(_motionManager.magnetometerAvailable)
    {
        [_motionManager startMagnetometerUpdates];
    }
    
    //監測重力感應器
    if(_motionManager.accelerometerAvailable)
    {
        [_motionManager startAccelerometerUpdates];
    }
    
    //監測Device Motion
    if(_motionManager.deviceMotionAvailable)
    {
        [_motionManager startDeviceMotionUpdates];
    }

開始更新不會產生像使用UIAccelerometer時遇到的委託回撥機制。作為替代,你將負責輪詢每個值,或者可以使用基於塊的更新機制,執行在每次更新時提供的一個塊(例如,startAccelerometerUpdatesToQueue:withHandler:).

2.使用Core motion做加速計蝴蝶飛的程式如下

@implementation TestBedViewController
{
    UIImageView *butterfly;
    
    float xaccel;
    float xvelocity;
    float yaccel;
    float yvelocity;
    
    float mostRecentAngle;
    
    CMMotionManager *motionManager;
    NSTimer *timer;
}

- (void) tick
{
    butterfly.transform = CGAffineTransformIdentity;
    
    // Move the butterfly according to the current velocity vector
    CGRect rect = CGRectOffset(butterfly.frame, xvelocity, 0.0f);
    if (CGRectContainsRect(self.view.bounds, rect))
        butterfly.frame = rect;
    
    rect = CGRectOffset(butterfly.frame, 0.0f, yvelocity);
    if (CGRectContainsRect(self.view.bounds, rect))
        butterfly.frame = rect;
    
    butterfly.transform = CGAffineTransformMakeRotation(mostRecentAngle + M_PI_2);
}

- (void) shutDownMotionManager
{
    NSLog(@"Shutting down motion manager");
    [motionManager stopAccelerometerUpdates];
    motionManager = nil;
    
    [timer invalidate];
    timer = nil;
}

- (void) establishMotionManager
{
    if (motionManager)
        [self shutDownMotionManager];
    
    NSLog(@"Establishing motion manager");
    
    // Establish the motion manager
    motionManager = [[CMMotionManager alloc] init];
    if (motionManager.accelerometerAvailable)
        [motionManager
         startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
         withHandler:^(CMAccelerometerData *data, NSError *error)
         {
             // extract the acceleration components
             float xx = -data.acceleration.x;
             float yy = data.acceleration.y;
             mostRecentAngle = atan2(yy, xx);
             
             // Has the direction changed?
             float accelDirX = SIGN(xvelocity) * -1.0f;
             float newDirX = SIGN(xx);
             float accelDirY = SIGN(yvelocity) * -1.0f;
             float newDirY = SIGN(yy);
             
             // Accelerate. To increase viscosity lower the additive value
             if (accelDirX == newDirX) xaccel = (abs(xaccel) + 0.85f) * SIGN(xaccel);
             if (accelDirY == newDirY) yaccel = (abs(yaccel) + 0.85f) * SIGN(yaccel);
             
             // Apply acceleration changes to the current velocity
             xvelocity = -xaccel * xx;
             yvelocity = -yaccel * yy;
         }];
    
    
    // Start the physics timer
    timer = [NSTimer scheduledTimerWithTimeInterval: 0.03f target: self selector: @selector(tick) userInfo: nil repeats: YES];
}

- (void) initButterfly
{
    CGSize size;
    
    // Load the animation cells
    NSMutableArray *butterflies = [NSMutableArray array];
    for (int i = 1; i <= 17; i++)
    {
        NSString *fileName = [NSString stringWithFormat:@"bf_%d.png", i];
        UIImage *image = [UIImage imageNamed:fileName];
        size = image.size;
        [butterflies addObject:image];
    }
    
    // Begin the animation
    butterfly = [[UIImageView alloc] initWithFrame:(CGRect){.size=size}];
    [butterfly setAnimationImages:butterflies];
    butterfly.animationDuration = 0.75f;
    [butterfly startAnimating];
    
    // Set the butterfly's initial speed and acceleration
    xaccel = 2.0f;
    yaccel = 2.0f;
    xvelocity = 0.0f;
    yvelocity = 0.0f;
    
    // Add the butterfly
    butterfly.center = RECTCENTER(self.view.bounds);
    [self.view addSubview:butterfly];
}

- (void) loadView
{
    [super loadView];
    self.view.backgroundColor = [UIColor whiteColor];
    [self initButterfly];
}

 

相關文章