gpt4 book ai didi

Android 手机方向概述,包括指南针

转载 作者:行者123 更新时间:2023-12-01 19:07:05 27 4
gpt4 key购买 nike

一段时间以来,我一直试图了解 Android 方向传感器。
我以为我明白了。然后我意识到我没有。现在我想(希望)我再次对它有更好的感觉,但我仍然不是 100%。我将尝试解释我对它的零散理解,希望人们能够在我部分错误或填写任何空白时纠正我。

我想象我站在 0 度经度(本初子午线)和 0 度纬度(赤道)。这个位置实际上在非洲海岸附近的海中,但请耐心等待。我将手机放在脸前,让手机底部指向我的脚;我面向北方(面向格林威治),因此手机的右手边指向非洲的东方。在这个方向上(引用下图),我的 X 轴指向东,Z 轴指向南,Y 轴指向天空。



现在,手机上的传感器允许您在这种情况下计算出设备的方向(而不是位置)。这部分一直让我感到困惑,可能是因为在我接受它确实有效之前,我想了解它是如何工作的。手机似乎使用两种不同技术的组合来确定其方向。

在我开始之前,想象一下回到站在上面提到的方向的 0 度纬度和经度的假想土地上。还想象一下,您被蒙住眼睛,鞋子被固定在游乐场的环形交叉路口。如果有人把你推到后面,你会向前跌倒(向北)并伸出双手以防止跌倒。同样,如果有人推你的左肩,你会摔倒在你的右手上。您的内耳有“重力感应器”(youtube clip)它允许您检测您是向前/向后跌倒,还是向左/向右跌落或跌倒(或向上!!)。因此,人类可以检测到与手机相同的 X 轴和 Z 轴周围的对齐和旋转。

现在想象一下现在有人在环形交叉路口将您旋转 90 度,因此您现在面向东方。您正在绕 Y 轴旋转。这个轴是不同的,因为我们无法从生物学上检测到它。我们知道我们有一定的角度,但我们不知道相对于地球磁北极的方向。
相反,我们需要使用外部工具……磁罗盘。这使我们能够确定我们面对的方向。我们的手机也是如此。

现在这款手机还有一个 3 轴加速度计。我有 想像它们实际上是如何工作的,但我想象它的方式是将重力想象为从天而降的恒定且均匀的“雨”,并将上图中的轴想象为可以检测流过的雨量的管子。当手机直立时,所有的雨水都会流过 Y“管”。如果手机逐渐旋转使其屏幕面向天空,流经 Y 的雨量将减少到零,而流经 Z 的雨量将稳步增加,直到流过最大量的雨。同样,如果我们现在将手机倾斜到侧面,X 管最终将收集最大量的雨水。因此,根据手机的方向,通过测量流经 3 个管子的雨水量,您可以计算出方向。

这款手机还有一个电子罗盘,它的作用就像一个普通的罗盘——它的“虚拟指针”指向磁北。 Android 会合并来自这两个传感器的信息,以便每当出现 SensorEventTYPE_ORIENTATION生成 values[3]数组有
值[0]:方位角 -(指南针方位以东磁北)
values[1]:俯仰,绕 x 轴旋转(手机是向前还是向后倾斜)
values[2]: 滚动,绕 y 轴旋转(手机是靠在左边还是右边)

所以我认为(即我不知道)Android 给出方位角(罗盘方位)而不是第三个加速度计的读数的原因是罗盘方位更有用。我不确定他们为什么不推荐使用这种类型的传感器,因为现在看来您需要为 SensorEvent 向系统注册一个监听器s 类型 TYPE_MAGNETIC_FIELD . Activity 的value[]数组需要传入SensorManger.getRotationMatrix(..)获取旋转矩阵(见下文)的方法,然后将其传递给 SensorManager.getOrientation(..)方法。
有谁知道为什么 Android 团队不赞成使用 Sensor.TYPE_ORIENTATION ?是效率问题吗?这就是对类似 question 的评论之一所暗示的。但是您仍然需要在 development/samples/Compass/src/com/example/android/compass/CompassActivity.java 中注册不同类型的监听器例如。





我现在想谈谈旋转矩阵。 (这是我最不确定的地方)
所以上面我们有来自 Android 文档的三个数字,我们将它们称为 A、B 和 C。

A = SensorManger.getRotationMatrix(..) 方法图并表示世界坐标系

B = Coordinate system used by the SensorEvent API.

C= SensorManager.getOrientation(..) 方法图

所以我的理解是 A 代表“世界坐标系”,我认为它是指地球上的位置以(纬度,经度)和可选(高度)的形式给出的方式。 X 是 "easting"坐标,Y 是 "northing"协调。 Z 指向天空并代表高度。

图 B 中的手机坐标系是固定的。它的 Y 轴总是指向顶部。手机不断计算旋转矩阵,并允许在两者之间进行映射。那么我认为旋转矩阵将 B 的坐标系转换为 C 是否正确?所以当你拨打 SensorManager.getOrientation(..)您使用的方法 values[]具有对应于图 C 的值的数组。
当手机指向天空时,旋转矩阵是单位矩阵(矩阵的数学等价于 1),这意味着不需要映射,因为设备与世界坐标系对齐。

好的。我想我现在最好停下来。就像我之前说的,我希望人们能告诉我我在哪里搞砸了或帮助了人们(或者让人们更加困惑!)

最佳答案

您可能想查看 One Screen Turn Deserves Another文章。它解释了为什么需要旋转矩阵。

简而言之,即使设备旋转,手机的传感器也始终使用相同的坐标系。

在未锁定到单一方向的应用程序中,旋转设备时屏幕坐标系会发生变化。因此,当设备从其默认 View 模式旋转时,传感器坐标系不再与屏幕坐标系相同。在这种情况下,旋转矩阵用于将 A 转换为 C(B 始终保持固定)。

这是一个代码 fragment ,向您展示如何使用它。

SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);

// Register this class as a listener for the accelerometer sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
// ...and the orientation sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);

//...
// The following code inside a class implementing a SensorEventListener
// ...

float[] inR = new float[16];
float[] I = new float[16];
float[] gravity = new float[3];
float[] geomag = new float[3];
float[] orientVals = new float[3];

double azimuth = 0;
double pitch = 0;
double roll = 0;

public void onSensorChanged(SensorEvent sensorEvent) {
// If the sensor data is unreliable return
if (sensorEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
return;

// Gets the value of the sensor that has been changed
switch (sensorEvent.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
gravity = sensorEvent.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomag = sensorEvent.values.clone();
break;
}

// If gravity and geomag have values then find rotation matrix
if (gravity != null && geomag != null) {

// checks that the rotation matrix is found
boolean success = SensorManager.getRotationMatrix(inR, I,
gravity, geomag);
if (success) {
SensorManager.getOrientation(inR, orientVals);
azimuth = Math.toDegrees(orientVals[0]);
pitch = Math.toDegrees(orientVals[1]);
roll = Math.toDegrees(orientVals[2]);
}
}
}

关于Android 手机方向概述,包括指南针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4819626/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com