首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OrientationSensor /测斜仪怪异,无文件记录的传感器面向地平线时的读数跳跃

OrientationSensor /测斜仪怪异,无文件记录的传感器面向地平线时的读数跳跃
EN

Stack Overflow用户
提问于 2017-07-10 13:52:13
回答 1查看 471关注 0票数 2

我正试图升级我的一个应用程序,使用Windows 10移动设备传感器作为个人电脑的虚拟现实设备(比如)。当设备从指向地平线以下变为地平线上方时,我在传感器读出方面遇到了问题(同时发生在景观和人像上,但是在这种情况下,只有景观才是重要的)。小品:

原始传感器读数(向下指向):

倾斜计俯仰:-000.677,滚动:-055.380,偏航:+013.978

现在改为向上指向:

倾斜计俯仰:-178.550,滚动:+083.841,偏航:+206.219

正如您所看到的,所有3个值都发生了很大的变化。在现实中,只有一个轴应该改变,滚动或俯仰(取决于传感器的方向)

我95%肯定,这个问题在Windows 8中并不存在。我找不到任何关于传感器这种奇怪行为的文档,它阻止了我创建增强现实和虚拟现实应用程序。

以下是问题的两张图片:

下面是这个演示的代码:

代码语言:javascript
复制
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock Style="{StaticResource BodyTextBlockStyle}"
                x:Name="output"
                FontFamily="Consolas"
                Foreground="Black"
                Text="test"/>

</Grid>

代码背后:

代码语言:javascript
复制
public MainPage()
{
    this.InitializeComponent();
    timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromMilliseconds(250);
    timer.Tick += Timer_Tick;
}

private void Timer_Tick(object sender, object e)
{
    output.Text = "";
    output.Text = DateTime.Now.ToString("HH:mm:ss.fff") + Environment.NewLine;
    Print();
}

DispatcherTimer timer;
public void WriteValue(String desc, String val)
{
    StringBuilder b = new StringBuilder();
    int length = desc.Length + val.Length;
    int topad = 40 - length;
    if (topad < 0)
        topad = length - 40;
    output.Text += desc + val.PadLeft(topad + val.Length) + Environment.NewLine;
}
public String ValueToString(double value)
{
    String ret = value.ToString("000.00000");
    if (value > 0)
        ret = " +" + ret;
    else if (value == 0)
        ret = "  " + ret;
    else
        ret = " " + ret;

    return ret;
}
public static double RadianToDegree(double radians)
{
    return radians * (180 / Math.PI);
}
public void Print()
{
    WriteValue("DisplayOrientation", LastDisplayOrient.ToString());

    WriteValue("Inclinometer", "");
    WriteValue("Pitch", ValueToString(LastIncline.PitchDegrees));
    WriteValue("Roll", ValueToString(LastIncline.RollDegrees));
    WriteValue("Yaw", ValueToString(LastIncline.YawDegrees));
    WriteValue("YawAccuracy", LastIncline.YawAccuracy.ToString());


    WriteValue("OrientationSensor", "");
    var q = LastOrient.Quaternion;


    double ysqr = q.Y * q.Y;
    // roll (x-axis rotation)
    double t0 = +2.0f * (q.W * q.X + q.Y * q.Z);
    double t1 = +1.0f - 2.0f * (q.X * q.X + ysqr);
    double Roll = RadianToDegree(Math.Atan2(t0, t1));
    // pitch (y-axis rotation)
    double t2 = +2.0f * (q.W * q.Y - q.Z * q.X);
    t2 = t2 > 1.0f ? 1.0f : t2;
    t2 = t2 < -1.0f ? -1.0f : t2;
    double Pitch = RadianToDegree(Math.Asin(t2));
    // yaw (z-axis rotation)
    double t3 = +2.0f * (q.W * q.Z + q.X * q.Y);
    double t4 = +1.0f - 2.0f * (ysqr + q.Z * q.Z);
    double Yaw = RadianToDegree(Math.Atan2(t3, t4));
    WriteValue("Roll", ValueToString(Roll));
    WriteValue("Pitch", ValueToString(Pitch));
    WriteValue("Yaw", ValueToString(Yaw));
}
Inclinometer sIncline;
DisplayInformation sDisplay;
OrientationSensor sOrient;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    sIncline = Inclinometer.GetDefault(SensorReadingType.Absolute);
    sDisplay = DisplayInformation.GetForCurrentView();
    sOrient = OrientationSensor.GetDefault(SensorReadingType.Absolute);
    sOrient.ReadingChanged += SOrient_ReadingChanged;
    sDisplay.OrientationChanged += SDisplay_OrientationChanged;
    sIncline.ReadingChanged += SIncline_ReadingChanged;

    LastDisplayOrient = sDisplay.CurrentOrientation;
    LastIncline = sIncline.GetCurrentReading();
    LastOrient = sOrient.GetCurrentReading();
    timer.Start();
}

private void SOrient_ReadingChanged(OrientationSensor sender, OrientationSensorReadingChangedEventArgs args)
{
    LastOrient = args.Reading;
}

private void SDisplay_OrientationChanged(DisplayInformation sender, object args)
{
    LastDisplayOrient = sDisplay.CurrentOrientation;
}
OrientationSensorReading LastOrient;
InclinometerReading LastIncline;
DisplayOrientations LastDisplayOrient;
private void SIncline_ReadingChanged(Inclinometer sender, InclinometerReadingChangedEventArgs args)
{
    LastIncline = args.Reading;
}

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    base.OnNavigatingFrom(e);

    sIncline.ReadingChanged -= SIncline_ReadingChanged;
    sDisplay.OrientationChanged -= SDisplay_OrientationChanged;
    sOrient.ReadingChanged -= SOrient_ReadingChanged;
    timer.Stop();
}

编辑:添加了以下草图和更多描述

看一看下面的更深入的草图:

如步骤(1)所示,将电话定位。手机在景观模式下,相机朝下,屏幕朝上。

改为步骤(2)。你稍微向前倾斜,只有一个轴应该改变(在这种情况下,测斜仪只会显示“滚动”变化。)这是正确的)

改为步骤(3)。你现在向后倾斜你的手机。一旦切换点来,那里的相机不再面对地面,但现在天空和屏幕正面临略微向下,所有三个数值都有很大的变化。俯仰将跳跃约-180°,滚动将额外跳约90°,你实际改变的数量,而偏航将跳跃约+180°。

只要相机只指向地球或天空,传感器就会表现得很好!只有当从一个切换到另一个时,这个问题才会发生!(这个场景总是发生在VR和AR上,所以这是一个大问题)

EN

回答 1

Stack Overflow用户

发布于 2017-07-11 09:16:52

原始传感器读数(向下指向): 倾斜计俯仰:-000.677,滚动:-055.380,偏航:+013.978 现在改为向上指向: 倾斜计俯仰:-178.550,滚动:+083.841,偏航:+206.219 正如您所看到的,所有3个值都发生了很大的变化。在现实中,只有一个轴应该改变,滚动或俯仰(取决于传感器的方向)

你的考试不严格。如果您想观察RollPitch,您应该为测试设置一个固定的坐标。

我已经在我的物理设备中测试了Inclinometer。当我沿着X轴的方向滑动手机的时候。所有3个值都发生了变化,但只有音调值变化最明显,其余两个值都在错误范围内。

测斜仪传感器指定设备的偏航、俯仰和滚动值,并与关心该设备在空间中的位置的应用程序协同工作。通过加速度计的重力矢量和陀螺仪数据的集成,得到俯仰和滚转。偏航是由磁强计和陀螺仪(类似于罗盘航向)数据建立的。测斜仪以一种易于理解和易懂的方式提供先进的方位数据。当您需要设备定位但不需要操作传感器数据时,请使用测斜仪。

要获得更多信息,您可以参考感应器

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45013854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档