在代码中将随时间推移的加速度转换为速度或速度



我有来自传感器的加速度数据。X Y & Z.我在 Y 轴上移动传感器。大多在一条直线上。所以我忽略了x和z。

来自传感器文档 5.2.1 加速度输出:

ax=((AxH<<8)|AxL)/32768*16g(g为重力加速度,9.8m/s2)

ay=((AyH<<8)|AyL)/32768*16g(g为重力加速度,9.8m/s2)

az=((AzH<<8)|AzL)/32768*16g(g为重力加速度,9.8m/s2)

数据在 (m/s2) 中

我需要一个简单的计算,java或C#可以轻松进行。我想用代码编写一些东西,计算随时间推移的加速度到最大速度和平均速度。我需要一个可以显示的"速度"值。例如,最大速度 12MPH 和平均速度 8MPH。

--编辑更好的数据将其移动12英寸 --这是工作代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CalculateSpeed
{
public class Program
{
public static void Main(string[] args)
{
List<TimeAccelData> timeVsAccelerationData = new List<TimeAccelData>();
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.614, Acceleration = 0.0001 });//not  Moving
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.655, Acceleration = 0.0025 });//Moving
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.655, Acceleration = 0.0045 });
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.655, Acceleration = 0.0098 });
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.684, Acceleration = 0.0059 });
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.684, Acceleration = 0.0079 });
timeVsAccelerationData.Add(new TimeAccelData() { Time = 910.684, Acceleration = 0.0094 });
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.684, Acceleration = 0.0186});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.684, Acceleration = 0.0357});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.684, Acceleration = 0.0582});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.684, Acceleration = 0.0611});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.695, Acceleration = 0.1368});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.714, Acceleration = 0.1207});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.729, Acceleration = 0.1661});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.734, Acceleration = 0.1632});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.747, Acceleration = 0.1627});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.754, Acceleration = 0.1788});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.764, Acceleration = 0.3746});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.816, Acceleration = 0.4893});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.82, Acceleration = 0.5806});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.82, Acceleration = 0.627});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.565});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.5899});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.5968});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.6632});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.6749});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.7237});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.849, Acceleration = 0.7511});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.866, Acceleration = 0.692});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.9, Acceleration = 0.7227});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.902, Acceleration = 0.7384});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.902, Acceleration = 0.6436});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.908, Acceleration = 0.6959});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.915, Acceleration = 0.5738});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.929, Acceleration = 0.4796});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.935, Acceleration = 0.3443});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.949, Acceleration = 0.1803});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 910.952, Acceleration = 0.0601});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.012, Acceleration = -0.1332});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.014, Acceleration = -0.3554});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.015, Acceleration = -0.5414});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.015, Acceleration = -0.6908});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.017, Acceleration = -0.7807});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.018, Acceleration = -0.9779});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.031, Acceleration = -0.8061});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.066, Acceleration = -0.9692});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.11, Acceleration = -1.0146});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.11, Acceleration = -1.5878});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.11, Acceleration = -1.0785});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.11, Acceleration = -1.1225});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.11, Acceleration = -1.1557});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.11, Acceleration = -1.0395});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.113, Acceleration = -0.9071});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.115, Acceleration = -0.4555});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.129, Acceleration = -0.3305});
timeVsAccelerationData.Add(new TimeAccelData() {Time = 911.136, Acceleration = -0.3266});
timeVsAccelerationData.Add(new TimeAccelData() { Time = 911.164, Acceleration = 0.002 });//STOPPED MOVING
//initial speed = 0.0001 and distance = 0.
var distance = RiemannIntegration(new List<TimeAccelData>(RiemannIntegration(timeVsAccelerationData, 0).ToArray()),0).Last().Acceleration;
//distance equals 0.028999999999996362 meters to inches = 1.1417322834644237
//fixed the double integration and now the value is lower
//distance equals 0.02675412494998913
}
public static IEnumerable<TimeAccelData> RiemannIntegration(List<TimeAccelData> xy, double initialValue)
{
var res = initialValue;
yield return (new TimeAccelData() {Time = xy[0].Time, Acceleration = initialValue});
for (var i = 1; i < xy.Count; i++)
{
res += (xy[i].Time - xy[i - 1].Time) * (xy[i].Acceleration + xy[i - 1].Acceleration) / 2;
yield return (new TimeAccelData() {Time = xy[i].Time, Acceleration = res});
}
}
public class TimeAccelData
{
public double Time { get; internal set; }
public double Acceleration { get; internal set; }
}
}
}

速度是加速度的积分。如果初始速度为 0,则可以使用黎曼积分 (*) 评估速度;加速度函数的面积。

对于一般功能fx您可以执行以下操作:

public static double RiemannIntegration
(Func<double, double> fx,
double x0,
double x1,
double step)
{
var previous = x0;
var res = 0d;
var semiStep = step / 2;
for (var x = x0 + step; x < x1; x += step)
{
res += semiStep * (fx(x) + fx(previous));
previous = x;
}
res += (x1 - previous) / 2 * (fx(x1) + fx(previous));
return res;
}

但也许更具体的实现对你的方案更有用;给定一系列(t, acc)数据,使用每个t定义的变量步长计算黎曼积分。此实现考虑了每个间隔内加速度的线性变化:

public static double RiemannIntegration(
(double X, double Y)[] xy)
{
var res = 0d;
for (var i = 1; i < xy.Length; i++)
{
res += (xy[i].X - xy[i - 1].X) * (xy[i].Y + xy[i - 1].Y) / 2;
}
return res;
}

更新:根据您的评论,您最终希望评估所覆盖的距离。您可以通过积分两倍加速度来做到这一点,但为了做到这一点,您实际上需要返回积分曲线,而不是总值。以下实现将执行此操作:

public static IEnumerable<(double X, double Y)> RiemannIntegration(
(double X, double Y)[] xy, double initialValue)
{
var res = initialValue;
yield return (xy[0].X, initialValue);
for (var i = 1; i < xy.Length; i++)
{
res += (xy[i].X - xy[i - 1].X) * (xy[i].Y + xy[i - 1].Y) / 2;
yield return (xy[i].X, res);
}
}

现在要评估距离形式的加速度数据,您需要执行以下操作:

var timeVsAccelerationData = new[] { (t0, a0), (t1, a1), ... };
//initial speed and distance are zero.
var distance = RiemmanIntegral(RiemannIntegral(
timeVsAccelerationData, 0).ToArray(), 0).Last().Y;

(*) 提出的算法并不完全是黎曼积分,我使用的是梯形区域,黎曼积分实际上使用高度等于时间间隔中心的函数值的矩形区域。

最新更新