我想让设备倾斜,所以我可以用它来测量某些表面的倾斜度,将设备放在表面上。
目前我正在使用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度。
由于
答案 0 :(得分:2)
我可能会为您正在寻找的功能推出自己的平台实现。从下面的答案中可以看出,DeviceMotion库看起来有点简单。我很确定你可以把它作为一个很好的起点,但需要延长一点。
<强>的Android 强>
在Android上,你应该使用Rotation Vector Sensor使用卡尔曼滤波器(带加速度计,磁力计和陀螺仪)来准确测量设备的旋转:
旋转矢量表示作为角度和轴的组合的装置的取向,其中装置围绕轴(x,y或z)旋转了角度θ。
<强>的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;
}
当我有更多时间时,我会尝试寻找原始来源,但我很确定这将为您的目的开箱即用。