From 12017ff721fdf8ead6deb4e5b38bf94b898e3921 Mon Sep 17 00:00:00 2001 From: Michael Krisper <michael.krisper@tugraz.at> Date: Tue, 23 Jun 2015 12:19:02 +0200 Subject: [PATCH] finished electric system, moved reading of acceleration file to components --- .../Models/Declaration/AccelerationCurve.cs | 61 ------------ .../Models/Declaration/DeclarationData.cs | 48 +-------- .../Models/Declaration/DeclarationSegments.cs | 24 ++--- .../Models/Declaration/ElectricSystem.cs | 49 ++++++++++ VectoCore/Models/Declaration/LookupData.cs | 39 ++++---- .../Data/AccelerationCurve.cs | 78 +++++++++++++++ .../Declaration/AccelerationFile.vacc | 6 -- .../Resources/Declaration/VAUX/ES-Tech.csv | 3 + .../Resources/Declaration/VAUX/Fan-Tech.csv | 12 +++ .../Resources/Declaration/VAUX/HVAC-Table.csv | 13 +++ .../Resources/Declaration/VAUX/PS-Table.csv | 13 +++ .../Resources/Declaration/VAUX/SP-Table.csv | 11 +++ .../Resources/Declaration/VAUX/SP-Tech.csv | 4 + VectoCore/Utils/DataRowExtensionMethods.cs | 4 + VectoCore/VectoCore.csproj | 10 +- VectoCoreTest/Models/DeclarationDataTest.cs | 97 ++++++++++--------- .../AccelerationCurveTest.cs | 83 ++++++++++++++++ .../GearboxDataTest.cs | 11 +-- VectoCoreTest/VectoCoreTest.csproj | 5 +- 19 files changed, 371 insertions(+), 200 deletions(-) delete mode 100644 VectoCore/Models/Declaration/AccelerationCurve.cs create mode 100644 VectoCore/Models/Declaration/ElectricSystem.cs create mode 100644 VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs delete mode 100644 VectoCore/Resources/Declaration/AccelerationFile.vacc create mode 100644 VectoCore/Resources/Declaration/VAUX/ES-Tech.csv create mode 100644 VectoCore/Resources/Declaration/VAUX/Fan-Tech.csv create mode 100644 VectoCore/Resources/Declaration/VAUX/HVAC-Table.csv create mode 100644 VectoCore/Resources/Declaration/VAUX/PS-Table.csv create mode 100644 VectoCore/Resources/Declaration/VAUX/SP-Table.csv create mode 100644 VectoCore/Resources/Declaration/VAUX/SP-Tech.csv create mode 100644 VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs diff --git a/VectoCore/Models/Declaration/AccelerationCurve.cs b/VectoCore/Models/Declaration/AccelerationCurve.cs deleted file mode 100644 index 5cd90094a0..0000000000 --- a/VectoCore/Models/Declaration/AccelerationCurve.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Declaration -{ - public class AccelerationCurve : LookupData<MeterPerSecond, AccelerationCurve.AccelerationEntry> - { - private List<KeyValuePair<MeterPerSecond, AccelerationEntry>> _entries; - - protected override string ResourceId - { - get { return "TUGraz.VectoCore.Resources.Declaration.AccelerationFile.vacc"; } - } - - protected override void ParseData(DataTable table) - { - _entries = table.Rows.Cast<DataRow>() - .Select(r => new KeyValuePair<MeterPerSecond, AccelerationEntry>( - r.ParseDouble("v").SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(), - new AccelerationEntry(r.ParseDouble("acc").SI<MeterPerSquareSecond>(), - r.ParseDouble("dec").SI<MeterPerSquareSecond>()))) - .OrderBy(x => x.Key) - .ToList(); - } - - public override AccelerationEntry Lookup(MeterPerSecond key) - { - var index = 1; - if (key < _entries[0].Key) { - Log.ErrorFormat("requested rpm below minimum rpm in pt1 - extrapolating. n: {0}, rpm_min: {1}", - key.ConvertTo().Rounds.Per.Minute, _entries[0].Key.ConvertTo().Rounds.Per.Minute); - } else { - index = _entries.FindIndex(x => x.Key > key); - if (index <= 0) { - index = (key > _entries[0].Key) ? _entries.Count - 1 : 1; - } - } - - var acc = VectoMath.Interpolate(_entries[index - 1].Key, _entries[index].Key, _entries[index - 1].Value.Acceleration, - _entries[index].Value.Acceleration, key); - var dec = VectoMath.Interpolate(_entries[index - 1].Key, _entries[index].Key, _entries[index - 1].Value.Deceleration, - _entries[index].Value.Deceleration, key); - - return new AccelerationEntry(acc, dec); - } - - public class AccelerationEntry - { - public AccelerationEntry(MeterPerSquareSecond acceleration, MeterPerSquareSecond deceleration) - { - Acceleration = acceleration; - Deceleration = deceleration; - } - - public MeterPerSquareSecond Acceleration { get; set; } - public MeterPerSquareSecond Deceleration { get; set; } - } - } -} \ No newline at end of file diff --git a/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/Models/Declaration/DeclarationData.cs index 91a67e7774..b903cc1134 100644 --- a/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/Models/Declaration/DeclarationData.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using TUGraz.VectoCore.Utils; +using System.Linq; namespace TUGraz.VectoCore.Models.Declaration { @@ -13,7 +9,6 @@ namespace TUGraz.VectoCore.Models.Declaration private readonly DeclarationRims _rims; private readonly DeclarationWheels _wheels; private readonly DeclarationPT1 _pt1; - private readonly AccelerationCurve _accelerationCurve; private readonly ElectricSystem _electricSystem; public static DeclarationWheels Wheels @@ -36,11 +31,6 @@ namespace TUGraz.VectoCore.Models.Declaration get { return Instance()._pt1; } } - public static AccelerationCurve AccelerationCurve - { - get { return Instance()._accelerationCurve; } - } - public static ElectricSystem ElectricSystem { get { return Instance()._electricSystem; } @@ -52,7 +42,6 @@ namespace TUGraz.VectoCore.Models.Declaration _rims = new DeclarationRims(); _segments = new DeclarationSegments(); _pt1 = new DeclarationPT1(); - _accelerationCurve = new AccelerationCurve(); _electricSystem = new ElectricSystem(); } @@ -61,39 +50,4 @@ 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 ed0965f933..9414323941 100644 --- a/VectoCore/Models/Declaration/DeclarationSegments.cs +++ b/VectoCore/Models/Declaration/DeclarationSegments.cs @@ -6,28 +6,30 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public class DeclarationSegments + public class DeclarationSegments : LookupData<VehicleCategory, AxleConfiguration, Kilogram, Kilogram, Segment> { private const string ResourceNamespace = "TUGraz.VectoCore.Resources.Declaration."; - private const string ResourceName = ResourceNamespace + "SegmentTable.csv"; - private readonly DataTable _segmentTable; - - public DeclarationSegments() + protected override string ResourceId { - var file = RessourceHelper.ReadStream(ResourceName); - _segmentTable = VectoCSVFile.ReadStream(file); + get { return ResourceNamespace + "SegmentTable.csv"; } + } + protected override void ParseData(DataTable table) + { // normalize column names, remove whitespaces and lowercase - foreach (DataColumn col in _segmentTable.Columns) { - _segmentTable.Columns[col.ColumnName].ColumnName = col.ColumnName.ToLower().Replace(" ", ""); + foreach (DataColumn col in table.Columns) { + table.Columns[col.ColumnName].ColumnName = col.ColumnName.ToLower().Replace(" ", ""); } + SegmentTable = table.Copy(); } - public Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, + private DataTable SegmentTable { get; set; } + + public override Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, Kilogram grossVehicleMassRating, Kilogram curbWeight) { - var row = _segmentTable.Rows.Cast<DataRow>().First(r => r.Field<string>("tvehcat") == vehicleCategory.ToString() + var row = SegmentTable.Rows.Cast<DataRow>().First(r => r.Field<string>("tvehcat") == vehicleCategory.ToString() && r.Field<string>("taxleconf") == axleConfiguration.GetName() && r.ParseDouble("gvw_min").SI<Ton>() <= grossVehicleMassRating && r.ParseDouble("gvw_max").SI<Ton>() > grossVehicleMassRating); diff --git a/VectoCore/Models/Declaration/ElectricSystem.cs b/VectoCore/Models/Declaration/ElectricSystem.cs new file mode 100644 index 0000000000..64d749a9cd --- /dev/null +++ b/VectoCore/Models/Declaration/ElectricSystem.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public class ElectricSystem : LookupData<MissionType, string[], Watt> + { + private const string BaseLine = "Baseline electric power consumption"; + + private readonly Dictionary<Tuple<MissionType, string>, Watt> _data = + new Dictionary<Tuple<MissionType, string>, Watt>(); + + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.ES-Tech.csv"; } + } + + protected override void ParseData(DataTable table) + { + foreach (DataColumn col in table.Columns) { + table.Columns[col.ColumnName].ColumnName = col.ColumnName.ToLower().Replace(" ", ""); + } + + 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().ToLower()).SI<Watt>(); + } + } + } + + public override Watt Lookup(MissionType missionType, string[] technologies) + { + var sum = _data[Tuple.Create(missionType, BaseLine)]; + + foreach (var s in technologies) { + if (_data.ContainsKey(Tuple.Create(missionType, s))) { + // todo: ask raphael why these technologies have to be subtracted? + sum -= _data[Tuple.Create(missionType, s)]; + } else { + Log.Warn("electric system technology not found."); + } + } + return sum; + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Declaration/LookupData.cs b/VectoCore/Models/Declaration/LookupData.cs index 955d7a9554..7959bfdc13 100644 --- a/VectoCore/Models/Declaration/LookupData.cs +++ b/VectoCore/Models/Declaration/LookupData.cs @@ -7,7 +7,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public abstract class LookupData<TKeyType, TEntryType> + public abstract class LookupData { protected LookupData() { @@ -21,18 +21,22 @@ namespace TUGraz.VectoCore.Models.Declaration protected abstract string ResourceId { get; } protected abstract void ParseData(DataTable table); - protected Dictionary<TKeyType, TEntryType> Data; - protected DataTable ReadCsvFile(string resourceId) { var myAssembly = Assembly.GetExecutingAssembly(); var file = myAssembly.GetManifestResourceStream(resourceId); return VectoCSVFile.ReadStream(file); } + } + - public virtual TEntryType Lookup(TKeyType key) + public abstract class LookupData<TKey, TValue> : LookupData + { + protected Dictionary<TKey, TValue> Data; + + public virtual TValue Lookup(TKey key) { - var retVal = default(TEntryType); + var retVal = default(TValue); if (Data.ContainsKey(key)) { retVal = Data[key]; } @@ -40,25 +44,18 @@ namespace TUGraz.VectoCore.Models.Declaration } } - public abstract class LookupData<TKey1, TKey2, TValue> + public abstract class LookupData<TKey1, TKey2, TValue> : LookupData { - [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); - } + public abstract class LookupData<TKey1, TKey2, TKey3, TValue> : LookupData + { + public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3); + } - protected DataTable ReadCsvFile(string resourceId) - { - var myAssembly = Assembly.GetExecutingAssembly(); - var file = myAssembly.GetManifestResourceStream(resourceId); - return VectoCSVFile.ReadStream(file); - } + public abstract class LookupData<TKey1, TKey2, TKey3, TKey4, TValue> : LookupData + { + public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3, TKey4 key4); } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs b/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs new file mode 100644 index 0000000000..3bff8e315e --- /dev/null +++ b/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using TUGraz.VectoCore.Exceptions; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Data +{ + public class AccelerationCurveData : SimulationComponentData + { + private List<KeyValuePair<MeterPerSecond, AccelerationEntry>> _entries; + + public static AccelerationCurveData ReadFromStream(Stream stream) + { + var data = VectoCSVFile.ReadStream(stream); + return ParseData(data); + } + + public static AccelerationCurveData ReadFromFile(string fileName) + { + var data = VectoCSVFile.Read(fileName); + return ParseData(data); + } + + private static AccelerationCurveData ParseData(DataTable data) + { + if (data.Columns.Count != 3) { + throw new VectoException("Acceleration Limiting File must consist of 3 columns."); + } + + if (data.Rows.Count < 2) { + throw new VectoException("Acceleration Limiting File must consist of at least two entries."); + } + + return new AccelerationCurveData { + _entries = data.Rows.Cast<DataRow>() + .Select(r => new KeyValuePair<MeterPerSecond, AccelerationEntry>( + r.ParseDouble("v").SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(), + new AccelerationEntry { + Acceleration = r.ParseDouble("acc").SI<MeterPerSquareSecond>(), + Deceleration = r.ParseDouble("dec").SI<MeterPerSquareSecond>() + })) + .OrderBy(x => x.Key) + .ToList() + }; + } + + public AccelerationEntry Lookup(MeterPerSecond key) + { + var index = 1; + if (key < _entries[0].Key) { + Log.ErrorFormat("requested velocity below minimum - extrapolating. velocity: {0}, min: {1}", + key.ConvertTo().Kilo.Meter.Per.Hour, _entries[0].Key.ConvertTo().Kilo.Meter.Per.Hour); + } else { + index = _entries.FindIndex(x => x.Key > key); + if (index <= 0) { + index = (key > _entries[0].Key) ? _entries.Count - 1 : 1; + } + } + + return new AccelerationEntry { + Acceleration = + VectoMath.Interpolate(_entries[index - 1].Key, _entries[index].Key, _entries[index - 1].Value.Acceleration, + _entries[index].Value.Acceleration, key), + Deceleration = + VectoMath.Interpolate(_entries[index - 1].Key, _entries[index].Key, _entries[index - 1].Value.Deceleration, + _entries[index].Value.Deceleration, key) + }; + } + + public class AccelerationEntry + { + public MeterPerSquareSecond Acceleration { get; set; } + public MeterPerSquareSecond Deceleration { get; set; } + } + } +} \ No newline at end of file diff --git a/VectoCore/Resources/Declaration/AccelerationFile.vacc b/VectoCore/Resources/Declaration/AccelerationFile.vacc deleted file mode 100644 index 54e7786487..0000000000 --- a/VectoCore/Resources/Declaration/AccelerationFile.vacc +++ /dev/null @@ -1,6 +0,0 @@ -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/VAUX/ES-Tech.csv b/VectoCore/Resources/Declaration/VAUX/ES-Tech.csv new file mode 100644 index 0000000000..66df1bda5b --- /dev/null +++ b/VectoCore/Resources/Declaration/VAUX/ES-Tech.csv @@ -0,0 +1,3 @@ +Technology,Long haul,Regional delivery,Urban delivery,Municipal utility,Construction,Heavy Urban,Urban,Suburban,Interurban,Coach +Baseline electric power consumption,1240,1055,974,974,975,0,0,0,0,0 +LED lights,-50,-50,-50,-50,-50,0,0,0,0,0 diff --git a/VectoCore/Resources/Declaration/VAUX/Fan-Tech.csv b/VectoCore/Resources/Declaration/VAUX/Fan-Tech.csv new file mode 100644 index 0000000000..6f2a7ad9b3 --- /dev/null +++ b/VectoCore/Resources/Declaration/VAUX/Fan-Tech.csv @@ -0,0 +1,12 @@ +Technology,Long haul,Regional delivery,Urban delivery,Municipal utility,Construction,Heavy Urban,Urban,Suburban,Interurban,Coach +Crankshaft mounted - Electronically controlled visco clutch (Default),618,671,516,566,1037,0,0,0,0,0 +Crankshaft mounted - Bimetallic controlled visco clutch,818,871,676,766,1277,0,0,0,0,0 +Crankshaft mounted - Discrete step clutch,668,721,616,616,1157,0,0,0,0,0 +Crankshaft mounted - On/Off clutch,718,771,666,666,1237,0,0,0,0,0 +Belt driven or driven via transm. - Electronically controlled visco clutch,889,944,733,833,1378,0,0,0,0,0 +Belt driven or driven via transm. - Bimetallic controlled visco clutch,1089,1144,893,1033,1618,0,0,0,0,0 +Belt driven or driven via transm. - Discrete step clutch,939,994,883,883,1498,0,0,0,0,0 +Belt driven or driven via transm. - On/Off clutch,989,1044,933,933,1578,0,0,0,0,0 +Hydraulic driven - Variable displacement pump,738,955,632,717,1672,0,0,0,0,0 +Hydraulic driven - Constant displacement pump,1000,1200,800,900,2100,0,0,0,0,0 +Hydraulic driven - Electronically controlled,700,800,600,600,1400,0,0,0,0,0 diff --git a/VectoCore/Resources/Declaration/VAUX/HVAC-Table.csv b/VectoCore/Resources/Declaration/VAUX/HVAC-Table.csv new file mode 100644 index 0000000000..e259441670 --- /dev/null +++ b/VectoCore/Resources/Declaration/VAUX/HVAC-Table.csv @@ -0,0 +1,13 @@ +HDV Class / Power,Long haul,Regional delivery,Urban delivery,Municipal utility,Construction,Heavy Urban,Urban,Suburban,Interurban,Coach +1,0,150,150,0,0,0,0,0,0,0 +2,200,200,150,0,0,0,0,0,0,0 +3,0,200,150,0,0,0,0,0,0,0 +4,350,200,0,300,0,0,0,0,0,0 +5,350,200,0,0,0,0,0,0,0,0 +6,0,0,0,0,0,0,0,0,0,0 +7,0,0,0,0,200,0,0,0,0,0 +8,0,0,0,0,0,0,0,0,0,0 +9,350,200,0,300,0,0,0,0,0,0 +10,350,200,0,0,0,0,0,0,0,0 +11,0,0,0,0,200,0,0,0,0,0 +12,0,0,0,0,200,0,0,0,0,0 diff --git a/VectoCore/Resources/Declaration/VAUX/PS-Table.csv b/VectoCore/Resources/Declaration/VAUX/PS-Table.csv new file mode 100644 index 0000000000..312d745fc1 --- /dev/null +++ b/VectoCore/Resources/Declaration/VAUX/PS-Table.csv @@ -0,0 +1,13 @@ +HDV Class / Power,Long haul,Regional delivery,Urban delivery,Municipal utility,Construction,Heavy Urban,Urban,Suburban,Interurban,Coach +1,0,1.3,1.24,0,0,0,0,0,0,0 +2,1.18,1.28,1.32,0,0,0,0,0,0,0 +3,0,1.36,1.38,0,0,0,0,0,0,0 +4,1.3,1.34,0,0,0,0,0,0,0,0 +5,1.34,1.82,0,0,0,0,0,0,0,0 +6,0,0,0,0,0,0,0,0,0,0 +7,0,0,0,0,0,0,0,0,0,0 +8,0,0,0,0,0,0,0,0,0,0 +9,1.34,1.54,0,0,0,0,0,0,0,0 +10,1.34,1.82,0,0,0,0,0,0,0,0 +11,0,0,0,0,0,0,0,0,0,0 +12,0,0,0,0,0,0,0,0,0,0 diff --git a/VectoCore/Resources/Declaration/VAUX/SP-Table.csv b/VectoCore/Resources/Declaration/VAUX/SP-Table.csv new file mode 100644 index 0000000000..53a2136afe --- /dev/null +++ b/VectoCore/Resources/Declaration/VAUX/SP-Table.csv @@ -0,0 +1,11 @@ +HDV Class / Power demand per share,Long haul,Regional delivery,Urban delivery,Municipal utility,Construction,Heavy Urban,Urban,Suburban,Interurban,Coach +1,0,110/130/20/0,100/120/20/30,0,0,0,0,0,0,0 +2,150/190/30/0,130/160/30/0,120/140/20/30,0,0,0,0,0,0,0 +3,0,140/170/30/0,130/150/30/40,0,0,0,0,0,0,0 +4,230/280/100/0,220/270/40/0,0,220/270/40/0,0,0,0,0,0,0 +5,270/330/120/0,250/290/90/0,220/260/80/60,0,0,0,0,0,0,0 +6,0,0,0,0,0,0,0,0,0,0 +7,0,0,0,0,0,0,0,0,0,0 +8,0,0,0,0,0,0,0,0,0,0 +9,270/330/120/0,220/270/60/0,0,220/270/60/0,0,0,0,0,0,0 +10,200/250/120/0,200/240/90/0,0,0,0,0,0,0,0,0 diff --git a/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv b/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv new file mode 100644 index 0000000000..ca7ebfb783 --- /dev/null +++ b/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv @@ -0,0 +1,4 @@ +Scaling Factors,U,F,B,S +Fixed displacement,1,1,1,1 +Variable displacement,0.6,0.6,0.6,0.6 +Hydraulic supported by electric,0.7,1,0.9,0.9 diff --git a/VectoCore/Utils/DataRowExtensionMethods.cs b/VectoCore/Utils/DataRowExtensionMethods.cs index 98a6dbf09e..5b91b0f7a8 100644 --- a/VectoCore/Utils/DataRowExtensionMethods.cs +++ b/VectoCore/Utils/DataRowExtensionMethods.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Globalization; using TUGraz.VectoCore.Exceptions; @@ -26,6 +27,9 @@ namespace TUGraz.VectoCore.Utils public static double ParseDouble(this DataRow row, string columnName) { + if (!row.Table.Columns.Contains(columnName)) { + throw new KeyNotFoundException(string.Format("Column {0} was not found in DataRow.", columnName)); + } return row.ParseDouble(row.Table.Columns[columnName]); } diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index a1dc00e0c2..02d81f8265 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -122,9 +122,10 @@ <Compile Include="Models\Connector\Ports\Impl\Response.cs" /> <Compile Include="Models\Connector\Ports\IFvPort.cs" /> <Compile Include="Models\Connector\Ports\ITnPort.cs" /> - <Compile Include="Models\Declaration\AccelerationCurve.cs" /> + <Compile Include="Models\SimulationComponent\Data\AccelerationCurve.cs" /> <Compile Include="Models\Declaration\DeclarationData.cs" /> <Compile Include="Models\Declaration\DeclarationPT1.cs" /> + <Compile Include="Models\Declaration\ElectricSystem.cs" /> <Compile Include="Models\Declaration\LookupData.cs" /> <Compile Include="Models\Declaration\Declaration.cs" /> <Compile Include="Models\Declaration\DeclarationWheels.cs" /> @@ -232,12 +233,17 @@ <EmbeddedResource Include="Resources\Declaration\MissionCycles\RegionalDelivery.vdri" /> <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" /> + <EmbeddedResource Include="Resources\Declaration\VAUX\ES-Tech.csv" /> + <EmbeddedResource Include="Resources\Declaration\VAUX\Fan-Tech.csv" /> + <EmbeddedResource Include="Resources\Declaration\VAUX\HVAC-Table.csv" /> + <EmbeddedResource Include="Resources\Declaration\VAUX\PS-Table.csv" /> + <EmbeddedResource Include="Resources\Declaration\VAUX\SP-Table.csv" /> + <EmbeddedResource Include="Resources\Declaration\VAUX\SP-Tech.csv" /> </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 b84aa0af1a..7e1e4ece13 100644 --- a/VectoCoreTest/Models/DeclarationDataTest.cs +++ b/VectoCoreTest/Models/DeclarationDataTest.cs @@ -7,6 +7,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models; using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Tests.Models @@ -94,47 +95,17 @@ namespace TUGraz.VectoCore.Tests.Models Assert.Inconclusive(); } - - public void EqualAcceleration(double velocity, double acceleration, double deceleration) - { - var entry = DeclarationData.AccelerationCurve.Lookup(velocity.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>()); - Assert.AreEqual(entry.Acceleration.Double(), acceleration, Tolerance); - Assert.AreEqual(entry.Deceleration.Double(), deceleration, Tolerance); - } - [TestMethod] - public void AccelerationTest() - { - // FIXED POINTS - EqualAcceleration(0, 1, -1); - EqualAcceleration(25, 1, -1); - EqualAcceleration(50, 0.642857143, -1); - EqualAcceleration(60, 0.5, -0.5); - EqualAcceleration(120, 0.5, -0.5); - - // INTERPOLATED POINTS - EqualAcceleration(20, 1, -1); - EqualAcceleration(40, 0.785714286, -1); - EqualAcceleration(55, 0.571428572, -0.75); - EqualAcceleration(80, 0.5, -0.5); - EqualAcceleration(100, 0.5, -0.5); - - // EXTRAPOLATE - EqualAcceleration(-20, 1, -1); - EqualAcceleration(140, 0.5, -0.5); - } - - [TestMethod] - public void AuxEXTechTest() + public void AuxESTechTest() { 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.LongHaul, Base = 1240, LED = 1290 }, + new { Mission = MissionType.RegionalDelivery, Base = 1055, LED = 1105 }, + new { Mission = MissionType.UrbanDelivery, Base = 974, LED = 1024 }, + new { Mission = MissionType.MunicipalUtility, Base = 974, LED = 1024 }, + new { Mission = MissionType.Construction, Base = 975, LED = 1025 }, new { Mission = MissionType.HeavyUrban, Base = 0, LED = 0 }, new { Mission = MissionType.Urban, Base = 0, LED = 0 }, new { Mission = MissionType.Suburban, Base = 0, LED = 0 }, @@ -144,8 +115,8 @@ namespace TUGraz.VectoCore.Tests.Models 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" }); + var baseConsumption = es.Lookup(expectation.Mission, technologies: new string[] { }); + var withLEDs = es.Lookup(expectation.Mission, technologies: new[] { "LED lights" }); Assert.AreEqual(expectation.Base, baseConsumption.Double(), Tolerance); Assert.AreEqual(expectation.LED, withLEDs.Double(), Tolerance); @@ -202,12 +173,18 @@ namespace TUGraz.VectoCore.Tests.Models Assert.AreEqual("2", segment.HDVClass); - Assert.AreEqual("Truck.vacc", segment.VACC); + + var data = AccelerationCurveData.ReadFromStream(segment.AccelerationFile); + TestAcceleration(data); + Assert.AreEqual(3, segment.Missions.Length); var longHaulMission = segment.Missions[0]; Assert.AreEqual(MissionType.LongHaul, longHaulMission.MissionType); - Assert.AreEqual("RigidSolo.vcdv", longHaulMission.VCDV); + + Assert.IsNotNull(longHaulMission.CrossWindCorrectionFile); + Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(longHaulMission.CrossWindCorrectionFile).ReadLine())); + Assert.IsTrue(new[] { 0.4, 0.6 }.SequenceEqual(longHaulMission.AxleWeightDistribution)); Assert.IsTrue(new double[] { }.SequenceEqual(longHaulMission.TrailerAxleWeightDistribution)); Assert.AreEqual(1900.SI<Kilogram>(), longHaulMission.MassExtra); @@ -220,10 +197,12 @@ namespace TUGraz.VectoCore.Tests.Models Assert.AreEqual(vehicleData.GrossVehicleMassRating - longHaulMission.MassExtra - vehicleData.CurbWeight, longHaulMission.MaxLoad); - var regionalDeliveryMission = segment.Missions[1]; Assert.AreEqual(MissionType.RegionalDelivery, regionalDeliveryMission.MissionType); - Assert.AreEqual("RigidSolo.vcdv", regionalDeliveryMission.VCDV); + + Assert.IsNotNull(regionalDeliveryMission.CrossWindCorrectionFile); + Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(regionalDeliveryMission.CrossWindCorrectionFile).ReadLine())); + Assert.IsTrue(new[] { 0.45, 0.55 }.SequenceEqual(regionalDeliveryMission.AxleWeightDistribution)); Assert.IsTrue(new double[] { }.SequenceEqual(regionalDeliveryMission.TrailerAxleWeightDistribution)); Assert.AreEqual(1900.SI<Kilogram>(), regionalDeliveryMission.MassExtra); @@ -236,10 +215,12 @@ namespace TUGraz.VectoCore.Tests.Models Assert.AreEqual(vehicleData.GrossVehicleMassRating - regionalDeliveryMission.MassExtra - vehicleData.CurbWeight, regionalDeliveryMission.MaxLoad); - var urbanDeliveryMission = segment.Missions[2]; Assert.AreEqual(MissionType.UrbanDelivery, urbanDeliveryMission.MissionType); - Assert.AreEqual("RigidSolo.vcdv", urbanDeliveryMission.VCDV); + + Assert.IsNotNull(urbanDeliveryMission.CrossWindCorrectionFile); + Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(urbanDeliveryMission.CrossWindCorrectionFile).ReadLine())); + Assert.IsTrue(new[] { 0.45, 0.55 }.SequenceEqual(urbanDeliveryMission.AxleWeightDistribution)); Assert.IsTrue(new double[] { }.SequenceEqual(urbanDeliveryMission.TrailerAxleWeightDistribution)); Assert.AreEqual(1900.SI<Kilogram>(), urbanDeliveryMission.MassExtra); @@ -294,5 +275,33 @@ namespace TUGraz.VectoCore.Tests.Models // } //} } + + public void EqualAcceleration(AccelerationCurveData data, double velocity, double acceleration, double deceleration) + { + var entry = data.Lookup(velocity.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>()); + Assert.AreEqual(entry.Acceleration.Double(), acceleration, Tolerance); + Assert.AreEqual(entry.Deceleration.Double(), deceleration, Tolerance); + } + + public void TestAcceleration(AccelerationCurveData data) + { + // FIXED POINTS + EqualAcceleration(data, 0, 1, -1); + EqualAcceleration(data, 25, 1, -1); + EqualAcceleration(data, 50, 0.642857143, -1); + EqualAcceleration(data, 60, 0.5, -0.5); + EqualAcceleration(data, 120, 0.5, -0.5); + + // INTERPOLATED POINTS + EqualAcceleration(data, 20, 1, -1); + EqualAcceleration(data, 40, 0.785714286, -1); + EqualAcceleration(data, 55, 0.571428572, -0.75); + EqualAcceleration(data, 80, 0.5, -0.5); + EqualAcceleration(data, 100, 0.5, -0.5); + + // EXTRAPOLATE + EqualAcceleration(data, -20, 1, -1); + EqualAcceleration(data, 140, 0.5, -0.5); + } } } \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs b/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs new file mode 100644 index 0000000000..7519b6863f --- /dev/null +++ b/VectoCoreTest/Models/SimulationComponentData/AccelerationCurveTest.cs @@ -0,0 +1,83 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData +{ + [TestClass] + public class AccelerationCurveTest + { + public const double Tolerance = 0.0001; + public AccelerationCurveData Data; + + public void EqualAcceleration(double velocity, double acceleration, double deceleration) + { + var entry = Data.Lookup(velocity.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>()); + Assert.AreEqual(entry.Acceleration.Double(), acceleration, Tolerance); + Assert.AreEqual(entry.Deceleration.Double(), deceleration, Tolerance); + } + + [TestMethod] + public void AccelerationTest() + { + Data = AccelerationCurveData.ReadFromFile(@"TestData\Components\Coach.vacc"); + + // FIXED POINTS + EqualAcceleration(0, 1.01570922360353, -0.231742702878269); + EqualAcceleration(5, 1.38546581120225, -0.45346198022574); + EqualAcceleration(10, 1.34993329755465, -0.565404125020508); + EqualAcceleration(15, 1.29026714002479, -0.703434814668512); + EqualAcceleration(20, 1.16369598822194, -0.677703399378421); + EqualAcceleration(25, 1.04024417156355, -0.63631961226452); + EqualAcceleration(30, 0.910278494884728, -0.548894523516266); + EqualAcceleration(35, 0.785875078338323, -0.453995336940216); + EqualAcceleration(40, 0.69560012996407, -0.385460695652016); + EqualAcceleration(45, 0.648984223443223, -0.349181329186105); + EqualAcceleration(50, 0.594249623931624, -0.309125096967231); + EqualAcceleration(55, 0.559156929181929, -0.296716093796643); + EqualAcceleration(60, 0.541508805860806, -0.270229542673924); + EqualAcceleration(65, 0.539582904761905, -0.256408113084341); + EqualAcceleration(70, 0.539103523809524, -0.217808535739946); + EqualAcceleration(75, 0.529581598997494, -0.18609307386602); + EqualAcceleration(80, 0.496418462064251, -0.142683384645006); + EqualAcceleration(85, 0.453932619248656, -0.117950211164234); + EqualAcceleration(90, 0.397824554210839, -0.102997621205622); + EqualAcceleration(95, 0.33969661577071, -0.102997621205622); + EqualAcceleration(100, 0.289428370365158, -0.102997621205622); + EqualAcceleration(105, 0.256471472751248, -0.102997621205622); + EqualAcceleration(110, 0.24, -0.102997621205622); + EqualAcceleration(115, 0.22, -0.102997621205622); + EqualAcceleration(120, 0.2, -0.102997621205622); + + // INTERPOLATED POINTS + EqualAcceleration(0, 1.015709224, -0.231742703); + EqualAcceleration(2.5, 1.200587517, -0.342602342); + EqualAcceleration(7.5, 1.367699554, -0.509433053); + EqualAcceleration(12.5, 1.320100219, -0.63441947); + EqualAcceleration(17.5, 1.226981564, -0.690569107); + EqualAcceleration(22.5, 1.10197008, -0.657011506); + EqualAcceleration(27.5, 0.975261333, -0.592607068); + EqualAcceleration(32.5, 0.848076787, -0.50144493); + EqualAcceleration(37.5, 0.740737604, -0.419728016); + EqualAcceleration(42.5, 0.672292177, -0.367321012); + EqualAcceleration(47.5, 0.621616924, -0.329153213); + EqualAcceleration(52.5, 0.576703277, -0.302920595); + EqualAcceleration(57.5, 0.550332868, -0.283472818); + EqualAcceleration(62.5, 0.540545855, -0.263318828); + EqualAcceleration(67.5, 0.539343214, -0.237108324); + EqualAcceleration(72.5, 0.534342561, -0.201950805); + EqualAcceleration(77.5, 0.513000031, -0.164388229); + EqualAcceleration(82.5, 0.475175541, -0.130316798); + EqualAcceleration(87.5, 0.425878587, -0.110473916); + EqualAcceleration(92.5, 0.368760585, -0.102997621); + EqualAcceleration(97.5, 0.314562493, -0.102997621); + EqualAcceleration(102.5, 0.272949922, -0.102997621); + EqualAcceleration(107.5, 0.248235736, -0.102997621); + EqualAcceleration(112.5, 0.23, -0.102997621); + EqualAcceleration(117.5, 0.21, -0.102997621); + + // EXTRAPOLATE + EqualAcceleration(130, 0.16, -0.103); + } + } +} \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs b/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs index e604c1e876..b244798b84 100644 --- a/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs +++ b/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs @@ -68,9 +68,6 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestMethod] public void TestInputOutOfRange() { - var rdyn = 520.0; - //var speed = double.Parse(TestContext.DataRow["v"].ToString(), CultureInfo.InvariantCulture); - var gbxData = GearboxData.ReadFromFile(GearboxFile); @@ -81,7 +78,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels); Assert.Fail("angular Speed too high"); } catch (Exception e) { - Assert.IsInstanceOfType(e, typeof (VectoSimulationException), "angular speed too high"); + Assert.IsInstanceOfType(e, typeof(VectoSimulationException), "angular speed too high"); } angSpeed = 1000.RPMtoRad(); @@ -90,7 +87,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels); Assert.Fail("torque too high"); } catch (Exception e) { - Assert.IsInstanceOfType(e, typeof (VectoSimulationException), "torque too high"); + Assert.IsInstanceOfType(e, typeof(VectoSimulationException), "torque too high"); } angSpeed = 1000.RPMtoRad(); @@ -99,7 +96,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels); Assert.Fail("torque too low"); } catch (Exception e) { - Assert.IsInstanceOfType(e, typeof (VectoSimulationException), "torque too low"); + Assert.IsInstanceOfType(e, typeof(VectoSimulationException), "torque too low"); } angSpeed = -1000.RPMtoRad(); @@ -108,7 +105,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels); Assert.Fail("negative angular speed"); } catch (Exception e) { - Assert.IsInstanceOfType(e, typeof (VectoSimulationException), "negative angular speed"); + Assert.IsInstanceOfType(e, typeof(VectoSimulationException), "negative angular speed"); } } diff --git a/VectoCoreTest/VectoCoreTest.csproj b/VectoCoreTest/VectoCoreTest.csproj index 0ab02b720d..d7ae801e17 100644 --- a/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCoreTest/VectoCoreTest.csproj @@ -71,6 +71,7 @@ <Compile Include="Exceptions\ExceptionTests.cs" /> <Compile Include="Integration\EngineOnlyCycle\EngineOnlyCycleTest.cs" /> <Compile Include="Models\DeclarationDataTest.cs" /> + <Compile Include="Models\SimulationComponentData\AccelerationCurveTest.cs" /> <Compile Include="Models\SimulationComponentData\FuelConsumptionMapTest.cs" /> <Compile Include="Models\SimulationComponentData\FullLoadCurveTest.cs" /> <Compile Include="Models\SimulationComponentData\GearboxDataTest.cs" /> @@ -131,7 +132,9 @@ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> <None Include="TestData\Components\24t_Coach_ALT.vaux" /> - <None Include="TestData\Components\Coach.vacc" /> + <None Include="TestData\Components\Coach.vacc"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> <None Include="TestData\Components\FullLoadCurve insufficient columns.vfld"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> -- GitLab