如何计算手机在y轴(滚动)平放时的旋转?

时间:2017-07-12 13:08:26

标签: c# math unity3d accelerometer tilt

这几行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;
}

如果手机平放在桌子上,你知道数学运算吗?即如果inclination小于25或大于155度? 该代码源自this SO post,其中提到可以使用指南针。不幸的是我不知道怎么做,所以非常感谢你的建议。另外,如果可能的话,我想避免使用陀螺仪,而是坚持使用加速度计。

欢迎任何建议。谢谢。

3 个答案:

答案 0 :(得分:4)

为什么不使用陀螺仪?

如果您认为如果旋转轴与加速度总和完全平行,则从加速度矢量中获取任何类型的旋转信息似乎在物理上是不可能的。

(也许你可以从向心力中获得它的速度,但没有别的。)

答案 1 :(得分:1)

您提出要求几乎是不可能的

归结为陀螺仪测量空间中的绝对方向,而加速度计测量速度的变化(加速度)。当你使用微积分从加速度(m / s ^ 2)到位置(m)时,你会得到距离偏移 - 这也是直观的。因为加速度计是在速度变化时触发的,所以在飞机上它甚至不会触发400mph的恒定速度。

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

要获得某种类型的传感器数据,必须使用陀螺仪(或罗盘)。事实上,要直接回答您的问题,不需要加速度计,因为这是一个寻找位置的问题。但是,如果您想对用户手势做出反应,那么您的实际需求可能会受益于加速度计。

Input.gyro.attitude应该为您提供绝对的方向值。获得这些值,以便它在没有滚动的情况下平放,然后在一定量的滚动下再次获得这些值。在此之后,您应该获得一些数据符合您的标准的数据以及该条件下的一些误差范围。

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

答案 2 :(得分:0)

您可以使用

 onSensorChanged(SensorEvent event)

在这种情况下,您可以检测传感器的类型并计算Roll,Azimut和Pitch,如给出的示例

  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: