iOS4中Core Motion框架的介绍和使用

NSGA(非支配排序遗传算法) 在多目标优化问题中,往往存在多个相互冲突的目标需要同时优化。传统的单目标优化算法无法直接应用于这类问题,因此需要专门的多目标优化算法。非支配排序遗传算法(Non-dominated Sorting Genetic Algorithm,NSGA)是一种经典的多目标优化算法,由印度科学家 Kalyanmoy Deb 等人于 1995 年提出。NSGA 通过非支配排序和拥挤度距离来引导种群向 Pareto 最优前沿进化,从而得到一组具有良好分布性和收敛性的 Pareto 最优解。 阅读详情

iOS4中Core Motion框架的介绍和使用

作为一个刚学习iPhone编程一周的人来说,其实写这篇文章的目的不是传道授业解惑,而是为了知识的总结。如果能吸引到各位为我传道授业解惑那再好不过了。文章基本的内容,整个流程是参照WWDC 2010上的session 423: Sensing Device Motion in iOS4写的,同时参考了开发文档Event Handling Guide for iPhone OS: Motion Events。当然,我在介绍的时候会添加一些个人的总结和原理的补充。文章可能有错误的叙述,发现后请指出,谢谢。

我之前的文章:移动设备智能化的基石–从iPhone4的传感器谈起曾经写过,iPhone4增加的陀螺仪弥补了很多现有motion sensor的不足,也介绍了很多背景知识。加速度计最大的缺陷,就是无法检测沿着重力加速度轴方面的旋转变化,而且,如果仅仅有加速度计,无法避免重力的干扰。传统的方法是怎么做的呢?先高通滤波,把近似于直流分量的重力加速度隔离出来,再低通滤波,把因为手机颤抖产生的高频噪声去掉。大量的滤波,不仅会影响到原本的加速度信号,还会严重减缓处理速度,并随之影响程序相应速度。电子罗盘在这方面毫无帮助,这玩意本身的读数都需要很长的稳定时间,还特别容易受环境干扰。所以,陀螺仪的引入,解决了这几个大问题,我们可以用它来测量沿重力加速度的旋转,也可以测量快速的旋转,大大增强了motion相关的处理工作,更重要的是,通过陀螺仪可以判断手机当前的摆放位置和姿势,然后通过这个信息能够得到相当准确的重力加速度分量,而不是从加速计采集的包含很多噪声的加速度值中提取。所以说,陀螺仪对于motion sensing方面的工作,是最关键的一个部件。陀螺仪的具体原理,请参考之前那篇文章。


在iOS4之前,加速度计由UIAccelerometer类来负责采集工作,而电子罗盘则由Core Location接管。而iPhone4的推出,由于加速度计的升级(有消息说使用的是这款芯片)和陀螺仪的引入,与motion相关的编程成为重头戏,所以,苹果在iOS4中增加一个一个专门负责该方面处理的框架,就是Core Motion Framework。这个Core Motion有什么好处呢?简单来说,它不仅仅提供给你获得实时的加速度值和旋转速度值,更重要的是,苹果在其中集成了很多算法,可以直接给你输出把重力加速度分量剥离的加速度,省去你的高通滤波操作,以及提供给你一个专门的设备的三维attitude信息!

有这么一个好东西,我们自然就要好好利用了。下面就介绍一下,如何利用Core Motion Framework,来获得对应的motion信息。

Core Motion在iOS4.0主要负责三种数据:加速度值,陀螺仪值,设备motion值。实际上,这个设备motion值就是通过加速度和旋转速度进行fusing变换算出来的,基本原理后面会介绍。Core Motion在系统中以单独的后台线程的方式去获得原始数据,并同时执行一些motion算法来提取更多的信息,然后呈献给应用层做进一步处理。Core Motion框架包含有一个专门的Manager类,CMMotionManager,然后由这个manager去管理三种和运动相关的数据封装类,而且,这些类都是CMLogItem类的子类,所以相关的motion数据都可以和发生的时间信息一起保存到对应文件中,有了时间戳,两个相邻数据之间的实际更新时间就很容易得到了。这个东西是非常有用的,比如有些时候,你得到的是50Hz的采样数据,但希望知道的是每一秒加速度的平均值。

从Core Motion中获取数据主要是两种方式,一种是Push,就是你提供一个线程管理器NSOperationQueue,再提供一个Block(有点像C中的回调函数),这样,Core Motion自动在每一个采样数据到来的时候回调这个Block,进行处理。在这中情况下,block中的操作会在你自己的主线程内执行。另一种方式叫做Pull,在这个方式里,你必须主动去像Core Motion Manager要数据,这个数据就是最近一次的采样数据。你不去要,Core Motion Manager就不会给你。当然,在这种情况下,Core Motion所有的操作都在自己的后台线程中进行,不会有任何干扰你当前线程的行为。

那接下来的问题就是,我在什么时候选择什么方式呢?苹果官方推荐了一个使用指南,比较了两种方式的优劣,并做出了使用场景的推荐。如下图所示。应该说,两种方式各自的优缺点还是很鲜明的,使用场景也大不一样,很好区分。

Core Motion的大体介绍就是这些。下面说说Core Motion具体负责的采集,计算和处理。Core Motion的使用就是一三部曲:初始化,获取数据,处理后事。

在初始化阶段,不管你要获取的是什么数据,首先需要做的就是

motionManager = [[CMMotionManager alloc] init];

所有的操作都会由这个manager接管。后面的初始化操作相当直观,以加速度的pull方式为例

if (!motionManager.accelerometerAvailable) {
// fail code // 检查传感器到底在设备上是否可用
}
motionManager.accelerometerUpdateInterval = 0.01; // 告诉manager,更新频率是100Hz
[motionManager startAccelerometerUpdates]; // 开始更新,后台线程开始运行。这是pull方式。

如果是push方式,更新的代码可以写成这样

[motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *latestAcc, NSError *error)
{
// Your code here
}];

接下来就是获取数据了。Again,很简单的代码

CMAccelerometerData *newestAccel = motionManager.accelerometerData;
filteredAcceleration[0] = newestAccel.acceleration.x;
filteredAcceleration[1] = newestAccel.acceleration.y;
filteredAcceleration[2] = newestAccel.acceleration.z;

通过定义的CMAccelerometerData变量,获取CMAcceleration信息。和以前的UIAccelerometer类的使用方式一样,CMAcceleration在Core Motion中是以结构体形式定义的

typedef struct {
double x;
double y;
double z;
}

对应的motion信息,比如加速度或者旋转速度,就可以直接从这三个成员变量中得到。

最后是处理后事,就是在你不需要Core Motion进行处理的时候,释放资源

[motionManager stopAccelerometerUpdates];
//[motionManager stopGyroUpdates];
//[motionManager stopDeviceMotionUpdates];
[motionManager release];

你看,就是这么简单。当然,如果这么Core Motion这么简单,就太无趣了。实际上,Core Motion最好玩的地方,既不是加速度,也不是角速度,而是经过sensor fusing算法处理的Device Motion信息的提供。Core Motion里面提供了一个叫做CMDeviceMotion的类,用来把下图所示的这些数据封装成Device Motion信息:

我们来看看这些被封装数据的介绍。

第一个attitude,就是刚才说到的三维attitude,通俗来讲,就是告诉你手机在当前空间的位置和姿势。
第二个是重力信息,其本质是重力加速度矢量在当前设备的参考坐标系中的表达,开发不再需要通过滤波来提取这个信息了,因为Core Motion已经给你了。
第三个是加速度信息。同样,滤波在这里不再需要(根据程序需求而加的滤波算法自然是可以保留的)。
第四个是即时的旋转速率,也就是rotation rate,是陀螺仪的输出。

下面就来详细介绍一下这四种数据。

1. Attitude。在CMDeviceMotion对象中,attitude是以

@property (readonly, nonatomic) CMAttitude *attitude;

属性定义的。一个CMAttitude的实例,封装了关于当前设备在空间中的姿态信息。这个信息是由下面集中数学表达式定义的:

  1. 一个四元数。
  2. 一个变换rotation矩阵
  3. 三个欧拉角 (roll, pitch, 和yaw)。关于欧拉角,again,请参考我上一篇文章。

四元数是一种Attitude Determination System经常使用的数据保存形式,我不是很清楚。而欧拉角和变换矩阵则是相辅相成的,两者之间可以相互推导。所以这里主要介绍一下对虚拟现实或者游戏都大有帮助的变换矩阵。

这个rotation变换矩阵究竟有什么用呢?我们来看看下面这张图

本质上讲,变换矩阵给我们阐述了从一个向量空间到另一个向量空间的映射关系。举个例子,在很多应用中都需要对加速度信息进行判断,但是,用户在使用手机的过程中,姿势是不断变换的,我们可以采集到某个设备在t1时间点的加速度以及重力信息,也可以采集到t2时间点的信息,我们却不能直接拿他们做运算。为什么?因为由于手机各个轴方向的变化,加速度和重力信息在t1时间点属于一个向量空间,在t2时间点,就属于另一个向量空间了,如果你硬拿acc.x1和acc.x2求设备的运动模式,自然不可能准的。

所以,现在的问题是,我们要找到两个三维空间的线性变换T,让这个变换关系帮我们把某个空间的值变换到另一个空间去,这样就可以在同一个空间做比较或者任何计算了。Core Motion如何解决这个问题呢?它首先让你可以在程序开始的初始时间点t1(比如你画第一祯的时候)采集一个attitude的值作为参照坐标系,我们假定这个向量是v_ref。在任何时间点,比如t2,采集一个attitude的值,假定这个向量是v_dev,位于当前设备的坐标系,那么我们有以下关系:

其中R就是rotation matrix。由于v_ref是正交基向量,所以

刚才说到了,v_ref和v_dev都是其对应向量空间的正交基,而这个R矩阵正好是正交矩阵,所有的列向量线性独立。所以,R所对应的变换,正是我们要找的这两个空间的线性变换,而且这是一对一变换。

好,上面这个结论告诉我们什么呢?你在当前时刻t2采集的当前坐标系下的加速度信息,不仅在t1时刻的参照坐标系下有对应的向量,而且仅有一个对应向量!如果我们定义a_dev是当前的加速度向量,那么它在参照坐标系里面对应的加速度向量只有一个,而且肯定可以由下面式子求出

这个式子不存在无解的情况,因为正交矩阵永远都是有逆矩阵的。经此变换,你就可以随意比较和计算不同时间点的加速度和重力信息,从而得出精确的用户运动模式了。

比较有趣的一点是,R变换矩阵的表达形式,正好表明了R和rotation rate的关系: 当前时间点的坐标系和参照坐标系的变换矩阵,是由陀螺仪提供的yaw, pitch和roll三个轴上角度信息推断的。于是,再一次,我们感受到了新加的陀螺仪强大的地方。更强大的地方在于,Core Motion直接就把R矩阵提供给开发者了,省去了开发者很多易错而繁琐的工作。

说了这么多铺垫,还是简单介绍一下获得当前时间点的R矩阵信息的步骤吧:

首先,获得参考矩阵信息

if (motionManager != nil) {
CMDeviceMotion *deviceMotion = motionManager.deviceMotion;
referenceAttitude = [deviceMotion.attitude retain];
}

然后在希望得到R矩阵的时候,执行下列操作:

CMRotationMatrix rotation;
CMDeviceMotion *deviceMotion = motionManager.deviceMotion;
CMAttitude *attitude = deviceMotion.attitude;
if (referenceAttitude != nil) {
[attitude multiplyByInverseOfAttitude:referenceAttitude];
}
rotation = attitude.rotationMatrix;

很简单,也很直观,一个multiplyByInverseOfAttitude的调用,正好反应了我们刚才推导的矩阵运算关系。至此,rotationMatrix被我们拿到,接下来的事情就只有想不到,没有做不到了。

2. Gravity和UserAcceleration。之所以把他们放在一起讲,是因为他们本质上比较类似,而且原始的加速度(就是通过[motionManager startAccelerometerUpdates]获得的那个值)本来就是他们的叠加和,换句话说,将原始加速度分解就得到了他们俩,只不过现在苹果帮你把这个滤波分解给做了。他俩在Core Motion中的属性定义是

@property (readonly, nonatomic) CMAcceleration gravity;
@property (readonly, nonatomic) CMAcceleration UserAcceleration;

都是CMAcceleration所包装的结构体。而且,两者的参考坐标系都是一样的,以设备的外框架为准:

得到这两种数据的方式比较简单,就是直接通过读取motionManager.deviceMotion.userAcceleration/gravity的三个成员变量即可。

3. Rotation rate。旋转速率是通过叫CMRotationRate的结构体封装的,其内部变量定义和CMAcceleration一模一样。正负的确定,由右手法则判断。看到这里,不少朋友可能会有问题:这个数据,和之前介绍的直接通过motionManager获得的CMGyroData有什么区别呢?通过Device Motion封装处理后的Rotation rate,去掉了原始的CMGyroData所有的bias。举个例子,如果我们把设备放在桌上静止不动,理想情况下,陀螺仪的输出应该是0。问题在于,你直接从陀螺仪获得的原始数据并不是0,而是由很多不确定因素导致的非0值,这其中就包括了很多的漂移误差等等,比如陀螺仪温漂,就会影响到我们的读数。Core Motion经过一些算法的处理,帮开发者消除了这种bias,极大方便了motion相关的开发工作。

说到Rotation rate,要讲一下这个输出数值的特点。如果你写一个简单的测试程序,把三个轴的数值都输出到屏幕上来看,会发现一个很有意思的现象:pitch和roll的值,和你读数时候的手机的attitude完全对应,而yaw的值,则是从0开始显示,手机的attitude在之后变了的话,yaw的值才有对应的变化。这是因为,对于pitch和roll来讲,他们都有明确的参照面,就是水平面,而且这个值肯定是在出厂之前就校正过。但yaw呢?没有,用户在刚打开app的时候,可能会朝向任何不同的方向。所以此时,Core Motion干脆就给你输出相对的初始值0,之后你再根据yaw方向上的相对变化来判断设备的位置变化。

另外一点要补充的是,对于设备的旋转,如果三个轴上都有变化,那么默认角度计算的顺序是先roll,再pitch,最后yaw。

总结

讲到现在,基本的Core Motion知识就都总结完了。在智能手机出现之前,我们都说,手机就是用来打电话的。智能手机改变了这一切。用户总是有各种各样的需求等待开发者满足,而关键就在于,开发者能不能理解用户,认识用户,做好个人化。Gyroscope的集成和Core Motion的推出,让很多以前在智能手机上无法实现或者难以实现的应用成为了可能。这是机遇,想象力的机遇,也是挑战,执行能力的挑战


http://www.kunli.info/2010/07/30/motion/

暗黑破坏神2重制版 mod制作教程(一) 暗黑2重制版mod修改教程 阅读详情

相关推荐

使用GitLab+Drone CI持续集成自动部署web项目,图文详细

kind: pipeline # 定义对象类型,还有secret和signature两种类型 type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型 name: mall-tiny-drone # 定义流水线名称 steps: # 定义流水线执行步骤,这些步骤将顺序执行 - name: package # 流水线名称 image: maven:3-jdk-8 # 定义创建容器的Docker镜像 volumes: # 将容器内目录挂载到宿主机,仓库

4105

陀螺仪重力感应(the gyroscope gravity induction)and (core Motion Framework)

在iOS4之前,加速度计由UIAccelerometer类来负责采集工作,而电子罗盘则由Core Location接管。而iPhone4的推出,由于加速度计的升级(有消息说使用的是这款芯片)和陀螺仪的引入,与motion相关的编程成为重头戏,所以,苹果在iOS4中增加一个一个专门负责该方面处理的框架,就是Core Motion Framework。这个Core Motion有什么好处呢?简单来

yuanfj86912的专栏 2908

Lumerical官方案例、FDTD时域有限差分法仿真学习(三)——环形谐振器(Ring resonator)之第二&第三部分

二、使用 MODE 的参数提取和蒙特卡罗 三、最终参数提取

weixin_45719141的博客 1万+

陀螺仪、加速计、磁力计等传感器汇总

陀螺仪就是内部有一个陀螺,它的轴由于陀螺效应始终与初始方向平行,这样就可以通过与初始方向的偏差计算出实际方向。手机里陀螺仪实际上是一个结构非常精密的芯片,内部包含超微小的陀螺。 加速计是用来检测手机受到的加速度的大小和方向的,而手机静置的时候是只受到重力加速度(这个高中学过)的.所以很多人把加速计功能又叫做重力感应功能。 磁力计是测试磁场强度和方向的。 陀螺仪测量是参考标准是内部中间

Wave的专栏 2万+

UFS 3.1协议实战解析:从MIPI M-PHY到SCSI命令的完整链路拆解

本文深入解析UFS 3.1存储协议,从MIPI M-PHY物理层到SCSI命令层,完整拆解数据链路。通过分析协议栈三层架构(UIC、UTP、UCS),结合Wireshark抓包实战,详解UPIU数据包传输与SCSI命令封装,并探讨GEAR模式对性能与功耗的影响,为嵌入式存储开发与调试提供实用指南。

weixin_29207533的博客 418

易康eCognition9.0分类|规则集和机器学习的方法的面向对象的多尺度分割分类

基于易康eCognition9.0软件的规则集和机器学习的方法的面向对象的多尺度分割分类

weixin_46493028的博客 1万+

【UAV】陀螺仪数据分析,以维特智能 JY901B 为例

文章目录简介1 加速度 Acceleration2 陀螺仪 Gyroscope3 欧拉角 Euler angles4 磁场 Magnetic5 四元数 Quaternion6 时间7 端口状态补充知识Ref: JY901B-资料详情-维特智能 十轴加速度计陀螺仪模块姿态角度传感器倾角磁力计气压高度JY901B 简介 能够测量的数据信息主要包含以下几部分: 三轴加速度 三轴陀螺仪 三轴角度 三轴磁场 气压+高度 200Hz回传 信息精度及输出信息主要包括: 角度精度:动态 0.1°0.1\degre

赵继超的笔记 6277

博客系统 - 系统简介与首页设计

用Bootstrap实现手机端的博客导航栏效果。

m0_53450409的博客 1237

JTS-AffineTransformation 仿射变换使用说明(十三)

org.locationtech.jts.geom.util.AffineTransformation 使用说明 AffineTransformation 仿射变换工具类 AffineTransformation 相关类关系图 说明 表示二维笛卡尔平面上的仿射变换。它可用于变换坐标或几何。 仿射变换是通过以下基本类型的一系列变换将2D平面映射到其自身: reflection反射(通过直线) rotation旋转(绕原点) scaling缩放(相对于原点) shearing剪切(在X和Y方向) transl

鸟语清晨 1321

树莓派5新手必看:保姆级ibus中文输入法安装与配置全流程(含.bashrc设置避坑)

本文详细介绍了在树莓派5上安装和配置ibus中文输入法的完整流程,包括系统环境准备、ibus框架安装、图形界面配置及常见问题解决方案。通过清晰的步骤说明和避坑指南,帮助新手快速实现中文输入功能,提升开发效率。

weixin_29159441的博客 524

GPS系统跟踪捕获算法的Verilog实现在FPGA

本文将介绍GPS系统中的跟踪捕获算法,并提供该算法的Verilog实现在FPGA上运行的源代码。常用的方法是将接收到的信号与一个本地振荡器产生的参考信号进行混频,然后使用带通滤波器提取出希望得到的频率分量。码跟踪的目的是通过检测接收到的信号中的码片序列来实现对导航数据的解调。以上是一个简化的GPS系统跟踪捕获算法的Verilog实现,其中包含了时间检测、频率跟踪和码跟踪三个模块。GPS信号由载波频率和导航数据组成。跟踪捕获算法的目标是通过对接收到的信号进行处理,从而获取到准确的载波频率和导航数据。

PixelEnigma的博客 1108

MPU6050姿态解算2-欧拉角&旋转矩阵

IMU姿态解算 IMU,即惯性测量单元,一般包含三轴陀螺仪与三轴加速度计。之前的文章MPU6050姿态解算1-DMP方式已将对MPU6050这款IMU作了简单的介绍,并通过其内部的DMP处理单元直接得到姿态解算的四元数结果。本篇将通过软件解算的方式,利用欧拉角与旋转矩阵来对陀螺仪与加速度计的原始数据进行姿态求解,并将两种姿态进行互补融合,最终得到IMU的实时姿态。 本篇的姿态解算选用的旋转顺序为ZYX,即IMU坐标系初始时刻与大地坐标系重合,然后依次绕自己的Z、Y、X轴进行旋转,这里先自定义一下每次的旋转名

码农爱学习的博客 2万+

HTML5+CSS3+JS小实例:扇形展开折叠菜单

你肯定见过那种圆形浮动按钮(FAB),点一下弹出几个选项。大部分实现就是菜单项从底下往上"弹"出来,排成一列——能用,但没啥记忆点。后来我看到 Path 那个经典的扇形菜单,点一下,五个按钮像花瓣一样从中心散开,每个带不同的延迟和弹性曲线。当时就觉得:这才对嘛,交互就该有点"戏剧性"。今天拆一个纯手写版本,HTML + CSS + JS,不依赖任何库。六菜单项、扇形 144° 展开、弹性过渡、点击关闭、键盘可达——该有的都有。

艾恩小灰灰的博客 164

解析iOS4中Core Motion框架使用方法

解析iOS4中Core Motion框架使用方法 原文:http://mobile.51cto.com/iphone-285018.htm iOS4中Core Motion框架使用方法是本文要介绍的内容,主要是来学习IOS4中框架的内容。在iOS4之前,加速度计由UIAccelerometer类来负责采集工作,而电子罗盘则由Core Location接管。 而iPhone4的

xiong1081的博客 565

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

iOS4 中 Core Motion 框架的介绍和使用

在iOS4之前,加速度计由UIAccelerometer类来负责采集工作,而电子罗盘则由Core Location接管。而iPhone4的推出,由于加速度计的升级(有消息说使用的是这款芯片) 和陀螺仪的引入,与motion相关的编程成为重头戏,所以,苹果在iOS4中增加一个一个专门负责该方面处理的框架,就是Core Motion Framework。这个Core Motion有什么好处呢?简单

感激赐教的专栏 1333

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

iOS高级进阶(1):iOS4 中 Core Motion 框架的介绍和使用

在iOS4之前,加速度计由UIAccelerometer类来负责采集工作,而电子罗盘则由Core Location接管。而iPhone4的推出,由于加速度计的升级(有消息说使用的是这款芯片) 和陀螺仪的引入,与motion相关的编程成为重头戏,所以,苹果在iOS4中增加一个一个专门负责该方面处理的框架,就是Core Motion Framework。这个Core Motion有什么好处呢?简单

lfr_dev的专栏 1154
上一篇: UIImageView上面放UIButton不响应事件
下一篇: UITextView
focusjava
博客等级 码龄14年 127粉丝 528原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值