如何从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
相关产品推荐
相关产品推荐

