手机放平时如何计算其绕y轴的旋转(翻滚)角度?

9
这几行C#代码使用加速度计计算手机绕y轴的旋转:
private float GetRoll() {
    /*
     * Sum up the accelerometer events
     */
    Vector3 accelerationVector = Vector3.zero;
    for (int i=0; i < Input.accelerationEventCount; i++) {
        AccelerationEvent accEvent = Input.GetAccelerationEvent(i);
        accelerationVector += accEvent.acceleration * accEvent.deltaTime;
    }
    accelerationVector.Normalize();

    int inclination = (int) Mathf.Round(Mathf.Rad2Deg * Mathf.Acos(accelerationVector.z));
    float roll = 0;
    if (inclination < 25 || inclination > 155) {
        /*
         * How to calculate the rotation here?
         */
    } else {
        roll = Mathf.Round(Mathf.Rad2Deg * Mathf.Atan2(accelerationVector.x, accelerationVector.y));
    }
    return roll;
}

你知道如果手机放在桌子上时,使它工作所需的数学吗?即如果倾斜度小于25度或大于155度,inclination是什么? 这段代码来自这篇SO文章,提到了可以使用指南针。不幸的是,我不知道如何操作,非常需要你的建议。此外,如果可能的话,我希望避免使用陀螺仪,而是坚持使用加速度计。
欢迎任何建议。谢谢。

除非您拥有手机放置之前的加速度历史记录,否则无法知道手机的旋转。这是欧拉角固有的坐标奇点。 - meowgoesthedog
是的,我同意 #meowgoesthedog 的观点。如果手机平放,则旋转相对于哪个XY平面?手机有自己的绝对坐标系,因此您必须给它一个参考。您可以使用Sensor.TYPE_MAGNETIC_FIELD获取指南针数据,请查看以下两篇文章:
  1. https://dev59.com/leo6XIcBkEYKwwoYTSxD
  2. https://dev59.com/9F7Va4cB1Zd3GeqPLZ6S
- Jay M
2
你对使用陀螺仪有什么问题? - cdo256
@cdo256:旧版(古老的)Android设备可能缺乏陀螺仪,因此我想坚持使用加速度计。 - SePröbläm
3个回答

4
为什么不使用陀螺仪呢?
如果你仔细思考,当旋转轴与加速度合力完全平行时,从加速向量中获取任何旋转信息似乎在物理上不可能。
也许你可以通过向心力得到它的速度,但是不能得到其他信息。

谢谢,我会看一下陀螺仪。 - SePröbläm

1

您的请求几乎是不可能的

问题在于陀螺仪测量空间中的绝对方向,而加速度计测量速度变化(加速度)。当您使用微积分从加速度(m / s ^ 2)转换为位置(m)时,您会得到位移距离 - 这也在直觉上有意义。由于加速度计在速度变化时被触发,因此即使在飞机上以400英里/小时的恒定速度行驶也不会触发。

您不仅需要整个加速度计历史记录,还需要原始位置和方向。更不用说所有的误差都要推断出来,1%的传感器误差在这种计算中变得更大。

要获取有关方向的某种类型的传感器数据,必须使用陀螺仪(或者可能是指南针)。实际上,为了直接回答您的问题,不需要加速度计,因为这是一个找到位置的问题。但是,如果您想对用户手势或其他内容做出反应,则您的实际需求可能会受益于加速度计。

Input.gyro.attitude 应该为您提供绝对方向值。在它平放且没有倾斜时获取这些值,然后再以某些倾斜度获取这些值。之后,您应该可以获得一些关于符合您条件的值范围和该条件的一些误差范围的数据。

https://docs.unity3d.com/ScriptReference/Gyroscope.html


0

你可以使用

 onSensorChanged(SensorEvent event)

在此事件中,您可以检测传感器类型并计算滚动、方位和俯仰,就像给定的示例一样。
  float azimuthVal = event.values[0];
  float pitchVal = event.values[1];
  float rollVal = event.values[2];

你需要读取哪些传感器数值可以从以下位置获取

event.sensor.getType()

为了找到倾斜度,您可以使用该方法获取方向

SensorManager.getOrientation

并且可以获取角度

azimutOrt = orientation[0];
pitchOrt = orientation[1];
rollOrt = orientation[2];

对于Unity,可以使用以下三个:

Input.acceleration: Accelerometer
Input.gyro.rotationRate:
Input.gyro.attitude
Input.gyro.gravity:

谢谢你分享这个。不幸的是,我不能使用Android API,因为项目是在Unity中完成的。 - SePröbläm
没有问题。这个Input.gyro.rotationRate.y怎么样?我已经为UNITY更新了答案。 - Ramankingdom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接