【问题标题】:Madgwick AHRS algorithm in Unity 3DUnity 3D 中的 Madgwick AHRS 算法
【发布时间】:2018-07-06 08:58:05
【问题描述】:

我正在尝试计算 Android 设备的绝对航向,并相应地旋转游戏对象。因此,无论设备方向如何,游戏对象都将充当 3D 指南针,在 3D 空间中指向地球的北方。

为了实现这一点,我使用 Madgwick AHRS algorithm 作为由 x-io Technologies 维护的 single file C# library

这是我附加到CompassArrow 游戏对象的脚本。

using System;
using UnityEngine;
using AHRS;

namespace MyCompass
{
    public class CompassArrowController : MonoBehaviour
    {
        static MadgwickAHRS AHRSInst = new MadgwickAHRS(1f / 256f, 0.1f);

        void Start()
        {
            Input.compass.enabled = true;
            Input.gyro.enabled = true;
            Input.location.Start();
        }

        void Update()
        {
            UpdateAHRS();
            //Get algorithm result quaternion
            var q = AHRSInst.Quaternion;
            //Create unity quaternion
            Quaternion arrowRotation = new Quaternion(q[0], q[1], q[2], q[3]);
            transform.rotation = Quaternion.Inverse(arrowRotation);
        }

        static void UpdateAHRS()
        {
            AHRSInst.Update(
                //Gyro
                Input.gyro.rotationRateUnbiased.x,
                Input.gyro.rotationRateUnbiased.y,
                Input.gyro.rotationRateUnbiased.z,
                //Acceleration
                Input.acceleration.x,
                Input.acceleration.y,
                Input.acceleration.z,
                //Magnetometer
                Input.compass.rawVector.x,
                Input.compass.rawVector.y,
                Input.compass.rawVector.z
            );
        }
    }
}

这是我能得出的最接近所需输出的值。但是轴仍然被交换了,我必须将设备旋转大约 4 次才能让指南针箭头完成一次完整的旋转。

我的猜测是,输入算法的传感器数据单位错误。我向您保证,我使用的设备具有运行该算法所需的全部 3 个传感器。

以下是库中Update() 方法的参数说明。

/*
Signature: public void Update(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz)
Summary: Algorithm AHRS update method. Requires only gyroscope and accelerometer data.
gx: Gyroscope x axis measurement in radians/s.
gy: Gyroscope y axis measurement in radians/s.
gz: Gyroscope z axis measurement in radians/s.
ax: Accelerometer x axis measurement in any calibrated units.
ay: Accelerometer y axis measurement in any calibrated units.
az: Accelerometer z axis measurement in any calibrated units.
mx: Magnetometer x axis measurement in any calibrated units.
my: Magnetometer y axis measurement in any calibrated units.
mz: Magnetometer z axis measurement in any calibrated units.
*/

该库还有一个 Update() 方法,它不需要磁力计读数。但由于我正在开发指南针,我认为这种方法不会有用。

谁能指出我做错了什么?我可以根据要求提供更多详细信息。

【问题讨论】:

  • this 有用吗?
  • @Programmer 感谢您的回复,但遗憾的是没有。 Unity Input.compass.trueHeading 在垂直握持设备时会感到困惑。可能下面没有倾斜补偿。
  • 如果是这种情况,那么您将需要构建一个插件来访问每个移动平台的传感器。
  • 是的@Programmer 这是我的后备,我正在努力。我正在尝试使用原生 android 调用 SensorManager.GetRotationMatrix,似乎它可以在没有任何 3rd 方算法的情况下完成这项工作。
  • 有时,原生插件是解决问题的正确方法。对于 iOS,CoreMotion 应该没问题。如果你解决了问题,请告诉我们如何

标签: c# unity3d android-sensors sensor-fusion


【解决方案1】:
 ahrs.Update(g.x,g.y,g.z,a.x,a.y,a.z);
 var _q = ahrs.Quaternion;
        
 Quaternion q = new Quaternion(_q[0],_q[1],_q[2],_q[3]);
 var qEualr = q.eulerAngles;
Quaternion correctQuaternion =  Quaternion.Euler(qEualr.z, -qEualr.y, qEualr.x);

会给你一个带有正确轴的四元数。与算法相比,似乎统一将它们交换了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    相关资源
    最近更新 更多