CMMotionManager与UIAccelerometer效率

gle*_*age 4 math performance uiaccelerometer ios cmmotionmanager

我一直在研究AR框架一段时间,我正在尝试从UIAccelerometer(已弃用)更新到CMMotionManager,但是遇到了一些效率问题?

基本上看起来CMMotionManager比UIAccelerometer更大更慢.有没有人以前遇到过CMMotionManager的性能问题?


正如你在这里看到的,我有这个:

accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.updateInterval = 0.01;
[accelerometer setDelegate:self];
Run Code Online (Sandbox Code Playgroud)

-(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);
}
Run Code Online (Sandbox Code Playgroud)

即使在像iPhone 4这样的"老式"设备上也能很好地工作(不是很老,但是......).

但是当使用CMMotionManager尝试完全相同的代码时:

motionManager = [[CMMotionManager alloc] init];
Run Code Online (Sandbox Code Playgroud)

[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);
                                    }];
Run Code Online (Sandbox Code Playgroud)

数学似乎减慢了它的废话..!我这样说是因为当我删除所有的数学部分时它很有用.

iPhone 5可以正常工作,但iPhone 4S会出现滞后迹象,iPhone 4将会冻结......

(如果你愿意,我可以给你更多详细信息,但解释相对复杂)

art*_*ton 7

我只是遇到了同样的问题,你不知道它,解决方案是在文档中;)

问题在于块格式.所有教程似乎都支持这种方法,但Apple建议定期轮询该方法CMMotionManager作为一种更加注重性能的方法.块格式增加了开销.

CMMotionManager类参考:

为了通过定期采样处理运动数据,app调用不带参数的"start"方法,并定期访问属性为给定类型的运动数据保存的运动数据.这种方法是游戏等应用程序的推荐方法.处理块中的加速度计数据会带来额外的开销,并且大多数游戏应用程序仅在渲染帧时对最新的运动数据样本感兴趣.

那么你想做什么,再次从文档:

调用startAccelerometerUpdates开始更新,并通过读取accelerometerData属性定期访问CMAccelerometerData对象.

沿着这些方向的东西

CMMotionManager *mManager = [(AppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];

[mManager startAccelerometerUpdates];
Run Code Online (Sandbox Code Playgroud)

然后,在您选择的某种定期更新方法中:

CMMotionManager *mManager = [(SEPAppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];

CMAccelerometerData *aData = mManager.accelerometerData;
Run Code Online (Sandbox Code Playgroud)

UIAccelerometer从我做过的有限测试来看,这个解决方案似乎和iPhone 4 一样好用.