Demo的github地址:加速计和陀螺仪

前言

今天我们学习的是CoreMotion框架中的加速计和陀螺仪。
通过CoreMotion框架提供的加速计来获取设备当前的加速度数据、陀螺仪数据、所处的磁场以及设备的方位等信息。
对于iOS应用开发者来说,开发传感器应用十分简单,CoreMotion框架的核心API就是CMMotionManager。
开发者只要创建一个CMMotionManager对象,接下来即可采用定时器周期性的从CMMotionManager对象获取加速度数据、陀螺仪数据等,也可采用基于代码块的方式来获取这些数据。
通过在iOS应用中添加加速计和陀螺仪,可以充分激发开发者、用户的的想象力,开发出各种新奇的程序,比如电子罗盘、水平仪等。
除此之外,还可以利用加速计和陀螺仪开发各种游戏,程序通过加速计和陀螺仪来感知用户动作,从而在游戏中提供相应的响应。
我之前呢,曾经相识一位CEO,在微信小程序问世之后,他们团队开发了一款叫“种子时间”的应用,大致的功能呢就是在你扣上手机,即把手机倒扣在桌面上,开始计时,记录你不玩手机的时间,来督促现代人脱离手机融入生活。
我当时就好奇,怎么判断手机是倒扣在桌面上的呢?是通过光的感应吗?还是别的?
因为小程序和咱们iOS使用的不是一门语言,故此,我希望针对iOS的实现进行一番研究。
但是那个时候工作繁忙,也无心考究,只能成为心中的一道疑惑。
后来,我又遇到了一款游戏,叫最囧游戏2,里面也有很多很多需要这个技术的地方,真的是新奇又好玩。
比如辨别哪个是男扮女装,把手机倒过来裙子就撩起来了,然后就会发现有什么奇怪的东西混进来了~
还有辨别哪个是雪碧?摇一摇有气泡出来就是雪碧。
还有一个特别难的就是哄小宝宝入睡,真的是好难,我无论如何也没有想到,还能有这种操作···
等等吧,非常多利用和手机的互动来过关的关卡,没玩过的大家可以去体验一下~

正文

1.理论基础

iOS加速计是一个什么东西呢?其实他是一个三轴加速计,这意味着它可以检测三维空间中的运动和重力,因此加速计不仅可以获取用户握持手机的方向是向上还是向下,而且可以感知手机正面向上还是向下。
加速计可以测量设备在特定方向加速度,使用重力g作为单位,当加速度返回值为0.1.时,表明设备在特定方向上感知到1g。
iOS设备的加速计所使用的三轴坐标系统如图(网上找的图)所示:
然而我看到的书上不是这样的···
 

我懵了,我陷入了矛盾中,因为我测试的结果是手机水平向左显示负值,向右显示正值,所以到底是怎么样的,请大家帮我确定一下下······

ok,有些东西说起来有些复杂,因为参照物不同,操作不同等原因,我就不多做解释了。比如这个加速度数据和陀螺仪数据啊什么的。大家可以做出来自己看看效果就大致懂了~

我们接下来要了解的是CMMotionManager。它大致可获取3种数据。

>>加速度数据:该数据通过CMAccelerometerData对象来表示。该对象只有一个CMAcceleration结构体类型的acceleration属性,该结构体属性包含x、y、z三个字段,分别代表设备在X、Y、Z轴方向检测到的加速度值。
>>陀螺仪数据:该数据通过CMGyroData对象来表示。该对象只有一个CMRotationRate结构体类型的rotationRate属性,该结构体属性值包含x、y、z三个字段,分别代表设备围绕X、Y、Z轴转动的速度。
>>磁场数据:该数据通过CMMagnetometerData对象来表示。该对象只有一个CMMagneticField结构体类型的magneticField属性,该结构体属性值包含x、y、z三个字段,分别代表设备在X、Y、Z轴方向检测到的磁场强度,以微特斯拉为单位。

除此之外,CMAccelerometerData、CMGyroData、CMMagnetometerData有一个公共的父类:CMLogItem,该父类定义了timestamp属性,这意味着不管是加速度数据、陀螺仪数据还是磁场数据,都可通过timestamp属性来访问程序得到该数据的时间。

iOS应用程序获取加速度数据、陀螺仪数据、磁场数据有两种方式。
(1)基于代码块的方式。
(2)周期性主动请求的方式。

接下来我用代码给大家说一下两种方式。

2.基于代码块获取

第一步:创建CMMotionManager对象。
第二步:为CMMotionManager设置获取加速度数据、陀螺仪数据、磁场数据的频率。即设置xxxUpdateInterval的值,属性单位是秒。(xxx代表加速度或者陀螺仪或者磁场数据)
第三步:调用CMMotionManager的startxxxUpdatesToQueue:queue withHandler: 方法来周期性地获取三种数据。
第四步:如果程序出错,或者想终止获取这些数据,可以调用stopxxxUpdates方法停止获取。
 
上代码了~

//基于代码块方式获取加速度数据、陀螺仪数据、磁场数据
- (void) getDataByCodeBlock {//创建CMMotionManager对象self.motionManager = [[CMMotionManager alloc] init];NSOperationQueue *queue = [[NSOperationQueue alloc] init];//如果CMMotionManager支持获取加速度数据if (self.motionManager.accelerometerAvailable) {//设置CMMotionManager的加速度数据更新频率为0.1秒self.motionManager.accelerometerUpdateInterval = 0.1;//使用代码块开始获取加速度数据[self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {NSString *labelText;//如果发生了错误,error不为空if (error) {//停止获取加速度数据[self.motionManager stopAccelerometerUpdates];labelText = [NSString stringWithFormat:@"获取加速度数据出现错误:%@",error];} else {//分别获取系统在XYZ轴上的加速度数据labelText = [NSString stringWithFormat:@"加速度为\n---------\nX轴:%+.2f\nY轴:%+.2f\nZ轴:%+.2f",accelerometerData.acceleration.x,accelerometerData.acceleration.y,accelerometerData.acceleration.z];}//在主线程中更新accelerometerLabel的文本,显示加速度数据[self.accelerometerLabel performSelectorOnMainThread:@selector(setText:) withObject:labelText waitUntilDone:NO];}];} else {NSLog(@"该设备不支持获取加速度数据!");}//如果CMMotionManager支持获取陀螺仪数据if (self.motionManager.gyroAvailable) {//设置CMMotionManager的陀螺仪数据更新频率为0.1秒self.motionManager.gyroUpdateInterval = 0.1;//通过代码块开始获取陀螺仪数据[self.motionManager startGyroUpdatesToQueue:queue withHandler:^(CMGyroData * _Nullable gyroData, NSError * _Nullable error) {NSString *labelText;//如果发生了错误,error不为空if (error) {//停止获取陀螺仪数据[self.motionManager stopGyroUpdates];labelText = [NSString stringWithFormat:@"获取陀螺仪数据出现错误:%@",error];} else {//分别获取设备绕XYZ轴的转速labelText = [NSString stringWithFormat:@"绕各轴的转速为\n---------\nX轴:%+.2f\nY轴:%+.2f\nZ轴:%+.2f",gyroData.rotationRate.x,gyroData.rotationRate.y,gyroData.rotationRate.z];}//在主线程中更新gyroLabel的文本,显示绕各轴的转速[self.gyroLabel performSelectorOnMainThread:@selector(setText:) withObject:labelText waitUntilDone:NO];}];} else {NSLog(@"该设备被不支持获取陀螺仪数据!");}//如果CMMotionManager支持获取磁场数据if (self.motionManager.magnetometerAvailable) {//设置CMMotionManager的磁场数据更新频率为0.1秒self.motionManager.magnetometerUpdateInterval = 0.1;//通过代码块开始获取磁场数据[self.motionManager startMagnetometerUpdatesToQueue:queue withHandler:^(CMMagnetometerData * _Nullable magnetometerData, NSError * _Nullable error) {NSString *labelText;if (error) {[self.motionManager stopMagnetometerUpdates];labelText = [NSString stringWithFormat:@"获取磁场数据出现错误:%@",error];} else {//分别获取设备在XYZ轴的磁场强度labelText = [NSString stringWithFormat:@"各轴的磁场强度为\n————\nX轴:%+.2f\nY轴:%+.2f\nZ轴:%+.2f",magnetometerData.magneticField.x,magnetometerData.magneticField.y,magnetometerData.magneticField.z];}//在主线程中更新magnetometerLabel的文本,显示磁场数据[self.magnetometerLabel performSelectorOnMainThread:@selector(setText:) withObject:labelText waitUntilDone:NO];}];} else {NSLog(@"该设备被不支持获取磁场数据!");}
}

运行效果图如下图所示,其中一个是正面放在桌子上,一个是倒扣在桌子上的。

需要注意的是,我们在效果图上能看到显示的X、Y轴上也有很小的加速度,这可能是由两方面原因造成的。一方面是桌子不是绝对平的,另一方面是当用户用手旋转手机时,实际上也会对手机的两侧产生加速度。

3.主动请求获取

第一步:创建CMMotionManager对象。
第二步:调用CMMotionManager对象的startxxxUpdates方法开始更新加速度数据、陀螺仪数据、磁场数据。
第三步:使用定时器、子线程或其他任意的可以周期性轮询机制通过CMMotionManager对象获得三种数据。
第四步:如果程序出现错误,或者程序想要终止获取这些数据,则可调用stopxxxUpdates方法停止获取。
上代码了~
- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];//启动定时器来周期性轮询加速度数据、陀螺仪数据、磁场数据updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateDisplay) userInfo:nil repeats:YES];
}
//主动请求获取加速度数据、陀螺仪数据、磁场数据
- (void)getDataByRequest {//创建CMMotionManager对象self.motionManager = [[CMMotionManager alloc] init];//如果CMMotionManager支持获取加速度数据if (self.motionManager.accelerometerAvailable) {[self.motionManager startAccelerometerUpdates];} else {NSLog(@"该设备不支持获取加速度数据!");}//如果CMMotionManager支持获取陀螺仪数据if (self.motionManager.gyroAvailable) {[self.motionManager startGyroUpdates];} else {NSLog(@"该设备不支持获取陀螺仪数据!");}//如果CMMotionManager支持获取磁场数据if (self.motionManager.magnetometerAvailable) {[self.motionManager startMagnetometerUpdates];} else {NSLog(@"该设备不支持获取磁场数据!");}
}//
- (void)updateDisplay {//如果CMMotionManager的加速度数据可用if (self.motionManager.accelerometerAvailable) {//主动请求获取加速度数据CMAccelerometerData *accelerometerData = self.motionManager.accelerometerData;self.accelerometerLabel.text =[NSString stringWithFormat:@"加速度为\n---------\nX轴:%+.2f\nY轴:%+.2f\nZ轴:%+.2f",accelerometerData.acceleration.x,accelerometerData.acceleration.y,accelerometerData.acceleration.z];}//如果CMMotionManager的陀螺仪数据可用if (self.motionManager.gyroAvailable) {//主动请求获取陀螺仪数据CMGyroData *gyroData = self.motionManager.gyroData;self.gyroLabel.text = [NSString stringWithFormat:@"绕各轴的转速为\n---------\nX轴:%+.2f\nY轴:%+.2f\nZ轴:%+.2f",gyroData.rotationRate.x,gyroData.rotationRate.y,gyroData.rotationRate.z];}//如果CMMotionManager的磁场数据可用if (self.motionManager.magnetometerAvailable) {CMMagnetometerData *magnetometerData = self.motionManager.magnetometerData;self.magnetometerLabel.text = [NSString stringWithFormat:@"各轴的磁场强度为\n---------\nX轴:%+.2f\nY轴:%+.2f\nZ轴:%+.2f",magnetometerData.magneticField.x,magnetometerData.magneticField.y,magnetometerData.magneticField.z];}
}

呈现的界面与数据与上面大致相同~

好了,今天我们的陀螺仪和加速计小课堂到此结束啦~ 赶快动动手指操作起来吧~

iOS CMMotionManager之加速计、陀螺仪相关推荐

  1. 3轴/6轴/9轴传感器是什么, 加速计/陀螺仪/磁力计又是什么?

    欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群 转自:加速计/陀螺仪/磁力计是什么,3轴/6轴/9轴传感器又是什么?_不积跬步,无以至千里!-CSDN博客 现在越来越多的设备 ...

  2. ESP8266-Arduino编程实例-MPU6500加速计陀螺仪驱动

    MPU6500加速计陀螺仪驱动 1.MPU6500介绍 MPU-6500 是一款 6 轴运动跟踪设备,将 3 轴陀螺仪.3 轴加速度计和数字运动处理器™ (DMP) 组合在一个 3x3x0.9 毫米的 ...

  3. iOS传感器:使用陀螺仪完成一个小球撞壁的小游戏

    上一次借着实现一个随屏幕旋转的小玩意,了解了iPhone内置的加速计.今天咱们继续搞点好玩的东东.按照计划这次要看看陀螺仪了. 最终咱们会完成一个小球撞壁的小游戏,一个超级贱的利用陀螺仪的APP.小球 ...

  4. 加速计陀螺仪信息采集

    Sensor.TYPE_GYROSCOPE 陀螺仪就是内部有一个陀螺,它的轴由于陀螺效应始终与初始方向平行,这样就可以通过与初始方向的偏差计算出实际方向.手机里陀螺仪实际上是一个结构非常精密的芯片,内 ...

  5. 加速计陀螺仪6轴数据融合算法解析

    四旋翼和云台都离不开加速计和陀螺仪.加速计提供实时的重力加速度方向,进而可以计算出机体姿态角度.陀螺仪提供实时的旋转角度,通过积分也能换算成机体姿态角度.加速计对机体振动非常敏感,稍有扰动,加速度方向 ...

  6. ios html js调用陀螺仪,Js 获取手机陀螺仪

    仅在移动端才能查看效果 问题: 1.请确保在https环境下打开 2.ios手机需要用户手动获取权限后才能调用 DeviceOrientationEvent name="viewport&q ...

  7. ios html js调用陀螺仪,javascript – chrome mobile和safari mobile中不同的陀螺仪值

    我目前正在构建一个小型全景照片查看器,可以选择使用陀螺仪导航场景.我从deviceOrientation事件中获取数据并将euler角度转换为旋转矩阵,然后将其放入一些变换并最终移动带有3dMatri ...

  8. iOS平台使用陀螺仪传感器

    iOS平台使用陀螺仪传感器 在移动端开发过程中,有时候会用到陀螺仪传感器获取当前手机的姿态,下面给出iOS端如何获取陀螺仪姿态数据的代码: 1 //根据陀螺仪的四元数转换为矩阵 2 + (GLKMat ...

  9. 加速计简单使用---迷宫游戏

    今天通过编写一个简单的迷宫游戏,来展示如何使用iPhone的内置加速计. 游戏效果如下图所示.用户通过上下左右摇晃屏幕控制这个橙色的pacman挪动,pacman撞到屏幕边缘或者墙壁(蓝色边框方块)会 ...

  10. 【iOS与EV3混合机器人编程系列之中的一个】iOS要干嘛?EV3能够更酷!

    乐高Mindstorm EV3智能机器人(下面简称EV3) 自从在2013年的CES(Consumer Electronics Show美国消费电子展)上展出之后, 就吸引了全球广大机器人爱好者的眼球 ...

最新文章

  1. Nginx rewrite使用
  2. BAD APPLE C++控制台程序
  3. 3DMax的OFusion插件的使用问题
  4. x12arima季节调整方法_《时间序列X-12-ARIMA季节调整:原理与方法》
  5. go编译so win10_windows搭建Go语言交叉编译环境
  6. php 数组对,PHP数组游标实现对数组的各种操作详解
  7. UVA11636 Hello World!【模拟】
  8. python自动化办公真的好用吗-Python做什么更合适?|老男孩Python自动化运维
  9. 【渝粤题库】广东开放大学mysql数据库及应用 形成性考核 - 副本 (5)
  10. Irrlicht引擎例子说明及中文链接
  11. windows如何安装pycharm2022版本?pycharm如何安装汉化语言包{www.423zy.com}
  12. 使用最小二乘法拟合曲线
  13. cmake 返回上层目录
  14. 2019 11月 月末总结
  15. 免费建立一个自己的网站
  16. 推荐一个巨好用的查看gihub源码的插件-Octotree
  17. 通过一道ARM PWN题引发的思考:jarvisOJ_typo
  18. xml文件中空格输入
  19. 搜索关键词挖掘,搜索关键词填写时需要注意的几项。
  20. 全球及中国用于癌症治疗的新型药物输送系统行业研究及十四五规划分析报告

热门文章

  1. 硬件工程师面试常见问题
  2. spring中创建excl表的几种方式并导出
  3. 关于app 元素定位
  4. PowerDesigner 反向工程获取数据库表结构
  5. Android信任Https自签名证书详细教程
  6. 天敏G10数位板安装完PS无压感,观看此教程
  7. Sphinx/coreseek/mysql全文检索
  8. java一元二次方程用if_用javascript写一个求一元二次方程的页面 用JAVA写一个求解一元二次方程的类...
  9. 孩子早餐要吃好,如何为孩子准备营养早餐
  10. 好用的在线客服系统PHP源码(开源代码+终身使用+安装教程)