diff options
| author | a1xd <[email protected]> | 2020-08-14 03:48:40 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-08-14 03:48:40 -0400 |
| commit | 0621a7ebd431102d720497a143190505dcfeb7a1 (patch) | |
| tree | 01d7df8f55e5a1cce90617fd876eaf994eb26846 /grapher/Models/Calculations | |
| parent | Merge pull request #14 from JacobPalecki/GainCap (diff) | |
| parent | Fix initial points, add poll time constant (diff) | |
| download | rawaccel-0621a7ebd431102d720497a143190505dcfeb7a1.tar.xz rawaccel-0621a7ebd431102d720497a143190505dcfeb7a1.zip | |
Merge pull request #15 from JacobPalecki/GUI
GUI: Add x/y graphs, moving dot
Diffstat (limited to 'grapher/Models/Calculations')
| -rw-r--r-- | grapher/Models/Calculations/AccelCalculator.cs | 145 | ||||
| -rw-r--r-- | grapher/Models/Calculations/AccelChartData.cs | 61 | ||||
| -rw-r--r-- | grapher/Models/Calculations/AccelData.cs | 74 |
3 files changed, 280 insertions, 0 deletions
diff --git a/grapher/Models/Calculations/AccelCalculator.cs b/grapher/Models/Calculations/AccelCalculator.cs new file mode 100644 index 0000000..bba3c32 --- /dev/null +++ b/grapher/Models/Calculations/AccelCalculator.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace grapher.Models.Calculations +{ + public static class AccelCalculator + { + public const int MaxCombined = 100; + public const int MaxXY = 150; + + public struct MagnitudeData + { + public double magnitude; + public int x; + public int y; + } + + public static ReadOnlyCollection<MagnitudeData> MagnitudesCombined = GetMagnitudes(); + public static ReadOnlyCollection<MagnitudeData> MagnitudesX = GetMagnitudesX(); + public static ReadOnlyCollection<MagnitudeData> MagnitudesY = GetMagnitudesY(); + + public static void Calculate(AccelData data, ManagedAccel accel) + { + data.Clear(); + + Calculate(data.Combined, accel, accel.GetSensitivityX(), MagnitudesCombined); + Calculate(data.X, accel, accel.GetSensitivityX(), MagnitudesX); + Calculate(data.Y, accel, accel.GetSensitivityY(), MagnitudesY); + } + + public static void Calculate(AccelChartData data, ManagedAccel accel, double starter, ICollection<MagnitudeData> magnitudeData) + { + double lastInputMagnitude = 0; + double lastOutputMagnitude = 0; + + foreach (var magnitudeDatum in magnitudeData) + { + var output = accel.Accelerate(magnitudeDatum.x, magnitudeDatum.y, 1); + + var outMagnitude = Magnitude(output.Item1, output.Item2); + var ratio = magnitudeDatum.magnitude > 0 ? outMagnitude / magnitudeDatum.magnitude : starter; + + var inDiff = magnitudeDatum.magnitude - lastInputMagnitude; + var outDiff = outMagnitude - lastOutputMagnitude; + var slope = inDiff > 0 ? outDiff / inDiff : starter; + + if (!data.AccelPoints.ContainsKey(magnitudeDatum.magnitude)) + { + data.AccelPoints.Add(magnitudeDatum.magnitude, ratio); + } + + if (!data.VelocityPoints.ContainsKey(magnitudeDatum.magnitude)) + { + data.VelocityPoints.Add(magnitudeDatum.magnitude, outMagnitude); + } + + if (!data.GainPoints.ContainsKey(magnitudeDatum.magnitude)) + { + data.GainPoints.Add(magnitudeDatum.magnitude, slope); + } + + lastInputMagnitude = magnitudeDatum.magnitude; + lastOutputMagnitude = outMagnitude; + } + + data.OrderedVelocityPointsList.AddRange(data.VelocityPoints.Values.ToList()); + } + + public static ReadOnlyCollection<MagnitudeData> GetMagnitudes() + { + var magnitudes = new List<MagnitudeData>(); + for (int i = 0; i < MaxCombined; i++) + { + for (int j = 0; j <= i; j++) + { + MagnitudeData magnitudeData; + magnitudeData.magnitude = Magnitude(i, j); + magnitudeData.x = i; + magnitudeData.y = j; + magnitudes.Add(magnitudeData); + } + } + + magnitudes.Sort((m1, m2) => m1.magnitude.CompareTo(m2.magnitude)); + + return magnitudes.AsReadOnly(); + } + + public static ReadOnlyCollection<MagnitudeData> GetMagnitudesX() + { + var magnitudes = new List<MagnitudeData>(); + + for (int i = 0; i < MaxXY; i++) + { + MagnitudeData magnitudeData; + magnitudeData.magnitude = i; + magnitudeData.x = i; + magnitudeData.y = 0; + magnitudes.Add(magnitudeData); + } + + return magnitudes.AsReadOnly(); + } + + public static ReadOnlyCollection<MagnitudeData> GetMagnitudesY() + { + var magnitudes = new List<MagnitudeData>(); + + for (int i = 0; i < MaxXY; i++) + { + MagnitudeData magnitudeData; + magnitudeData.magnitude = i; + magnitudeData.x = 0; + magnitudeData.y = i; + magnitudes.Add(magnitudeData); + } + + return magnitudes.AsReadOnly(); + } + + public static double Magnitude(int x, int y) + { + return Math.Sqrt(x * x + y * y); + } + + public static double Magnitude(double x, double y) + { + return Math.Sqrt(x * x + y * y); + } + + public static double Velocity(int x, int y, double time) + { + return Magnitude(x, y) / time; + } + + public static double Velocity(double x, double y, double time) + { + return Magnitude(x, y) / time; + } + } +} diff --git a/grapher/Models/Calculations/AccelChartData.cs b/grapher/Models/Calculations/AccelChartData.cs new file mode 100644 index 0000000..20142a7 --- /dev/null +++ b/grapher/Models/Calculations/AccelChartData.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace grapher.Models.Calculations +{ + public class AccelChartData + { + public AccelChartData() + { + AccelPoints = new SortedDictionary<double, double>(); + VelocityPoints = new SortedDictionary<double, double>(); + GainPoints = new SortedDictionary<double, double>(); + OrderedVelocityPointsList = new List<double>(); + OutVelocityToPoints = new Dictionary<double, (double, double, double)>(); + } + + public SortedDictionary<double, double> AccelPoints { get; } + + public SortedDictionary<double, double> VelocityPoints { get; } + + public SortedDictionary<double, double> GainPoints { get; } + + public List<double> OrderedVelocityPointsList { get; } + + public Dictionary<double, (double, double, double)> OutVelocityToPoints { get; } + + public void Clear() + { + AccelPoints.Clear(); + VelocityPoints.Clear(); + GainPoints.Clear(); + OrderedVelocityPointsList.Clear(); + OutVelocityToPoints.Clear(); + } + + public (double, double, double) FindPointValuesFromOut(double outVelocityValue) + { + if (OutVelocityToPoints.TryGetValue(outVelocityValue, out var values)) + { + return values; + } + else + { + var velIdx = OrderedVelocityPointsList.BinarySearch(outVelocityValue); + + if (velIdx < 0) + { + velIdx = ~velIdx; + } + + velIdx = Math.Min(velIdx, VelocityPoints.Count - 1); + values = (VelocityPoints.ElementAt(velIdx).Key, AccelPoints.ElementAt(velIdx).Value, GainPoints.ElementAt(velIdx).Value); + OutVelocityToPoints.Add(outVelocityValue, values); + return values; + } + } + } +} diff --git a/grapher/Models/Calculations/AccelData.cs b/grapher/Models/Calculations/AccelData.cs new file mode 100644 index 0000000..683c67e --- /dev/null +++ b/grapher/Models/Calculations/AccelData.cs @@ -0,0 +1,74 @@ +using grapher.Models.Charts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static grapher.AccelCharts; + +namespace grapher.Models.Calculations +{ + public class AccelData + { + + public AccelData( + EstimatedPoints combined, + EstimatedPoints x, + EstimatedPoints y) + { + Combined = new AccelChartData(); + X = new AccelChartData(); + Y = new AccelChartData(); + + Estimated = combined; + EstimatedX = x; + EstimatedY = y; + } + + public AccelChartData Combined { get; } + + public AccelChartData X { get; } + + public AccelChartData Y { get; } + + private EstimatedPoints Estimated { get; } + + private EstimatedPoints EstimatedX { get; } + + private EstimatedPoints EstimatedY { get; } + + public void Clear() + { + Combined.Clear(); + X.Clear(); + Y.Clear(); + } + + public void CalculateDots(int x, int y, double timeInMs) + { + var magnitude = AccelCalculator.Velocity(x, y, timeInMs); + + (var inCombVel, var combSens, var combGain) = Combined.FindPointValuesFromOut(magnitude); + Estimated.Velocity.Set(inCombVel, magnitude); + Estimated.Sensitivity.Set(inCombVel, combSens); + Estimated.Gain.Set(inCombVel, combGain); + } + + public void CalculateDotsXY(int x, int y, double timeInMs) + { + var outX = Math.Abs(x); + var outY = Math.Abs(y); + + (var inXVelocity, var xSensitivity, var xGain) = X.FindPointValuesFromOut(outX); + EstimatedX.Velocity.Set(inXVelocity, outX); + EstimatedX.Sensitivity.Set(inXVelocity, xSensitivity); + EstimatedX.Gain.Set(inXVelocity, xGain); + + (var inYVelocity, var ySensitivity, var yGain) = Y.FindPointValuesFromOut(outY); + EstimatedY.Velocity.Set(inYVelocity, outY); + EstimatedY.Sensitivity.Set(inYVelocity, ySensitivity); + EstimatedY.Gain.Set(inYVelocity, yGain); + } + + } +} |