using System;
using System.Collections.Generic;
using System.Globalization;
namespace HC_APTBS.Models
{
///
/// Maps a motor RPM setpoint to the corresponding analogue control voltage
/// required to drive the bench motor to that speed.
///
///
/// The lookup table is ordered by ascending RPM.
/// performs a linear scan and returns the voltage of the last entry whose
/// RPM is ≤ the requested value (step interpolation).
///
///
public class RpmVoltageRelation
{
/// Analogue voltage to apply to the motor controller (V).
public double Voltage { get; set; }
/// Target motor speed (RPM).
public int Rpm { get; set; }
/// Motor control voltage (V).
/// Corresponding motor speed (RPM).
public RpmVoltageRelation(double voltage, int rpm)
{
Voltage = voltage;
Rpm = rpm;
}
// ── Lookup ────────────────────────────────────────────────────────────────
///
/// Returns the control voltage for the given
/// by scanning the ordered for the closest lower entry.
/// Returns 0 if the table is empty or no lower entry is found.
///
/// Requested motor speed in RPM.
/// Ordered (ascending RPM) lookup table.
public static double VoltageForRpm(int targetRpm, IReadOnlyList 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 ─────────────────────────────────────────────────────────
///
/// Serialises a list of relations to the compact pipe-separated storage format
/// used in config.xml: RPM|Voltage;RPM|Voltage;…
///
public static string Serialise(IReadOnlyList relations)
{
if (relations == null || relations.Count == 0) return string.Empty;
var parts = new List(relations.Count);
foreach (var r in relations)
parts.Add($"{r.Rpm}|{r.Voltage.ToString(CultureInfo.InvariantCulture)}");
return string.Join(";", parts);
}
///
/// Deserialises a list of relations from the compact storage format.
///
public static List Deserialise(string serialised)
{
var result = new List();
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;
}
}
}