gpt4 book ai didi

c# - 用倾角计计算重力

转载 作者:可可西里 更新时间:2023-11-01 08:28:02 24 4
gpt4 key购买 nike

如何将倾角计(俯仰、偏航和滚转)转换为系统在 [X,Y,Z] 中预期的引力?

在特定的 Pitch、Yaw 和 Roll 角度下静止的系统应该在特定的 [X*g,Y*g,Z*g] 处被拉到地面,假设这是为了模拟目的。我想创建一个函数,其输入为 Pitch、Yaw 和 Roll,输出为向下时刻的 Vector3(X,Y,Z)

意味着静止的物体向后向下会从加速度计输出类似 [0,-1,0][pitch,yaw,roll]->[0 ,-1,0],其中 [0,-1,0] 减去 [0,-1,0] 得到 [0 ,0,0]。或者,如果我们以 1g 的速度向左拉,我们就会有一个加速度计显示 [1,-1,0] 使新值 [1,0,0]

系统支持 [pitch,yaw,roll]->[0,-1,0] 函数是我所追求的

Vector3 OriToXYZ(float pitch, float yaw, float roll){
Vector3 XYZ = Vector.Zero;
//Simulate what the XYZ should be on a object in this orientation
//oriented against gravity
...
return XYZ;
}

是的,我知道,因为下面的解释表明我无法根据滚动检测系统是否颠倒,因为滚动只给出(-90 到 90),但这是一个不同的问题。

这就是方向的布局方式。 inclometer decriptor

有关为什么、什么以及如何使用此信息的更多信息,请继续阅读。

计划是通过模拟/计算方向(俯仰、偏航、滚动)的预期重力值,使用增量计替代陀螺仪,以去除加速度计数据中的重力分量。

由于加速度计 (XYZ) 是重力 (XYZ) 和运动 (XYZ) 两个分量的组合,我假设 gravity(XYZ)-calc_g(XYZ) = 0, 允许我执行 accelerometer(XYZ)- calc_g(XYZ) =movement(XYZ)

展示为什么我认为这是可能的。当我绘制手机的值并以某种钟摆运动用力向侧面移动手机时,看起来像正弦/余弦运动的线是倾斜计,其他线是 XYZ 加速度计:

  • red = (Pitch & accell-X)
  • green = (Yaw & accell-Y)
  • blue = (Roll & accell-Z)

加速度值乘以 90,因为它的范围是(-2 到 2),所以它在绘图中的范围是从 -180 到 180,俯仰偏航和滚动范围如上图所示。图片中间是Y = 0,左边是X=0(X=时间)

Sensor measurements

已解决Romasz

的解决方案
VectorX = Cos(Pitch)*Sin(Roll);
VectorY = -Sin(Pitch);
VectorZ = -Cos(Pitch)*Cos(Roll);

结果 enter image description here

*图表并非来自同一测量。

最佳答案

(评论后(完全)编辑)

如果你想计算倾斜方向的重力分量,那么你只需要俯仰和滚动(在 WP 约定中)——关于 Z(偏航)的旋转对加速度计没有影响。该公式应如下所示:

VectorX = Cos(Pitch)*Sin(Roll);
VectorY = -Sin(Pitch);
VectorZ = -Cos(Pitch)*Cos(Roll);

(您可以找到类似的公式,例如 herehere )

由于多种原因,准确性可能存在一些问题:

  • 倾角为单精度,加速度为 double
  • 倾角仪可能需要一段时间才能稳定
  • 执行倾斜计和加速度计读数时的不同时间(注意,因为这些传感器具有不同的最小报告间隔)
  • 加速度计的精度取决于它们的位置

另请注意,加速度计可能会过载(其范围为 +-2g)- 例如,如果您拍下手机。


为了测试它,我编写了一个简单的应用程序 ( which you can download here ) - 比较加速度计指示的值和通过倾斜计算的值。因为加速度计的值是相对于重力的,所以很简单:
在 XAML 中 - 几个 TextBlocks:

<Grid x:Name="LayoutRoot" Background="Transparent" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock Text="Incliation:" FontSize="16"/>
<TextBlock Name="incXTB" Margin="10"/>
<TextBlock Name="incYTB" Margin="10"/>
</StackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock Text="Accelerometers:" FontSize="16"/>
<TextBlock Name="accXTB" Margin="10"/>
<TextBlock Name="accYTB" Margin="10"/>
<TextBlock Name="accZTB" Margin="10"/>
</StackPanel>
<StackPanel Grid.Row="2" VerticalAlignment="Center" Orientation="Horizontal">
<TextBlock Text="Through Inc:" FontSize="16"/>
<TextBlock Name="accincXTB" Margin="10"/>
<TextBlock Name="accincYTB" Margin="10"/>
<TextBlock Name="accincZTB" Margin="10"/>
</StackPanel>
</Grid>

在后面的代码中:

public partial class MainPage : PhoneApplicationPage
{
private Inclinometer myIncMeter = null;
private float inclX = 0;
private float inclY = 0;

private Accelerometer myAccel = null;
private double accX = 0;
private double accY = 0;
private double accZ = 0;

public MainPage()
{
InitializeComponent();
this.DataContext = this;
myIncMeter = Inclinometer.GetDefault();
myIncMeter.ReportInterval = myIncMeter.MinimumReportInterval;
myAccel = Accelerometer.GetDefault();
myAccel.ReportInterval = myIncMeter.MinimumReportInterval;

CompositionTarget.Rendering += CompositionTarget_Rendering;
}

private void CompositionTarget_Rendering(object sender, EventArgs e)
{
InclinometerReading incRead = myIncMeter.GetCurrentReading();
AccelerometerReading accRead = myAccel.GetCurrentReading();

accX = accRead.AccelerationX;
accY = accRead.AccelerationY;
accZ = accRead.AccelerationZ;

inclX = incRead.RollDegrees;
inclY = incRead.PitchDegrees;

incXTB.Text = "X: " + inclX.ToString("0.00");
incYTB.Text = "Y: " + inclY.ToString("0.00");

accXTB.Text = "X: " + accX.ToString("0.00");
accYTB.Text = "Y: " + accY.ToString("0.00");
accZTB.Text = "Z: " + accZ.ToString("0.00");

accincXTB.Text = "X: " + ((Math.Cos(inclY * Math.PI / 180) * Math.Sin(inclX * Math.PI / 180))).ToString("0.00");
accincYTB.Text = "Y: " + (-Math.Sin(inclY * Math.PI / 180)).ToString("0.00");
accincZTB.Text = "Z: " + (-(Math.Cos(inclX * Math.PI / 180) * Math.Cos(inclY * Math.PI / 180))).ToString("0.00");
}
}

关于c# - 用倾角计计算重力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21462691/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com