iOS CoreMotion框架(传感器)

我们知道iOS的应用真的太多了,很多应用让我们惊叹不已!!!很多意想不到的应用!

比如:

1.电子罗盘指南针之类的应用-让我们知道方向。

2.运动类型软件-让我们知道我们跑步多少公里。

3.社交软件中的摇一摇功能。

4.游戏中扮演角色类中根据设备的晃动等进行操作。

等等。。而且还有很多应用正在层出不穷的展现再我们面前。

 

其实,他们多半是使用了iOS中的一个框架-核心运动框架-CoreMotion.framework

 

CoreMotion.framework框架是做什么的

 

我们可以使用iOS提供给我们的CoreMotion 框架来访问加速度器陀螺仪的相关数据!

它不仅仅提供给你获得实时的加速度值和旋转速度值,更重要的是,苹果在其中集成了很多算法,可以直接给你输出把重力加速度分量剥离的加速度,省去你的高通滤波操作,以及提供给你一个专门的设备的三维attitude信息!

 

  

我刚接触的时候,也是一头雾水啊。那就普及一下相关的知识。

 

我们知道,智能手机已经普及到我们日常生活中了,尤其iPhone等iOS设备,也已经相当的普遍(俗称:街机)。在它的硬件设备中,其实安装了很多的传感器。其中的加速度器陀螺仪就是其中的两种传感器!

 

智能机中常见的传感器

1. 接近传感器

接近传感器,顾名思义,就是用来检测非常接近的目标物体的。这类传感器通常利用电磁场或者静电场的改变,或者测量发射的电磁波的反射波的改变,来进行判断。因为手段不一样,所以接近传感器的目标物体种类也不一样,有的针对金属物体,有的针对塑料物体。具体到手机上来说,现在的手机都是使用了新一代的反射光学接近传感器,可以针对较多种表面类型来检测。过程很简单,它们会发出人眼看不到的红外光,一旦手机来电话了,你肯定会接听,接听会导致脸部皮肤离传感器很近,这样只需要用光学探测器检测从皮肤反射回来的光的总量的变化,接近传感器就检测到了这个接近。这个传感结果有什么用呢?一个明显的例子,就是可以改进手机的节电功能,比如判断什么时候自动打开或关闭显示屏,键盘背光或者触摸功能,甚至于什么时候自动关机/待机,取决于设备的主人是正在通话,正在打字,还是就直接把设备扔到口袋中了。这些任务,就由接近传感器一肩挑了。

 

2. 加速度传感器

我个人估计,大家最熟悉的,就是加速度传感器。由于其带来了更多的直觉游戏体验,基本姿态识别和环境感知功能,这类传感器从08年开始井喷,因iPhone、iPod的带动而红火,因Wii的集成而大规模部署,并由此带动了价格的下降。现在如果还有哪款手机或者音乐播放器不配备这个传感器阿,出厂去商店都不好意思和摆在一起的别的设备打招呼。加速度计的原理很简单,现在手机里面基本配备的都是3维线传感器,也就是说,用来测量x,y,z三个轴上的加速力。加速力就是当物体在加速过程中作用在物体上的力,就好比地球引力,也就是重力。

我为什么说大家应该都熟悉加速度传感器呢,如果用IBM笔记本的朋友就知道,前IBM,现联想,的Thinkpad系列笔记本,一直都有硬盘保护功能,这个功能利用的就是通过加速度传感器动态监测出笔记本的震动,并根据这个震动选择关闭硬盘还是继续运行。这样可以最大程度的保护由于振动,比如颠簸的工作环境,或者不小心摔了电脑做造成的硬盘损害,最大程度的保护里面的数据。类似的一个非常普及的用处就是目前用的数码相机和摄像机里,用加速度传感器,来检测拍摄时候的手部的振动,并根据这些振动,自动调节相机的聚焦。现在,我们手头都有iPhone,Android军团,Nokia N900等手机,我们至少都知道,加速度传感器可以帮助你打游戏。典型的例子比如Labyrinth2,中文名叫做迷宫滚球。但更广义地说,加速度传感器在检测人的即时背景环境信息上更有用处。比如说,通过三个轴上加速度的变化值的分析处理,手机可以知道你现在是在走路还是骑车还是坐车,是上坡还是下坡,等等。

从理论上讲,有了三个轴的加速度立体信息,我们可以推断出加速方向的信息,比如,你加速骑车的方向,或者你乘坐的电梯正在朝上还是朝下。根据初中数学的知识,这些方向和角度都是可以通过矢量的加减运算算出来的。可惜的是,我们没法仅仅依靠加速度传感器来检测加速方向的角度,也无法得知手机本身的朝向。这是为什么呢?要解释这个,就牵涉到一个困扰加速度仪的大问题,就是重力加速度分量的干扰。

当你的移动设备处于静止状态时,加速度计能告诉你它相对于地平面的朝向,这是没有问题的; 然而,当设备动起来的时候,分析朝向就相当复杂了。这种情况下,要分四种类型讨论

  1. 设备处于水平完全静止或者匀速运动,这时的它会在垂直方向的轴上输出一个值,那就是重力加速度,接近9.8 。
  2. 设备自由落体的时候,会三个轴都输出0呢。
  3. 设备静止或者匀速运动状态时,但没有处于绝对水平。此时任何轴都可能有输出值,但都是重力加速度的分量。一旦处于这种状态,我们可以通过求分量于三个轴的角度来得知手机旋转的角度。
  4. 设备沿着任意方向加速。这时,问题就变复杂了,因为你没办法知道设备目前的方向角度信息,所以你根本就不知道重力加速度的分量到底是怎么分解的,于是……你也就不清楚某个轴所报告的数值,哪些是重力加速度部分,哪些是真正的线性加速度部分

除此之外,另一个加速度传感器无能为力的地方,就是纯水平旋转,或者匀速水平变向。

这类运动,加速度传感器也只会输出一个值:g。因为无论是x,y,还是z轴,都没有真正意义上的加速运动。这会带来什么问题呢?好比你带着一个手机在街上走,沿着一条大街走了一段路,这段路的加速度自然是能被采到的。然后你转弯,在另一条路上走一段,这一段的加速度也是能被采到的。你回到家,拿出手机看数据,没错阿,两端加速度都有,手机知道我走了两段路,很智能阿,缺少了什么东西?你转弯的动作和角度!这个加速度计是采不到的,而这个信息,在很多增强现实的智能应用中,却是非常有用的。为了解决这个问题,人们开始引入其他种类的传感器,比如接下来要介绍的这个陀螺仪。

关于加速度器的坐标:

 

3. 陀螺仪

陀螺仪代表着另一个重要的,但可能还需要等待一两年才能腾飞的传感器领域,主要是因为导航级MEMS陀螺仪目前对于手机来说仍然过于昂贵,普通陀螺仪一般厂商都很少看上眼。当然,在iPhone4的带动下,可以预见的手机军备竞赛,迟早会让陀螺仪逐渐普及开来。陀螺仪的主要作用,是基于角动量守恒的理论,沿着某个特定的坐标轴测量旋转速率。在使用中,陀螺仪的转子在高速旋转时,始终指向一个固定的方向,当运动物体的运动方向偏离预定方向时,陀螺仪就可以感受出来。在现代航空装备中,飞机驾驶的时候,就是通过多达十多个的陀螺仪来测量机体是否翻滚,以及如何翻滚的。

 

4. 电子罗盘

电子罗盘,也称磁力计,或者电子指南针,是继加速度计之后,从09年开始井喷的一种传感器。如果我没记错的话,最早集成这个传感器的主流智能手机就是Google的G1,从这个意义上讲,G1对于磁性传感器市场的带动作用,可能堪比iPhone对于加速度传感器的意义。这玩意啥用处?顾名思义,就是告诉你南北极方向的。以前古老的那种指南针,或者叫平面罗盘,可以在你放平罗盘后告诉你南极北极在哪,这样,你就知道了目前你的正前方在地球这个大平面坐标轴上的角度了。当然,出于技术的限制,平面罗盘要求你保持水平,如果有倾斜就不准确了。后来出现的电子罗盘,很多是两轴的,也就是说,等同于电子平面罗盘。在我记忆中,几年前的openmoko手机就是集成的这种,所以有同样的限制。现在高端智能手机里面集成的都是三维电子罗盘,由于加入了倾角传感器,可以对罗盘进行倾斜补偿,这样就克服了这个缺陷,可以输出三维方向上的角度信息。

电子罗盘的原理也很简单,就是我们物理都学过的霍尔效应。当电流通过一个位于磁场中的导体的时候,磁场会对导体中的电子产生一个横向的洛伦兹力,电荷因此产生偏转,偏转的方向垂直于电流方向和磁场方向,而且正电荷和负电荷偏转的方向相反,从而在导体的两端产生电压差。 这个电压差也叫霍尔电压,和两个因素成比例:电流大小和磁场强度。当然这里有一个要注意的问题,如果磁场的方向是和导体非垂直的话,实际作用的磁场实际上是原来磁场的一个矢量分量。如何知道这个磁场分量的角度呢?我们可以用两个或者多个霍尔效应传感器,相互垂直,这样的话,磁场的方向就可以通过不同传感器上霍尔电压的比例值来求出,这个计算过程只需要知道基本的线性代数运算即可。当然,具体的计算中肯定有一些tricky的地方,不过不是关键点,所以这里就暂时不介绍了。所以和陀螺仪不一样的是,电子罗盘输出的是角方向值,而陀螺仪输出的是角方向的加速度。

所以大家应该都明白了,在电子罗盘的应用中,上述的磁场就是地球磁场,电子罗盘测量地球磁场的矢量值,然后再转换并表示在系统坐标中。在理想情况下,这样测出来的方向值也是比较准确的,一旦我知道移动设备刚开始的方向值,就能通过之后电子罗盘的输出,求出该设备接下来的一系列方向改变信息。

不幸的是,这个世界上的理想情况不存在。在我们经常使用移动设备的环境中,有时候会存在除了地球以外的别的,未被有效屏蔽的磁场,这个外加磁场会有很大可能干扰电子罗盘的读书,而让结果不可信。而且,如果移动设备周围有金属,一旦金属被磁化,电子罗盘也会受很大的影响。

 

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

    

    // 加速度器的检测

    if ([self.motionManager isAccelerometerAvailable]){

        NSLog(@"Accelerometer is available.");

    } else{

        NSLog(@"Accelerometer is not available.");

    }

    if ([self.motionManager isAccelerometerActive]){

        NSLog(@"Accelerometer is active.");

    } else {

        NSLog(@"Accelerometer is not active.");

    }

    

    // 陀螺仪的检测

    if([self.motionManager isGyroAvailable]){

        NSLog(@"Gryro is available.");

    } else {

        NSLog(@"Gyro is not available.");

    }

    if ([self.motionManager isGyroActive]){

        NSLog(@"Gryo is active.");

        

    } else {

        NSLog(@"Gryo is not active.");

    }

 

说明:

1.对加速度器和陀螺仪相关的访问,都被封装在CoreMotion.framework框架下的CMMotionManager类中。我们通过使用类的方法,来得到我们想要的加速度数据和陀螺仪数据。

2. isAccelerometerAvailable方法用来查看加速度器是否可用。

3. isAccelerometerAvailable方法用来查看加速度器的状态:是否Active(启动)。

4.同理isGyroAvailable方法和isGyroActive方法用来检测陀螺仪。

 

用来CMMotionManager获取加速度的数据

说到获取加速度器的数据。主要有两种方式。

1.push方式

这种方式,是实时获取到Accelerometer的数据,并且用相应的队列来显示。即主动。

// 加速度器的检测

    if ([self.motionManager isAccelerometerAvailable]){

        NSLog(@"Accelerometer is available.");

        NSOperationQueue *queue = [[NSOperationQueue alloc] init];

        [self.motionManager startAccelerometerUpdatesToQueue: queue

                                                 withHandler:^(CMAccelerometerData*accelerometerData, NSError *error) {

                                                                                                          NSLog(@"X = %.04f, Y = %.04f, Z = %.04f",accelerometerData.acceleration.x, accelerometerData.acceleration.y, accelerometerData.acceleration.z);

                }];

    } 

 

2.pull方式

就是获取数据,如果要显示,就要向Accelerometer来索要数据。即:被动的方式。

self.motionManager.accelerometerUpdateInterval = 0.01; // 告诉manager,更新频率是100Hz

        [self.motionManager startAccelerometerUpdates]; // 开始更新,后台线程开始运行。

用来CMMotionManager获取陀螺仪的数据

跟加速度器获取数据类似,我们来获取关于陀螺仪的数据

 

// 陀螺仪的检测

    if([self.motionManager isGyroAvailable]){

        NSLog(@"Gryro is available.");

        if ([self.motionManager  isGyroActive] == NO){

            [self.motionManager  setGyroUpdateInterval:1.0f / 1.0f];

            NSOperationQueue *queue = [[NSOperationQueue alloc] init];

            [self.motionManager 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);

                                            }];

        }

    }else {

        NSLog(@"Gyro is not available.");

    }

 

第1类数据:CMAccelerometerData应该是设备总的加速度数据

第2类数据:CMGyroData 设备的三轴角速度数据

第3类数据:CMMagnetometerData设备的三轴磁力数据

第4类数据:CMDeviceMotion 比较特殊:1,重复提供了角速度数据(旋转速率,即陀螺仪的输出);2,把设备总的加速度数据进行了分离(即原始加速度是后面两个的叠加),分离出单纯的重力加速度数据(即重力加速度矢量在当前设备的参考坐标系中的表达,开发中不再需要通过滤波来提取这个信息)和用户加速度数据(不再需要滤波,但根据程序需求而加的滤波算法可以保留);3,提供了设备姿势数据,用于判断手机在当前空间的位置和姿势。

posted @ 2014-08-12 22:32  WFApple  阅读(2124)  评论(0编辑  收藏  举报