From 9e698fa8208b77e5a29d114f0caa381e3041bc3d Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Wed, 11 May 2016 12:03:17 +0200
Subject: [PATCH] LAC Decision Factor

---
 .../Models/Declaration/LACDecisionFactor.cs   | 130 ++++++++++--------
 .../Simulation/LACDecisionFactorTest.cs       |   7 +-
 2 files changed, 72 insertions(+), 65 deletions(-)

diff --git a/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs
index 856481b2db..5c9ca9f40f 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 7616af9913..39a76e1eb8 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));
 
-- 
GitLab