diff --git a/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs index 856481b2dbb3be2fd31ead260307f8aa2837bef5..5c9ca9f40f4a74f78b0cb229593fb2771c3b64a0 100644 --- a/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs +++ b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs @@ -6,92 +6,102 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - /// <summary> - /// Class for Look Ahead Coasting Decision Factor (DF_coast) - /// </summary> - public sealed class LACDecisionFactor : LookupData<MeterPerSecond, MeterPerSecond, double> + public static class LACDecisionFactor { - private readonly LACDecisionFactorVTarget _vTarget = new LACDecisionFactorVTarget(); - private readonly LACDecisionFactorVdrop _vDrop = new LACDecisionFactorVdrop(); + private static readonly DecisionFactor LAC = new DecisionFactor(); - public override double Lookup(MeterPerSecond targetVelocity, MeterPerSecond velocityDrop) + public static double Lookup(MeterPerSecond targetVelocity, MeterPerSecond velocityDrop) { - // normalize values inverse from [0 .. 1] to [2.5 .. 1] - return 2.5 - 1.5 * _vTarget.Lookup(targetVelocity) * _vDrop.Lookup(velocityDrop); + return LAC.Lookup(targetVelocity, velocityDrop); } - protected override void ParseData(DataTable table) {} - - private sealed class LACDecisionFactorVdrop : LookupData<MeterPerSecond, double> + /// <summary> + /// Class for Look Ahead Coasting Decision Factor (DF_coast) + /// </summary> + private sealed class DecisionFactor : LookupData<MeterPerSecond, MeterPerSecond, double> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vdrop.csv"; + private readonly LACDecisionFactorVTarget _vTarget = new LACDecisionFactorVTarget(); + private readonly LACDecisionFactorVdrop _vDrop = new LACDecisionFactorVdrop(); - public LACDecisionFactorVdrop() + public override double Lookup(MeterPerSecond targetVelocity, MeterPerSecond velocityDrop) { - ParseData(ReadCsvResource(ResourceId)); + // normalize values inverse from [0 .. 1] to [2.5 .. 1] + return 2.5 - 1.5 * _vTarget.Lookup(targetVelocity) * _vDrop.Lookup(velocityDrop); } - public override double Lookup(MeterPerSecond targetVelocity) - { - var section = Data.GetSection(kv => kv.Key < targetVelocity); - return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, section.Item1.Value, section.Item2.Value, - targetVelocity); - } + protected override void ParseData(DataTable table) {} - protected override void ParseData(DataTable table) + private sealed class LACDecisionFactorVdrop : LookupData<MeterPerSecond, double> { - if (table.Columns.Count < 2) { - throw new VectoException("LAC Decision Factor File for Vdrop must consist of at least 2 columns."); - } + private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vdrop.csv"; - if (table.Rows.Count < 2) { - throw new VectoException( - "LAC Decision Factor File for Vdrop must consist of at least two lines with numeric values (below file header)"); + public LACDecisionFactorVdrop() + { + ParseData(ReadCsvResource(ResourceId)); } - if (table.Columns.Contains("v_target") && table.Columns.Contains("decision_factor")) { - Data = table.Rows.Cast<DataRow>() - .ToDictionary(r => r.ParseDouble("v_drop").KMPHtoMeterPerSecond(), r => r.ParseDouble("decision_factor")); - } else { - Data = table.Rows.Cast<DataRow>() - .ToDictionary(r => r.ParseDouble(0).KMPHtoMeterPerSecond(), r => r.ParseDouble(1)); + public override double Lookup(MeterPerSecond targetVelocity) + { + var section = Data.GetSection(kv => kv.Key < targetVelocity); + return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, section.Item1.Value, section.Item2.Value, + targetVelocity); } - } - } - private sealed class LACDecisionFactorVTarget : LookupData<MeterPerSecond, double> - { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vtarget.csv"; + protected override void ParseData(DataTable table) + { + if (table.Columns.Count < 2) { + throw new VectoException("LAC Decision Factor File for Vdrop must consist of at least 2 columns."); + } - public LACDecisionFactorVTarget() - { - ParseData(ReadCsvResource(ResourceId)); - } + if (table.Rows.Count < 2) { + throw new VectoException( + "LAC Decision Factor File for Vdrop must consist of at least two lines with numeric values (below file header)"); + } - public override double Lookup(MeterPerSecond targetVelocity) - { - var section = Data.GetSection(kv => kv.Key < targetVelocity); - return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, section.Item1.Value, section.Item2.Value, - targetVelocity); + if (table.Columns.Contains("v_target") && table.Columns.Contains("decision_factor")) { + Data = table.Rows.Cast<DataRow>() + .ToDictionary(r => r.ParseDouble("v_drop").KMPHtoMeterPerSecond(), r => r.ParseDouble("decision_factor")); + } else { + Data = table.Rows.Cast<DataRow>() + .ToDictionary(r => r.ParseDouble(0).KMPHtoMeterPerSecond(), r => r.ParseDouble(1)); + } + } } - protected override void ParseData(DataTable table) + private sealed class LACDecisionFactorVTarget : LookupData<MeterPerSecond, double> { - if (table.Columns.Count < 2) { - throw new VectoException("LAC Decision Factor File for Vtarget must consist of at least 2 columns."); + private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vtarget.csv"; + + public LACDecisionFactorVTarget() + { + ParseData(ReadCsvResource(ResourceId)); } - if (table.Rows.Count < 2) { - throw new VectoException( - "LAC Decision Factor File for Vtarget must consist of at least two lines with numeric values (below file header)"); + public override double Lookup(MeterPerSecond targetVelocity) + { + var section = Data.GetSection(kv => kv.Key < targetVelocity); + return VectoMath.Interpolate(section.Item1.Key, section.Item2.Key, section.Item1.Value, section.Item2.Value, + targetVelocity); } - if (table.Columns.Contains("v_target") && table.Columns.Contains("decision_factor")) { - Data = table.Rows.Cast<DataRow>() - .ToDictionary(r => r.ParseDouble("v_target").KMPHtoMeterPerSecond(), r => r.ParseDouble("decision_factor")); - } else { - Data = table.Rows.Cast<DataRow>() - .ToDictionary(r => r.ParseDouble(0).KMPHtoMeterPerSecond(), r => r.ParseDouble(1)); + protected override void ParseData(DataTable table) + { + if (table.Columns.Count < 2) { + throw new VectoException("LAC Decision Factor File for Vtarget must consist of at least 2 columns."); + } + + if (table.Rows.Count < 2) { + throw new VectoException( + "LAC Decision Factor File for Vtarget must consist of at least two lines with numeric values (below file header)"); + } + + if (table.Columns.Contains("v_target") && table.Columns.Contains("decision_factor")) { + Data = table.Rows.Cast<DataRow>() + .ToDictionary(r => r.ParseDouble("v_target").KMPHtoMeterPerSecond(), r => r.ParseDouble("decision_factor")); + } else { + Data = table.Rows.Cast<DataRow>() + .ToDictionary(r => r.ParseDouble(0).KMPHtoMeterPerSecond(), r => r.ParseDouble(1)); + } } } } diff --git a/VectoCore/VectoCoreTest/Models/Simulation/LACDecisionFactorTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/LACDecisionFactorTest.cs index 7616af9913fe0dd2169403ef0ca6058b5471b16b..39a76e1eb8d060af1f0ce003be36e237c7cc34b7 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/LACDecisionFactorTest.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/LACDecisionFactorTest.cs @@ -1,5 +1,4 @@ -using System.Diagnostics; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Tests.Utils; @@ -12,13 +11,11 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation [TestMethod] public void LAC_DF_Test() { - var lac = new LACDecisionFactor(); - for (var vVehicle = 0.SI<MeterPerSecond>(); vVehicle < 100.KMPHtoMeterPerSecond(); vVehicle += 1.KMPHtoMeterPerSecond()) { for (var vTarget = vVehicle; vTarget > 0; vTarget -= 1.KMPHtoMeterPerSecond()) { - var df_coast = lac.Lookup(vTarget, vVehicle - vTarget); + var df_coast = LACDecisionFactor.Lookup(vTarget, vVehicle - vTarget); if (vTarget < 48.KMPHtoMeterPerSecond()) AssertHelper.AreRelativeEqual(df_coast, 2.5, string.Format("vVehicle: {0}, vTarget: {1}", vVehicle, vTarget));