首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CMMotionManager与UIAccelerometer效率的比较

CMMotionManager与UIAccelerometer效率的比较
EN

Stack Overflow用户
提问于 2013-07-15 16:42:07
回答 2查看 5.7K关注 0票数 4

我已经在AR框架上工作了一段时间了,并且正在尝试从UIAccelerometer (已弃用)更新到CMMotionManager,但是遇到了一些效率问题?

基本上,CMMotionManager似乎比UIAccelerometer大得多,速度也慢得多。以前有没有人经历过CMMotionManager的性能问题?

正如您所看到的,这里,我有以下内容:

代码语言:javascript
复制
accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.updateInterval = 0.01;
[accelerometer setDelegate:self];

代码语言:javascript
复制
-(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);
}

而且,即使在iPhone 4这样的“旧”设备上,所有的功能都很好(虽然不是很老,但是.)。

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

代码语言:javascript
复制
motionManager = [[CMMotionManager alloc] init];

使用

代码语言:javascript
复制
[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);
                                    }];

数学似乎让它变慢了..!我这么说是因为当我去掉所有的数学部分时,效果很好。

iPhone 5可以正常工作,但是iPhone 4S会显示滞后的迹象,iPhone 4会冻结.

(如果你想要的话,我可以给你更多的细节,但解释起来比较复杂)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-18 06:46:17

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

问题在于块格式。所有的教程似乎都支持这种方法,但是苹果建议定期轮询CMMotionManager作为一种更加面向性能的方法。块格式增加了开销。

来自CMMotionManager类引用:

为了通过周期性采样来处理运动数据,应用程序调用一个不带参数的“开始”方法,并周期性地访问给定类型的运动数据的属性所持有的运动数据。这种方法是应用程序(如游戏)的推荐方法。在块中处理加速度计数据会带来额外的开销,大多数游戏应用在呈现帧时只对最新的运动数据样本感兴趣。

所以,你想要做的,从文档中再一次看到:

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

沿着这条线的东西

代码语言:javascript
复制
CMMotionManager *mManager = [(AppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];

[mManager startAccelerometerUpdates];

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

代码语言:javascript
复制
CMMotionManager *mManager = [(SEPAppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];

CMAccelerometerData *aData = mManager.accelerometerData;

从我所做的有限测试来看,这个解决方案在iPhone 4上的效果似乎与iPhone 4一样好。

票数 7
EN

Stack Overflow用户

发布于 2013-11-20 12:48:12

我使用CADisplayLink.

首先,设置CMMotionManager实例。

代码语言:javascript
复制
-(void)viewDidLoad
{
    [super viewDidLoad];

    self.motionManager = [[CMMotionManager alloc]init];

    if(self.motionManager.isDeviceMotionAvailable)
    {
        [self.motionManager startDeviceMotionUpdates];
    }


    [self setupDisplayLink];
}

其次,设置displaylink实例如下:

代码语言:javascript
复制
-(void)setupDisplayLink
{
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
    displayLink.frameInterval = 10;// how many frames to skip before next update
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

显示链接是一个连接到设备屏幕的对象,它可以以指定的帧率运行指定的选择器,更多地介绍这里

第三,您应该实现update:您指定为显示链接选择器的方法。

代码语言:javascript
复制
-(void)update:(CADisplayLink *)displayLink
{
    // handle new accelerometer data here
    CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion;
    NSLog(@"Acceleration: %@", deviceMotion.accelerometerData.acceleration);
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17659352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档