You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Android设备获取Raw、Pitch、Yaw数据?MAUI下四元数转欧拉角方法

在MAUI(Android 11)中将传感器四元数转换为Yaw、Pitch、Roll角度

要从MAUI获取的设备四元数中还原出Yaw(偏航角)、Pitch(俯仰角)、Roll(翻滚角),你可以通过四元数转欧拉角的数学公式实现,以下是具体的代码实现和使用说明:

核心转换方法

使用C#实现四元数到欧拉角的转换,同时处理万向锁场景:

public static (double Yaw, double Pitch, double Roll) QuaternionToEulerAngles(double x, double y, double z, double w)
{
    // 计算Yaw(绕Z轴,范围:-180° 到 180°)
    double sinyCosp = 2 * (w * z + x * y);
    double cosyCosp = 1 - 2 * (y * y + z * z);
    double yaw = Math.Atan2(sinyCosp, cosyCosp);

    // 计算Pitch(绕X轴,范围:-90° 到 90°)
    double sinp = 2 * (w * y - z * x);
    double pitch = Math.Abs(sinp) >= 1 
        ? Math.CopySign(Math.PI / 2, sinp) 
        : Math.Asin(sinp);

    // 计算Roll(绕Y轴,范围:-180° 到 180°)
    double sinrCosp = 2 * (w * x + y * z);
    double cosrCosp = 1 - 2 * (x * x + y * y);
    double roll = Math.Atan2(sinrCosp, cosrCosp);

    // 将弧度转换为角度(若需要弧度可移除此部分)
    yaw = yaw * 180 / Math.PI;
    pitch = pitch * 180 / Math.PI;
    roll = roll * 180 / Math.PI;

    return (yaw, pitch, roll);
}

在MAUI Android项目中获取传感器数据并转换

针对Android 11平台,你可以直接调用原生传感器API获取旋转向量(转换为四元数),再调用上述方法得到欧拉角:

using Android.Hardware;
using Android.App;

public class OrientationSensorHandler : Java.Lang.Object, ISensorEventListener
{
    private readonly SensorManager _sensorManager;
    private readonly Sensor _rotationSensor;

    public event Action<double, double, double> EulerAnglesUpdated;

    public OrientationSensorHandler()
    {
        _sensorManager = (SensorManager)Application.Context.GetSystemService(Context.SensorService);
        _rotationSensor = _sensorManager.GetDefaultSensor(SensorType.RotationVector);
    }

    public void StartListening()
    {
        _sensorManager.RegisterListener(this, _rotationSensor, SensorDelay.Normal);
    }

    public void StopListening()
    {
        _sensorManager.UnregisterListener(this);
    }

    public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy) { }

    public void OnSensorChanged(SensorEvent e)
    {
        if (e.Sensor.Type != SensorType.RotationVector) return;

        float[] quaternion = new float[4];
        SensorManager.GetQuaternionFromVector(quaternion, e.Values);
        
        var angles = QuaternionToEulerAngles(quaternion[0], quaternion[1], quaternion[2], quaternion[3]);
        EulerAnglesUpdated?.Invoke(angles.Yaw, angles.Pitch, angles.Roll);
    }
}

注意事项

  • 万向锁处理:当Pitch角度接近±90°时,Yaw和Roll会出现万向锁现象,数值会不稳定,若你的应用对角度精度要求高,需针对此场景做特殊处理。
  • 传感器校准:确保设备的方向传感器已校准,否则转换后的角度会存在误差。
  • 单位选择:上述代码默认输出角度,若需要弧度值,移除* 180 / Math.PI的转换逻辑即可。

内容的提问来源于stack exchange,提问作者deppenkaiser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:30:29