Android API Guides---Motion Sensors

Motion Sensors

Android平台提供了多种感应器,让你监控设备的运动。这些传感器的两个总是基于硬件的(加速度计和陀螺仪),并且可以要么基于硬件或基于软件的这三个传感器(重力,线性加速度和旋转矢量传感器)。例如,在某些设备上的基于软件的传感器从加速度计和磁力计获得它们的数据,但在其他装置也可以使用陀螺仪来导出他们的数据。大多数Android设备有一个加速度计,现在许多人包括陀螺仪。基于软件的传感器的可用性是更加可变的,因为它们通常依赖于一个或一个以上硬件传感器来导出他们的数据。

运动传感器用于监视设备的运动,比如倾斜,摇动,旋转或摇摆有用。运动通常是直接用户输入的反射(例如,用户在游戏或控制在游戏中球的用户操纵汽车),但它也可以是在该装置所坐的物理环境的反射(例如,与你动,而你开你的车)。在第一种情况下,您正在监视相对于参考设备的框架或引用您的应用程序框架的议案;在第二种情况下,你正在监测相对于参考世界帧运动。本身运动传感器通常不用于监控设备的位置,但它们可以与其他传感器,例如地磁场传感器中使用,以确定设备的相对于参考世界帧位置(更多信息参见位置传感器)。

所有的运动传感器返回传感器值的多维数组每个SensorEvent。例如,一个单一的传感器事件期间加速度返回加速度力数据为三个坐标轴,和陀螺仪返回旋转数据的速率为三个坐标轴。这些数据值与其他SensorEvent参数一起float数组(值)返回。表1总结了可用的Andr??oid平台上的运动传感器。

所支持的Andr??oid平台上表1.运动传感器。

传感器传感器事件数据说明测量单位

TYPE_ACCELEROMETER SensorEvent.values?? [0]沿x轴(包括重力)加速力。米/秒2

沿y轴(包括重力)SensorEvent.values?? [1]加速力。

沿z轴(包括重力)SensorEvent.values?? [2]加速力。

TYPE_GRAVITY SensorEvent.values?? [0]沿x轴的重力的力。米/秒2

SensorEvent.values?? [1]沿y轴的重力的力。

SensorEvent.values?? [2]沿着z轴的重力的力。

TYPE_GYROSCOPE SensorEvent.values?? [0]速率围绕x轴的旋转。弧度/秒

SensorEvent.values?? [1]速率绕y轴的旋转。

SensorEvent.values?? [2]速率围绕z轴的旋转。

型陀螺仪无标定传感器Event.values?? [0]速率旋转(无漂移补偿)的绕x轴。弧度/秒

SensorEvent.values?? [1]速率绕y轴的旋转(无漂移补偿)的。

SensorEvent.values?? [2]速率围绕z轴的旋转(无漂移补偿)的。

SensorEvent.values?? [3]围绕x轴的估计漂移。

SensorEvent.values?? [4]绕y轴的估计漂移。

SensorEvent.values?? [5]围绕z轴的估计漂移。

TYPE_LINEAR_ACCELERATION SensorEvent.values?? [0]沿x轴(不包括重力)加速力。米/秒2

SensorEvent.values?? [1]加速沿y轴(不包括重力)的力。

沿z轴(不包括重力)SensorEvent.values?? [2]加速力。

沿x轴TYPE_ROTATION_VECTOR SensorEvent.values?? [0]旋转矢量分量(X * SIN(θ/ 2))。无单位

沿y轴(y * SIN(θ/ 2))SensorEvent.values?? [1]旋转矢量分量。

沿z轴SensorEvent.values?? [2]旋转矢量成分(Z * SIN(θ/ 2))。

旋转向量的SensorEvent.values?? [3]标量成分((COS(θ/ 2))。1

TYPE_SIGNIFICANT_MOTION N / A N / A N / A

TYPE_STEP_COUNTER SensorEvent.values?? [0],而传感器被激活自上次重启用户采取步数。脚步

TYPE_STEP_DETECTOR N / A N / A N / A

1标量分量是可选的值。

旋转矢量传感器和重力传感器是用于运动检测和监测中最常用的传感器。旋转矢量传感器是特别通用,可用于广泛范围的运动相关的任务,如检测的手势,监测的角度变化,和监测的相对定向的改变。例如,如果你正在开发一个游戏,增强现实应用,二维或三维罗盘,或相机稳定应用的旋转矢量传感器是理想的。在大多数情况下,使用这些传感器比使用加速度计和地磁传感器或方位传感器更好的选择。

Android开源项目的传感器

Android开源项目(AOSP)提供了三个基于软件的运动传感器:重力传感器,线性加速度传感器和旋转矢量传感器。这些传感器中的Andr??oid 4.0更新和现在使用的装置的陀螺仪(除了其他传感器),以改善稳定性和性能。如果你想尝试这些传感器,可以通过使用getVendor()方法和getVersion()方法识别它们(供应商是谷歌公司;版本号为3)。由供应商和版本号识别这些传感器是必要的,因为Android系统认为这些三个传感器是次要传感器。例如,如果一个设备制造商提供了其自身的重力传感器,则AOSP重力传感器示出了作为辅助重力传感器。所有这三个传感器依靠一个陀螺仪:如果一个装置不具有一个陀螺仪,这些传感器没有显示出来,并且不能使用。

使用加速度计

加速度传感器测量施加到该装置的加速度,包括重力的力。下面的代码展示了如何获得默认加速度传感器的一个实例:

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

概念上,加速度传感器确定是通过测量被施加到使用以下关系传感器本身(FS)的力施加到一个装置(广告)的加速度:

AD = - ΣFs/质谱

然而,在重力的作用根据以下关系总是影响所测量的加速度:

AD =-g - ΣF/质谱

因为这个原因,当装置坐在一个表(而不是加速)时,加速计读取g的大小=9.81米/秒2。类似地,当设备处于自由下落,并在9.81米/秒2朝向接地因此迅速加快,其加速度计读出G =0米/ s2的大小。因此,测量设备的实际加速度,在重力的力的贡献必须来自加速度计的数据被删除。这可以通过应用高通滤波器来实现。相反,一个低通滤波器可以用来在重力的作用隔离。下面的例子演示了如何做到这一点:

public void onSensorChanged(SensorEvent event){
  // In this example, alpha is calculated as t / (t + dT),
  // where t is the low-pass filter‘s time-constant and
  // dT is the event delivery rate.

  final float alpha = 0.8;

  // Isolate the force of gravity with the low-pass filter.
  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];

  // Remove the gravity contribution with the high-pass filter.
  linear_acceleration[0] = event.values[0] - gravity[0];
  linear_acceleration[1] = event.values[1] - gravity[1];
  linear_acceleration[2] = event.values[2] - gravity[2];
}

注意:您可以使用许多不同的技术来过滤传感器数据。上面的代码示例使用一个简单的过滤器常数(阿尔法)来创建一个低通滤波器。此滤波器常数从一个时间常数(t)的,它是延迟的粗略表示该滤波器增加了传感器事件,并且传感器的事件传递率(DT)的。该代码示例使用的0.8用于演示的alpha值。如果使用这种过滤方法可能需要选择不同的alpha值。

加速度计使用标准的传感器坐标系。在实践中,这意味着,当一个设备是在其自然取向的表平放以下条件适用:

如果按下设备上的左侧(所以它移动到右侧)中,x加速度值是正的。

如果按下设备上的底部(因此它移动远离您),在y加速度值是正的。

如果按下该设备朝向天空具有A米/秒2的加速度,则Z加速度值等于A + 9.81,其对应于该装置的加速度(+ A米/秒2)减去重力( - 9.81米/秒2)。

该固定设备将具有9.81的加速度值,其对应于该装置的加速度(0米/秒2减去重力的作用,这是-9.81米/秒2)。

一般来说,加速度计,如果要监视设备的运动一个很好用的传感器。几乎每一个Android平台的手机和平板电脑有一个加速度计,它使用较少的约10倍的功率比其它运动传感器。一个缺点是,你可能必须实现低通和高通滤波器来消除引力,降低噪音。

Android SDK中提供了一个示例应用程序,展示了如何使用加速度传感器(加速度计播放)。

使用重力感应

重力传感器提供指示的方向和重力的大小的三维矢量。下面的代码展示了如何获得默认重力感应的一个实例:

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

单位是相同的那些由加速度传感器(米/秒2)中使用,和坐标系是与由加速度传感器所使用的。

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

使用陀螺仪

陀螺仪测量围绕一个设备的x,y和z轴中弧度/秒的速率或旋转。下面的代码展示了如何获得默认陀螺仪的实例:

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

传感器的坐标系中是一样的用于加速度传感器中之一。旋转是在反时针方向阳性;即,从在x一些积极的位置看的观察者,在定位在原点的装置y或z轴方向会如果设备出现逆时针方向被旋转报告正转。这是正转的标准的数学定义,是不一样的是,用于由方位传感器的定义为辊。

通常情况下,陀螺仪的输出对时间积分来计算描述角度在时间步长的变化的旋转。 例如:

// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;

public void onSensorChanged(SensorEvent event) {
  // This timestep‘s delta rotation to be multiplied by the current rotation
  // after computing it from the gyro sample data.
  if (timestamp != 0) {
    final float dT = (event.timestamp - timestamp) * NS2S;
    // Axis of the rotation sample, not normalized yet.
    float axisX = event.values[0];
    float axisY = event.values[1];
    float axisZ = event.values[2];

    // Calculate the angular speed of the sample
    float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);

    // Normalize the rotation vector if it‘s big enough to get the axis
    // (that is, EPSILON should represent your maximum allowable margin of error)
    if (omegaMagnitude > EPSILON) {
      axisX /= omegaMagnitude;
      axisY /= omegaMagnitude;
      axisZ /= omegaMagnitude;
    }

    // Integrate around this axis with the angular speed by the timestep
    // in order to get a delta rotation from this sample over the timestep
    // We will convert this axis-angle representation of the delta rotation
    // into a quaternion before turning it into the rotation matrix.
    float thetaOverTwo = omegaMagnitude * dT / 2.0f;
    float sinThetaOverTwo = sin(thetaOverTwo);
    float cosThetaOverTwo = cos(thetaOverTwo);
    deltaRotationVector[0] = sinThetaOverTwo * axisX;
    deltaRotationVector[1] = sinThetaOverTwo * axisY;
    deltaRotationVector[2] = sinThetaOverTwo * axisZ;
    deltaRotationVector[3] = cosThetaOverTwo;
  }
  timestamp = event.timestamp;
  float[] deltaRotationMatrix = new float[9];
  SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
    // User code should concatenate the delta rotation we computed with the current rotation
    // in order to get the updated rotation.
    // rotationCurrent = rotationCurrent * deltaRotationMatrix;
   }
}

标准陀螺仪提供没有经过任何过滤或更正噪声和漂移(偏差)的原始数据旋转。在实践中,陀螺仪的噪声和漂移将引入需要被补偿的误差。通常你确定通过监控其它传感器,如重力传感器或加速度计的漂移(偏差)和噪音。

使用未校准陀螺仪

未校正陀螺仪是类似于陀螺仪,除了不陀螺漂移补偿被施加到旋转速率。工厂校准和温度补偿仍施加到旋转的速率。未校准陀螺仪是后处理和melding方向的数据是有用的。在一般情况下,gyroscope_event.values?? [0]将接近uncalibrated_gyroscope_event.values?? [0] - uncalibrated_gyroscope_event.values?? [3]。那是,

calibrated_x?= uncalibrated_x - bias_estimate_x

注意:未校准传感器,提供更多的原始结果和可能包括一些偏见,但他们的测量结果包含更正减少跳跃通过应用校准。一些应用可能更喜欢这些未校正结果更平滑,更可靠。例如,如果一个应用程序试图自行进行传感器融合,引入校准实际上可以扭曲的结果。

除了旋转的速率,未校正陀螺仪还提供了围绕每个轴线的估计漂移。下面的代码展示了如何获得默认未校准陀螺仪的一个实例:

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);

用线性加速度计

线性加速度传感器提供使用表示沿每个设备轴加速度的三维向量,不含重力。下面的代码演示如何得到默认的线性加速度传感器的一个实例:

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

概念上,该传感器根据以下的关系提供了加速度数据:

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

当你想获得加速度数据没有重力的影响,通常使用此传感器。例如,你可以使用这个传感器来看看你的车有多快。线性加速度传感器总是有偏移,您需要删除。要做到这一点最简单的方法是建立一个校准步骤到应用程序中。在校准过程中,你可以要求用户设置设备在桌子上,然后读取偏移量所有三个轴。然后,您可以减去从加速度传感器直接读数偏差获得实际的线性加速度。

该传感器坐标系中是相同的由加速度传感器中所使用的一样,都是测量单位(米/秒2)。

使用旋转矢量传感器

旋转矢量表示设备的方向作为角度和一个轴,其中该设备已通过旋转角度θ绕轴(x,y或z)的组合。下面的代码演示了如何获取默认的旋转矢量传感器的一个实例:

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

旋转矢量的三个元素表示如下:

x*sin(θ/2)
y*sin(θ/2)
z*sin(θ/2)

于旋转轴的方向。

图1.通过坐标旋转矢量传感器使用的系统。

旋转矢量的三个元素是等于一个单位四元数的最后三个组成部分(COS(θ/ 2)中,x * SIN(θ/ 2)中,y * SIN(θ/ 2)中,z * SIN(θ/ 2))。旋转向量的元素是无单位的。在x,y和z轴都以相同的方式如加速度传感器所定义。参照坐标系被定义为一个直接正交基(见图1)。这个坐标系统具有以下特征:

X定义为向量积Y X Z的是在该装置的当前位置相切于地面并指出约东。

Y是在该装置的当前位置相切地朝向地磁北极指向。

朝向天空?点并垂直于地平面。

Android SDK中提供了一个示例应用程序,展示了如何使用旋转矢量传感器。示例应用程序位于API演示代码(OS - RotationVectorDemo)。

利用重大运动传感器

该显著运动传感器触发检测每次显著运动事件,然后自行禁用。一个显著运动,可能导致用户的位置变化的议案;例如步行,骑自行车,或坐在行驶的汽车。下面的代码演示了如何获得默认显著运动传感器的一个实例,以及如何注册一个事件监听器:

private SensorManager mSensorManager;
private Sensor mSensor;
private TriggerEventListener mTriggerEventListener;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);

mTriggerEventListener = new TriggerEventListener() {
    @Override
    public void onTrigger(TriggerEvent event) {
        // Do work
    }
};

mSensorManager.requestTriggerSensor(mTriggerEventListener, mSensor);

欲了解更多信息,请参见触发事件侦听器。

使用步骤计数传感器

步进计数器传感器提供的,而在传感器被激活自上次重启由用户所采取的步骤的数目。在步骤计数器有更多的等待时间(最长10秒),但更精确度高于所述步骤检测器的传感器。下面的代码演示了如何获得缺省步计数传感器的一个实例:

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);

使用步骤检测仪传感器

步骤检测仪传感器触发事件在用户每次花费了一步。的等待时间预计为低于2秒。下面的代码演示了如何获得缺省步检测传感器的一个实例:

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
时间: 2024-10-21 15:34:43

Android API Guides---Motion Sensors的相关文章

android API Guides学习--Introduction(1)

android介绍: android提供了丰富的应用程序开发框架,它允许你在java语言环境中为移动设备创建独特的应用程序与环境. 1android应用程序提供多个入口点 android 应用程序是由不同的组件组合而成的,每个组件都被单独调用.activity组件提供一块屏幕作为使用者的界面.service独立的在幕后执行. 你可以使用intent类来实现组件的切换.也可以在一个app中多次调用同一个组件.例如在一个地图应用程序中显示地址的activity组件.该模型为一个单一的应用程序提供了多

Android API Guides – Introduction to Android

Android介绍 声明: 本文由Gordon翻译 发布于www.dlvoice.com 欢迎转载,但请保留此声明 原文地址:http://developer.android.com/guide/index.html Android提供了丰富的应用框架以便用户能够创建使用Java的环境来在移动设备上开发有创新性的应用和游戏.Android API Guides文档将会详细描述如何使用Android不同API来开发应用. 假如你是Android开发的新手,最好首先了解一下下面列出的Android

翻译Android API Guides: App Manifest

原文在这里:http://developer.android.com/guide/topics/manifest/manifest-intro.html *Manifest译作"清单",这里沿用英文便于理解,其它术语同理. **文中链接都会跳转到android开发者网站. App Manifest 每一个应用都必须在它的根目录有一份AndroidManifest.xml文件(必须使用这个名字).Android系统必须在运行应用的任何代码之前了解一些重要信息,这些信息就来自于这份mani

Android API Guides –Device Compatibility

设备的兼容性 声明: 本文由Gordon翻译 发布于www.dlvoice.com 欢迎转载,但请保留此声明 原文地址:http://developer.android.com/guide/practices/compatibility.html Android可以运行在不同类型的设备上,从手机到平板以及电视都可以运行.这些不同的设备将为开发者提供大量的潜在用户.那么为了能够让你的应用在所有的设备上运行良好,你就需要接受一些特性的多样性以及提供一个不同屏幕配置的友好的用户接口. 为了达到这样的目

【Android API Guides 简译(三)】Data Storage--Storage Options

Android提供了几种永久储存手机数据的选项,而我们选择存储的方式依据于我们存储的不同的特定需求,比如你的数据是否需要只对自己公开,数据是否可以被其他应用得到或者你想要储存多大的数据. 数据存储的方式如下: Shared Preferences 通过xml类型的键值对,存储私密的原始数据. Internal Storage 内部存储 通过手机内存存储私密数据 External Storage 外部存储 在设备外部共享里存储公开的数据 SQLite Databases Android 原生内部数

【Android API Guides 简译(一)】App Resourses--Overview

将数据与程序分开的原因,表面是为了独立的管理数据,深层原因是使App兼容不同的环境即使你的数据支持不同语言或者不同屏幕大小的特殊设备.这是非常且越来越重要的! 对于各种各样的资源,我们统一分成两种: 默认资源和针对不同环境的备选资源 举个例子,默认资源存放在res/layout/ directory下,针对于横摆方向的设备的备选资源存放在res/layout-land/ directory(横摆方向的设备的具体方式见图).当只有默认资源时,见图1.当设置了备选资源时,见图二,Android系统会

android API Guides学习--Introduction(2)

应用程序基本原理: android应用程序是用java语言编写的,android SDK工具在APK(Android package)里编译代码(数据文件和资源文件).apk是一个后缀为.apk的档案文件,1个apk文件包含了android应用程序的所有内容,apk是用来安装应用程序的基于android的设备.一旦安装了apk文件,每个app运行在自己安全的沙盒中. android操作系统是一个多用户的Linux操作系统,每一个app有一个不同的用户. 系统默认给各自的app分配一个唯一的Lin

android API Guides学习--Intent and Intent Filters

Intent是一个消息传递类,同时可以启动一些组件 作用: 1启动一个activity组件. 通过Context类的 startActivity()/ startActivity ()方法启动activity组件. 2启动一个service组件 通过Context类的startService()方法启动此组件,只能执行一次性操作(例如下载文件). 通过Context类的 bindService()方法 3发送一条广播 通过Context类的sendBroadcast(), sendOrdered

Android API Guides –System Permissions

系统权限 声明: 本文由Gordon翻译 发布于www.dlvoice.com 欢迎转载,但请保留此声明 原文地址:http://developer.android.com/guide/topics/security/permissions.html Android是一个特权分离的操作系统,运行在其上的应用都有一个特定的系统身份(Linux的用户ID和组ID).系统的部分也会被分为特定的身份,Linux就是通过这个身份来区别各个应用的. 更加详细的安全特性是通过"权限"机制来控制一个进

Android API Guides – Application Fundamentals

应用基础 声明: 本文由Gordon翻译 发布于www.dlvoice.com 欢迎转载,但请保留此声明 原文地址:http://developer.android.com/guide/components/fundamentals.html Android应用是用Java语言来开发的.Android的SDK工具将会把你的代码和数据以及资源文件编译到APK中,所谓的APK就是一个Android包,它是以.apk结尾的压缩包文件.APK文件包含了Android应用的所有部分,一个真正的Androi