diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index 5174534314af747bc016b9c84aa2565047440822..4d9fe9a9585e99eb140847d0619e00eee0188f87 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -337,7 +337,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter return points; } - protected static SquareMeter ComputeDeltaCd(double beta, AirDrag.AirDragEntry values) + protected static SquareMeter ComputeDeltaCd(double beta, AirDrag.Entry values) { return (values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta).SI<SquareMeter>(); } diff --git a/VectoCore/VectoCore/Models/Declaration/AirDrag.cs b/VectoCore/VectoCore/Models/Declaration/AirDrag.cs index 119d3bf3d44e59d7c49d8fb7c5926f2f053aaa89..a0d21640c2c8cd852c58ca03d3cf390e6a0f58a8 100644 --- a/VectoCore/VectoCore/Models/Declaration/AirDrag.cs +++ b/VectoCore/VectoCore/Models/Declaration/AirDrag.cs @@ -37,25 +37,26 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class AirDrag : LookupData<string, AirDrag.AirDragEntry> + public sealed class AirDrag : LookupData<string, AirDrag.Entry> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VCDV.parameters.csv"; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.VCDV.parameters.csv"; } + } - public AirDrag() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { throw new NotImplementedException(); } } protected override void ParseData(DataTable table) { - Data = table.Rows.Cast<DataRow>().ToDictionary(row => row.Field<string>("Parameters"), row => new AirDragEntry { - A1 = row.ParseDouble("a1"), - A2 = row.ParseDouble("a2"), - A3 = row.ParseDouble("a3") - }); + Data = table.Rows.Cast<DataRow>().ToDictionary( + row => row.Field<string>("Parameters"), + row => new Entry(row.ParseDouble("a1"), row.ParseDouble("a2"), row.ParseDouble("a3"))); } - public AirDragEntry Lookup(VehicleCategory category) + public Entry Lookup(VehicleCategory category) { switch (category) { case VehicleCategory.CityBus: @@ -71,39 +72,17 @@ namespace TUGraz.VectoCore.Models.Declaration } } - public class AirDragEntry + public class Entry { - public double A1 { get; set; } - public double A2 { get; set; } - public double A3 { get; set; } - - protected bool Equals(AirDragEntry other) - { - return A1.Equals(other.A1) && A2.Equals(other.A2) && A3.Equals(other.A3); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != GetType()) { - return false; - } - return Equals((AirDragEntry)obj); - } + public double A1; + public double A2; + public double A3; - public override int GetHashCode() + public Entry(double a1, double a2, double a3) { - unchecked { - var hashCode = A1.GetHashCode(); - hashCode = (hashCode * 397) ^ A2.GetHashCode(); - hashCode = (hashCode * 397) ^ A3.GetHashCode(); - return hashCode; - } + A1 = a1; + A2 = a2; + A3 = a3; } } } diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 592758e8df095caff2c199e4261277f5a0382581..bcf0887dc66e249c6dc692b0fb0b472027332055 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -97,7 +97,7 @@ namespace TUGraz.VectoCore.Models.Declaration try { var rimsEntry = Rims.Lookup(rims); - var correction = wheelsEntry.SizeClass != "a" ? rimsEntry.F_b : rimsEntry.F_a; + var correction = wheelsEntry.SizeClass != "a" ? rimsEntry.Fb : rimsEntry.Fa; return wheelsEntry.DynamicTyreRadius * correction / (2 * Math.PI); } catch (KeyNotFoundException) { diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationRims.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationRims.cs index f9522e8812e9b8c85e5019fb37b7dc9e06ce12fb..dc35a4ba56063969a4fe14ef29a3c539b4977cec 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationRims.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationRims.cs @@ -35,31 +35,37 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public class DeclarationRims : LookupData<string, DeclarationRims.RimsEntry> + public sealed class DeclarationRims : LookupData<string, DeclarationRims.RimsEntry> { - protected string ResourceId = "TUGraz.VectoCore.Resources.Declaration.Rims.csv"; - - public DeclarationRims() + protected override string ResourceId { - ParseData(ReadCsvResource(ResourceId)); + get { return "TUGraz.VectoCore.Resources.Declaration.Rims.csv"; } } + protected override string ErrorMessage + { + get { return "Auxiliary Lookup Error: No value found for Rims. Key: '{0}'"; } + } - protected override sealed void ParseData(DataTable table) + protected override void ParseData(DataTable table) { - Data = (from DataRow row in table.Rows - select new RimsEntry { - RimsType = row[0].ToString(), - F_a = row.ParseDouble(1), - F_b = row.ParseDouble(2) - }).ToDictionary(e => e.RimsType); + Data = table.Rows.Cast<DataRow>() + .Select(row => new RimsEntry(row[0].ToString(), row.ParseDouble(1), row.ParseDouble(2))) + .ToDictionary(e => e.RimsType); } public class RimsEntry { public string RimsType; - public double F_a; - public double F_b; + public double Fa; + public double Fb; + + public RimsEntry(string rimsType, double fa, double fb) + { + RimsType = rimsType; + Fa = fa; + Fb = fb; + } } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs b/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs index 3d3e787b42b492fcdd4d95c6ecd393fa55a80131..5293685895a4c23b90b24af14d662270cd1bbcba 100644 --- a/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs +++ b/VectoCore/VectoCore/Models/Declaration/ElectricSystem.cs @@ -30,98 +30,75 @@ */ using System; -using System.Collections.Generic; using System.Data; -using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class ElectricSystem : LookupData<MissionType, string[], Watt> + public sealed class ElectricSystem : LookupData<MissionType, string, Watt> { private readonly Alternator _alternator = new Alternator(); - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.ES-Tech.csv"; - 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"; } + } - public ElectricSystem() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { return "Auxiliary Lookup Error: No value found for Electric System. Mission: '{0}', Technology: '{1}'"; } } protected override void ParseData(DataTable table) { + Data.Clear(); NormalizeTable(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().ToLower()).SI<Watt>(); + Data[Tuple.Create(mission, name)] = row.ParseDouble(mission.ToString().ToLower()).SI<Watt>(); } } } - public override Watt Lookup(MissionType missionType, string[] technologies) + public override Watt Lookup(MissionType missionType, string technology) { - var sum = _data[Tuple.Create(missionType, BaseLine)]; - - if (technologies != null) { - foreach (var technology in technologies) { - try { - sum += _data[Tuple.Create(missionType, technology)]; - } catch (KeyNotFoundException) { - throw new VectoException( - "Auxiliary Lookup Error: No value found for Electric System with mission '{0}' and technology '{1}'", - missionType, technology); - } - } - } - - return sum / _alternator.Lookup(missionType, null); + var value = base.Lookup(missionType, technology); + return value / _alternator.Lookup(missionType); } internal sealed class Alternator : LookupData<MissionType, string, double> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.ALT-Tech.csv"; - private const string Default = "Standard alternator"; - - private readonly Dictionary<Tuple<MissionType, string>, double> _data = - new Dictionary<Tuple<MissionType, string>, double>(); + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.ALT-Tech.csv"; } + } - public Alternator() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { return "Auxiliary Lookup Error: No value found for Alternator. Mission: '{0}', Technology: '{1}'"; } } protected override void ParseData(DataTable table) { + Data.Clear(); NormalizeTable(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().ToLower()); + var name = row.Field<string>("technology"); + foreach (DataColumn col in table.Columns) { + if (col.Caption != "technology") { + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), name)] = row.ParseDouble(col); + } } } } - public override double Lookup(MissionType missionType, string technology) + public override double Lookup(MissionType missionType, string technology = "Standard alternator") { - if (string.IsNullOrWhiteSpace(technology)) { - technology = Default; - } - - try { - return _data[Tuple.Create(missionType, technology)]; - } catch (KeyNotFoundException) { - throw new VectoException( - "Auxiliary Lookup Error: No value found for Alternator with mission '{0}' and technology '{1}'", - missionType, technology); - } + return base.Lookup(missionType, technology); } } } diff --git a/VectoCore/VectoCore/Models/Declaration/Fan.cs b/VectoCore/VectoCore/Models/Declaration/Fan.cs index e3aa0a43a97d57fcd0f3d4ba88e92d9c0142f798..3103fda578519355723160e3e37cbf2d0efd456e 100644 --- a/VectoCore/VectoCore/Models/Declaration/Fan.cs +++ b/VectoCore/VectoCore/Models/Declaration/Fan.cs @@ -30,9 +30,7 @@ */ using System; -using System.Collections.Generic; using System.Data; -using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -40,43 +38,35 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class Fan : LookupData<MissionType, string, Watt> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.Fan-Tech.csv"; - private const string DefaultTechnology = "Crankshaft mounted - Electronically controlled visco clutch (Default)"; - - private readonly Dictionary<Tuple<MissionType, string>, Watt> _data = - new Dictionary<Tuple<MissionType, string>, Watt>(); - - public Fan() + protected override string ResourceId { - ParseData(ReadCsvResource(ResourceId)); + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.Fan-Tech.csv"; } } + protected override string ErrorMessage + { + get { return "Auxiliary Lookup Error: No value found for Fan. Mission: '{0}', Technology: '{1}'"; } + } protected override void ParseData(DataTable table) { + Data.Clear(); NormalizeTable(table); - _data.Clear(); foreach (DataRow row in table.Rows) { - foreach (var mission in EnumHelper.GetValues<MissionType>()) { - _data[Tuple.Create(mission, row.Field<string>("Technology"))] = - row.ParseDouble(mission.ToString().ToLower()).SI<Watt>(); + var name = row.Field<string>("technology"); + foreach (DataColumn col in table.Columns) { + if (col.Caption != "technology") { + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), name)] = row.ParseDouble(col).SI<Watt>(); + } } } } - public override Watt Lookup(MissionType mission, string technology) + public override Watt Lookup(MissionType mission, + string technology = "Crankshaft mounted - Electronically controlled visco clutch") { - if (string.IsNullOrWhiteSpace(technology)) { - technology = DefaultTechnology; - } - - try { - return _data[Tuple.Create(mission, technology)]; - } catch (KeyNotFoundException) { - throw new VectoException("Auxiliary Lookup Error: No value found for Fan with key '{0}' in mission '{1}'", - technology, mission); - } + return base.Lookup(mission, technology); } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/HVAC.cs b/VectoCore/VectoCore/Models/Declaration/HVAC.cs index a0a8201492a396b12f2384b124967d85c7791de2..aab0ac55b746589781dd00cf8ab986f3c0c18582 100644 --- a/VectoCore/VectoCore/Models/Declaration/HVAC.cs +++ b/VectoCore/VectoCore/Models/Declaration/HVAC.cs @@ -30,9 +30,7 @@ */ using System; -using System.Collections.Generic; using System.Data; -using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -40,34 +38,27 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class HeatingVentilationAirConditioning : LookupData<MissionType, VehicleClass, Watt> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.HVAC-Table.csv"; - private readonly Dictionary<Tuple<MissionType, VehicleClass>, Watt> _data = - new Dictionary<Tuple<MissionType, VehicleClass>, Watt>(); - - public HeatingVentilationAirConditioning() + protected override string ResourceId { - ParseData(ReadCsvResource(ResourceId)); + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.HVAC-Table.csv"; } } - public override Watt Lookup(MissionType mission, VehicleClass hdvClass) + protected override string ErrorMessage { - try { - return _data[Tuple.Create(mission, hdvClass)]; - } catch (KeyNotFoundException) { - throw new VectoException("Auxiliary Lookup Error: No value found for HVAC with mission '{0}' and HDVClass '{1}'", - mission, hdvClass); - } + get { return "Auxiliary Lookup Error: No value found for HVAC. Mission: '{0}', HDVClass: '{1}'"; } } protected override void ParseData(DataTable table) { - _data.Clear(); + Data.Clear(); NormalizeTable(table); foreach (DataRow row in table.Rows) { - var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass/power")); - foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) { - _data[Tuple.Create(mission, hdvClass)] = row.ParseDouble(mission.ToString().ToLower()).SI<Watt>(); + var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")); + foreach (DataColumn col in table.Columns) { + if (col.Caption != "hdvclass") { + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), hdvClass)] = row.ParseDouble(col.Caption).SI<Watt>(); + } } } } diff --git a/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs index 355a2d79956868017505d2c63f8619ed24e36059..c3319c6c0050a27b36270f4f08008e5c8347b201 100644 --- a/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs +++ b/VectoCore/VectoCore/Models/Declaration/LACDecisionFactor.cs @@ -37,70 +37,51 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public class LACDecisionFactor + /// <summary> + /// Class for Look Ahead Coasting Decision Factor (DF_coast) + /// </summary> + public sealed class LACDecisionFactor { - private readonly DecisionFactor LAC; + private readonly LACDecisionFactorVTarget _vTarget; + private readonly LACDecisionFactorVdrop _vDrop; + private readonly double _offset; + private readonly double _scaling; public LACDecisionFactor() { - LAC = new DecisionFactor(); + _offset = DeclarationData.Driver.LookAhead.DecisionFactorCoastingOffset; + _scaling = DeclarationData.Driver.LookAhead.DecisionFactorCoastingScaling; + _vTarget = new LACDecisionFactorVTarget(); + _vDrop = new LACDecisionFactorVdrop(); } public LACDecisionFactor(double offset, double scaling, DataTable vTargetLookup, DataTable vDropLookup) { - LAC = new DecisionFactor(offset, scaling, vTargetLookup, vDropLookup); + _offset = offset; + _scaling = scaling; + _vTarget = new LACDecisionFactorVTarget(vTargetLookup); + _vDrop = new LACDecisionFactorVdrop(vDropLookup); } public double Lookup(MeterPerSecond targetVelocity, MeterPerSecond velocityDrop) { - return LAC.Lookup(targetVelocity, velocityDrop); + // normalize values from [0 .. 1] to [2.5 .. 1] + return _offset - _scaling * _vTarget.Lookup(targetVelocity) * _vDrop.Lookup(velocityDrop); } - /// <summary> - /// Class for Look Ahead Coasting Decision Factor (DF_coast) - /// </summary> - public sealed class DecisionFactor : LookupData<MeterPerSecond, MeterPerSecond, double> + private sealed class LACDecisionFactorVdrop : LookupData<MeterPerSecond, double> { - private readonly LACDecisionFactorVTarget _vTarget; - private readonly LACDecisionFactorVdrop _vDrop; - private readonly double _offset; - private readonly double _scaling; - - public DecisionFactor(double offset, double scaling, DataTable vTargetLookup, DataTable vDropLookup) - { - _offset = offset; - _scaling = scaling; - _vTarget = new LACDecisionFactorVTarget(vTargetLookup); - _vDrop = new LACDecisionFactorVdrop(vDropLookup); - } - - public DecisionFactor() + protected override string ResourceId { - _offset = DeclarationData.Driver.LookAhead.DecisionFactorCoastingOffset; - _scaling = DeclarationData.Driver.LookAhead.DecisionFactorCoastingScaling; - _vTarget = new LACDecisionFactorVTarget(); - _vDrop = new LACDecisionFactorVdrop(); + get { return "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vdrop.csv"; } } - - public override double Lookup(MeterPerSecond targetVelocity, MeterPerSecond velocityDrop) + protected override string ErrorMessage { - // normalize values inverse from [0 .. 1] to [2.5 .. 1] - return _offset - _scaling * _vTarget.Lookup(targetVelocity) * _vDrop.Lookup(velocityDrop); + get { throw new System.NotImplementedException(); } } - - protected override void ParseData(DataTable table) {} - } - - public sealed class LACDecisionFactorVdrop : LookupData<MeterPerSecond, double> - { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vdrop.csv"; - - public LACDecisionFactorVdrop() - { - ParseData(ReadCsvResource(ResourceId)); - } + public LACDecisionFactorVdrop() {} public LACDecisionFactorVdrop(DataTable vDrop) { @@ -125,32 +106,31 @@ namespace TUGraz.VectoCore.Models.Declaration "LAC Decision Factor File for Vdrop must consist of at least two lines with numeric values (below file header)"); } - if (table.Columns.Contains(Fields.VelocityDrop) && table.Columns.Contains(Fields.DecisionFactor)) { + if (table.Columns.Contains("v_drop") && table.Columns.Contains("decision_factor")) { Data = table.Rows.Cast<DataRow>() - .ToDictionary(r => r.ParseDouble(Fields.VelocityDrop).KMPHtoMeterPerSecond(), - r => r.ParseDouble(Fields.DecisionFactor)); + .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 static class Fields - { - public const string VelocityDrop = "v_drop"; - public const string DecisionFactor = "decision_factor"; - } } - public sealed class LACDecisionFactorVTarget : LookupData<MeterPerSecond, double> + private sealed class LACDecisionFactorVTarget : LookupData<MeterPerSecond, double> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vtarget.csv"; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.LAC-DF-Vtarget.csv"; } + } - public LACDecisionFactorVTarget() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { throw new System.NotImplementedException(); } } + public LACDecisionFactorVTarget() {} + public LACDecisionFactorVTarget(DataTable vTargetLookup) { ParseData(vTargetLookup ?? ReadCsvResource(ResourceId)); @@ -174,21 +154,15 @@ namespace TUGraz.VectoCore.Models.Declaration "LAC Decision Factor File for Vtarget must consist of at least two lines with numeric values (below file header)"); } - if (table.Columns.Contains(Fields.TargetVelocity) && table.Columns.Contains(Fields.DecisionFactor)) { + if (table.Columns.Contains("v_target") && table.Columns.Contains("decision_factor")) { Data = table.Rows.Cast<DataRow>() - .ToDictionary(r => r.ParseDouble(Fields.TargetVelocity).KMPHtoMeterPerSecond(), - r => r.ParseDouble(Fields.DecisionFactor)); + .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)); } } - - public static class Fields - { - public const string TargetVelocity = "v_target"; - public const string DecisionFactor = "decision_factor"; - } } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/LookupData.cs b/VectoCore/VectoCore/Models/Declaration/LookupData.cs index 8fff0ce72410acec9106f6442951d8af8d0b5f4c..70ac3cb58bf77dd21c87aad6b32e434a315eb5c2 100644 --- a/VectoCore/VectoCore/Models/Declaration/LookupData.cs +++ b/VectoCore/VectoCore/Models/Declaration/LookupData.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.Data; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -40,6 +41,14 @@ namespace TUGraz.VectoCore.Models.Declaration { public abstract class LookupData : LoggingObject { + protected LookupData() + { + ParseData(ReadCsvResource(ResourceId)); + } + + protected abstract string ResourceId { get; } + protected abstract string ErrorMessage { get; } + protected abstract void ParseData(DataTable table); protected DataTable ReadCsvResource(string resourceId) @@ -67,7 +76,11 @@ namespace TUGraz.VectoCore.Models.Declaration public virtual TValue Lookup(TKey key) { - return Data[key]; + try { + return Data[key]; + } catch (KeyNotFoundException) { + throw new VectoException(string.Format(ErrorMessage, key)); + } } } @@ -77,13 +90,26 @@ namespace TUGraz.VectoCore.Models.Declaration public virtual TValue Lookup(TKey1 key1, TKey2 key2) { - return Data[Tuple.Create(key1, key2)]; + try { + return Data[new Tuple<TKey1, TKey2>(key1, key2)]; + } catch (KeyNotFoundException) { + throw new VectoException(string.Format(ErrorMessage, key1, key2)); + } } } public abstract class LookupData<TKey1, TKey2, TKey3, TValue> : LookupData { - public abstract TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3); + protected Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue> Data = new Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue>(); + + public virtual TValue Lookup(TKey1 key1, TKey2 key2, TKey3 key3) + { + try { + return Data[new Tuple<TKey1, TKey2, TKey3>(key1, key2, key3)]; + } catch (KeyNotFoundException) { + throw new VectoException(string.Format(ErrorMessage, key1, key2, key3)); + } + } } public abstract class LookupData<TKey1, TKey2, TKey3, TKey4, TValue> : LookupData diff --git a/VectoCore/VectoCore/Models/Declaration/PT1.cs b/VectoCore/VectoCore/Models/Declaration/PT1.cs index 4aae13967b97b2653c79f6b757daf33df4a6af4f..db88c2e9e115983ea4af701a8d1a4c5cd20c27fb 100644 --- a/VectoCore/VectoCore/Models/Declaration/PT1.cs +++ b/VectoCore/VectoCore/Models/Declaration/PT1.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -40,9 +41,18 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class PT1 : LookupData<PerSecond, Second> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.PT1.csv"; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.PT1.csv"; } + } + + protected override string ErrorMessage + { + get { throw new InvalidOperationException("ErrorMessage not applicable."); } + } + private List<KeyValuePair<PerSecond, Second>> _entries; - + public PT1() { ParseData(ReadCsvResource(ResourceId)); diff --git a/VectoCore/VectoCore/Models/Declaration/Payloads.cs b/VectoCore/VectoCore/Models/Declaration/Payloads.cs index 56495305f3da176a8ef80872c8a8e051955cae06..abf14d3cc6a82c56a7f7af06ec593d3ca62d06c3 100644 --- a/VectoCore/VectoCore/Models/Declaration/Payloads.cs +++ b/VectoCore/VectoCore/Models/Declaration/Payloads.cs @@ -39,23 +39,23 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class Payloads : LookupData<Kilogram, Payloads.PayloadEntry> { - public sealed class PayloadEntry + protected override string ResourceId { - public Kilogram Payload50Percent; - public Kilogram Payload75Percent; + get { return "TUGraz.VectoCore.Resources.Declaration.Payloads.csv"; } } - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.Payloads.csv"; - - public Payloads() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { throw new InvalidOperationException("ErrorMessage not applicable."); } } + /// <summary> + /// Obsolete. Call Lookup50Percent, Lookup75Percent or LookupTrailer instead! + /// </summary> [Obsolete("Call Lookup50Percent, Lookup75Percent or LookupTrailer!", true)] private new PayloadEntry Lookup(Kilogram grossVehicleWeight) { - throw new NotImplementedException("Call Lookup50Percent, Lookup75Percent or LookupTrailer!"); + throw new InvalidOperationException("Call Lookup50Percent, Lookup75Percent or LookupTrailer!"); } public Kilogram Lookup50Percent(Kilogram grossVehicleWeight) @@ -82,6 +82,7 @@ namespace TUGraz.VectoCore.Models.Declaration protected override void ParseData(DataTable table) { NormalizeTable(table); + Data = table.Rows.Cast<DataRow>() .ToDictionary( kv => kv.ParseDouble("grossvehicleweight").SI<Kilogram>(), @@ -90,5 +91,11 @@ namespace TUGraz.VectoCore.Models.Declaration Payload75Percent = kv.ParseDouble("payload75%").SI<Kilogram>() }); } + + public sealed class PayloadEntry + { + public Kilogram Payload50Percent; + public Kilogram Payload75Percent; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs b/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs index 3dbbfe6f2de33fe632be41abfe76b1a112c63b49..8af8363c1075bc169268997a6d6c1faaa0c3e78b 100644 --- a/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs +++ b/VectoCore/VectoCore/Models/Declaration/PneumaticSystem.cs @@ -30,9 +30,7 @@ */ using System; -using System.Collections.Generic; using System.Data; -using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -40,35 +38,25 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class PneumaticSystem : LookupData<MissionType, VehicleClass, Watt> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.PS-Table.csv"; - private readonly Dictionary<Tuple<MissionType, VehicleClass>, Watt> _data = - new Dictionary<Tuple<MissionType, VehicleClass>, Watt>(); - - public PneumaticSystem() + protected override string ResourceId { - ParseData(ReadCsvResource(ResourceId)); + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.PS-Table.csv"; } } - public override Watt Lookup(MissionType mission, VehicleClass hdvClass) + protected override string ErrorMessage { - try { - return _data[Tuple.Create(mission, hdvClass)]; - } catch (KeyNotFoundException) { - throw new VectoException( - "Auxiliary Lookup Error: No value found for Pneumatic System with mission '{0}' and HDVClass '{1}'", - mission, hdvClass); - } + get { return "Auxiliary Lookup Error: No value found for Pneumatic System. Mission: '{0}', HDVClass: '{1}'"; } } protected override void ParseData(DataTable table) { - _data.Clear(); + Data.Clear(); NormalizeTable(table); foreach (DataRow row in table.Rows) { var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass/power")); foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) { - _data[Tuple.Create(mission, hdvClass)] = row.ParseDouble(mission.ToString().ToLower()).SI<Watt>(); + Data[Tuple.Create(mission, hdvClass)] = row.ParseDouble(mission.ToString().ToLower()).SI<Watt>(); } } } diff --git a/VectoCore/VectoCore/Models/Declaration/Rims.cs b/VectoCore/VectoCore/Models/Declaration/Rims.cs index e6935f8606707112b34ceac1e66737ebe880ad47..b0337513aa96480e1490c948ec43a529487f7526 100644 --- a/VectoCore/VectoCore/Models/Declaration/Rims.cs +++ b/VectoCore/VectoCore/Models/Declaration/Rims.cs @@ -35,31 +35,33 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public class Rims : LookupData<string, Rims.RimsEntry> + public sealed class Rims : LookupData<string, Rims.Entry> { - protected const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.Rims.csv"; - - public Rims() + protected override string ResourceId { - ParseData(ReadCsvResource(ResourceId)); + get { return "TUGraz.VectoCore.Resources.Declaration.Rims.csv"; } } + protected override string ErrorMessage + { + get { return "Auxiliary Lookup Error: no value found for Rims. Key: '{0}'"; } + } - protected override sealed void ParseData(DataTable table) + protected override void ParseData(DataTable table) { - Data = (from DataRow row in table.Rows - select new RimsEntry { + Data = table.Rows.Cast<DataRow>() + .Select(row => new Entry { RimsType = row[0].ToString(), - F_a = row.ParseDouble(1), - F_b = row.ParseDouble(2) + Fa = row.ParseDouble(1), + Fb = row.ParseDouble(2) }).ToDictionary(e => e.RimsType); } - public class RimsEntry + public class Entry { public string RimsType; - public double F_a; - public double F_b; + public double Fa; + public double Fb; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/Segments.cs b/VectoCore/VectoCore/Models/Declaration/Segments.cs index 892732d581769fa50d65145a18a5d8068e26ad4f..28bef70c3846b77505d1b0e475bc682782780a66 100644 --- a/VectoCore/VectoCore/Models/Declaration/Segments.cs +++ b/VectoCore/VectoCore/Models/Declaration/Segments.cs @@ -43,21 +43,27 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class Segments : LookupData<VehicleCategory, AxleConfiguration, Kilogram, Kilogram, Segment> { - public Segments() + private DataTable _segmentTable; + + protected override string ResourceId { - ParseData(ReadCsvResource(RessourceHelper.Namespace + "SegmentTable.csv")); + get { return RessourceHelper.Namespace + "SegmentTable.csv"; } } - protected override void ParseData(DataTable table) + protected override string ErrorMessage { - // normalize column names, remove whitespaces and lowercase - foreach (DataColumn col in table.Columns) { - table.Columns[col.ColumnName].ColumnName = col.ColumnName.ToLower().RemoveWhitespace(); + get + { + return + "ERROR: Could not find the declaration segment for vehicle. Category: {0}, AxleConfiguration: {1}, GrossVehicleWeight: {2}"; } - SegmentTable = table.Copy(); } - private DataTable SegmentTable { get; set; } + protected override void ParseData(DataTable table) + { + NormalizeTable(table); + _segmentTable = table.Copy(); + } public override Segment Lookup(VehicleCategory vehicleCategory, AxleConfiguration axleConfiguration, Kilogram grossVehicleMassRating, Kilogram curbWeight) @@ -68,7 +74,7 @@ namespace TUGraz.VectoCore.Models.Declaration DataRow row; try { - row = SegmentTable.Rows.Cast<DataRow>().First(r => { + row = _segmentTable.Rows.Cast<DataRow>().First(r => { var isValid = r.Field<string>("valid"); var category = r.Field<string>("vehiclecategory"); var axleConf = r.Field<string>("axleconf."); @@ -83,9 +89,7 @@ namespace TUGraz.VectoCore.Models.Declaration && grossVehicleMassRating <= massMax; }); } catch (InvalidOperationException e) { - var errorMessage = string.Format( - "ERROR: Could not find the declaration segment for vehicle. Category: {0}, AxleConfiguration: {1}, GrossVehicleWeight: {2}", - vehicleCategory, axleConfiguration.GetName(), grossVehicleMassRating); + var errorMessage = string.Format(ErrorMessage, vehicleCategory, axleConfiguration.GetName(), grossVehicleMassRating); Log.Fatal(errorMessage); throw new VectoException(errorMessage, e); } @@ -117,12 +121,12 @@ namespace TUGraz.VectoCore.Models.Declaration : TrailerType.None; var trailer = trailerIsUsed ? DeclarationData.StandardBodies.Lookup(trailerField) - : DeclarationData.StandardBodies.Empty; + : StandardBodies.Empty; var semiTrailerField = row.Field<string>("semitrailer"); var semiTrailer = !string.IsNullOrWhiteSpace(semiTrailerField) ? DeclarationData.StandardBodies.Lookup(semiTrailerField) - : DeclarationData.StandardBodies.Empty; + : StandardBodies.Empty; trailer += semiTrailer; diff --git a/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs b/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs index aeecd0fbeff54fdcaa1f3dca7d6ce6eeafa79b77..9fc0ffb834e3dd0cf175b1d764945300d5946279 100644 --- a/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs +++ b/VectoCore/VectoCore/Models/Declaration/StandardBodies.cs @@ -29,10 +29,8 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System.Collections.Generic; using System.Data; using System.Linq; -using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -40,30 +38,30 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class StandardBody { - public StandardBody(Kilogram curbWeight, Kilogram grossVehicleWeight, SquareMeter deltaCrossWindArea, - Wheels.WheelsEntry wheels) - { - CurbWeight = curbWeight; - GrossVehicleWeight = grossVehicleWeight; - DeltaCrossWindArea = deltaCrossWindArea; - Wheels = wheels; - } - public Kilogram CurbWeight; public Kilogram GrossVehicleWeight; + public SquareMeter DeltaCrossWindArea; + public string Name; + public Wheels.Entry Wheels; public Kilogram MaxPayLoad { get { return GrossVehicleWeight - CurbWeight; } } - public SquareMeter DeltaCrossWindArea; - - public Wheels.WheelsEntry Wheels; + public StandardBody(string name, Kilogram curbWeight, Kilogram grossVehicleWeight, SquareMeter deltaCrossWindArea, + Wheels.Entry wheels) + { + Name = name; + CurbWeight = curbWeight; + GrossVehicleWeight = grossVehicleWeight; + DeltaCrossWindArea = deltaCrossWindArea; + Wheels = wheels; + } public static StandardBody operator +(StandardBody first, StandardBody second) { - return new StandardBody(first.CurbWeight + second.CurbWeight, + return new StandardBody(first.Name + second.Name, first.CurbWeight + second.CurbWeight, first.GrossVehicleWeight + second.GrossVehicleWeight, first.DeltaCrossWindArea + second.DeltaCrossWindArea, null); @@ -81,42 +79,36 @@ namespace TUGraz.VectoCore.Models.Declaration /// </summary> public sealed class StandardBodies : LookupData<string, StandardBody> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.Body_Trailers_Weights.csv"; + public static StandardBody Empty = new StandardBody("", 0.SI<Kilogram>(), 0.SI<Kilogram>(), 0.SI<SquareMeter>(), null); - public StandardBodies() + protected override string ResourceId { - ParseData(ReadCsvResource(ResourceId)); + get { return "TUGraz.VectoCore.Resources.Declaration.Body_Trailers_Weights.csv"; } } - public StandardBody Empty = new StandardBody(0.SI<Kilogram>(), 0.SI<Kilogram>(), 0.SI<SquareMeter>(), null); + protected override string ErrorMessage + { + get { return "StandardWeigths Lookup Error: No value found for ID '{0}'"; } + } public override StandardBody Lookup(string id) { - if (string.IsNullOrWhiteSpace(id)) { - return Empty; - } - - try { - return Data[id]; - } catch (KeyNotFoundException) { - throw new VectoException("StandardWeigths Lookup Error: No value found for ID '{0}'", id); - } + return string.IsNullOrWhiteSpace(id) ? Empty : base.Lookup(id); } protected override void ParseData(DataTable table) { NormalizeTable(table); - Data = table.Rows.Cast<DataRow>() - .ToDictionary( - kv => kv.Field<string>("name"), - kv => new StandardBody( - kv.ParseDoubleOrGetDefault("curbmass").SI<Kilogram>(), - kv.ParseDoubleOrGetDefault("maxgrossmass").SI<Kilogram>(), - kv.ParseDoubleOrGetDefault("deltacdxafortraileroperationinlonghaul").SI<SquareMeter>(), - !string.IsNullOrWhiteSpace(kv.Field<string>("wheels")) - ? DeclarationData.Wheels.Lookup(kv.Field<string>("wheels")) - : null)); + Data = table.Rows.Cast<DataRow>().Select(k => new StandardBody( + k.Field<string>("name"), + k.ParseDoubleOrGetDefault("curbmass").SI<Kilogram>(), + k.ParseDoubleOrGetDefault("maxgrossmass").SI<Kilogram>(), + k.ParseDoubleOrGetDefault("deltacdxafortraileroperationinlonghaul").SI<SquareMeter>(), + !string.IsNullOrWhiteSpace(k.Field<string>("wheels")) + ? DeclarationData.Wheels.Lookup(k.Field<string>("wheels")) + : null)) + .ToDictionary(kv => kv.Name); } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs b/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs index 426b6d172b756b7926bf503fe07afcba96b169d7..92a2a8aac82781c86992ce23bc370aca72aeef9b 100644 --- a/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs +++ b/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs @@ -33,36 +33,20 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; -using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class SteeringPump : LookupData<MissionType, VehicleClass, IEnumerable<string>, Watt> + public sealed class SteeringPump { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Table.csv"; - private readonly SteeringPumpTechnologies _technologies = new SteeringPumpTechnologies(); + private readonly SteeringPumpBaseLine _baseline = new SteeringPumpBaseLine(); private readonly SteeringPumpAxles _axles = new SteeringPumpAxles(); + private readonly SteeringPumpTechnologies _technologies = new SteeringPumpTechnologies(); - private readonly Dictionary<Tuple<MissionType, VehicleClass>, SteeringPumpValues<Watt>> _data = - new Dictionary<Tuple<MissionType, VehicleClass>, SteeringPumpValues<Watt>>(); - - public SteeringPump() - { - ParseData(ReadCsvResource(ResourceId)); - } - - public override Watt Lookup(MissionType mission, VehicleClass hdvClass, IEnumerable<string> technologies) + public Watt Lookup(MissionType mission, VehicleClass hdvClass, IEnumerable<string> technologies) { - SteeringPumpValues<Watt> powerShares; - try { - powerShares = _data[Tuple.Create(mission, hdvClass)]; - } catch (KeyNotFoundException) { - throw new VectoException( - "Auxiliary Lookup Error: No value found for Steering Pump. Mission: '{0}', HDVClass: '{1}'", mission, hdvClass); - } - + var powerShares = _baseline.Lookup(mission, hdvClass); var sum = 0.SI<Watt>(); var i = 1; foreach (var technology in technologies) { @@ -76,31 +60,46 @@ namespace TUGraz.VectoCore.Models.Declaration return sum; } - protected override void ParseData(DataTable table) + private sealed class SteeringPumpBaseLine : LookupData<MissionType, VehicleClass, SteeringPumpValues<Watt>> { - NormalizeTable(table); - _data.Clear(); - - foreach (DataRow row in table.Rows) { - var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass/powerdemandpershare")); - foreach (var mission in EnumHelper.GetValues<MissionType>()) { - var values = - row.Field<string>(mission.ToString().ToLower()).Split('/') - .Select(v => v.ToDouble() / 100.0).Concat(0.0.Repeat(3)).SI<Watt>().ToList(); - _data[Tuple.Create(mission, hdvClass)] = new SteeringPumpValues<Watt>(values[0], values[1], values[2]); + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Table.csv"; } + } + + protected override string ErrorMessage + { + get { return "Auxiliary Lookup Error: No value found for Steering Pump. Mission: '{0}', HDVClass: '{1}'"; } + } + + protected override void ParseData(DataTable table) + { + NormalizeTable(table); + Data.Clear(); + + foreach (DataRow row in table.Rows) { + var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass/powerdemandpershare")); + foreach (var mission in EnumHelper.GetValues<MissionType>()) { + var values = row.Field<string>(mission.ToString().ToLower()) + .Split('/').Select(v => v.ToDouble() / 100.0).Concat(0.0.Repeat(3)).SI<Watt>().ToList(); + Data[Tuple.Create(mission, hdvClass)] = new SteeringPumpValues<Watt>(values[0], values[1], values[2]); + } } } } - private sealed class SteeringPumpTechnologies : LookupData<string, SteeringPumpValues<double>> + private sealed class SteeringPumpTechnologies : LookupData<string, MissionType, SteeringPumpValues<double>> { private readonly ElectricSystem.Alternator _alternator = new ElectricSystem.Alternator(); - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Tech.csv"; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Tech.csv"; } + } - public SteeringPumpTechnologies() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { return "Auxiliary Lookup Error: No value found for SteeringPump Technology. Key: '{0}'"; } } protected override void ParseData(DataTable table) @@ -109,38 +108,31 @@ namespace TUGraz.VectoCore.Models.Declaration Data.Clear(); Data = table.Rows.Cast<DataRow>().ToDictionary( - key => key.Field<string>("Technology"), + key => Tuple.Create(key.Field<string>("Technology"), MissionType.LongHaul), value => new SteeringPumpValues<double>(value.ParseDouble("UF"), value.ParseDouble("B"), value.ParseDouble("S"))); } - [Obsolete("Use Lookup(string, MissionType) instead!", true)] - public new SteeringPumpValues<double> Lookup(string tech) + public override SteeringPumpValues<double> Lookup(string tech, MissionType mission) { - throw new NotImplementedException("Use Lookup(string, MissionType) instead!"); - } - - public SteeringPumpValues<double> Lookup(string tech, MissionType mission) - { - try { - var values = Data[tech]; - if (tech == "Electric") { - values.Banking /= _alternator.Lookup(mission, ""); - values.Steering /= _alternator.Lookup(mission, ""); - } - return values; - } catch (KeyNotFoundException) { - throw new VectoException("Auxiliary Lookup Error: No value found for SteeringPump Technology with key '{0}'", tech); + var values = base.Lookup(tech, MissionType.LongHaul); + if (tech == "Electric") { + values.Banking /= _alternator.Lookup(mission); + values.Steering /= _alternator.Lookup(mission); } + return values; } } private sealed class SteeringPumpAxles : LookupData<MissionType, int, SteeringPumpValues<double>> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Axles.csv"; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Axles.csv"; } + } - public SteeringPumpAxles() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { return "Auxiliary Lookup Error: No value found for SteeringPump Axle. Mission: '{0}', Axle Count: '{1}'"; } } protected override void ParseData(DataTable table) @@ -159,19 +151,19 @@ namespace TUGraz.VectoCore.Models.Declaration } } } - } - - internal struct SteeringPumpValues<T> - { - public T UnloadedFriction; - public T Banking; - public T Steering; - public SteeringPumpValues(T unloadedFriction, T banking, T steering) + private class SteeringPumpValues<T> { - UnloadedFriction = unloadedFriction; - Banking = banking; - Steering = steering; + public T UnloadedFriction; + public T Banking; + public T Steering; + + public SteeringPumpValues(T unloadedFriction, T banking, T steering) + { + UnloadedFriction = unloadedFriction; + Banking = banking; + Steering = steering; + } } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/TorqueConverter.cs b/VectoCore/VectoCore/Models/Declaration/TorqueConverter.cs index 9aa9837f63135794a7a34dcb24ed659679b1d40c..91903156d9803ffc6a4b42f869a822cc8e44f6dc 100644 --- a/VectoCore/VectoCore/Models/Declaration/TorqueConverter.cs +++ b/VectoCore/VectoCore/Models/Declaration/TorqueConverter.cs @@ -38,22 +38,28 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class TorqueConverter : LookupData<double, TorqueConverter.TorqueConverterEntry> { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.DefaultTC.vtcc"; - + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.DefaultTC.vtcc"; } + } + + protected override string ErrorMessage + { + get { throw new InvalidOperationException("ErrorMessage not applicable."); } + } + public TorqueConverter() { ParseData(ReadCsvResource(ResourceId)); } - - [Obsolete("Default Lookup not available. Use LookupMu or LookupTorque instead.", true)] + [Obsolete("Default Lookup not implemente. Use LookupMu or LookupTorque instead.", true)] private new TorqueConverterEntry Lookup(double key) { throw new InvalidOperationException( "Default Lookup not available. Use TorqueConverter.LookupMu() or TorqueConverter.LookupTorque() instead."); } - public NewtonMeter LookupTorque(double nu, PerSecond angularSpeedIn, PerSecond referenceSpeed) { var sec = Data.GetSection(kv => kv.Key < nu); @@ -77,7 +83,6 @@ namespace TUGraz.VectoCore.Models.Declaration return VectoMath.Interpolate(sec.Item1.Key, sec.Item2.Key, sec.Item1.Value.Mu, sec.Item2.Value.Mu, nu); } - protected override void ParseData(DataTable table) { Data.Clear(); diff --git a/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs b/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs index fa7e2073d3691837b01b32f479ef72998efe8994..06b305fffd088267fe3f23194c5759bcf229b0cf 100644 --- a/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs +++ b/VectoCore/VectoCore/Models/Declaration/WHTCCorrection.cs @@ -30,7 +30,6 @@ */ using System; -using System.Collections.Generic; using System.Data; using System.Linq; using TUGraz.VectoCommon.Utils; @@ -38,39 +37,45 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public sealed class WHTCCorrection : LookupData<MissionType, double, double, double, double> + public sealed class WHTCCorrection { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.WHTC-Weighting-Factors.csv"; - private readonly Dictionary<MissionType, WHTCCorrectionEntry> _data = - new Dictionary<MissionType, WHTCCorrectionEntry>(); - - public WHTCCorrection() - { - ParseData(ReadCsvResource(ResourceId)); - } + private readonly WHTCCorrectionData _data = new WHTCCorrectionData(); - public override double Lookup(MissionType mission, double rural, double urban, double motorway) + public double Lookup(MissionType mission, double rural, double urban, double motorway) { - var entry = _data[mission]; + var entry = _data.Lookup(mission); return rural * entry.Rural + urban * entry.Urban + motorway * entry.Motorway; } - - protected override void ParseData(DataTable table) + private sealed class WHTCCorrectionData : LookupData<MissionType, Entry> { - _data.Clear(); - NormalizeTable(table); - foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) { - var values = table.Columns[mission.ToString().ToLower()].Values<string>().ToDouble().ToArray(); - _data[mission] = new WHTCCorrectionEntry { Urban = values[0], Rural = values[1], Motorway = values[2] }; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.WHTC-Weighting-Factors.csv"; } + } + + protected override string ErrorMessage + { + get { return "WHTC Correction Lookup Error: no value found. Mission: '{0}'"; } + } + + protected override void ParseData(DataTable table) + { + NormalizeTable(table); + Data.Clear(); + + foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) { + var values = table.Columns[mission.ToString().ToLower()].Values<string>().ToDouble().ToArray(); + Data[mission] = new Entry { Urban = values[0], Rural = values[1], Motorway = values[2] }; + } } } - private class WHTCCorrectionEntry + private class Entry { - public double Rural { get; set; } - public double Urban { get; set; } - public double Motorway { get; set; } + public double Rural; + public double Urban; + public double Motorway; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/Wheels.cs b/VectoCore/VectoCore/Models/Declaration/Wheels.cs index dbc2aa5606bc5183a437c58423cb7cb62955cf00..5bf4a77f3217cc1c953988cd18bf1ba10832af82 100644 --- a/VectoCore/VectoCore/Models/Declaration/Wheels.cs +++ b/VectoCore/VectoCore/Models/Declaration/Wheels.cs @@ -36,32 +36,36 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Declaration { - public class Wheels : LookupData<string, Wheels.WheelsEntry> + public sealed class Wheels : LookupData<string, Wheels.Entry> { - protected const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.Wheels.csv"; + protected override string ResourceId + { + get { return "TUGraz.VectoCore.Resources.Declaration.Wheels.csv"; } + } - public Wheels() + protected override string ErrorMessage { - ParseData(ReadCsvResource(ResourceId)); + get { return "Auxiliary Lookup Error: No value found for Wheels. Key: '{0}'"; } } - public override WheelsEntry Lookup(string key) + public override Entry Lookup(string key) { return base.Lookup(key.RemoveWhitespace()); } - protected sealed override void ParseData(DataTable table) + protected override void ParseData(DataTable table) { - Data = (from DataRow row in table.Rows - select new WheelsEntry { + Data = table.Rows.Cast<DataRow>() + .Select(row => new Entry { WheelType = row.Field<string>(0).RemoveWhitespace(), Inertia = row.ParseDouble(1).SI<KilogramSquareMeter>(), DynamicTyreRadius = row.ParseDouble(2).SI().Milli.Meter.Cast<Meter>(), SizeClass = row.Field<string>(3) - }).ToDictionary(e => e.WheelType); + }) + .ToDictionary(e => e.WheelType); } - public class WheelsEntry + public class Entry { public string WheelType; public KilogramSquareMeter Inertia; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/PT1Curve.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/PT1Curve.cs index 3a8434e773ba8023eae91b3c8697c6466e610f53..091e43fef5a9ecb3fd2ea885fcef89b5ddc1ed99 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/PT1Curve.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/PT1Curve.cs @@ -44,14 +44,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine { private List<KeyValuePair<PerSecond, Second>> _entries; - public static PT1Curve ReadFromFile(string fileName) + protected override string ResourceId { - return new PT1Curve(fileName); + get { throw new NotImplementedException(); } } - public static PT1Curve Create(DataTable data) + protected override string ErrorMessage { - return new PT1Curve(data); + get { throw new NotImplementedException(); } } private PT1Curve(DataTable data) @@ -71,6 +71,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine ParseData(data); } + public static PT1Curve ReadFromFile(string fileName) + { + return new PT1Curve(fileName); + } + + public static PT1Curve Create(DataTable data) + { + return new PT1Curve(data); + } protected override void ParseData(DataTable data) { @@ -83,33 +92,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine "FullLoadCurve/PT1 must consist of at least two lines with numeric values (below file header)"); } - if (HeaderIsValid(data.Columns)) { + if (data.Columns.Contains("engine speed") && data.Columns.Contains("PT1")) { _entries = data.Rows.Cast<DataRow>() - .Select( - r => - new KeyValuePair<PerSecond, Second>(r.ParseDouble(Fields.EngineSpeed).RPMtoRad(), - r.ParseDouble(Fields.PT1).SI<Second>())) - .OrderBy(x => x.Key) - .ToList(); + .Select(r => new KeyValuePair<PerSecond, Second>(r.ParseDouble("engine speed").RPMtoRad(), + r.ParseDouble("PT1").SI<Second>())) + .OrderBy(x => x.Key).ToList(); } else { _entries = data.Rows.Cast<DataRow>() - .Select( - r => new KeyValuePair<PerSecond, Second>(r.ParseDouble(0).RPMtoRad(), r.ParseDouble(3).SI<Second>())) - .OrderBy(x => x.Key) - .ToList(); + .Select(r => new KeyValuePair<PerSecond, Second>(r.ParseDouble(0).RPMtoRad(), r.ParseDouble(3).SI<Second>())) + .OrderBy(x => x.Key).ToList(); } } - private bool HeaderIsValid(DataColumnCollection columns) - { - return columns.Contains(Fields.EngineSpeed) && columns.Contains(Fields.PT1); - } - - /// <summary> - /// [rad/s] => [s] - /// </summary> - /// <param name="key">[rad/s]</param> - /// <returns>[s]</returns> public override Second Lookup(PerSecond key) { var index = 1; @@ -130,18 +124,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine } return pt1; } - - private static class Fields - { - /// <summary> - /// [rpm] engine speed - /// </summary> - public const string EngineSpeed = "engine speed"; - - /// <summary> - /// [s] time constant - /// </summary> - public const string PT1 = "PT1"; - } } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index 3208636862d2c557475cdfde7d4c3cda5d0d9456..a85f1ba05d8a5d0d17faf95caac37aa6677f3e04 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -69,8 +69,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration { var tmp = DeclarationData.Rims.Lookup(rim); - Assert.AreEqual(fa, tmp.F_a, Tolerance); - Assert.AreEqual(fb, tmp.F_b, Tolerance); + Assert.AreEqual(fa, tmp.Fa, Tolerance); + Assert.AreEqual(fb, tmp.Fb, Tolerance); } [ @@ -165,33 +165,23 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration { var airDrag = DeclarationData.AirDrag; - var expected = new Dictionary<string, AirDrag.AirDragEntry> { - { "RigidSolo", new AirDrag.AirDragEntry { A1 = 0.013526, A2 = 0.017746, A3 = -0.000666 } }, - { "RigidTrailer", new AirDrag.AirDragEntry { A1 = 0.017125, A2 = 0.072275, A3 = -0.004148 } }, - { "TractorSemitrailer", new AirDrag.AirDragEntry { A1 = 0.034767, A2 = 0.039367, A3 = -0.001897 } }, - { "CoachBus", new AirDrag.AirDragEntry { A1 = -0.000794, A2 = 0.02109, A3 = -0.00109 } } + var expected = new Dictionary<string, AirDrag.Entry> { + { "RigidTruck", new AirDrag.Entry(0.013526, 0.017746, -0.000666) }, + { "RigidTrailer", new AirDrag.Entry(0.017125, 0.072275, -0.004148) }, + { "TractorSemitrailer", new AirDrag.Entry(0.034767, 0.039367, -0.001897) }, + { "CoachBus", new AirDrag.Entry(-0.000794, 0.02109, -0.00109) } }; foreach (var kv in expected) { Assert.AreEqual(kv.Value, airDrag.Lookup(kv.Key)); } - var expectedCat = new Dictionary<VehicleCategory, AirDrag.AirDragEntry> { - { - VehicleCategory.RigidTruck, - new AirDrag.AirDragEntry { A1 = 0.013526, A2 = 0.017746, A3 = -0.000666 } - }, { - VehicleCategory.Tractor, - new AirDrag.AirDragEntry { A1 = 0.034767, A2 = 0.039367, A3 = -0.001897 } - }, { - VehicleCategory.CityBus, - new AirDrag.AirDragEntry { A1 = -0.000794, A2 = 0.02109, A3 = -0.00109 } - }, { - VehicleCategory.Coach, new AirDrag.AirDragEntry { A1 = -0.000794, A2 = 0.02109, A3 = -0.00109 } - }, { - VehicleCategory.InterurbanBus, - new AirDrag.AirDragEntry { A1 = -0.000794, A2 = 0.02109, A3 = -0.00109 } - } + var expectedCat = new Dictionary<VehicleCategory, AirDrag.Entry> { + { VehicleCategory.RigidTruck, new AirDrag.Entry(0.013526, 0.017746, -0.000666) }, + { VehicleCategory.Tractor, new AirDrag.Entry(0.034767, 0.039367, -0.001897) }, + { VehicleCategory.CityBus, new AirDrag.Entry(-0.000794, 0.02109, -0.00109) }, + { VehicleCategory.Coach, new AirDrag.Entry(-0.000794, 0.02109, -0.00109) }, + { VehicleCategory.InterurbanBus, new AirDrag.Entry(-0.000794, 0.02109, -0.00109) } }; foreach (var kv in expectedCat) { @@ -321,7 +311,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration foreach (var expectation in expected) { var baseConsumption = es.Lookup(expectation.Mission, null); - var leds = es.Lookup(expectation.Mission, new[] { "LED lights" }); + var leds = es.Lookup(expectation.Mission, "LED lights"); AssertHelper.AreRelativeEqual(expectation.Base / expectation.Efficiency, baseConsumption); AssertHelper.AreRelativeEqual(expectation.LED / expectation.Efficiency, leds);