如何让设备以xamarin形式倾斜?

时间:2017-08-29 19:23:43

标签: xamarin xamarin.forms devicemotion

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

目前我正在使用Device Motion Plugin for xamarin表格https://github.com/rdelrosario/xamarin-plugins

以及以下代码:

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度。

由于

1 个答案:

答案 0 :(得分:2)

我可能会为您正在寻找的功能推出自己的平台实现。从下面的答案中可以看出,DeviceMotion库看起来有点简单。我很确定你可以把它作为一个很好的起点,但需要延长一点。

<强>的Android

在Android上,你应该使用Rotation Vector Sensor使用卡尔曼滤波器(带加速度计,磁力计和陀螺仪)来准确测量设备的旋转:

  旋转矢量表示作为角度和轴的组合的装置的取向,其中装置围绕轴(x,y或z)旋转了角度θ。   enter image description here

     

Image from the official Android documentation

<强>的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;
}
  

enter image description here

     

Image from the official Xamarin documentation

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