I. Introduction to CoreMotion framework

We know that some iOS apps have special requirements, such as:

  1. Electronic compasses and the like: let us know the direction.
  2. Exercise Type software: Lets us know how many kilometers we run.
  3. The shake feature in social software.
  4. Play a role in the game class according to the device shaking operation.

In fact, they mostly use coremotion. framework, a CoreMotion framework in iOS

  • Use what iOS provides usCoreMotionFramework, mainly for accessThe accelerometerandgyroscopeRelevant data.
  • Not only does it give you real-time acceleration and rotation speed values, but more importantly, Apple has integrated algorithms into it that directly give you the acceleration with the gravity component stripped out, eliminating your high-pass filtering, and providing you with three-dimensional position information for a dedicated device.
Sensor introduction:
  1. Accelerometer: The principle of the accelerometer is very simple, now mobile phones are basically equipped with a three-dimensional sensor, that is, to measure the acceleration force on the X, Y and Z axes. Accelerating force is the force acting on an object as it accelerates, just like gravity, or gravity.
  2. Gyroscope: The main function of a gyroscope is to measure the rotation rate along a specific coordinate axis based on the theory of conservation of angular momentum. In use, the rotor of the gyroscope always points in a fixed direction when rotating at high speed, and the gyroscope can sense when the moving object’s motion direction deviates from the predetermined direction.

Two, CoreMotion use

CoreMotion is responsible for three types of data:
  • Acceleration valueCMAccelerometerData
  • Gyroscope valueCMGyroData
  • Equipment motion valueCMDeviceMotion

In fact, the motion value of the device is calculated by the transformation of acceleration and rotation speed

  1. attitude: Basically, it tells you the position and posture of the phone in the current space
  2. gravity: Gravity information, its essence is the expression of gravity acceleration vector in the reference coordinate system of the current equipment
  3. userAcceleration: Acceleration information
  4. rotationRate: Instant rotation rate, which is the output of the gyroscope

###### How to use CoreMotion:

  1. Initialize theCMMotionManagerManagement object
  2. There are two ways to get data by calling the object method of the managed object
  3. Process the data
  4. Stop getting data when you don’t need it
- (void)stopAccelerometerUpdates;// Stop getting accelerometer data- (void)stopGyroUpdates;// Stop getting gyro data- (void)stopDeviceMotionUpdates;// Stop getting device motion data
Copy the code

###### There are two ways to get data in CoreMotion:

  1. PushMethod: Provide a thread managerNSOperationQueueAnd a callbackBlock.CoreMotionThis is automatically called back every time a sample data comes inBlockTo process. In this case,BlockThe operation will be in your ownThe main threadWithin the execution.
  2. PullHow: You have to be proactiveCMMotionManagerThis data is the last sampled data. If you don’t ask,CMMotionManagerI won’t give it to you.
1. Accelerometer is obtained in Pull mode:
- (void)useAccelerometerPull{
    // Initializes the global managed object
    CMMotionManager *manager = [[CMMotionManager alloc] init];
    self.motionManager = manager;
    // Check whether the accelerometer is available, check whether the accelerometer is on
    if([manager isAccelerometerAvailable] && ! [manager isAccelerometerActive]){// Tell manager that the update frequency is 100Hz
        manager.accelerometerUpdateInterval = 0.01;
        // Update starts, background thread starts running. This is Pull.
        [manager startAccelerometerUpdates];
    }
    // Get and process accelerometer data
    CMAccelerometerData *newestAccel = self.motionManager.accelerometerData;
    NSLog(@"X = %.04f",newestAccel.acceleration.x);
    NSLog(@"Y = %.04f",newestAccel.acceleration.y);
    NSLog(@"Z = %.04f",newestAccel.acceleration.z);
}
Copy the code
2. Accelerometer is obtained in Push mode:
- (void)useAccelerometerPush{
    // Initializes the global managed object
    CMMotionManager *manager = [[CMMotionManager alloc] init];
    self.motionManager = manager;
    // Check whether the accelerometer is available, check whether the accelerometer is on
    if([manager isAccelerometerAvailable] && ! [manager isAccelerometerActive]){// Tell manager that the update frequency is 100Hz
        manager.accelerometerUpdateInterval = 0.01;
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        // Get and process data in Push mode
        [manager startAccelerometerUpdatesToQueue:queue
                 withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
         {
             NSLog(@"X = %.04f",accelerometerData.acceleration.x);
             NSLog(@"Y = %.04f",accelerometerData.acceleration.y);
             NSLog(@"Z = %.04f",accelerometerData.acceleration.z); }]; }}Copy the code
3. Gyroscope is obtained by Push mode, while Pull mode is not listed, which is similar to accelerometer:
- (void)useGyroPush{
    // Initializes the global managed object
    CMMotionManager *manager = [[CMMotionManager alloc] init];
    self.motionManager = manager;
    // Check whether the gyroscope is working, check whether the gyroscope is on
    if([manager isGyroAvailable] && ! [manager isGyroActive]){NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        // Tell manager that the update frequency is 100Hz
        manager.gyroUpdateInterval = 0.01;
        // Get and process data in Push mode
        [manager startGyroUpdatesToQueue:queue
                             withHandler:^(CMGyroData *gyroData, NSError *error)
        {
            NSLog(@"Gyro Rotation x = %.04f", gyroData.rotationRate.x);
            NSLog(@"Gyro Rotation y = %.04f", gyroData.rotationRate.y);
            NSLog(@"Gyro Rotation z = %.04f", gyroData.rotationRate.z); }]; }}Copy the code

The above code must be real for it to work. Using the above knowledge we can do something like this:

- (void)keepBalance {
    if(self, manager isDeviceMotionAvailable) {/ / set the accelerometer sampling frequency self. The manager. DeviceMotionUpdateInterval = 0.05 f; [self.manager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) { double rotation = atan2(motion.gravity.x, motion.gravity.y) - M_PI;  self.imageView.transform = CGAffineTransformMakeRotation(rotation); }]; }}Copy the code

##### have any suggestions in the comments section below!