From 287d80b61743a448249e4c3549f2721bf764cf44 Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Tue, 10 May 2016 16:00:38 +0200
Subject: [PATCH] added Lookup Class for LAC Decision Factor

---
 .../Models/Declaration/LACDecisionFactor.cs   | 99 +++++++++++++++++++
 .../Resources/Declaration/LAC-DF-Vdrop.csv    |  5 +
 .../Resources/Declaration/LAC-DF-Vtarget.csv  |  5 +
 VectoCore/VectoCore/VectoCore.csproj          |  3 +
 4 files changed, 112 insertions(+)
 create mode 100644 VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs
 create mode 100644 VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vdrop.csv
 create mode 100644 VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vtarget.csv

diff --git a/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs
new file mode 100644
index 0000000000..c5d61b3958
--- /dev/null
+++ b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs
@@ -0,0 +1,99 @@
+using System.Data;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
+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>
+	{
+		private readonly LACDecisionFactorVTarget _vTarget = new LACDecisionFactorVTarget();
+		private readonly LACDecisionFactorVdrop _vDrop = new LACDecisionFactorVdrop();
+
+		public override 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);
+		}
+
+		protected override void ParseData(DataTable table) {}
+
+		private sealed class LACDecisionFactorVdrop : LookupData<MeterPerSecond, double>
+		{
+			private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vdrop.csv";
+
+			public LACDecisionFactorVdrop()
+			{
+				ParseData(ReadCsvResource(ResourceId));
+			}
+
+			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)
+			{
+				if (table.Columns.Count < 2) {
+					throw new VectoException("LAC Decision Factor File for Vdrop must consist of at least 2 columns.");
+				}
+
+				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)");
+				}
+
+				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));
+				}
+			}
+		}
+
+		private sealed class LACDecisionFactorVTarget : LookupData<MeterPerSecond, double>
+		{
+			private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vtarget.csv";
+
+			public LACDecisionFactorVTarget()
+			{
+				ParseData(ReadCsvResource(ResourceId));
+			}
+
+			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)
+			{
+				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));
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vdrop.csv b/VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vdrop.csv
new file mode 100644
index 0000000000..8fa9f00ab4
--- /dev/null
+++ b/VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vdrop.csv
@@ -0,0 +1,5 @@
+v_drop [km/h], decision_factor [-]
+-100          , 1
+9             , 1
+11            , 0
+100           , 0
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vtarget.csv b/VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vtarget.csv
new file mode 100644
index 0000000000..259f9639f2
--- /dev/null
+++ b/VectoCore/VectoCore/Resources/Declaration/LAC-DF-Vtarget.csv
@@ -0,0 +1,5 @@
+v_target [km/h], decision_factor [-]
+0              , 0
+48             , 0
+52             , 1
+100            , 1
\ No newline at end of file
diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj
index fa99d46a50..2f27bdd07c 100644
--- a/VectoCore/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore/VectoCore.csproj
@@ -130,6 +130,7 @@
     <Compile Include="Models\Declaration\AirDrag.cs" />
     <Compile Include="Models\Declaration\Fan.cs" />
     <Compile Include="Models\Declaration\HVAC.cs" />
+    <Compile Include="Models\Declaration\LACDecisionFactor.cs" />
     <Compile Include="Models\Declaration\PneumaticSystem.cs" />
     <Compile Include="Models\Declaration\PT1.cs" />
     <Compile Include="Models\Declaration\Rims.cs" />
@@ -306,6 +307,8 @@
       <Generator>TextTemplatingFileGenerator</Generator>
       <LastGenOutput>Version.cs</LastGenOutput>
     </None>
+    <EmbeddedResource Include="Resources\Declaration\LAC-DF-Vdrop.csv" />
+    <EmbeddedResource Include="Resources\Declaration\LAC-DF-Vtarget.csv" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Resources\Declaration\Report\4x2r.png" />
-- 
GitLab