Android系统运动传感器

2023-11-02

转自:https://blog.csdn.net/liang123l/article/details/53992197

Android平台提供了多种感应器,让你监控设备的运动。

传感器的架构因传感器类型而异:

  • 重力,线性加速度,旋转矢量,重要运动,计步器和步检测传感器是基于硬件或基于软件的。
  • 加速计和陀螺仪传感器是始终基于硬件的。

大多数Android设备有一个加速度计,现在大部分Android设备还有陀螺仪。基于软件的传感器的可用性是更加可变,因为它们通常依赖于一个或一个以上硬件传感器来导出他们的数据。根据设备,这些基于软件的传感器可以从加速度计和磁力计或陀螺仪导出其数据。

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

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

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

传感器 传感器事件数据 描述 计量单位
TYPE_ACCELEROMETER SensorEvent.values[0] 沿x轴(包括重力)的加速度力。 m/s2
SensorEvent.values[1] 沿y轴(包括重力)的加速度力。
SensorEvent.values[2] 沿z轴(包括重力)的加速度力。
TYPE_GRAVITY SensorEvent.values[0] 沿x轴的重力的力。 m/s2
SensorEvent.values[1] 沿y轴重力的力量。
SensorEvent.values[2] 沿着z轴重力的力量。
TYPE_GYROSCOPE SensorEvent.values[0] 率围绕x轴的旋转。 rad/s
SensorEvent.values[1] 率绕y轴的旋转。
SensorEvent.values[2] 率绕z轴的旋转。
TYPE_GYROSCOPE_UNCALIBRATED SensorEvent.values[0] 率围绕x轴的旋转(无漂移补偿)的。 rad/s
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轴(不包括重力)的加速度力。 m/s2
SensorEvent.values[1] 沿y轴(不包括重力)的加速度力。
SensorEvent.values[2] 沿z轴(不包括重力)的加速度力。
TYPE_ROTATION_VECTOR SensorEvent.values[0] 沿x轴旋转矢量分量(X * SIN(θ/ 2))。 无单位
SensorEvent.values[1] 沿y轴旋转矢量分量(γ* SIN(θ/ 2))。
SensorEvent.values[2] 沿z轴旋转矢量成分(Z * SIN(θ/ 2))。
SensorEvent.values[3] 旋转矢量的标量分量((COS(θ/ 2))。
TYPE_SIGNIFICANT_MOTION N / A N / A N / A
TYPE_STEP_COUNTER SensorEvent.values[0] 传感器激活时自上次重新启动以来用户采取的步骤数。 Steps
TYPE_STEP_DETECTOR N / A N / A N / A

Android开源项目传感器

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

使用重力传感器

重力传感器提供指示重力的方向和大小的三维矢量。通常,该传感器用于确定设备在空间中的相对定向。

以下代码显示如何获取默认重力传感器的实例:

 

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

 

 

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

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

用线性加速度计

线性加速度传感器为您提供表示沿每个设备轴的加速度的三维矢量,不包括重力。你可以使用此值执行手势检测。该值还可以用作惯性导航系统的输入,其使用航位推算。

下面的代码演示如何得到默认的线性加速度传感器:

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

 

 

概念上,该传感器根据以下公式计算加速度数据:

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

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

传感器坐标系与加速度传感器使用的坐标系相同,测量单位(m / s2)

使用旋转矢量传感器

旋转向量表示作为角度和轴的组合的装置的取向,其中装置围绕轴(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)

其中旋转矢量的幅度等于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代码中。

利用显著运动传感器


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

 

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);

 

为了保持运行你的应用程序的设备,电池,你应该使用 JobScheduler类在一个特定的时间间隔来检索步数传感器的电流值。虽然不同类型的应用程序需要不同的传感器读数的时间间隔,你应该除非你的应用程序需要从传感器实时数据做出尽可能长时间这个区间。

使用步检测器传感器

步进检测器传感器在每次用户采取步骤时触发事件。延迟预计低于2秒。

下面的代码演示了如何获得缺省步检测传感器:

 

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

 

使用原始数据


以下传感器为您的应用程序提供有关应用于设备的线性和旋转力的原始数据。为了有效地使用这些传感器的值,你需要过滤掉环境中的因素,如重力。你可能还需要对值的趋势应用平滑算法以减少噪声。

使用加速度计

加速度传感器测量施加到装置的加速度,包括重力。

下面的代码展示了如何获得默认加速度传感器:

 

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

 

概念上,加速度传感器确定被施加到一个装置(A中的加速度ð通过测量被施加到传感器本身(F上的力)小号使用以下关系):

 
Ad = - ∑Fs / mass

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

 
Ad = -g - ∑F / mass

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

 

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加速度值是正的。
  • 如果按设备向天宇米/秒的加速度2,Z轴加速度值等于A + 9.81,对应于设备的加速度(+ A米/秒2)减去重力(-9.81米/秒2)。
  • 该固定设备将具有9.81的加速度值,其对应于该装置的加速度(0米/秒2的重力减去的力,这是-9.81米/秒2)。

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

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

使用陀螺仪

陀螺仪测量在弧度/秒的旋转围绕设备的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);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android系统运动传感器 的相关文章

随机推荐

  • 【框架1-springboot整合Knife4j框架-API文档框架】

    一 简介 图示 编辑 二 框架使用 1 引入依赖 2 配置config 3 配置application yml 启动knife4j 4 设置端口 5 进入doc html 三 框架配置 1 菜单项设置 2 菜单子项设置 3 请求参数设置 四
  • AcWing600.仰视奶牛(单调栈)

    输入样例 6 3 2 6 1 1 2 输出样例 3 3 0 6 6 0 include
  • 微信小程序接入微信支付流程

    一 基本介绍 1 支付场景 点击支付按钮唤起微信支付弹窗 输入正确密码后完成支付 2 基本流程 点击支付按钮首先生成一个订单 然后在后端调用微信api接口进行统一下单 将接口返回的数据回传到前端拉起支付操作 然后异步通知支付结果 二 配置信
  • Inno Setup打包教程

    简述 Inno Setup 是一个免费的 Windows 安装程序制作软件 第一次发表是在 1997 年 现在已经更新到Inno Setup 5了 Inno Setup是一个十分简单实用的打包小工具 可以按照我们自己的意愿设置功能 稳定性也
  • shell中的变量 $VAR 与 ${VAR}区别

    VAR 最好VAR在定义的时候 采用VAR abcdefg 这种带引号的定义 VAR 这种写法比较规范 VAR在定义的时候 采用VAR abcdefg 这种不带引号的定义也没有关系
  • 微信抓包您的连接不是私密连接解决办法

    问题 在对微信公众号进行抓包时出现以下问题 您的连接不是私密连接 攻击者可能会试图从 x x x x 窃取您的信息 例如 密码 通讯内容或信用卡信息 了解详情 NET ERR CERT INVALID 将您访问的部分网页的网址 有限的系统信
  • 面向 Android* 设备的英特尔® USB 驱动程序

    作者 Tao Wang Intel 利用英特尔 Android USB 驱动程序包 您能够将您基于 Windows 的机器连接至安装了英特尔 凌动 处理器的 Android 设备 注 英特尔 USB 驱动程序包 版本 1 1 5 增加了对
  • el-input 只能输入数字并限制长度

    在上一个博客中 有关于限制长度的使用 本文介绍限制只能输入数字的方法 el input 代码如下
  • 为什么要用数据库视图?

    视图的定义 视图 View 是一种虚拟的表 其结构和数据来自于一个或多个基本表 可以被当作普通表一样进行查询操作 但实际上不存储任何数据 在数据库中 视图可以被看作是一种数据访问的方式 它可以隐藏底层表的复杂性 提供简洁易懂的数据访问接口
  • chmod 666后文件不能看了!!!

    蛋疼 makefile里不能 mkdir 试着在终端改变下权限 sudo chmod 666 你的目录 R 然后 你的目录 就不能普通用户查看了 没事 再改回权限 755 或者 765 然后就正常了
  • 对角遍历矩阵算法c语言,C Tricks(十七)—— 对角线元素的屏蔽、二维数组(矩阵)的遍历...

    1 对角线元素的屏蔽 使用 if continue 实现对对角线元素的屏蔽 for u in range n for v in range n if u v continue 2 矩阵 二维数组 的遍历方法 遍历方法取决于最内层的操作 比如
  • 湖北 医学院

    http job hust edu cn show article htm id 25736 华中科技大学2014届医科毕业生专场招聘会 邀 请 函 尊敬的用人单位负责人 您好 感谢贵单位多年来对我校就业工作的大力支持 目前 2014届毕业
  • 【技术碎片】基于指数扩散二分搜索的重名文件重命名后缀

    目录 前言 linearSearch exponentialDiffusionBinarySearch 实现 ExponentialDiffusionBinarySearch java 运行 前言 一般我们在重命名文件时可以发现是这种结构
  • cppcheck linux安装和使用

    环境 centos7 下载cppcheck地址 官网 ccpcheck版本 cppcheck 2 6 上传到响应的目录执行编译 unzip cppcheck 2 6 zip cd cppcheck 2 6 make 代码检查命令 cppch
  • jenkins 插件安装缓慢

    两条命令解决 cd 你的Jenkins工作目录 updates sed i s http updates jenkins ci org download https mirrors tuna tsinghua edu cn jenkins
  • maskrcnn掩膜拟合效果不好是什么原因引起的,分类倒是很准确

    可能是因为训练数据中目标物体的掩膜标记不够精确或者数量不足 导致模型在预测掩膜时出现误差 或者是因为模型没有足够的参数 在处理复杂的图像时表现不佳
  • cacheput注解 用法_spring cache常用注解使用

    1 CacheConfig 主要用于配置该类中会用到的一些共用的缓存配置 示例 CacheConfig cacheNames users public interface UserService 配置了该数据访问对象中返回的内容将存储于名为
  • SpringBoot + MyBatis 结合 MVC框架设计 第1关:项目整合 - SpringBoot + MyBatis

    目录 任务描述 相关知识 使用MyBatis Spring Boot Starter进行整合SpringBoot MyBatis 使用SpringBoot MyBatis编写一个查询用户信息的接口 编程要求 测试说明 参考代码 任务描述 本
  • PCL 4PCS算法实现点云配准

    4PCS算法 一 算法原理 1 算法流程 2 参考文献 二 代码实现 1 主要参数 2 完整代码 三 结果展示 四 相关链接 一 算法原理 1 算法流程 4PCS算法是计算机图形学中一种流行的配准工具 给定两个点集 P Q P Q
  • Android系统运动传感器

    转自 https blog csdn net liang123l article details 53992197 Android平台提供了多种感应器 让你监控设备的运动 传感器的架构因传感器类型而异 重力 线性加速度 旋转矢量 重要运动