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

Converting acceleration over time to velocity or speed in code

我有来自传感器的加速度数据。 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# 可以轻松进行的简单计算。我想用代码写一些东西来计算随时间推移的加速度到最大速度和平均速度。我需要一个可以显示的 "speed" 值。对于前。最大速度 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,则可以使用 Riemann integral(*) 计算速度;加速函数的面积。

对于一般函数 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;
}

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

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;

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