简体   繁体   中英

Finding iOS device idle state

I want to find the device idle state through program. ie find the state when the device is not moved or moved. I tried the following accelerometer and core motion APIs. But, I couldn't understand the device idle state from the values it is giving.

Any suggestions will be appreciated.

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.
    currentMaxAccelX = 0;
    currentMaxAccelY = 0;
    currentMaxAccelZ = 0;

    currentMaxRotX = 0;
    currentMaxRotY = 0;
    currentMaxRotZ = 0;

    value = 0;

    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.accelerometerUpdateInterval = .2;
    self.motionManager.gyroUpdateInterval = .2;

    [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
                                             withHandler:^(CMAccelerometerData  *accelerometerData, NSError *error) {
                                                 [self outputAccelertionData:accelerometerData.acceleration];
                                                 if(error){

                                                     NSLog(@"%@", error);
                                                 }
                                             }];

    [self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue]
                                    withHandler:^(CMGyroData *gyroData, NSError *error) {
                                        [self outputRotationData:gyroData.rotationRate];
                                    }];
}

-(void)outputAccelertionData:(CMAcceleration)acceleration
{
    self.accX.text = [NSString stringWithFormat:@"accX: %.2fg",acceleration.x];
    if(fabs(acceleration.x) > fabs(currentMaxAccelX))
    {
        currentMaxAccelX = acceleration.x;
    }

    self.accY.text = [NSString stringWithFormat:@"accY: %.2fg",acceleration.y];
    if(fabs(acceleration.y) > fabs(currentMaxAccelY))
    {
        currentMaxAccelY = acceleration.y;
    }

    if (fabs(acceleration.y) - fabs(value) > 0.2 || fabs(value) - fabs(acceleration.y) > 0.2 )
    {
        NSLog(@"Not idle");
    }
    value = acceleration.y;


    self.accZ.text = [NSString stringWithFormat:@"accZ: %.2fg",acceleration.z];
    if(fabs(acceleration.z) > fabs(currentMaxAccelZ))
    {
        currentMaxAccelZ = acceleration.z;
    }

    self.maxAccX.text = [NSString stringWithFormat:@"maxAccX: %.2f",currentMaxAccelX];
    self.maxAccY.text = [NSString stringWithFormat:@"maxAccY: %.2f",currentMaxAccelY];
    self.maxAccZ.text = [NSString stringWithFormat:@"maxAccZ: %.2f",currentMaxAccelZ];

}

-(void)outputRotationData:(CMRotationRate)rotation
{
    self.rotX.text = [NSString stringWithFormat:@"rotX: %.2fr/s",rotation.x];
    if(fabs(rotation.x) > fabs(currentMaxRotX))
    {
        currentMaxRotX = rotation.x;
    }
    self.rotY.text = [NSString stringWithFormat:@"rotY: %.2fr/s",rotation.y];
    if(fabs(rotation.y) > fabs(currentMaxRotY))
    {
        currentMaxRotY = rotation.y;
    }
    self.rotZ.text = [NSString stringWithFormat:@"rotZ: %.2fr/s",rotation.z];
    if(fabs(rotation.z) > fabs(currentMaxRotZ))
    {
        currentMaxRotZ = rotation.z;
    }
    self.maxRotX.text = [NSString stringWithFormat:@"maxRotX: %.2f",currentMaxRotX];
    self.maxRotY.text = [NSString stringWithFormat:@"maxRotY: %.2f",currentMaxRotY];
    self.maxRotZ.text = [NSString stringWithFormat:@"maxRotZ: %.2f",currentMaxRotZ];
}

You can check this reference CmMotionManager reference .

self.deviceQueue = [[NSOperationQueue alloc] init];
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 5.0 / 60.0;

// UIDevice *device = [UIDevice currentDevice];

[self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical
                                                    toQueue:self.deviceQueue
                                                withHandler:^(CMDeviceMotion *motion, NSError *error)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    CGFloat x = motion.gravity.x;
    CGFloat y = motion.gravity.y;
    CGFloat z = motion.gravity.z;
}];
}];

The approach with measuring acceleration is correct, so in case you managed to obtain acceleration vector, you simply should calculate the norm of the vector and check if the value is grater than some constant.

CGFloat norm = sqrt(acceleration.x * acceleration.x + acceleration.y * acceleration.y + acceleration.z * acceleration.z);
NSLog(@"Norm of the vector = %f", norm);
CGFloat minimumValueToConsiderThatDeviceIsMoving = 0.2; // obtain more accurate value experimentally
if (norm > minimumValueToConsiderThatDeviceIsMoving) {
    NSLog(@"Device is moving!");
} else {
    NSLog(@"Device is still!");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM