From 404e5f620784f5fb14141765e6524bad8e7fac96 Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Mon, 22 Jun 2015 13:38:48 +0200
Subject: [PATCH] adding Electric System aux

---
 .../Models/Declaration/DeclarationData.cs     | 46 +++++++++++++++++++
 .../Models/Declaration/DeclarationSegments.cs |  4 +-
 VectoCore/Models/Declaration/LookupData.cs    | 22 +++++++++
 VectoCore/Models/Declaration/Mission.cs       |  2 +-
 VectoCore/Models/Declaration/MissionType.cs   |  6 ++-
 VectoCore/Models/Declaration/Segment.cs       |  5 +-
 .../Resources/Declaration/VACC/Truck.vacc     |  6 +++
 .../Resources/Declaration/VCDV/CoachBus.vcdv  | 27 +++++++++++
 .../Resources/Declaration/VCDV/RigidSolo.vcdv | 27 +++++++++++
 .../Declaration/VCDV/RigidTrailer.vcdv        | 27 +++++++++++
 .../Declaration/VCDV/TractorSemitrailer.vcdv  | 27 +++++++++++
 VectoCore/VectoCore.csproj                    |  5 ++
 VectoCoreTest/Models/DeclarationDataTest.cs   | 26 ++++++++++-
 13 files changed, 223 insertions(+), 7 deletions(-)
 create mode 100644 VectoCore/Resources/Declaration/VACC/Truck.vacc
 create mode 100644 VectoCore/Resources/Declaration/VCDV/CoachBus.vcdv
 create mode 100644 VectoCore/Resources/Declaration/VCDV/RigidSolo.vcdv
 create mode 100644 VectoCore/Resources/Declaration/VCDV/RigidTrailer.vcdv
 create mode 100644 VectoCore/Resources/Declaration/VCDV/TractorSemitrailer.vcdv

diff --git a/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/Models/Declaration/DeclarationData.cs
index 0c27989955..91a67e7774 100644
--- a/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/Models/Declaration/DeclarationData.cs
@@ -1,4 +1,8 @@
 using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.Declaration
 {
@@ -10,6 +14,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 		private readonly DeclarationWheels _wheels;
 		private readonly DeclarationPT1 _pt1;
 		private readonly AccelerationCurve _accelerationCurve;
+		private readonly ElectricSystem _electricSystem;
 
 		public static DeclarationWheels Wheels
 		{
@@ -36,6 +41,11 @@ namespace TUGraz.VectoCore.Models.Declaration
 			get { return Instance()._accelerationCurve; }
 		}
 
+		public static ElectricSystem ElectricSystem
+		{
+			get { return Instance()._electricSystem; }
+		}
+
 		private DeclarationData()
 		{
 			_wheels = new DeclarationWheels();
@@ -43,6 +53,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 			_segments = new DeclarationSegments();
 			_pt1 = new DeclarationPT1();
 			_accelerationCurve = new AccelerationCurve();
+			_electricSystem = new ElectricSystem();
 		}
 
 		private static DeclarationData Instance()
@@ -50,4 +61,39 @@ namespace TUGraz.VectoCore.Models.Declaration
 			return _instance ?? (_instance = new DeclarationData());
 		}
 	}
+
+	internal class ElectricSystem : LookupData<MissionType, string[], Watt>
+	{
+		private static string baseLine = "Baseline electric power consumption";
+		private Dictionary<Tuple<MissionType, string>, Watt> _data = new Dictionary<Tuple<MissionType, string>, Watt>();
+
+		protected override string ResourceId
+		{
+			get { return "TUGraz.VectoCore.Resources.Declaration.ES-Tech.csv"; }
+		}
+
+		protected override void ParseData(DataTable table)
+		{
+			foreach (DataRow row in table.Rows) {
+				var name = row.Field<string>("Technology");
+				foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) {
+					_data[Tuple.Create(mission, name)] = row.ParseDouble(mission.ToString()).SI<Watt>();
+				}
+			}
+		}
+
+		public override Watt Lookup(MissionType key1, string[] key2)
+		{
+			var sum = _data[Tuple.Create(key1, baseLine)];
+
+			foreach (var s in key2) {
+				if (_data.ContainsKey(Tuple.Create(key1, s))) {
+					sum -= _data[Tuple.Create(key1, s)];
+				} else {
+					Log.Warn("electric system technology not found.");
+				}
+			}
+			return sum;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/Declaration/DeclarationSegments.cs b/VectoCore/Models/Declaration/DeclarationSegments.cs
index bb40e5e125..ed0965f933 100644
--- a/VectoCore/Models/Declaration/DeclarationSegments.cs
+++ b/VectoCore/Models/Declaration/DeclarationSegments.cs
@@ -37,7 +37,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 				VehicleCategory = vehicleCategory,
 				AxleConfiguration = axleConfiguration,
 				HDVClass = row.Field<string>("hdv_class"),
-				VACC = row.Field<string>("vacc"),
+				AccelerationFile = RessourceHelper.ReadStream(ResourceNamespace + "VACC." + row.Field<string>("vacc")),
 				Missions = CreateMissions(grossVehicleMassRating, curbWeight, row).ToArray()
 			};
 			return segment;
@@ -63,7 +63,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 
 				var mission = new Mission {
 					MissionType = missionType,
-					VCDV = row.Field<string>(vcdvField),
+					CrossWindCorrectionFile = RessourceHelper.ReadStream(ResourceNamespace + "VCDV." + row.Field<string>(vcdvField)),
 					MassExtra = row.ParseDouble("massextra-" + missionType.ToString().ToLower()).SI<Kilogram>(),
 					CycleFile = RessourceHelper.ReadStream(ResourceNamespace + "MissionCycles." + missionType + ".vdri"),
 					AxleWeightDistribution = row.Field<string>(axleField).Split('/').ToDouble().Select(x => x / 100.0).ToArray()
diff --git a/VectoCore/Models/Declaration/LookupData.cs b/VectoCore/Models/Declaration/LookupData.cs
index 2932bce333..955d7a9554 100644
--- a/VectoCore/Models/Declaration/LookupData.cs
+++ b/VectoCore/Models/Declaration/LookupData.cs
@@ -39,4 +39,26 @@ namespace TUGraz.VectoCore.Models.Declaration
 			return retVal;
 		}
 	}
+
+	public abstract class LookupData<TKey1, TKey2, TValue>
+	{
+		[NonSerialized] protected ILog Log;
+		protected abstract string ResourceId { get; }
+		protected abstract void ParseData(DataTable table);
+		public abstract TValue Lookup(TKey1 key1, TKey2 key2);
+
+		protected LookupData()
+		{
+			Log = LogManager.GetLogger(GetType());
+			var csvFile = ReadCsvFile(ResourceId);
+			ParseData(csvFile);
+		}
+
+		protected DataTable ReadCsvFile(string resourceId)
+		{
+			var myAssembly = Assembly.GetExecutingAssembly();
+			var file = myAssembly.GetManifestResourceStream(resourceId);
+			return VectoCSVFile.ReadStream(file);
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/Declaration/Mission.cs b/VectoCore/Models/Declaration/Mission.cs
index a88edb8cd1..148934e551 100644
--- a/VectoCore/Models/Declaration/Mission.cs
+++ b/VectoCore/Models/Declaration/Mission.cs
@@ -7,7 +7,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 	public class Mission
 	{
 		public MissionType MissionType { get; set; }
-		public string VCDV { get; set; }
+		public Stream CrossWindCorrectionFile { get; set; }
 		public double[] AxleWeightDistribution { get; set; }
 		public double[] TrailerAxleWeightDistribution { get; set; }
 
diff --git a/VectoCore/Models/Declaration/MissionType.cs b/VectoCore/Models/Declaration/MissionType.cs
index aa68bc4b33..3c53bfa23d 100644
--- a/VectoCore/Models/Declaration/MissionType.cs
+++ b/VectoCore/Models/Declaration/MissionType.cs
@@ -1,4 +1,8 @@
-namespace TUGraz.VectoCore.Models
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace TUGraz.VectoCore.Models
 {
 	public enum MissionType
 	{
diff --git a/VectoCore/Models/Declaration/Segment.cs b/VectoCore/Models/Declaration/Segment.cs
index 2ab8be003e..2e34c439ae 100644
--- a/VectoCore/Models/Declaration/Segment.cs
+++ b/VectoCore/Models/Declaration/Segment.cs
@@ -1,4 +1,5 @@
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using System.IO;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.Declaration
@@ -11,7 +12,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 		public Kilogram GrossVehicleWeightMax { get; set; }
 
 		public string HDVClass { get; internal set; }
-		public string VACC { get; internal set; }
+		public Stream AccelerationFile { get; internal set; }
 		public Mission[] Missions { get; internal set; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Resources/Declaration/VACC/Truck.vacc b/VectoCore/Resources/Declaration/VACC/Truck.vacc
new file mode 100644
index 0000000000..54e7786487
--- /dev/null
+++ b/VectoCore/Resources/Declaration/VACC/Truck.vacc
@@ -0,0 +1,6 @@
+v [km/h],acc [m/s²],dec [m/s²]
+0,1,-1
+25,1,-1
+50,0.642857143,-1
+60,0.5,-0.5
+120,0.5,-0.5
diff --git a/VectoCore/Resources/Declaration/VCDV/CoachBus.vcdv b/VectoCore/Resources/Declaration/VCDV/CoachBus.vcdv
new file mode 100644
index 0000000000..39a23feda9
--- /dev/null
+++ b/VectoCore/Resources/Declaration/VCDV/CoachBus.vcdv
@@ -0,0 +1,27 @@
+# Crosswind influence on CdxA as a function of vehicle speed
+# Vehicle category: coach bus
+# Absolute yaw angle influence from ACEA Whitebook April 2014
+# Average crosswind: 3 m/s
+# Baseline CdxA assumed with: 4.68 [m²]
+v_veh [km/h],cdx_rel [-]
+0,1.16368917057624
+5,1.16368917057624
+10,1.16368917057624
+15,1.16368917057624
+20,1.16368917057624
+25,1.16368917057624
+30,1.16368917057624
+35,1.16368917057624
+40,1.16368917057624
+45,1.16368917057624
+50,1.16368917057624
+55,1.16368917057624
+60,1.16368917057624
+65,1.14636945173252
+70,1.13130108969249
+75,1.11820564231065
+80,1.10682947645795
+85,1.09694460329622
+90,1.08828107916225
+95,1.08068278133074
+100,1.07400028829548
diff --git a/VectoCore/Resources/Declaration/VCDV/RigidSolo.vcdv b/VectoCore/Resources/Declaration/VCDV/RigidSolo.vcdv
new file mode 100644
index 0000000000..934c3e5825
--- /dev/null
+++ b/VectoCore/Resources/Declaration/VCDV/RigidSolo.vcdv
@@ -0,0 +1,27 @@
+# Crosswind influence on CdxA as a function of vehicle speed
+# Vehicle category: rigid solo
+# Absolute yaw angle influence from ACEA Whitebook April 2014
+# Average crosswind: 3 m/s
+# Baseline CdxA assumed with: 5.3 [m²]
+v_veh [km/h],cdx_rel (v_veh) [-]
+0,1.16995889058525
+5,1.16995889058525
+10,1.16995889058525
+15,1.16995889058525
+20,1.16995889058525
+25,1.16995889058525
+30,1.16995889058525
+35,1.16995889058525
+40,1.16995889058525
+45,1.16995889058525
+50,1.16995889058525
+55,1.16995889058525
+60,1.16995889058525
+65,1.14969968431834
+70,1.13284015316129
+75,1.11867388752005
+80,1.10667545890928
+85,1.09644348982345
+90,1.08762853580613
+95,1.07999428002092
+100,1.07334468074717
diff --git a/VectoCore/Resources/Declaration/VCDV/RigidTrailer.vcdv b/VectoCore/Resources/Declaration/VCDV/RigidTrailer.vcdv
new file mode 100644
index 0000000000..205473b64f
--- /dev/null
+++ b/VectoCore/Resources/Declaration/VCDV/RigidTrailer.vcdv
@@ -0,0 +1,27 @@
+# Crosswind influence on CdxA as a function of vehicle speed
+# Vehicle category: rigid trailer
+# Absolute yaw angle influence from ACEA Whitebook April 2014
+# Average crosswind: 3 m/s
+# Baseline CdxA assumed with: 6.33 [m²]
+v_veh [km/h],cdx_rel (v_veh) [-]
+0,1.35547110023335
+5,1.35547110023335
+10,1.35547110023335
+15,1.35547110023335
+20,1.35547110023335
+25,1.35547110023335
+30,1.35547110023335
+35,1.35547110023335
+40,1.35547110023335
+45,1.35547110023335
+50,1.35547110023335
+55,1.35547110023335
+60,1.35547110023335
+65,1.32382413546552
+70,1.29486615012693
+75,1.26877023747113
+80,1.24548620694966
+85,1.22484426801493
+90,1.20642747216762
+95,1.19005025706557
+100,1.17548319913321
diff --git a/VectoCore/Resources/Declaration/VCDV/TractorSemitrailer.vcdv b/VectoCore/Resources/Declaration/VCDV/TractorSemitrailer.vcdv
new file mode 100644
index 0000000000..50cfff436b
--- /dev/null
+++ b/VectoCore/Resources/Declaration/VCDV/TractorSemitrailer.vcdv
@@ -0,0 +1,27 @@
+# Crosswind influence on CdxA as a function of vehicle speed
+# Vehicle category: tractor semitrailer
+# Absolute yaw angle influence from ACEA Whitebook April 2014
+# Average crosswind: 3 m/s
+# Baseline CdxA assumed with: 5.7 [m²]
+v_veh [km/h],cdx_rel [-]
+0,1.27614894491372
+5,1.27614894491372
+10,1.27614894491372
+15,1.27614894491372
+20,1.27614894491372
+25,1.27614894491372
+30,1.27614894491372
+35,1.27614894491372
+40,1.27614894491372
+45,1.27614894491372
+50,1.27614894491372
+55,1.27614894491372
+60,1.27614894491372
+65,1.24890735180796
+70,1.22499288657568
+75,1.20405384590645
+80,1.18574578066132
+85,1.1697448123524
+90,1.15564641074318
+95,1.14321982822533
+100,1.13223910374519
diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj
index 8329b85d59..a1dc00e0c2 100644
--- a/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore.csproj
@@ -233,6 +233,11 @@
     <EmbeddedResource Include="Resources\Declaration\MissionCycles\UrbanDelivery.vdri" />
     <EmbeddedResource Include="Resources\Declaration\PT1.csv" />
     <EmbeddedResource Include="Resources\Declaration\AccelerationFile.vacc" />
+    <EmbeddedResource Include="Resources\Declaration\VACC\Truck.vacc" />
+    <EmbeddedResource Include="Resources\Declaration\VCDV\CoachBus.vcdv" />
+    <EmbeddedResource Include="Resources\Declaration\VCDV\RigidSolo.vcdv" />
+    <EmbeddedResource Include="Resources\Declaration\VCDV\RigidTrailer.vcdv" />
+    <EmbeddedResource Include="Resources\Declaration\VCDV\TractorSemitrailer.vcdv" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
diff --git a/VectoCoreTest/Models/DeclarationDataTest.cs b/VectoCoreTest/Models/DeclarationDataTest.cs
index d054f3d960..b84aa0af1a 100644
--- a/VectoCoreTest/Models/DeclarationDataTest.cs
+++ b/VectoCoreTest/Models/DeclarationDataTest.cs
@@ -1,4 +1,6 @@
 using System;
+using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -125,7 +127,29 @@ namespace TUGraz.VectoCore.Tests.Models
 		[TestMethod]
 		public void AuxEXTechTest()
 		{
-			Assert.Inconclusive();
+			var es = DeclarationData.ElectricSystem;
+
+			var expected = new[] {
+				new { Mission = MissionType.LongHaul, Base = 1240, LED = 1190 },
+				new { Mission = MissionType.RegionalDelivery, Base = 1055, LED = 1005 },
+				new { Mission = MissionType.UrbanDelivery, Base = 974, LED = 924 },
+				new { Mission = MissionType.MunicipalUtility, Base = 975, LED = 925 },
+				new { Mission = MissionType.Construction, Base = 0, LED = 0 },
+				new { Mission = MissionType.HeavyUrban, Base = 0, LED = 0 },
+				new { Mission = MissionType.Urban, Base = 0, LED = 0 },
+				new { Mission = MissionType.Suburban, Base = 0, LED = 0 },
+				new { Mission = MissionType.Interurban, Base = 0, LED = 0 },
+				new { Mission = MissionType.Coach, Base = 0, LED = 0 }
+			};
+			Assert.AreEqual(expected.Length, Enum.GetValues(typeof(MissionType)).Length);
+
+			foreach (var expectation in expected) {
+				Watt baseConsumption = es.Lookup(expectation.Mission, technologies = new string[] { });
+				Watt withLEDs = es.Lookup(expectation.Mission, technologies = new[] { "LED lights" });
+
+				Assert.AreEqual(expectation.Base, baseConsumption.Double(), Tolerance);
+				Assert.AreEqual(expectation.LED, withLEDs.Double(), Tolerance);
+			}
 		}
 
 		[TestMethod]
-- 
GitLab