【问题标题】:Getting magnetic field values in global coordinates获取全局坐标中的磁场值
【发布时间】:2012-11-01 21:32:39
【问题描述】:

对于 Android 应用程序,我需要跨全球(世界)坐标系的轴进行磁场测量。以下是我将如何(猜测)实现这一点。如有必要,请纠正我。另外,请注意,问题是关于任务的算法部分,而不是关于传感器的 Android API - 我对后者有经验。

第一步是获取TYPE_MAGNETIC_FIELD传感器数据(M)和TYPE_ACCELEROMETER传感器数据(G)。第二个应该根据Android的文档使用,但我不确定它是否不应该是TYPE_GRAVITY(同样是G),因为加速度计似乎提供的不是纯粹的重力。

下一步是通过getRotationMatrix(R, I, G, M)得到旋转矩阵,其中RI分别是旋转和倾角矩阵。

现在是最值得怀疑的部分:为了将M 向量转换为世界坐标系,我想乘以[R * I] * M

我不确定这是将磁场读数转换为另一个基础的正确方法。另外,我不知道是否应该使用remapCoordinateSystem 另外作为替代上面的东西。

如果已经存在一些可以执行此操作的源代码,我会很高兴发布一个链接,但我不想为这个特定任务使用大型通用库(例如,用于增强现实支持),因为我想让它尽可能简单。

附言

为了清晰起见,我想在原始帖子中添加一些信息。

让我们假设一个设备放在一张桌子上,并不断地从它的磁传感器中读取数据。每个测量值包含 3 个值,表示 X、Y、Z 轴上的磁场,它们是设备的局部坐标系。我认为我可以忽略环境场波动(通过低通滤波器平滑),所以这 3 个值应该在设备保持在原位的所有时间内保持几乎相同。如果我们围绕任何轴旋转设备,值会改变,因为我们改变了局部坐标系。但是该字段本身实际上并没有改变。所以我想将本地 X、Y、Z 场测量转换为这样的 X'、Y'、Z',只要设备没有从其位置移动(仅旋转),它们就会保持各自的值而不管设备旋转。

我已经实现了上面描述的算法,并且通过建议的转换获得了值 X'、Y'、Z' 的规律和显着变化,所以它有问题。

附言

有时我在 SO - How can I get the magnetic field vector, independent of the device rotation? 上找到了我的问题的完全相同的副本 - 但不幸的是,答案包含我的建议,并且该问题的 OP 确认它们不起作用。

【问题讨论】:

  • 我不相信这是可能的。重力只会将设备方向固定在一个轴上,因此您可以了解真实世界,但设备仍可能指向平原内的任何方向...
  • 这就是为什么Android使用2个传感器的组合:重力和磁力,所以设备的方向是完全已知的,磁场在设备的坐标系中也是已知的。如果你在一个基础上有一个向量,你绝对可以把它转换成另一个。
  • 只有当磁场始终与真北对齐时,它才不是……更不用说局部干扰了。我以为你是在将真实测量的磁场映射到世界坐标之后,这样你就可以测量局部变化了。
  • 不幸的是,您似乎没有按照我的任务。我需要测量场的局部属性(在兴趣点),它们必须绑定到全局坐标系。只有作为平均值的附加值,变化才有意义。
  • 您可以在 Android 开发者 官方网站上找到答案:SensorEvents Android Official

标签: android coordinates sensors magnetometer


【解决方案1】:

M相对于单词坐标的坐标就是乘法R*M

旋转矩阵R在数学上是基矩阵从设备坐标到单词坐标的变化。 设XYZ为设备坐标基础,W_1W_2 , W_3 为词坐标基础,则
M = m_1 X + m_2 Y + m_3
还有
M = c_1 W_1 + c_2 W_2 + c_3 W_3
其中 R * (m_1, m_2, m_3) = (c_1, c_2, c_3) 转置。

低通滤波器仅用于滤除XY方向的加速度。 RemapCoordinateSystem用于改变基的顺序,即从W_1、W_2、W_3变为W_1、W_3、W_2。

【讨论】:

【解决方案2】:

您设备上的磁力计传感器返回设备坐标中的 3 向量。您可以使用 getRotationMatrix() 获取可用于转换该设备坐标的矩阵 矢量到世界坐标。您还可以了解四元数并使用 TYPE_ROTATION_VECTOR 直接。但是,Android 中没有 Quaternion 库(据我所知),这是超出本问题范围的讨论。

但是,这对您没有任何好处,因为设备方向信息部分基于磁力计的值。换句话说,设备将始终告诉您磁矢量正朝向北方。

现在,您可以做的是磁倾角。这是 getRotationMatrix() 的输出之一,尽管您必须将矩阵转换为角度才能使用它。这也超出了这个问题的范围。

最后,你的最后一个选择是建立一个水平的桌子,上面有一个指向正北的箭头。 (您必须在晚上将其对准星星或其他东西。)然后,将您的设备平放在桌子上,设备顶部朝北。在这种情况下,设备坐标将与世界坐标相同,并且磁力计传感器将产生您想要的值。

您的 cmets 表明您对局部变化感兴趣。仅凭您的 Android 设备根本无法到达真正的北方。从理论上讲,您可以按照我的描述构建一张桌子,然后以与之前完全相同的方向拿着设备四处走动,并留意桌子以供参考。不过,我怀疑你能否成功。

您可以尝试在您的应用中使用陀螺仪,以帮助您始终保持设备方向完全相同,但您使用的任何 Android 设备中的陀螺仪都可能漂移太多而无法正常工作。

或者我们仍然不明白您要做什么。不过,最重要的是,您根本无法仅使用 Android 设备获得全局坐标系——无论您获得什么,都将始终与该确切位置的局部磁场对齐。

【讨论】:

  • 你读过 P.S.在问题中?我想不出比这更容易理解的方式来提出我的要求。好的,我们在特定位置有一个局部磁场。如果场是稳定的,并且设备“知道”它的方向如何改变(没有方向移动),那么为什么我不能根据当前点坐标系重新计算场测量?让我们假设这不是世界的全球系统,而是地点的坐标系统,但它在设备外部。我需要消除设备旋转对磁场值的影响。
  • 啊,现在我明白了(我想)。你想把设备放在一个地方,并测量它周围的场是如何变化的?在这种情况下,我会获取初始磁力计和重力(或加速度计)读数,并将它们传递给 getRotationMatrix() 以获得将本地坐标转换为世界坐标的旋转矩阵。然后,从那时起,只需将您的磁力计输出通过该矩阵。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 2011-04-27
  • 2011-03-27
  • 1970-01-01
相关资源
最近更新 更多