我们知道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,中文名叫做迷宫滚球。但更广义地说,加速度传感器在检测人的即时背景环境信息上更有用处。比如说,通过三个轴上加速度的变化值的分析处理,手机可以知道你现在是在走路还是骑车还是坐车,是上坡还是下坡,等等。
从理论上讲,有了三个轴的加速度立体信息,我们可以推断出加速方向的信息,比如,你加速骑车的方向,或者你乘坐的电梯正在朝上还是朝下。根据初中数学的知识,这些方向和角度都是可以通过矢量的加减运算算出来的。可惜的是,我们没法仅仅依靠加速度传感器来检测加速方向的角度,也无法得知手机本身的朝向。这是为什么呢?要解释这个,就牵涉到一个困扰加速度仪的大问题,就是重力加速度分量的干扰。
当你的移动设备处于静止状态时,加速度计能告诉你它相对于地平面的朝向,这是没有问题的; 然而,当设备动起来的时候,分析朝向就相当复杂了。这种情况下,要分四种类型讨论
除此之外,另一个加速度传感器无能为力的地方,就是纯水平旋转,或者匀速水平变向。
这类运动,加速度传感器也只会输出一个值:g。因为无论是x,y,还是z轴,都没有真正意义上的加速运动。这会带来什么问题呢?好比你带着一个手机在街上走,沿着一条大街走了一段路,这段路的加速度自然是能被采到的。然后你转弯,在另一条路上走一段,这一段的加速度也是能被采到的。你回到家,拿出手机看数据,没错阿,两端加速度都有,手机知道我走了两段路,很智能阿,缺少了什么东西?你转弯的动作和角度!这个加速度计是采不到的,而这个信息,在很多增强现实的智能应用中,却是非常有用的。为了解决这个问题,人们开始引入其他种类的传感器,比如接下来要介绍的这个陀螺仪。
关于加速度器的坐标:
陀螺仪代表着另一个重要的,但可能还需要等待一两年才能腾飞的传感器领域,主要是因为导航级MEMS陀螺仪目前对于手机来说仍然过于昂贵,普通陀螺仪一般厂商都很少看上眼。当然,在iPhone4的带动下,可以预见的手机军备竞赛,迟早会让陀螺仪逐渐普及开来。陀螺仪的主要作用,是基于角动量守恒的理论,沿着某个特定的坐标轴测量旋转速率。在使用中,陀螺仪的转子在高速旋转时,始终指向一个固定的方向,当运动物体的运动方向偏离预定方向时,陀螺仪就可以感受出来。在现代航空装备中,飞机驾驶的时候,就是通过多达十多个的陀螺仪来测量机体是否翻滚,以及如何翻滚的。
先来看看iPhone中,陀螺仪硬件吧:
再看看,陀螺仪的样子:
关于陀螺仪的坐标:
Roll轴的信息:
Pitch轴的信息:
Yaw轴信息:
需要注意的是,这里的三个角度,和加速度计的x,y,z三维意义完全不同,不要混淆了。
陀螺仪的测量是随时间累计的,要知道当前的角度,只需要将之前所有的输出数值积分即可。当然,陀螺仪只会输出当前旋转的变化值,比如说,如果一架飞机是以60度的倾斜角度径直飞行,此时陀螺仪的输出为0,因为当前就没有机体旋转。但是,你可以通过之前的输出累计计算出当前机体倾斜角度是多少。陀螺仪有两个好处:
说完了陀螺仪的优点,说说缺点吧。聪明的读者在看到陀螺仪计算角度的原理是,肯定能一下就发现陀螺仪的缺陷:这玩意的误差是累计的!也就是说,某一个时刻你因为不管什么样的原因引进了角度的误差,可能是静态漂移误差,可能是读数误差,whatever,这个误差就会一直跟着你,一直在后面的读数和计算中延续!更有趣的是,陀螺仪有一个臭名昭著的特性:它会随着时间而漂移!换句话说,每分每秒,它都会自动引入附加的误差!!时间一长,完了,你关于旋转度的测量值就变成了中国有关部门:可信度为0 。当然,科技是在发展的,现在很多高端的陀螺仪的随机误差很小,普通应用有时候都可以不用管这个误差。当然,一分钱一分货,这种高端陀螺仪通常都很贵,很少会采用到手机系统中。
这下好玩了,在一个短的时间刻度里,加速度值噪声特别大,而且还有重力的影响。在长的时间刻度里呢,加速度值总体是靠谱的,没有误差累计。而在短的时间刻度里,陀螺仪很准,因为误差累计的速度还是很慢的。但在长的时间刻度里,陀螺仪就不准得离谱。在某些情况下,加速度传感器可以用来校准陀螺仪,比如设备完全静止的时候,和重力相关的方向上,就可以这样做。那么,什么时候不行呢?回头看我们刚才放的那三个图,其中yaw的示意图
yaw角度的变化方向是垂直于重力方向的!所以,通过刚才关于加速度的介绍我们知道,在这个垂直于重力的平面上,加速度传感器就没办法帮陀螺仪了。
本质上,通过三维加速度传感器+三维陀螺仪的合作,我们等同于拥有了一个六维的传感器,但无处不在的误差会让这个六维传感器偶尔感到无助。这时候,我们就需要另外的设备来帮忙做进一步的校正,这就是下面要介绍的电子罗盘。
4. 电子罗盘
电子罗盘,也称磁力计,或者电子指南针,是继加速度计之后,从09年开始井喷的一种传感器。如果我没记错的话,最早集成这个传感器的主流智能手机就是Google的G1,从这个意义上讲,G1对于磁性传感器市场的带动作用,可能堪比iPhone对于加速度传感器的意义。这玩意啥用处?顾名思义,就是告诉你南北极方向的。以前古老的那种指南针,或者叫平面罗盘,可以在你放平罗盘后告诉你南极北极在哪,这样,你就知道了目前你的正前方在地球这个大平面坐标轴上的角度了。当然,出于技术的限制,平面罗盘要求你保持水平,如果有倾斜就不准确了。后来出现的电子罗盘,很多是两轴的,也就是说,等同于电子平面罗盘。在我记忆中,几年前的openmoko手机就是集成的这种,所以有同样的限制。现在高端智能手机里面集成的都是三维电子罗盘,由于加入了倾角传感器,可以对罗盘进行倾斜补偿,这样就克服了这个缺陷,可以输出三维方向上的角度信息。
电子罗盘的原理也很简单,就是我们物理都学过的霍尔效应。当电流通过一个位于磁场中的导体的时候,磁场会对导体中的电子产生一个横向的洛伦兹力,电荷因此产生偏转,偏转的方向垂直于电流方向和磁场方向,而且正电荷和负电荷偏转的方向相反,从而在导体的两端产生电压差。 这个电压差也叫霍尔电压,和两个因素成比例:电流大小和磁场强度。当然这里有一个要注意的问题,如果磁场的方向是和导体非垂直的话,实际作用的磁场实际上是原来磁场的一个矢量分量。如何知道这个磁场分量的角度呢?我们可以用两个或者多个霍尔效应传感器,相互垂直,这样的话,磁场的方向就可以通过不同传感器上霍尔电压的比例值来求出,这个计算过程只需要知道基本的线性代数运算即可。当然,具体的计算中肯定有一些tricky的地方,不过不是关键点,所以这里就暂时不介绍了。所以和陀螺仪不一样的是,电子罗盘输出的是角方向值,而陀螺仪输出的是角方向的加速度。
所以大家应该都明白了,在电子罗盘的应用中,上述的磁场就是地球磁场,电子罗盘测量地球磁场的矢量值,然后再转换并表示在系统坐标中。在理想情况下,这样测出来的方向值也是比较准确的,一旦我知道移动设备刚开始的方向值,就能通过之后电子罗盘的输出,求出该设备接下来的一系列方向改变信息。
不幸的是,这个世界上的理想情况不存在。在我们经常使用移动设备的环境中,有时候会存在除了地球以外的别的,未被有效屏蔽的磁场,这个外加磁场会有很大可能干扰电子罗盘的读书,而让结果不可信。而且,如果移动设备周围有金属,一旦金属被磁化,电子罗盘也会受很大的影响。
注:以上文章摘自:移动设备智能化的基石–从iPhone4的传感器谈起
理论很长。总结一下:目的在于告诉我们,iPhone设备中,集成了很多的传感器。以及对每一种传感器进行了分析说明。
看了上面的介绍,相信大家心里面也都有了数。这些传感器,各有神通,也各有缺陷,很多时候还真得相互配合来使用,才能达到预期的效果,真正准确检测出设备主人的行动信息。这个协作的过程比较复杂。但是,我们很多情况下,不需要去了解太多细节,要不,就不用写代码了,直接去中科院搞飞机,卫星,导弹去了!为什么说,我们不需要明白关于加速度器和陀螺仪的太多的原理性的东西?因为,底层的实现全部由CorMotion框架给你准备好了!我们只需要来使用框架提供的属性方法,就可以得到我们想要的信息!
使用CorMotion框架
切回正题,来进行CorMotion框架的使用!
先贴:
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.");
}
希望对你有所帮助!