【问题标题】:Calculating Lean Angle with Core Motion用核心运动计算倾斜角
【发布时间】:2012-07-19 13:27:56
【问题描述】:

我的应用程序有一个记录会话。当用户开始记录会话时,我开始从设备的 CMMotionManager 对象中收集数据并将它们存储在 CoreData 上以供稍后处理和呈现。我正在收集的数据包括 gps 数据、加速度计数据和陀螺仪数据。数据频率为10Hz。

目前我正在努力用运动数据计算设备的倾斜角度。可以使用重力数据计算设备的哪一侧是陆地,但我想计算用户与地面之间的右角或左角,无论行进方向如何。

这个问题需要一些线性代数知识来解决。例如,对于某个点的计算,我必须在计算平面上计算 3D 线的方程。我正在研究这个一天,它变得越来越复杂。我一点也不擅长数学。一些与该问题相关的数学示例也值得赞赏。

【问题讨论】:

  • 你使用attitude reference frame吗?你想测量角度的参考是什么?例如,假设用户开始站立,然后躺在地上,即pitches 设备成 90 度角,那么您认为左右角度是什么,转向运动还是倾斜?
  • @Key 用户将在录制期间将设备放在他/她的口袋里。因此,我们没有参考框架。我想我可以通过检查重力加速度来计算设备位置。你怎么看?不可能吗?

标签: iphone ios math linear-algebra core-motion


【解决方案1】:

这取决于您想对收集的数据做什么,以及用户将如何使用她/他的口袋里的录音 iPhone。原因是欧拉角不是安全的,尤其是没有唯一的方式来表达旋转。考虑这样一种情况,用户将手机直立放入牛仔裤的后口袋,然后向左转约 90°。因为 CMAttitude 与平放在桌子上的设备有关,所以根据 picture,您有两个后续旋转 (pitch=x, roll=y, yaw=z):

  • 倾斜 +90° 让手机直立 => (90, 0, 0)
  • 滚动 +90° 左转 => (90, 90, 0)

但是你可以通过以下方式获得相同的位置:

  • yaw +90° 向左转动手机 (0, 0, 90)
  • 俯仰 -90° 使手机直立(-90、0、90)

您会看到两种不同的表示 (90, 90, 0) 和 (-90, 0, 90) 来获得相同的旋转,而且还有更多。所以你按下开始按钮,做一些花哨的旋转把手机放进口袋里,你就有麻烦了,因为在做更复杂的动作时你不能依赖欧拉角(s.gimbal lock 对此更头疼;-)

现在好消息:你说得对,线性代数可以胜任。您可以做的是强迫您的用户将手机始终放在相同的位置,例如垂直固定在右后袋中,并通过从CMDeviceMotion g = (x, y, z) 和位置构建重力矢量dot product 来计算相对于地面的角度向量 p 是 -Y 轴 (0, -1, 0) 的直立位置:

g • x = x*0 + y*(-1) + z*0 = -y = ||g||*1*cos (alpha)

=> alpha = arccos (-y/9.81) 作为总角度。请注意,重力加速度 g 始终约为 9.81

为了得到左右倾斜角度和前后角度,我们使用切线:

alphaLR = arctan (x/y)

alphaFB = arctan (z/y)


[更新:]

如果您不能将手机置于上述等式中的 (0, -1, 0) 之类的预定义位置,则只能计算总角度,而不能计算特定的 alphaLR 和 alphaFB。原因是你只有一个新坐标系的轴,你需要其中的两个。新的 Y 轴 y' 将被定义为平均重力矢量,但您不知道新的 X 轴,因为垂直于 y' 的每个矢量都是有效的。

因此,您必须提供更多信息,例如让用户在一个方向上走更长的距离而不偏离,并使用 GPS 和磁力计数据来获取第二轴 z'。在实践中听起来很容易出错。

总角度没问题,我们可以将(0, -1, 0)换成平均重力向量(pX, pY, pZ):

g•p = xpX + ypY + zpZ = ||g||||p||*cos(alpha) = ||g| |^2*cos(alpha)

alpha = arccos ((xpX + ypY + z*pZ) / 9.81^2)


还有两点要记住:

  • 不同的人穿着不同的裤子,不同的口袋。因此,即使是同一个人穿着其他衣服,重力矢量也会有所不同,您可能需要某种归一化
  • CMMotionManager 无法在后台运行,即用户不得按下待机按钮

【讨论】:

  • 感谢您的出色回答。那一个真的帮助我更多地了解情况。不幸的是,我无法强迫用户在记录期间将手机保持在同一位置。但我确信设备在记录期间将保持“几乎”相同的状态。可以计算设备的平均位置。我认为如果用重力数据的点积计算相对坐标系,并在录制期间通过设备的平均位置计算角度,我可以近似计算倾斜角度。知道如何计算相对坐标系吗?
  • @CemalEker 很抱歉,这并不容易。查看我的更新答案
【解决方案2】:

如果我理解您的问题,我认为您有兴趣了解您设备的态度。您可以使用从CMMotionManager 对象的deviceMotion 属性获得的CMDeviceMotion 对象的attitude 属性来执行此操作。

您可能会对CMAttitude 类感兴趣的两个不同角度:rollpitch。如果您将您的设备想象成一架螺旋桨位于顶部(耳机插孔所在的位置)的飞机,那么俯仰是飞机/设备在飞机爬升或俯冲时与地面形成的角度。同时,横滚是当飞机倾斜或在桶状横滚时“机翼”与地面形成的角度。

(顺便说一句,我认为第三个角度称为 yaw 与您的问题无关。)

角度将以弧度表示,但如果您需要,可以很容易地将它们转换为度数(乘以 180,然后除以 pi)。

假设我明白你想要什么,好消息是你可能不需要了解任何线性代数来捕捉和使用这些角度。 (如果我遗漏了什么,请澄清,我很乐意提供进一步帮助。)

更新(基于 cmets):

CMAttitude 对象中的姿态值是相对于地面的(即默认参考系的 Z 轴是垂直的,即指向与重力相反的方向),因此您不必担心抵消重力。因此,例如,如果您将设备放在平坦的桌面上,然后将其卷到一边,CMAttitude 对象的roll 属性将从 0 变为正负 90 度(+- .5pi 弧度) ),取决于您将其滚动到哪一侧。同时,如果您开始将其平放,然后逐渐将其竖起,pitch 属性也会发生同样的情况。

虽然您可以根据需要直接使用俯仰角、滚动角和偏航角,但您也可以设置不同的参考系(例如,“向上”的不同方向)。为此,只需在“校准”步骤中捕获该方向的姿态,然后使用 CMAttitude 的 multiplyByInverseOfAttitude: 方法将姿态数据转换为新的参考系。

即使您的问题仅提到捕获“倾斜角度”(与地面),您可能希望至少捕获 3 个姿态角中的 2 个(例如,俯仰和滚动或偏航,取决于他们在做什么),如果设备要放在一个人的口袋里,则可能是所有三个。 (例如,如果口袋很宽松,该设备可以在口袋中以各种方式旋转。)不过,我认为在大多数情况下,你可能只能依赖这三个中的两个(除非你看到彻底的转变在整个录音过程中偏航)。例如,在我的牛仔裤口袋里,手机通常几乎是垂直的。因此,对我来说,当我走路、坐着或跑步时,音高会发生很大的变化。每当我改变我面对的方向时,滚动都会发生变化。同时,偏航不会有太大变化(除非我做卡丁车,我不能!)。所以偏航对我来说可能可以忽略。

总结要点:要使用这些姿态角,您无需进行任何线性代数,也无需担心重力(当然,您可能希望将其用于其他目的)。

更新 2(基于 Kay 的新帖子):

Kay 刚刚回复并展示了如何使用重力和线性代数来确保您的角度是唯一的。 (顺便说一句,我认为你应该给那个帖子赏金,fwiw。)

根据您想要做的事情,您可能想要使用这个数学。你会想要使用线性代数和重力如果你需要一种标准化的方式来“谈论”和/或比较在你的录音过程中的态度。如果您只是想将它们可视化,您可能仍然可以不使用增加的复杂性。 (例如,可视化 (pitch=90, roll=0, yaw=0) 应该与可视化 (pitch=0, roll=90, yaw=90) 相同。)在我上面的方法中,虽然您可以有多种方法提到“相同”的态度,它们本身实际上都。它们仍会为您提供相对于地面的角度。

但是陀螺仪可以从一种有效的姿态描述切换到另一种这一事实意味着,我上面写的关于只使用 3 个组件中的 2 个的内容需要更正:因此,您需要捕获无论如何,所有三个组件。对不起。

【讨论】:

  • 实际上我确实收集了我在问题中指出的态度数据。实际问题不是收集和转换数据。实际的问题是计算设备的角度,我认为 CMDeviceMotion 对象的重力参数为该部分做的事情。然后比较这些角度并将差异呈现给用户。
  • 姿态数据确实为您提供了设备的角度。我想我需要更好地理解的是角度 with respect to what。想要它们相对于用户还是相对于地面?
  • 我们需要计算相对于地面的角度。
  • @Cernal_Eker 啊,这很好,因为这意味着您几乎可以直接使用姿态角。我会更新我的答案以反映这一点。
  • @Kay 谢谢。但我看到你的更好!我试图避免线性代数,我仍然认为他可能能够做到,但你的解释可能是他想要的。我会再更新一次我的帖子以供参考。
猜你喜欢
  • 1970-01-01
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
相关资源
最近更新 更多