initial commit
This commit is contained in:
96
Models/RpmVoltageRelation.cs
Normal file
96
Models/RpmVoltageRelation.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace HC_APTBS.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps a motor RPM setpoint to the corresponding analogue control voltage
|
||||
/// required to drive the bench motor to that speed.
|
||||
///
|
||||
/// <para>
|
||||
/// The lookup table is ordered by ascending RPM. <see cref="VoltageForRpm"/>
|
||||
/// performs a linear scan and returns the voltage of the last entry whose
|
||||
/// RPM is ≤ the requested value (step interpolation).
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class RpmVoltageRelation
|
||||
{
|
||||
/// <summary>Analogue voltage to apply to the motor controller (V).</summary>
|
||||
public double Voltage { get; set; }
|
||||
|
||||
/// <summary>Target motor speed (RPM).</summary>
|
||||
public int Rpm { get; set; }
|
||||
|
||||
/// <param name="voltage">Motor control voltage (V).</param>
|
||||
/// <param name="rpm">Corresponding motor speed (RPM).</param>
|
||||
public RpmVoltageRelation(double voltage, int rpm)
|
||||
{
|
||||
Voltage = voltage;
|
||||
Rpm = rpm;
|
||||
}
|
||||
|
||||
// ── Lookup ────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Returns the control voltage for the given <paramref name="targetRpm"/>
|
||||
/// by scanning the ordered <paramref name="table"/> for the closest lower entry.
|
||||
/// Returns 0 if the table is empty or no lower entry is found.
|
||||
/// </summary>
|
||||
/// <param name="targetRpm">Requested motor speed in RPM.</param>
|
||||
/// <param name="table">Ordered (ascending RPM) lookup table.</param>
|
||||
public static double VoltageForRpm(int targetRpm, IReadOnlyList<RpmVoltageRelation> table)
|
||||
{
|
||||
double previousVoltage = -1;
|
||||
foreach (var entry in table)
|
||||
{
|
||||
if (entry.Rpm == targetRpm)
|
||||
return entry.Voltage;
|
||||
|
||||
if (targetRpm < entry.Rpm)
|
||||
return previousVoltage < 0 ? 0 : previousVoltage;
|
||||
|
||||
previousVoltage = entry.Voltage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ── Serialisation ─────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Serialises a list of relations to the compact pipe-separated storage format
|
||||
/// used in config.xml: <c>RPM|Voltage;RPM|Voltage;…</c>
|
||||
/// </summary>
|
||||
public static string Serialise(IReadOnlyList<RpmVoltageRelation> relations)
|
||||
{
|
||||
if (relations == null || relations.Count == 0) return string.Empty;
|
||||
|
||||
var parts = new List<string>(relations.Count);
|
||||
foreach (var r in relations)
|
||||
parts.Add($"{r.Rpm}|{r.Voltage.ToString(CultureInfo.InvariantCulture)}");
|
||||
|
||||
return string.Join(";", parts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialises a list of relations from the compact storage format.
|
||||
/// </summary>
|
||||
public static List<RpmVoltageRelation> Deserialise(string serialised)
|
||||
{
|
||||
var result = new List<RpmVoltageRelation>();
|
||||
if (string.IsNullOrWhiteSpace(serialised)) return result;
|
||||
|
||||
foreach (var part in serialised.Split(';'))
|
||||
{
|
||||
var tokens = part.Split('|');
|
||||
if (tokens.Length != 2) continue;
|
||||
if (!int.TryParse(tokens[0], out int rpm)) continue;
|
||||
if (!double.TryParse(tokens[1], NumberStyles.Float,
|
||||
CultureInfo.InvariantCulture, out double voltage)) continue;
|
||||
|
||||
result.Add(new RpmVoltageRelation(voltage, rpm));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user