免费开源的iOS开发学习平台

CoreMotion框架:2-获取运动传感器的裸数据(Raw Data)

iOS设备中的运动传感器,可以借助陀螺仪、加速计以及磁力计来获取设备的运动数据,我们可以使用CoreMotion框架来分别获取3种传感器当前采样的数据,此时获取的数据可以认为是传感器的裸数据。但是,裸数据通常不能直接应用于实际的App开发,而是需要对裸数据采用数学方法进行综合计算,得到CMDeviceMotion数据后,才更加具有实际使用价值。本章节主要介绍如何使用Push以及Pull方式分别获取传感器的裸数据。

加速计的裸数据

  • Push模式:在Push模式下,通过accelerometerUpdateInterval属性来设置加速计的数据采样间隔. 然后调用 startAccelerometerUpdatesToQueue:withHandler: 方法即可获取加速计的裸数据。 在该方法中提供一个回调block,即采样获取数据成功后,采样到的数据即CMAccelerometerData对象,把该采样数据作为参数传递到block中,可以对数据进行后续处理。
- (IBAction)startAcc:(id)sender {
    //设置采样间隔
    self.motionMgr.accelerometerUpdateInterval = 1.0;
    //开始采样
    [self.motionMgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {        
        NSLog(@"x:%f, y:%f, z:%f",accelerometerData.acceleration.x, accelerometerData.acceleration.y,accelerometerData.acceleration.z);       
    }];
} 
- (IBAction)stopAcc:(id)sender {
    [self.motionMgr stopAccelerometerUpdates];
}
  • Pull模式:在Pull模式下,首先推荐检查一下加速计是否可用,如果可用,则调用startAccelerometerUpdates方法启动。当需要获取当前加速计数据的时候,可以通过CMMotionManager的accelerometerData属性获取。
- (void)viewDidLoad {
    [super viewDidLoad]; 
    //Pull模式--加速计Accelerometer
    if (self.motionMgr.isAccelerometerAvailable) {
        //启动采样
        [self.motionMgr startAccelerometerUpdates];
    }else {
        NSLog(@"加速计Accelerometer不可用");
    }
} 
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //获取加速计当前状态
    CMAcceleration  acceleration = self.motionMgr.accelerometerData.acceleration;
    NSLog(@"accelerometer current state:x:%f, y:%f, z:%f", acceleration.x, acceleration.y, acceleration.z);
   }

陀螺仪的裸数据

  • Push模式:在Push模式下,通过gyroUpdateInterval属性来设置陀螺仪的数据采样间隔,然后调用startGyroUpdatesToQueue:withHandler: 方法获取陀螺仪的裸数据。 在该方法中具有一个回调block,即采样获取数据成功后,采样到的数据即CMGyroData对象,把该采样数据作为参数传递到block中,可以对数据进行后续处理。
- (IBAction)startGyro:(id)sender {
    //设置采样间隔
    self.motionMgr.gyroUpdateInterval = 1.0;
    //开始采样
    [self.motionMgr startGyroUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMGyroData * _Nullable gyroData, NSError * _Nullable error) {
        NSLog(@"x:%f, y:%f, z:%f", gyroData.rotationRate.x, gyroData.rotationRate.y, gyroData.rotationRate.z);
    }];
}
- (IBAction)stopGyro:(id)sender {
    [self.motionMgr stopGyroUpdates];
}
  • Pull模式:在Pull模式下,首先推荐检查一下陀螺仪是否可用,如果可用,则调用startGyroUpdates方法启动。当需要获取当前陀螺仪数据的时候,可以通过CMMotionManager的gyroData属性获取。
- (void)viewDidLoad {
    [super viewDidLoad]; 
    //Pull模式--加速计Accelerometer
    if (self.motionMgr.isAccelerometerAvailable) {
        //启动采样
        [self.motionMgr startAccelerometerUpdates];
    }else {
        NSLog(@"加速计Accelerometer不可用");
    }  
    //Pull模式--陀螺仪
    if (self.motionMgr.isGyroAvailable) {
        [self.motionMgr startGyroUpdates];
    }else {
        NSLog(@"陀螺仪GyroScope不可用");
    }
} 
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
    //获取陀螺仪当前状态
    CMRotationRate rationRate = self.motionMgr.gyroData.rotationRate;
    NSLog(@"gyroscope current state: x:%f, y:%f, z:%f", rationRate.x, rationRate.y, rationRate.z);
}

磁力计的裸数据

  • Push模式:在Push模式下,通过magnetometerUpdateInterval属性来设置磁力计的数据采样间隔. 然后调用startMagnetometerUpdatesToQueue::withHandler: 方法获取磁力计的裸数据。 在该方法中具有一个回调block,即采样获取数据成功后,采样到的数据即CMMagnetometerData对象,把该采样数据作为参数传递到block中,可以对数据进行后续处理。
- (IBAction)startMagneto:(id)sender {
    //设置采样间隔
    self.motionMgr.magnetometerUpdateInterval = 1.0;
    //开始采样
    [self.motionMgr startMagnetometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMMagnetometerData * _Nullable magnetometerData, NSError * _Nullable error) {
        NSLog(@"x:%f, y:%f, z:%f", magnetometerData.magneticField.x, magnetometerData.magneticField.y, magnetometerData.magneticField.z);
    }];
}
- (IBAction)stopMageto:(id)sender {
    [self.motionMgr stopMagnetometerUpdates];
}
  • Pull模式:在Pull模式下,首先推荐检查一下磁力计是否可用,如果可用,则调用startMagnetometerUpdates方法启动。当需要获取当前磁力计数据的时候,可以通过CMMotionManager的magnetometerData属性获取。
- (void)viewDidLoad {
    [super viewDidLoad];
    //Pull模式--磁力计
    if (self.motionMgr.isMagnetometerAvailable) {
        [self.motionMgr startMagnetometerUpdates];
    }else {
        NSLog(@"磁力计Magnetometer不可用");
    }
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    
    //获取磁力计当前状态
    CMMagneticField magneticField = self.motionMgr.magnetometerData.magneticField;
    NSLog(@"magnetometer current state: x:%f, y:%f, z:%f", magneticField.x,magneticField.y,magneticField.z);
}

示例代码

https://github.com/99ios/17.5.2.1

https://github.com/99ios/17.5.2.2

https://github.com/99ios/17.5.2.3