如何平滑陀螺仪输入?
How to smooth gyroscope input?
我正在 Unity 中制作一款游戏,游戏的主摄像头由 phone 方向控制。我遇到的问题是陀螺仪的数据非常嘈杂,使相机以非常紧张的方式旋转。我尝试了不同的 phone 以确保硬件不是问题(Galaxy s6 和 Sony Xperia T2)。
我尝试了以下方法,但 none 似乎有效:
-当前旋转和新姿态之间的 Slerp(抖动太多,无论我将 Time.deltaTime 乘以什么)
//called at each update
transform.rotation = Quaternion.Slerp(transform.rotation, new Quaternion(-Input.gyro.attitude.x, -Input.gyro.attitude.y,
Input.gyro.attitude.z, Input.gyro.attitude.w), 60 * Time.deltaTime);
-平均最后的陀螺仪样本(Euleur 角平均值或 Quaternion average;无论我跟踪多少样本,这两种情况仍然会产生太多抖动)
//called at each update
if (vectQueue.Count >= 5)
{
vectQueue.Enqueue(Input.gyro.attitude.eulerAngles);
vectQueue.Dequeue();
foreach (Vector3 vect in vectQueue) {
avgr = avgr + vect;
}
avgr = new Vector3(avgr.x/5, avgr.y/5,avgr.z/5);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(avgr),Time.deltaTime*100);
}
else
{
vectQueue.Enqueue(Input.gyro.attitude.eulerAngles);
}
-舍入陀螺仪数据(迄今为止防止抖动的最佳解决方案,但显然这根本不平滑)
-应用 high/low 通过过滤器(似乎什么也没做)
public float alpha = 0.5f;
//called at each update
v1 = Input.gyro.attitude.eulerAngles;
if (v2== null)
{
v2 =v1;
v3 = Input.gyro.attitude.eulerAngles;
}
else
{
v3 = (1 - alpha) * v3 + (1 - alpha)*(v1 - v2);
v2 = v1;
transform.Rotate(v3);
}
-从像this这样的人那里复制粘贴代码;但是抖动在所有情况下都太强了。
所以现在我想我会尝试学习卡尔曼滤波器并统一实施它,但显然我更喜欢黑盒解决方案以节省时间。
使用模拟输入时始终使用噪声消除,您可以通过计算当前帧中的陀螺仪值与前一帧中的陀螺仪值之间的差异来实现,如果差异大于所需的量(0.002 或 0.03 可能是好)在陀螺仪值上旋转你的相机。
这将最终解决你抖动的问题。希望你能得到它
找到问题;我前面提到的任何方法在正常情况下都是有效的(使用组合以获得最佳效果)。导致疯狂抖动的是相机的位置。它有非常大的数字作为坐标,我猜这会弄乱引擎。
你好,虽然我认为你已经找到了解决方案,但我知道如何使用 Quaternion.Lerp 来平滑它。
#rot用于面向前方
Quaternion rot = new Quaternion(0,0,1,0)
Quaternion.lerp(transform.rotation* rot,gyro*rot,10)
我正在 Unity 中制作一款游戏,游戏的主摄像头由 phone 方向控制。我遇到的问题是陀螺仪的数据非常嘈杂,使相机以非常紧张的方式旋转。我尝试了不同的 phone 以确保硬件不是问题(Galaxy s6 和 Sony Xperia T2)。
我尝试了以下方法,但 none 似乎有效:
-当前旋转和新姿态之间的 Slerp(抖动太多,无论我将 Time.deltaTime 乘以什么)
//called at each update
transform.rotation = Quaternion.Slerp(transform.rotation, new Quaternion(-Input.gyro.attitude.x, -Input.gyro.attitude.y,
Input.gyro.attitude.z, Input.gyro.attitude.w), 60 * Time.deltaTime);
-平均最后的陀螺仪样本(Euleur 角平均值或 Quaternion average;无论我跟踪多少样本,这两种情况仍然会产生太多抖动)
//called at each update
if (vectQueue.Count >= 5)
{
vectQueue.Enqueue(Input.gyro.attitude.eulerAngles);
vectQueue.Dequeue();
foreach (Vector3 vect in vectQueue) {
avgr = avgr + vect;
}
avgr = new Vector3(avgr.x/5, avgr.y/5,avgr.z/5);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(avgr),Time.deltaTime*100);
}
else
{
vectQueue.Enqueue(Input.gyro.attitude.eulerAngles);
}
-舍入陀螺仪数据(迄今为止防止抖动的最佳解决方案,但显然这根本不平滑)
-应用 high/low 通过过滤器(似乎什么也没做)
public float alpha = 0.5f;
//called at each update
v1 = Input.gyro.attitude.eulerAngles;
if (v2== null)
{
v2 =v1;
v3 = Input.gyro.attitude.eulerAngles;
}
else
{
v3 = (1 - alpha) * v3 + (1 - alpha)*(v1 - v2);
v2 = v1;
transform.Rotate(v3);
}
-从像this这样的人那里复制粘贴代码;但是抖动在所有情况下都太强了。
所以现在我想我会尝试学习卡尔曼滤波器并统一实施它,但显然我更喜欢黑盒解决方案以节省时间。
使用模拟输入时始终使用噪声消除,您可以通过计算当前帧中的陀螺仪值与前一帧中的陀螺仪值之间的差异来实现,如果差异大于所需的量(0.002 或 0.03 可能是好)在陀螺仪值上旋转你的相机。 这将最终解决你抖动的问题。希望你能得到它
找到问题;我前面提到的任何方法在正常情况下都是有效的(使用组合以获得最佳效果)。导致疯狂抖动的是相机的位置。它有非常大的数字作为坐标,我猜这会弄乱引擎。
你好,虽然我认为你已经找到了解决方案,但我知道如何使用 Quaternion.Lerp 来平滑它。
#rot用于面向前方
Quaternion rot = new Quaternion(0,0,1,0)
Quaternion.lerp(transform.rotation* rot,gyro*rot,10)