android传感器获取运动方向,Android开发者指南-运动传感器Motion Sensor[原创译文]...

Android

平台支持很多监测设备运动的传感器。其中有两个传感器一定是基于硬件的(加速度计和陀螺仪),有三个可能基于硬件或软件(重力计、线性加速计和旋转向量传感器)。

比如,某些设备的软传感器利用加速度计和磁力计来报送数据,而其它一些设备可能用陀螺仪来报送数据。 大部分 Android

平台的设备都带有加速计,有很多现在还带有陀螺仪。软传感器的可用性变数更大一些,因为它们常常依靠一个以上硬件传感器来报送数据。

运动传感器对于监测设备的移动非常有用,诸如倾斜、震动、旋转、摇摆等。

这些动作通常是直观反映了用户的输入(比如用户在游戏中操纵汽车或者运球),但也可能反映了设备所处的物理环境变化(比如你在开车,设备也随着移动)。

在第一种场合中,你监测的运动是以设备或应用为参照系;而在第二种场合,运动是以地球为参照系的。

一般情况下,运动传感器不是用来监测设备的方位的,但它们可以与其他传感器合作使用,比如地磁传感器,用于检测设备的在地球参照系中的方位(详见

方位传感器)

所有的运动传感器都会在 float 数组的方式在参数中返回。表

1 列出了 Android 平台支持的所有运动传感器:

表 1.. Android 平台支持的运动传感器。

传感器

传感器事件数据

说明

测量单位

SensorEvent.values[0]

沿 x 轴的加速度(包括重力)。

m/s2

SensorEvent.values[1]

沿 y 轴的加速度(包括重力)。

SensorEvent.values[2]

沿 z 轴的加速度(包括重力)。

SensorEvent.values[0]

沿 x 轴的重力加速度。

m/s2

SensorEvent.values[1]

沿 y 轴的重力加速度。

SensorEvent.values[2]

沿 z 轴的重力加速度。

SensorEvent.values[0]

围绕 x 轴的旋转角速度。

rad/s

SensorEvent.values[1]

围绕 y 轴的旋转角速度。

SensorEvent.values[2]

围绕 z 轴的旋转角速度。

SensorEvent.values[0]]

沿 x 轴的加速度(不包括重力)。

m/s2

SensorEvent.values[1]

沿 y 轴的加速度(不包括重力)。

SensorEvent.values[2]

沿 z 轴的加速度(不包括重力)。

SensorEvent.values[0]]

旋转向量沿 x 轴的部分(x * sin(θ/2))。

无无

SensorEvent.values[1]

旋转向量沿 y 轴的部分(y * sin(θ/2))。

SensorEvent.values[2]]

旋转向量沿 z 轴的部分(z * sin(θ/2))。

SensorEvent.values[3]]

旋转向量的数值部分((cos(θ/2))1。

1 数值部分是可选的。

检测和监视运动最常用的就是旋转向量传感器和重力传感器。

旋转向量传感器尤为强大,在有关运动的任务中用途十分广泛,诸如检测手势、监测角度变化、监测相对方位的变化。

比如,如果你正在开发游戏、增强现实(Augmented

Reality)应用、二维或三维罗盘、相机防抖应用,那么旋转向量传感器将十分有用。

在大多数场合,使用这两个传感器要比加速度计、磁力传感器和方向传感器更加合适。

Android 开源项目传感器

Android 开源项目(AOSP)提供了三种基于软件的运动传感器:重力传感器、线性加速度传感器和旋转向量传感器。

Android 4.0 中对这三种传感器进行了升级,目前利用陀螺仪(除了其它传感器)来增加稳定性和提高性能。

如果你想试试这些传感器,你可以用 备选传感器,所以必须用 vendor 和版本号来识别它们。

比如,如果设备制造商已经提供了重力传感器,则 AOSP 重力传感器会显示为备选传感器。

这三个传感器都依赖于陀螺仪:如果设备未提供陀螺仪,则它们都不会显示出来,也无法使用。

加速度传感器测量设备的加速度,包括重力加速度。以下代码展示了如何获取缺省的加速度传感器的一个实例:

privateSensorManagermSensorManager;privateSensormSensor;...mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

从概念上说,加速度传感器通过测量施于传感器上的作用力,并按以下关系来检测设备的加速度(Ad)。

Ad = - ∑Fs / mass

然而,重力总是会按以下关系影响测量的精度。

Ad = -g - ∑F / mass

因此,如果设备是平放在桌子上的(没有加速度),加速度计会读到g = 9.81 m/s2。

同理,设备在自由落体或以 9.81 m/s2 的加速度坠向地面时,加速度计会读到 g = 0

m/s2。 因此,要测出设备真实的加速度,必须排除加速计数据中的重力干扰。这可以通过高通滤波器来实现。

反之,低通滤波器则可以用于分离出重力加速度值。以下例程展示了它们的用法:

publicvoidonSensorChanged(SensorEventevent){// 在本例中,alpha 由 t / (t + dT)计算得来,// 其中 t 是低通滤波器的时间常数,dT 是事件报送频率finalfloatalpha=0.8;// 用低通滤波器分离出重力加速度gravity[0]=alpha*gravity[0]+(1-alpha)*event.values[0];gravity[1]=alpha*gravity[1]+(1-alpha)*event.values[1];gravity[2]=alpha*gravity[2]+(1-alpha)*event.values[2];// 用高通滤波器剔除重力干扰linear_acceleration[0]=event.values[0]-gravity[0];linear_acceleration[1]=event.values[1]-gravity[1];linear_acceleration[2]=event.values[2]-gravity[2];}

注意: 你可以使用很多技术来过滤传感器数据。

以上例程只是使用了过滤器常量(alpha)来创建一个低通滤波器。

这个过滤器常量是由时间常量(t)和传感器事件报送频率(dt)推导出来的,t 大致等于过滤器触发传感器事件的间隔时间。

为了演示,此例程使用 0.8 作为 alpha 的值。如果你要用这个过滤方法,你可能需选用其它的 alpha 值。

加速计使用了标准的传感器 坐标系 。这意味着,设备以原始方位平放在桌子上时,会发生以下状况:

如果你从左侧平推设备(它向右移),则 x 方向加速度为正值。

如果你从下侧平推设备(它向前移),则 y 方向加速度为正值。

如果以 A m/s2的加速度向空中移动设备,则 z 方向加速度等于 A + 9.81,即设备加速度(+A

m/s2)减去重力加速度(-9.81 m/s2)。

静止设备的加速度值为 +9.81,即设备加速度(0 m/s2)减去重力加速度(-9.81

m/s2)。

一般情况下,加速度计已足够应付对设备移动情况的监测。几乎所有 Android

平台的手持和桌面终端都带有加速度计,它的能耗比其它运动传感器要少10倍。

不过它有一个缺点,就是你不得不实现低通和高通滤波器,以消除重力影响并减少噪声数据。

Android SDK 给出了一个应用示例,展示了加速度传感器的使用方法( Accelerometer Play )。

重力传感器能以三维向量的方式提供重力方向和数量值。以下代码展示了如何获取缺省的重力传感器的一个实例:

privateSensorManagermSensorManager;privateSensormSensor;...mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);

单位与加速度传感器的一样(m/s2),坐标系也相同。

注意: 当设备静止时,重力传感器的输出应该与加速度计相同。

陀螺仪测量设备围绕 x、y、z 轴旋转的速率,单位是 rad/s。以下代码展示了如何获取缺省的陀螺仪的一个实例:

privateSensorManagermSensorManager;privateSensormSensor;...mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

陀螺仪的 坐标系 与加速度传感器的相同。逆时针方向旋转用正值表示,也就是说,从 x、y、z

轴的正向位置观看处于原始方位的设备,如果设备逆时针旋转,将会收到正值。

这是标准的数学意义上的正向旋转定义,而与方向传感器定义的转动不同。

通常,陀螺仪的输出反映了转动时的角度变化速率。例如:

// 创建常量,把纳秒转换为秒。privatestaticfinalfloatNS2S=1.0f/1000000000.0f;privatefinalfloat[]deltaRotationVector=newfloat[4]();privatefloattimestamp;publicvoidonSensorChanged(SensorEventevent){// 根据陀螺仪采样数据计算出此次时间间隔的偏移量后,它将与当前旋转向量相乘。if(timestamp!=0){finalfloatdT=(event.timestamp-timestamp)*NS2S;// 未规格化的旋转向量坐标值,。floataxisX=event.values[0];floataxisY=event.values[1];floataxisZ=event.values[2];// 计算角速度floatomegaMagnitude=sqrt(axisX*axisX+axisY*axisY+axisZ*axisZ);// 如果旋转向量偏移值足够大,可以获得坐标值,则规格化旋转向量// (也就是说,EPSILON 为计算偏移量的起步值。小于该值的偏移视为误差,不予计算。)if(omegaMagnitude>EPSILON){axisX/=omegaMagnitude;axisY/=omegaMagnitude;axisZ/=omegaMagnitude;}// 为了得到此次取样间隔的旋转偏移量,需要把围绕坐标轴旋转的角速度与时间间隔合并表示。// 在转换为旋转矩阵之前,我们要把围绕坐标轴旋转的角度表示为四元组。floatthetaOverTwo=omegaMagnitude*dT/2.0f;floatsinThetaOverTwo=sin(thetaOverTwo);floatcosThetaOverTwo=cos(thetaOverTwo);deltaRotationVector[0]=sinThetaOverTwo*axisX;deltaRotationVector[1]=sinThetaOverTwo*axisY;deltaRotationVector[2]=sinThetaOverTwo*axisZ;deltaRotationVector[3]=cosThetaOverTwo;}timestamp=event.timestamp;float[]deltaRotationMatrix=newfloat[9];SensorManager.getRotationMatrixFromVector(deltaRotationMatrix,deltaRotationVector);// 为了得到旋转后的向量,用户代码应该把我们计算出来的偏移量与当前向量叠加。// rotationCurrent = rotationCurrent * deltaRotationMatrix;}}

标准的陀螺仪能够提供未经过滤的原始旋转数据,或是经过噪声及漂移修正的数据。

实际生活中,陀螺仪的噪声和漂移都会引入误差,这是需要补偿的。

通常你要利用其它传感器来确定漂移和噪声值,比如重力传感器或加速计。

线性加速度传感器能向你提供一个三维向量,表示延着三个坐标轴方向的加速度,但不包括重力加速度。

以下代码展示了如何获取缺省的线性加速度传感器的一个实例:

privateSensorManagermSensorManager;privateSensormSensor;...mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);

理论上说,这个传感器基于以下公式给出加速度数据:

线性加速度 = 加速度 - 重力加速度

这个传感器的典型应用是获取去除了重力干扰的加速度数据。比如,你可以用这个传感器来获取汽车加速度。

线性加速度传感器总是会有些偏差,你需要把这个偏差值抵消掉。最简单的消除方式就是在你的应用中增加一个校准的环节。

在校准过程中,你可以要求用户先把设备放在桌子上,再来读取三个坐标轴的偏差值。

然后你就可以从传感器的读数中减去这个偏差值,以获取真实的线性加速度。

传感器 坐标系 与加速度传感器使用的相同,单位也一样(m/s2)。

旋转向量代表了设备的方位,由角度和坐标轴信息组成,包含了设备围绕坐标轴(x、y、z)旋转的角度θ。

以下代码展示了如何获取缺省的旋转向量传感器的一个实例:

privateSensorManagermSensorManager;privateSensormSensor;...mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);

旋转向量的三个元素用以下方式表示:

x*sin(θ/2)

y*sin(θ/2)

z*sin(θ/2)

旋转向量的大小等于 sin(θ/2),方向等于旋转轴的方向。

blog_48d4913001010w0h.html

a4c26d1e5885305701be709a3d33442f.png

图 1. 旋转向量传感器的坐标系。

旋转向量的三个元素等于四元组的后三个部分(cos(θ/2)、x*sin(θ/2)、y*sin(θ/2)、z*sin(θ/2)),没有单位。

x、y、z 轴的定义与加速度传感器的相同。坐标参照系定义为直接正交基(参见图 1)。 这个坐标系具有以下特点:

X 定义为向量积 Y x Z。它是以设备当前位置为切点的地球切线,方向朝东。

Y 是以设备当前位置为切点的地球切线,指向地磁北极。

Z 与地平面垂直,指向天空。

Android SDK 提供了一个示例应用,展示了旋转向量传感器的使用方法。 示例应用在 API Demos 中(

OS - RotationVectorDemo )。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android传感器MotionSensor开发实验 ⽬录 ⼀、实验⽬的 ⼀、实验⽬的 1. 了解Android开发 2. 掌握传感器调⽤ 3. 交互式界⾯设计 ⼆、实验要求 ⼆、实验要求 1) 搭建开发平台; 2)编写简单程序,实现按钮、屏幕操作的基本功能,应⽤程序下传安装在⼿机运⾏; 3)调⽤传感器,采集数据; 4)使⽤屏幕显⽰功能,实时显⽰采集的数据; 5)使⽤屏幕绘图功能,实时绘制采集的传感器数据; 6)使⽤对话框⽅式设置存储位置,保存数据; 7)实地测试,数据分析处理(根据实际数据情况,各⾃选⽤有效地⽅法) 三、实验原理 三、实验原理 (⼀)第⼀次实验 (⼀)第⼀次实验 本次实验我们将搭建开发平台,编写简单程序,实现按钮、屏幕操作的基本功能,应⽤程序下传安装在⼿机运⾏。我们需要搭建Android的 开发环境并开发⼀个按键交互⼩程序。下⾯我们⾸先介绍⼀下Android开发所需要⽤到的基础框架:JDK和Android SDK开发套件。 1.JDK(Java Development Kit) JAVA作为⼀款知名的编程语⾔,⾃⾯世以来⼀直⾮常的流⾏。在最近⼏年的编程语⾔排⾏榜上更是稳坐第⼀名的宝位。⽽Android系统在 开发之时也选择了JAVA作为其编程语⾔。JDK的全名叫做Java Development Kit JAVA开发包,从⽽为我们使⽤JAVA编程提供了相应的 环境以及类库。到⽬前为⽌,Java已经发展到了Java V8版,并在不断完善之中。⽽本次实验使⽤的Android开发均要使⽤JDK作为基础的 开发环境。 2.Android SDK Android SDK是⼀个为Android开发的软件包,它包含了调试器、API函数库、安卓模拟器以及⼀系列开发⽂档在内的各种⼯具。⾕歌官⽅ 开发出了基于Eclipse的ADT(Android Develop Tools)插件,通过为Eclipse安装插件的⽅式⽀持Android的开发,⽬前官⽅已经停⽌ADT 插件的开发与维护⼯作,并开发出了更加强⼤以及好⽤的Android Studio软件。本次实验则使⽤JDK+Android Studio的组合来开发 Android APP。 3.AVD(Android Virtual Devices) AVD就是运⾏于电脑上的安卓虚拟器,它可以使我们在没有⼿机的情况下通过电脑测试数据。 这与我们真实运⾏⼿机的情况⾮常相近。这样我们就可以⾮常⽅便的在电脑上调试程序。 4.Android 系统平台架构分析 系统平台架构分析 Android 平台由Linux内核、中间件、应⽤程序平台和应⽤软件组成,其系统架构如下图所⽰: 从图中我们可以看到整个安卓系统由Linux核⼼层、库、安卓运⾏时、应⽤程序框架以及应⽤层构成。⽽我们⼀般开发APP都在应⽤层进⾏ 开发。 a) Linux操作系统和驱动(Linux kernel): 由C语⾔实现。 Android核⼼系统服务依赖于Linux2.6内核,包括:安全性、内存管理、进程管理、⽹络协议、驱动模型。Linux内核也作 为硬件和软件栈之间的抽象层。除了标准的Linux内核外,Android还增加了内核的驱动程序:Binder(IPC)驱动、显⽰驱动、输⼊设备驱 动、⾳频系统驱动、摄像头驱动、WiFi驱动、蓝⽛驱动、电源管理。 b) 程序库 (LIBRARIES) 程序库是指可供使⽤的各种标准程序、⼦程序、⽂件以及它们的⽬录等信息的有序集合,Android包含⼀些C/C++库,Android系统中不同的 组件通过应⽤程序框架可以使⽤这些库本地框架是有C/C++实现。包含C/C++库,被Android系统中不同组件使⽤,它们通过Android应 ⽤程序框架为开发者进⾏服务。 c) Java运⾏环境(ANDROIDRUNTIME) Android运⾏库包括两部分:⼀是核⼼库,⼆是⾃⾝的Dalvik虚拟机。 核⼼库提供Java编程语⾔核⼼库的⼤多数功能。 Dalvik虚拟机是Google专为Android开发的 。每⼀个Android应⽤程序都在⾃⼰的进程中运⾏,都拥有⼀个独⽴的Dalvik虚拟机实例。 d) Android应⽤框架(ANDROIDFRAMEWORK) 应⽤程序框架是指定义了⼀个应⽤程序运⾏所必须的全部功能组件,开发者也可以访问核⼼应⽤程序所使⽤的API框架。在Android系统中, 开发⼈员也可以完全访问核⼼应⽤程序所使⽤的API框架。 e) Android应⽤程序(APPLICATIONS) Android应⽤程序都是有Java语⾔编写的。⽤户开发的Android应⽤程序和Android的核⼼应⽤程序是同⼀层次的,它们都是基于Android 的系统API构建的。 (⼆)第⼆次实验 (⼆)第⼆

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值