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),方向等于旋转轴的方向。

图 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 )。

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

  1. Android开发者指南-搜索配置文件-Searchable Configuration[原创译文]

    Searchable Configuration 译者署名:呆呆大虾 译者链接: 版本:Android 4.0 r1 参阅 创建搜索界面 添加最近请求建议项 添加自定义建议项 为了能在Android系 ...

  2. android 方向sensor,Android开发者指南-方位传感器-Position Sensor[原创译文]

    Android 平台提供了两种传感器来检测设备的方位:地磁传感器和方向传感器. Android 平台还提供了一种传感器,用于检测屏幕表面与其它物体的邻近程度,即被称为距离传感器. 地磁传感器和距离传感 ...

  3. android百度地图标方向,Android百度地图之方向感应和模式更改

    本文实例为大家分享了Android百度地图之方向感应和模式更改,供大家参考,具体内容如下 目标效果: 菜单中设置几种模式,点击可查看不同的地图形式,这里随便截几张图. 1.首先要去百度地图网站 htt ...

  4. android拍照保存照片方向,Android:Camera2开发详解(上):实现预览、拍照、保存照片等功能...

    android.jpg 前言 在前几篇文章中介绍了如何调用系统相机拍照和使用Camera1的实现自定义相机拍照.人脸检测等功能 文章传送门: 接下来的几篇文章中,我将给大家介绍如何使用Camera2实 ...

  5. android拍照保存照片方向,android 拍照的照片方向问题,读取图片EXIF信息

    Exif是一种图象文件格式,它的数据存储与JPEG格式是完全相同的.实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈.快门.白平衡.ISO.焦距.日期时间等各种和拍摄条件 ...

  6. android x5获取播放地址,Android 使用WebView 实现播放爱奇艺视频,可全屏(使用的腾讯的X5内核) (一)...

    Android 使用WebView 实现播放爱奇艺视频,可全屏(使用的腾讯的X5内核) (一) 发布时间:2018-06-27 18:30, 浏览次数:1438 , 标签: Android WebVi ...

  7. android 代码获取图片信息吗,Android 通过网络获取图片的代码

    Android 通过网络获取图片的代码 主activity package com.netimg; import android.app.Activity; import android.graphi ...

  8. android代码获取应用名称,Android获取应用程序名称(ApplicationName)

    MainActivity如下: package cn.testapplicationname; import android.os.Bundle; import android.widget.Text ...

  9. android自动获取系统时间,Android获取系统时间的多种方法

    Android中获取系统时间有多种方法,可分为Java中Calendar类获取,java.util.date类实现,还有android中Time实现. 现总结如下: 方法一: void getTime ...

最新文章

  1. 爬虫之selenium替换user-agent
  2. CNN边缘检测--Richer Convolutional Features for Edge Detection
  3. 成为顶尖机器学习算法专家需要知道哪些算法?
  4. 【转】C#中数组复制的4种方法
  5. SSG 550 6条公网接入的解决方法
  6. Android 自定义View绘制的基本开发流程 Android自定义View(二)
  7. React Native与React的关系及特点
  8. 下血本了!京东宣布未来三年向湖北投资,助力经济恢复
  9. Kotlin协程入门初级篇
  10. ubuntu离线安装fish
  11. 节约里程法解决VRP物流配送路径优化问题及局部优化改进-matlab代码
  12. 恩智浦(飞思卡尔)智能车舵机和电机PID控制
  13. word添加引用及自动更新的方法
  14. 短信验证码平台哪家速度快又稳定,推荐下?
  15. 自制新型文字密码,聊天记录的画风都不一样了,再也不怕被女朋友偷窥手机了!
  16. 社区信息综合管理平台
  17. Word2vec代码实现
  18. Jetson TX2 arm板子刷机,安装Caffe
  19. 央视影音大屏版apk下载_cboxtv_2.2.0(央视影音大屏版).apk
  20. live555学习-H264VideoStreamParser详解

热门文章

  1. Angular里ngModel双向绑定的一个使用例子
  2. SAP Spartacus应用启用时导入的一些模块
  3. 使用正则表达式解析http请求url中的参数和参数值
  4. SAP CRM Opportunity response area
  5. some VM operation when debugging appointment startup
  6. SAP Marketing Cloud功能简述(一)Contacts和Profiles
  7. SAP Gateway currency conversion utility
  8. UI5 datajs.js response handling
  9. Marketing Cloud里Odata请求响应结构的解析
  10. ABAP where used list