Android电话方向概述包括指南针
-
26-10-2019 - |
题
我一直在努力将自己的头围绕Android取向传感器。我以为我明白了。然后我意识到我没有。现在,我认为(希望)我对此有更好的感觉,但我仍然不是100%。我将尝试解释我对此的零星理解,希望人们能够纠正我,如果我错了零件或填写任何空白。
我想我站在0度的经度(原始子午线)和0度纬度(赤道)。这个位置实际上位于非洲海岸附近的海中,但陪伴着我。我将手机握在脸前,使手机的底部指向我的脚。我面对北(朝北看),因此电话的右侧向东指向非洲。在这个方向(参考下图)我的X轴指向东方,Z轴指向南方,Y轴指向天空。
现在,手机上的传感器允许您在这种情况下确定设备的方向(不是位置)。这部分总是让我感到困惑,可能是因为我想在接受它确实起作用之前了解某事的工作方式。手机似乎使用两种不同技术的组合来弄清楚其方向。
在我做到这一点之前,请想象一下站在那片想象中的纬度和经度上,站在上面提到的方向上。想象一下,您蒙住眼睛,鞋子固定在游乐场的环形交叉路口上。如果有人将您推向后面,您将向前(向北)跌落,并将双手伸出来打破您的跌倒。同样,如果有人推您左肩,您将掉在右手上。您的内耳有“重力传感器” (YouTube剪辑) 这使您可以检测到您是向前/向后掉下,还是向左/右掉落或跌倒(或向上!)。因此,人类可以检测到与手机相同的X和Z轴周围的对齐和旋转。
现在想象一下,现在有人在回旋处旋转90度,以便您现在面对东方。您正在围绕y轴旋转。该轴是不同的,因为我们无法从生物学上检测到它。我们知道我们有一定数量的角度,但我们不知道与行星磁性北极有关的方向。相反,我们需要使用外部工具...磁性指南针。这使我们能够确定我们面临的方向。我们的手机也是如此。
现在,手机还具有3轴加速度计。我有 不 了解它们实际上是如何工作的,但是我可视化它的方式是将重力想象为恒定而均匀的“雨水”从天上掉下来,并想象上图中的轴作为可以检测到雨水量的管子。当手机直立时,所有的雨都会流过Y'Tube'。如果手机逐渐旋转,那么它的屏幕面向天空,流经Y的降雨量将减少到零,而通过Z的体积将稳定增加,直到最大的降雨量流通为止。同样,如果我们现在将手机倾斜到侧面,则X管最终将收集最大的降雨量。因此,根据手机的方向,通过测量流经3个试管的雨量,您可以计算方向。
手机还具有电子指南针,其行为就像普通指南针 - 其“虚拟针”指向磁性北方。 Android合并了这两个传感器的信息,以便每当 SensorEvent
的 TYPE_ORIENTATION
被生成 values[3]
数组有
值[0]:方位角 - (磁性北部以东的指南针)
值[1]:俯仰,围绕X轴旋转(手机向前或向后倾斜)
值[2]:滚动,围绕y轴旋转(手机靠在左侧或右侧)
因此,我认为(即我不知道)Android给出了方位角(指南针),而不是读取第三加速度计的原因是,指南针的轴承更有用。我不确定他们为什么弃用这种类型的传感器,因为现在您似乎需要在系统中注册一个侦听器 SensorEvent
类型 TYPE_MAGNETIC_FIELD
. 。事件 value[]
阵列需要进入 SensorManger.getRotationMatrix(..)
获取旋转矩阵的方法(见下文),然后传递到 SensorManager.getOrientation(..)
方法。有人知道为什么Android团队弃用 Sensor.TYPE_ORIENTATION
?这是效率吗?这就是类似的评论之一中暗示的 问题 但是您仍然需要在 开发/样品/指南针/src/com/example/android/compass/commasactivity.java 例子。
我现在想谈谈旋转矩阵。 (这是我最不确定的地方)因此,在上面,我们有来自Android文档的三个数字,我们将其称为A,B和C。
a = sensormanger.getRotationMatrix(..)方法图形,代表世界的坐标系
c = sensormanager.getorientation(..)方法图
因此,我的理解是,A代表“世界的坐标系统”,我认为这是指地球上的位置的方式,是一对具有可选(高度)的(纬度,经度)夫妇的方式。 x是 “驻扎” 协调,y是 “北边” 协调。 Z指向天空,代表高度。
手机坐标系统在图B中显示为固定。它的Y轴总是指出顶部。旋转矩阵正在通过手机不断计算,并允许在两者之间进行映射。因此,我认为旋转矩阵将B的坐标系转换为C,我是否正确?所以当你打电话 SensorManager.getOrientation(..)
您使用的方法 values[]
具有与图C相对应的值的数组时,当手机指向天空时,旋转矩阵是身份矩阵(矩阵数学等效量),这意味着由于设备与世界坐标系对齐,因此无需映射。
好的。我想我现在最好停下来。就像我说的那样,我希望人们会告诉我我在哪里搞砸或帮助人们(或更加困惑的人!)
解决方案
您可能想检查一下 一个屏幕应得的 文章。它解释了为什么您需要旋转矩阵。
简而言之,即使设备旋转,手机的传感器也始终使用相同的坐标系。
在未锁定到单个方向的应用程序中,旋转设备时,屏幕坐标系统会更改。因此,当设备从其默认视图模式旋转时,传感器坐标系不再与屏幕坐标系相同。在这种情况下,旋转矩阵用于将A转换为C(B始终保持固定)。
这是一个代码片段,可以向您展示如何使用它。
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]);
}
}
}
其他提示
滚动是重力的函数,90度卷将所有重力放入X寄存器中。
音高相同,一个90度的音高将所有重力的组成部分都放入Y寄存器中。
偏航 /标题 /方位角对重力没有影响,它始终与重力成直角,因此无论您面对重力的方式都将是可观的。
这就是为什么您需要指南针进行评估的原因,也许有意义?
看看这个: Stackoverflow.com:Q.5202147
直到3图A,B,c。之后,您感到困惑。
我遇到了这个问题,所以我绘制了不同方向上发生的事情。如果设备以景观方式安装,例如在汽车安装中,指南针的“学位”似乎从269上以上(西部和北之间的0-275(顺时针方向)运行,则从-90到0从0到269。270变为-90
仍处于景观状态,但是设备躺在后面,我的传感器给出了0-360。在肖像模式下,它均躺在背面并站在肖像中。
希望对某人有帮助