一段时间以来,我一直试图了解 Android 方向传感器。我以为我明白了。然后我意识到我没有。现在我想(希望)我再次对它有更好的感觉,但我仍然不是 100%。我将尝试解释我对它的不完整的理解,如果我在部分错误或填写任何空白处,希望人们能够纠正我。
我想我站在经度 0 度(本初子午线)和纬度 0 度(赤道)。这个位置实际上是在非洲海岸附近的海域,但请耐心等待。我把手机放在脸前,让手机底部指向我的脚;我面向北方(朝向格林威治),因此电话的右侧指向东方,指向非洲。在这个方向(参考下图)我有 X 轴指向东方,Z 轴指向南方,Y 轴指向天空。
现在,手机上的传感器允许您在这种情况下计算出设备的方向(而不是位置)。这部分一直让我感到困惑,可能是因为在我接受它确实有效之前,我想了解它是如何工作的。手机似乎使用两种不同技术的组合来确定其方向。
在我开始之前,想象一下你站在那块假想的 0 度纬度和经度的土地上,站在上面提到的方向。还想象一下,你被蒙上眼睛,你的鞋子被固定在操场上的环形交叉路口。如果有人从背后推你,你会向前(朝北)摔倒并伸出双手来阻止摔倒。同样,如果有人推你的左肩,你会用右手摔倒。您的内耳有“重力传感器” (youtube 剪辑),可让您检测您是向前/向后跌倒,还是向左/向右跌倒或跌倒(或向上!!)。因此,人类可以检测到与手机相同的 X 轴和 Z 轴周围的对齐和旋转。
现在想象有人现在在环形交叉路口将你旋转 90 度,这样你现在面向东方。您正在绕 Y 轴旋转。这个轴是不同的,因为我们无法从生物学上检测到它。我们知道我们有一定的角度,但我们不知道相对于地球磁北极的方向。相反,我们需要使用外部工具……磁罗盘。这使我们能够确定我们所面对的方向。我们的手机也是如此。
现在这款手机还配备了一个 3 轴加速度计。我没有了解它们实际上是如何工作的,但我想象它的方式是将重力想象为从天而降的恒定且均匀的“雨”,并将上图中的轴想象为可以检测流过的雨水量的管子。当手机直立时,所有的雨水都会流过 Y '管'。如果手机逐渐旋转,使其屏幕面向天空,流过 Y 的雨量将减少到零,而流过 Z 的音量将稳步增加,直到流过的雨量达到最大。同样,如果我们现在将手机倾斜到一侧,X 管最终将收集到最大量的雨水。因此,根据手机的方向,通过测量流过 3 个管子的雨水量,您可以计算出方向。
这款手机还有一个电子罗盘,其行为类似于普通罗盘——它的“虚拟指针”指向磁北。Android 会合并来自这两个传感器的信息,因此每当生成a SensorEvent
of时,数组都有
值 [0]:方位角 - (磁北以东的罗盘方位)
值 [1]:俯仰,绕 x 轴旋转(是手机向前或向后倾斜)
值[2]:滚动,围绕 y 轴旋转(手机是向左侧还是右侧倾斜)TYPE_ORIENTATION
values[3]
所以我认为(即我不知道)Android 给出方位角(罗盘方位)而不是第三个加速度计读数的原因是罗盘方位更有用。我不确定他们为什么不推荐使用这种类型的传感器,因为现在看来您需要为SensorEvent
s 类型的系统注册一个侦听器TYPE_MAGNETIC_FIELD
。事件的value[]
数组需要传递到SensorManger.getRotationMatrix(..)
方法中以获取旋转矩阵(见下文),然后将其传递到SensorManager.getOrientation(..)
方法中。有谁知道为什么Android团队不推荐使用Sensor.TYPE_ORIENTATION
?是效率问题吗?这就是对类似问题的评论之一所暗示的内容,但您仍然需要在development/samples/Compass/src/com/example/android/compass/CompassActivity.java示例。
我现在想谈谈旋转矩阵。(这是我最不确定的地方)所以上面我们有来自 Android 文档的三个数字,我们将它们称为 A、B 和 C。
A = SensorManger.getRotationMatrix(..) 方法图,代表世界坐标系
C= SensorManager.getOrientation(..) 方法图
所以我的理解是,A 代表“世界坐标系”,我认为它是指地球上的位置以(纬度,经度)和可选(高度)的形式给出的方式。X 是“东”坐标,Y 是“北”坐标。Z 指向天空,代表高度。
手机坐标系如图B所示是固定的。它的 Y 轴总是指向顶部。手机不断计算旋转矩阵,并允许两者之间的映射。那么我认为旋转矩阵将 B 的坐标系转换为 C 的想法是否正确?因此,当您调用SensorManager.getOrientation(..)
方法时,您使用的values[]
数组的值对应于图 C。当手机指向天空时,旋转矩阵是单位矩阵(矩阵数学等价于 1),这意味着在设备对齐时不需要映射与世界坐标系。
行。我想我现在最好停下来。就像我之前说的那样,我希望人们会告诉我我在哪里搞砸了或帮助了人们(或者让人们更加困惑!)