Xamarin方向传感器四元数

时间:2019-02-05 17:36:32

标签: c# xamarin math xamarin.forms xamarin.essentials

我正在尝试确定一个3d向量Vector3,该向量表示我的手机方向而没有角度。我要寻找的是从手机背面像射线一样从手机背面出来的矢量,基本上是手机的正常矢量。

我知道四元数给了我一个转换,但是要做什么呢?

此外,我发现Quaternion.ToAxisAngle()可以将四元数转换为轴及其相应的横滚角。我想,太好了,这就是我所需要的,我可以忽略角度。

当电话放在桌子上时,我得到以下轴:

axis = [0,0,-1]

并且角度基本上代表指南针的角度。在那种特殊情况下,这就是我的期望。但是当手机具有不同的任意空间位置时,轴似乎不再是手机的法线向量。

如何计算手机平面的法线向量?

1 个答案:

答案 0 :(得分:1)

“一切都是相对的”

因此,您需要做的是保存一个四元数并将其用作原点(也称为bindPopup()),然后可以对任何新的四元数进行本地化以确定发生了什么方向变化。

校准

可以通过告诉用户保持手机平稳,然后采样并消除四元数流并将它们在一段时间内求平均值来执行校准。但是对于这个例子。只需将设备放在桌子上,进行筛选,然后再启动应用程序,然后抓取第一个示例(不是很好,但是可以快速使用)。

注意:系统。反应式可观察性非常适合采样和去抖动

注意:将该四元数存储为其倒数(centre),因为这比每个样本都要少计算一次。

计算每个样本的差异:

您想将当前采样的四元数乘以原点/中心(倒数形式)。

注意:请记住,乘法与四元数是不可交换的,因此顺序很重要(!)

Quaternion.Inverse

转换您的本地化四元数

因此,现在您有了一个本地化的四元数,您可以将其转换为Vector3(通过基本向量(上,前,下,...)对其进行转换)或获得一些Euler角或...

示例:

因此,使用Xamarin Essentials示例,这就是我如何将var currentQ = e.Reading.Orientation; var q = Quaternion.Multiply(originQ, currentQ); 事件更改为非常快的示例的方法。

注意:取决于设备,采样事件称为A LOT,而OrientationSensor_ReadingChanged对于控制输出速率实际上是无用的。如果您直接尝试使用这些示例(以1对1的基础)更新屏幕,则可能会遇到严重的问题(Mono垃圾收集器几乎不能跟上GC更新UI时创建的字符串的速度) (监视应用程序输出,即使设置了SensorSpeed,GC周期仍在不断发生。)在更新UI之前,我使用了反应式可观察对象对样本进行平滑处理并将传感器输出调整为合理的更新周期(16ms或更长时间)。 / p>

SensorSpeed.UI

注意:只需将最喜欢的四元数替换为Euler angles例程(并根据需要编写平滑和节流例程)。

输出:

enter image description here