4

我想得到设备的倾斜度,所以我可以用它来测量某个表面的倾斜度,将设备放在表面上。

现在我正在从这里https://github.com/rdelrosario/xamarin-plugins为 xamarin 表单使用 Device Motion 插件

和下面的代码:

CrossDeviceMotion.Current.Start(MotionSensorType.Accelerometer);

    CrossDeviceMotion.Current.SensorValueChanged += (s, a) =>
    {

        switch (a.SensorType)
        {
            case MotionSensorType.Accelerometer:
                {
                    Debug.WriteLine("A: {0},{1},{2}", ((MotionVector)a.Value).X, ((MotionVector)a.Value).Y,
                     ((MotionVector)a.Value).Z);
                    Exposicao.Inclinacao = ((MotionVector)a.Value).Z;
                    break;
                }
            case MotionSensorType.Compass:
                {
                    // Debug.WriteLine("H: {0}", a.Value);
                    Exposicao.Bussola = (double)a.Value.Value;
                    break;
                }
        }
    };

指南针部分没问题,加速度计部分正在工作,但有一些问题。

如果我没记错的话,我会得到 Z 轴的倾斜,所以 z.Value.Value。

这个值对于 android 和 ios 是不同的,让我们专注于 android。

z 值从 10(当设备放置在平面上时)到 0(如果设备直立),仅聚焦在一个象限。

我做错了什么来实现我所解释的?

如何将这些值转换为 0 到 90 之间的角度?它似乎不是线性的,所以 5 似乎不是 45 度。

谢谢

4

1 回答 1

2

我可能会为您正在寻找的功能推出我自己的平台实现。DeviceMotion 库对于您的目的来说看起来有点简单,从下面的答案中可以看出。我很确定您可以将其用作一个很好的起点,但需要对其进行一些扩展。

安卓

在 Android 上,您应该使用使用卡尔曼滤波器(带有加速度计、磁力计和陀螺仪)的旋转矢量传感器来获得设备旋转的准确测量值:

旋转矢量将设备的方向表示为角度和轴的组合,其中设备已围绕轴(x、y 或 z)旋转角度 θ。 在此处输入图像描述

图片来自 Android 官方文档

IOS:

对于 iOS,您必须自己做更多的工作。关键是利用 CMAttitude,它描述了设备相对于初始姿态的姿态。我在这里找到了一个我从未知来源(不能归功于原作者)保存到我的收藏中的片段:

public void CalculateLeanAngle ()
{           
    motionManager = new CMMotionManager ();
    motionManager.DeviceMotionUpdateInterval = 0.02; 

    if (motionManager.DeviceMotionAvailable) {
        motionManager.StartDeviceMotionUpdates(CMAttitudeReferenceFrame.XArbitraryZVertical, NSOperationQueue.CurrentQueue, (data, error) => { 
            CMQuaternion quat = motionManager.DeviceMotion.Attitude.Quaternion;
            double x = quat.x;
            double y = quat.y;
            double w = quat.w;
            double z = quat.z;
            double degrees = 0.0;

            //Roll
            double roll = Math.Atan2 (2 * y * w - 2 * x * z, 1 - 2 * y * y - 2 * z * z);                        
            degrees = Math.Round (-applyKalmanFiltering (roll) * 180.0 / Constants.M_PI);
    });
}

public double applyKalmanFiltering (double yaw)
{
    if (motionLastYaw == 0)
        motionLastYaw = yaw;

    float q = 0.1f;   // process noise
    float r = 0.1f;   // sensor noise
    float p = 0.1f;   // estimated error
    float k = 0.5f;   // kalman filter gain

    double x = motionLastYaw;
    p = p + q;
    k = p / (p + r);
    x = x + k * (yaw - x);
    p = (1 - k) * p;
    motionLastYaw = x;

    return motionLastYaw;
}

在此处输入图像描述

图片来自 Xamarin 官方文档

当我有更多时间时,我会尝试寻找原始来源,但我很确定这对于您的目的来说是开箱即用的。

于 2017-08-29T19:50:30.453 回答