我正在使用来自设备的加速度值(x、y、z)来处理手势。
如果我将设备握在手中处于静止位置 (x,y,z) = ((0,0,0))。但是,如果我改变设备的方向(仍处于静止位置),则值将更改为((766,766,821))。由于所有 x、y、z 轴与其原始方向相比都发生了变化。
有没有办法(三角函数或其他)来解决这个问题?
我正在使用来自设备的加速度值(x、y、z)来处理手势。
如果我将设备握在手中处于静止位置 (x,y,z) = ((0,0,0))。但是,如果我改变设备的方向(仍处于静止位置),则值将更改为((766,766,821))。由于所有 x、y、z 轴与其原始方向相比都发生了变化。
有没有办法(三角函数或其他)来解决这个问题?
由于重力的加速度将始终存在。当设备处于特定方向时,您似乎正在从其中一个轴中减去该值。
要检测手势,您需要做的是检测设备开始移动时由于重力而产生的加速度瞬间出现的微小差异。您将无法检测设备是静止的还是以恒定速度移动,但您将能够确定它是在转动还是在加速。
(x,y,z) 值给你一个向量,它给出了加速度的方向。您可以将此向量的(平方)长度计算为 x^2 + y^2 + x^2。如果这与设备静止时相同,则您知道设备未加速,但处于某个方向。(无论是静止的,还是匀速运动的。)
要检测运动,您需要注意该向量的长度在设备开始移动时的瞬间变化,以及在它停止时再次发生的变化。与重力相比,这种变化可能很小。
您需要在运动过程中比较加速度矢量的方向以确定运动的方向。请注意,您将无法区分每个手势。例如,向前移动设备(并停在那里)与稍微倾斜设备,然后将其恢复到相同的方向具有相同的效果。
更容易检测的手势是那些改变设备方向的手势。其他手势,例如出拳动作,将更难检测。它们将显示为加速度矢量长度的变化,但变化量可能很小。
编辑:
上面的讨论是针对 x、y 和 z 的归一化值。您需要确定要从读数中减去的值以获得向量。从上面的评论中,看起来 766 是要减去的“零”值。但是对于您设备上的不同轴,它们可能会有所不同。使用面向所有六个方向的设备测量读数。即获取 x、y 和 z 的最大值和最小值。中心值应该在两个极端之间(希望是 766)。
某些手势会有明显的签名。
放下设备将暂时减小加速度矢量,然后在设备停止时暂时增加它。
升高设备将暂时增加矢量,然后暂时减少它。
向前运动将暂时增加矢量,但稍微向前倾斜,然后在设备停止时再次暂时增加,但向后倾斜。
大多数情况下,矢量的长度将等于重力加速度。
我觉得你的问题不清楚。你到底测量了什么,你期望什么?
通常,如果将加速度计固定在固定位置,则可以测量地球的重力。这显示为向上的加速度,起初听起来可能很奇怪,但完全正确:由于重力正在“向下”加速并且设备处于固定位置,因此需要在相反方向(即“向上”)施加一些力。将设备保持在固定位置所需的力就是这个力,它在“向上”方向具有相应的加速度。
根据您的设备,在您获得 PC 中的值之前,可能会减去此重力加速度。但是,如果你转动加速度计,重力加速度仍然在附近并且仍然指向相同的“向上”方向。如果在转动加速度计之前,“向上”对应于x,如果转动 90°,它将对应于不同的轴,比如y。因此,在x轴和y轴上测量的加速度都会发生变化。
因此,要回答您的问题,有必要知道您的加速度计如何呈现这些值。我怀疑在静止位置测量的加速度值是(0,0,0)。
您的评论使您的问题更清楚。你需要做的是每次方向改变时校准你的加速度计。没有办法解决这个问题。您可以将其作为应用程序中的 UI 元素,或者如果它适合您的用途,如果加速度在一段时间内相对恒定,则重新校准为 0(如果您测量长加速度则不起作用)。
校准要么内置在设备的 api 中(查看文档),要么您必须手动执行。要手动执行此操作,您必须读取当前加速度并存储这 3 个值。然后,每当您从设备读取读数时,从每个读取值中减去这 3 个值。
如果设备没有自动补偿重力加速度,您需要从设备的输出中减去 (0,0,~9.8m/s2) 矢量。
但是,您还需要知道设备的方向(欧拉角或旋转矩阵)。如果您的设备没有提供,则基本上无法判断信号加速度是由实际移动设备(线性加速)还是通过简单地旋转设备(重力改变方向)引起的。
您的补偿加速度将变为:
OutputAcc = InputAcc x RotMat - (0,0,9.8)
This way your OutputAcc vecor will always be in a local coord frame (ie. Z is always up)