I've been working on an AR framework for a while now and am trying to update from UIAccelerometer (deprecated) to CMMotionManager but am running into some efficiency problems?
Basically it seems like CMMotionManager is MUCH larger and slower than UIAccelerometer is. Has anyone experienced performance issues with CMMotionManager before?
As you can see here, I had this:
accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.updateInterval = 0.01;
[accelerometer setDelegate:self];
and
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
rollingZ = (acceleration.z * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor));
rollingX = (acceleration.y * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
if (rollingZ > 0.0) currentInclination = inc_avg(atan(rollingX / rollingZ) + M_PI / 2.0);
else if (rollingZ < 0.0) currentInclination = inc_avg(atan(rollingX / rollingZ) - M_PI / 2.0);
else if (rollingX < 0) currentInclination = inc_avg(M_PI/2.0);
else if (rollingX >= 0) currentInclination = inc_avg(3 * M_PI/2.0);
}
and all works great even on "older" devices like the iPhone 4 (not really old but yea...).
But when trying the exact same code but with CMMotionManager:
motionManager = [[CMMotionManager alloc] init];
with
[motionManager setAccelerometerUpdateInterval:0.01];
[motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler: ^(CMAccelerometerData *accelerometerData, NSError *error){
rollingZ = (accelerometerData.acceleration.z * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor));
rollingX = (accelerometerData.acceleration.y * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
if (rollingZ > 0.0) currentInclination = inc_avg(atan(rollingX / rollingZ) + M_PI / 2.0);
else if (rollingZ < 0.0) currentInclination = inc_avg(atan(rollingX / rollingZ) - M_PI / 2.0);
else if (rollingX < 0) currentInclination = inc_avg(M_PI/2.0);
else if (rollingX >= 0) currentInclination = inc_avg(3 * M_PI/2.0);
}];
The math seems to slow the crap out of it..! I say this because when I remove all the math part it works great.
An iPhone 5 will work alright but an iPhone 4S will show signs of lag and the iPhone 4 will just freeze...
(I can give you more details if you want but its relatively complicated to explain)
I was just having this same problem, and wouldn't you know it, the solution was in the documentation ;)
The problem is with the block format. All of the tutorials seem to favor that method, but Apple recommends periodic polling of the
CMMotionManager
as a more performance oriented approach. The block format adds overhead.From the
CMMotionManager
Class Reference:So what you want to do, from the docs again:
Something along these lines
Then, in some sort of periodically updating method of your choosing:
This solution appears to work as well as
UIAccelerometer
on an iPhone 4 from the limited testing I've done.