diff --git a/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs b/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs index 92a2a8aac82781c86992ce23bc370aca72aeef9b..9ca31587c35721d85ebf962ac059582445058078 100644 --- a/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs +++ b/VectoCore/VectoCore/Models/Declaration/SteeringPump.cs @@ -40,24 +40,34 @@ namespace TUGraz.VectoCore.Models.Declaration { public sealed class SteeringPump { - private readonly SteeringPumpBaseLine _baseline = new SteeringPumpBaseLine(); - private readonly SteeringPumpAxles _axles = new SteeringPumpAxles(); - private readonly SteeringPumpTechnologies _technologies = new SteeringPumpTechnologies(); - - public Watt Lookup(MissionType mission, VehicleClass hdvClass, IEnumerable<string> technologies) + public static Watt Lookup(MissionType mission, VehicleClass hdvClass, IEnumerable<string> technologies) { - var powerShares = _baseline.Lookup(mission, hdvClass); - var sum = 0.SI<Watt>(); - var i = 1; + var baseLookup = new SteeringPumpBaseLine(); + var axleLookup = new SteeringPumpAxles(); + var techLookup = new SteeringPumpTechnologies(); + + var baseLine = baseLookup.Lookup(mission, hdvClass); + var power = new SteeringPumpValues<Watt>(0.SI<Watt>(), 0.SI<Watt>(), 0.SI<Watt>()); + var factors = new SteeringPumpValues<double>(0, 0, 0); + var i = 0; foreach (var technology in technologies) { - var factors = _technologies.Lookup(technology, mission); - var axles = _axles.Lookup(mission, i); - sum += powerShares.UnloadedFriction * axles.UnloadedFriction * factors.UnloadedFriction - + powerShares.Banking * axles.Banking * factors.Banking - + powerShares.Steering * axles.Banking * factors.Steering; i++; + var axles = axleLookup.Lookup(mission, i); + power.UnloadedFriction += baseLine.UnloadedFriction * axles.UnloadedFriction; + power.Banking += baseLine.Banking * axles.Banking; + power.Steering += baseLine.Steering * axles.Steering; + + var f = techLookup.Lookup(technology, mission); + factors.UnloadedFriction += f.UnloadedFriction; + factors.Banking += f.Banking; + factors.Steering += f.Steering; } - return sum; + + power.UnloadedFriction *= factors.UnloadedFriction / i; + power.Banking *= factors.Banking / i; + power.Steering *= factors.Steering / i; + + return power.UnloadedFriction + power.Banking + power.Steering; } private sealed class SteeringPumpBaseLine : LookupData<MissionType, VehicleClass, SteeringPumpValues<Watt>> @@ -78,20 +88,21 @@ namespace TUGraz.VectoCore.Models.Declaration 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]); + var hdvClass = VehicleClassHelper.Parse(row.Field<string>("hdvclass")); + foreach (DataColumn col in table.Columns) { + if (col.Caption == "hdvclass" || string.IsNullOrWhiteSpace(row.Field<string>(col.Caption))) + continue; + var values = row.Field<string>(col.Caption).Split('/') + .Select(v => v.ToDouble() / 100.0).Concat(0.0.Repeat(3)).SI<Watt>().ToList(); + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), hdvClass)] = new SteeringPumpValues<Watt>(values[0], + values[1], values[2]); } } } } - private sealed class SteeringPumpTechnologies : LookupData<string, MissionType, SteeringPumpValues<double>> + private sealed class SteeringPumpTechnologies : LookupData<string, SteeringPumpValues<double>> { - private readonly ElectricSystem.Alternator _alternator = new ElectricSystem.Alternator(); - protected override string ResourceId { get { return "TUGraz.VectoCore.Resources.Declaration.VAUX.SP-Tech.csv"; } @@ -108,16 +119,28 @@ namespace TUGraz.VectoCore.Models.Declaration Data.Clear(); Data = table.Rows.Cast<DataRow>().ToDictionary( - key => Tuple.Create(key.Field<string>("Technology"), MissionType.LongHaul), + key => key.Field<string>("Technology"), value => new SteeringPumpValues<double>(value.ParseDouble("UF"), value.ParseDouble("B"), value.ParseDouble("S"))); } - public override SteeringPumpValues<double> Lookup(string tech, MissionType mission) + public override SteeringPumpValues<double> Lookup(string key) + { + throw new InvalidOperationException("Standard lookup is not supported. Use Lookup(string, MissionType) instead."); + } + + /// <summary> + /// Lookup for Steering Pump Technologies. + /// </summary> + /// <param name="tech">The technology string.</param> + /// <param name="mission">Only used when Tech is Electric System.</param> + /// <returns></returns> + public SteeringPumpValues<double> Lookup(string tech, MissionType mission) { - var values = base.Lookup(tech, MissionType.LongHaul); + var values = base.Lookup(tech); if (tech == "Electric") { - values.Banking /= _alternator.Lookup(mission); - values.Steering /= _alternator.Lookup(mission); + var alternator = new ElectricSystem.Alternator(); + values.Banking /= alternator.Lookup(mission); + values.Steering /= alternator.Lookup(mission); } return values; } @@ -140,14 +163,18 @@ namespace TUGraz.VectoCore.Models.Declaration NormalizeTable(table); Data.Clear(); - var i = 1; foreach (DataRow row in table.Rows) { - foreach (MissionType mission in Enum.GetValues(typeof(MissionType))) { - var values = - row.Field<string>(mission.ToString().ToLowerInvariant()).Split('/').ToDouble(0).Concat(0.0.Repeat(3)).ToList(); - Data[Tuple.Create(mission, i)] = new SteeringPumpValues<double>(values[0], values[1], values[2]); + var axleNumber = int.Parse(row.Field<string>("steeredaxles")); + foreach (DataColumn col in table.Columns) { + if (col.Caption == "steeredaxles") + continue; + var field = row.Field<string>(col.Caption); + if (string.IsNullOrWhiteSpace(field)) + continue; + var values = field.Split('/').ToDouble().Concat(0.0.Repeat(3)).ToList(); + Data[Tuple.Create(col.Caption.ParseEnum<MissionType>(), axleNumber)] = new SteeringPumpValues<double>(values[0], + values[1], values[2]); } - i++; } } } diff --git a/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Axles.csv b/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Axles.csv index 6344dfdebef8b8e9af2672b9bf94e80bbe741508..10f0a576ec75bae5b336277d9571fd2a53e23580 100644 --- a/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Axles.csv +++ b/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Axles.csv @@ -1,5 +1,5 @@ -Steered axles / power demand percentage [%],Long haul,Regional delivery,Urban delivery,Municipal utility,construction,Heavy Urban,Urban,Suburban,Interurban,Coach -1,100/100/100,100/100/100,100/100/100,100/100/100,100/100/100,0,0,0,0,0 -2,100/70/70,100/70/70,100/70/70,100/70/70,100/70/70,0,0,0,0,0 -3,100/50/50,100/50/50,100/50/50,100/50/50,100/50/50,0,0,0,0,0 -4,100/50/50,100/50/50,100/50/50,100/50/50,100/50/50,0,0,0,0,0 +Steered axles,Long haul,Regional delivery,Urban delivery,Municipal utility,construction +1,100/100/100,100/100/100,100/100/100,100/100/100,100/100/100 +2,100/70/70,100/70/70,100/70/70,100/70/70,100/70/70 +3,100/50/50,100/50/50,100/50/50,100/50/50,100/50/50 +4,100/50/50,100/50/50,100/50/50,100/50/50,100/50/50 diff --git a/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Table.csv b/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Table.csv index 754b6ef9958d0f1be1d80a6a478ea9d7f4fcbe8f..66a43eee79e97a7462474bd77ac78691bfc808da 100644 --- a/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Table.csv +++ b/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Table.csv @@ -1,14 +1,14 @@ -HDV Class / Power demand per share [W],Long haul,Regional delivery,Urban delivery,Municipal utility,Construction,Heavy Urban,Urban,Suburban,Interurban,Coach -1,0,240/20/20,220/20/30,0,0,0,0,0,0,0 -2,340/30/0,290/30/20,260/20/30,0,0,0,0,0,0,0 -3,0,310/30/30,280/30/40,0,0,0,0,0,0,0 -4,510/100/0,490/40/40,0,430/30/50,0,0,0,0,0,0 -5,600/120/0,540/90/40,480/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,600/120/0,490/60/40,0,430/30/50,0,0,0,0,0,0 -10,450/120/0,440/90/40,0,0,0,0,0,0,0,0 -11,600/120/0,490/60/40,0,430/30/50,640/50/80,0,0,0,0,0 -12,450/120/0,440/90/40,0,0,640/50/80,0,0,0,0,0 -16,0,0,0,0,640/50/80,0,0,0,0,0 +HDV Class,Long haul,Regional delivery,Urban delivery,Municipal utility,Construction +1,,240/20/20,220/20/30,, +2,340/30/0,290/30/20,260/20/30,, +3,,310/30/30,280/30/40,, +4,510/100/0,490/40/40,,430/30/50, +5,600/120/0,540/90/40,480/80/60,, +6,,,,, +7,,,,, +8,,,,, +9,600/120/0,490/60/40,,430/30/50, +10,450/120/0,440/90/40,,, +11,600/120/0,490/60/40,,430/30/50,640/50/80 +12,450/120/0,440/90/40,,,640/50/80 +16,,,,,640/50/80 diff --git a/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv b/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv index 594c6320c6d725f52f8ec18ad2620c9c2770de1f..494581d6c09dce30c428ab1b6880079aaf34b87f 100644 --- a/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv +++ b/VectoCore/VectoCore/Resources/Declaration/VAUX/SP-Tech.csv @@ -1,6 +1,6 @@ Technology,UF,B,S Fixed displacement,1,1,1 -Fixed displacement elec. controlled,0.95,1,1 +Fixed displacement with elec. control,0.95,1,1 Dual displacement,0.85,0.85,0.85 Variable displacement mech. controlled,0.75,0.75,0.75 Variable displacement elec. controlled,0.6,0.6,0.6 diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index 8acfdc79762c6cedf72a593456b4c78f023b0f38..2356e5cf416ab791072f5a9fafdb13d2c16ebf0b 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -372,46 +372,72 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration } } - [Test, - TestCase("Fixed displacement", VehicleClass.Class1, new[] { 0, 260, 270, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class2, new[] { 370, 320, 310, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class3, new[] { 0, 340, 350, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class4, new[] { 610, 530, 0, 530, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class5, new[] { 720, 630, 620, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class6, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class7, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class8, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class9, new[] { 720, 550, 0, 550, 0, 0, 0, 0, 0, 0 }), - TestCase("Fixed displacement", VehicleClass.Class10, new[] { 570, 530, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class1, new[] { 0, 156, 162, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class2, new[] { 222, 192, 186, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class3, new[] { 0, 204, 210, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class4, new[] { 366, 318, 0, 318, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class5, new[] { 432, 378, 372, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class6, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class7, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class8, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class9, new[] { 432, 330, 0, 330, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement mech. controlled", VehicleClass.Class10, new[] { 342, 318, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class1, new[] { 0, 225, 235, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class2, new[] { 322, 278, 269, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class3, new[] { 0, 295, 304, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class4, new[] { 531, 460, 0, 460, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class5, new[] { 627, 546, 540, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class6, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class7, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class8, new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class9, new[] { 627, 478, 0, 478, 0, 0, 0, 0, 0, 0 }), - TestCase("Variable displacement elec. controlled", VehicleClass.Class10, new[] { 498, 461, 0, 0, 0, 0, 0, 0, 0, 0 }), + [ + TestCase(MissionType.LongHaul, VehicleClass.Class2, 370, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class4, 610, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class5, 720, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class9, 720, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class10, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class11, 720, "Fixed displacement", null, null, null), + TestCase(MissionType.LongHaul, VehicleClass.Class12, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class1, 280, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 340, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class3, 370, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class4, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class5, 670, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class9, 590, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class10, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class11, 590, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class12, 570, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class1, 270, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class2, 310, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class3, 350, "Fixed displacement", null, null, null), + TestCase(MissionType.UrbanDelivery, VehicleClass.Class5, 620, "Fixed displacement", null, null, null), + TestCase(MissionType.MunicipalUtility, VehicleClass.Class4, 510, "Fixed displacement", null, null, null), + TestCase(MissionType.MunicipalUtility, VehicleClass.Class9, 510, "Fixed displacement", null, null, null), + TestCase(MissionType.MunicipalUtility, VehicleClass.Class11, 510, "Fixed displacement", null, null, null), + TestCase(MissionType.Construction, VehicleClass.Class11, 770, "Fixed displacement", null, null, null), + TestCase(MissionType.Construction, VehicleClass.Class12, 770, "Fixed displacement", null, null, null), + TestCase(MissionType.Construction, VehicleClass.Class16, 770, "Fixed displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 325.5, "Fixed displacement with elec. control", null, + null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 289, "Dual displacement", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 255, "Variable displacement mech. controlled", null, null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 204, "Variable displacement elec. controlled", null, null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 92.8571, "Electric", null, null, null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 665, "Fixed displacement", "Fixed displacement", null, + null), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 1295, "Fixed displacement", "Fixed displacement", + "Fixed displacement", "Fixed displacement"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, 1021.5, "Dual displacement", + "Variable displacement mech. controlled", "Fixed displacement with elec. control", + "Variable displacement elec. controlled"), ] - public void AuxSteeringPumpTest(string technology, VehicleClass hdvClass, int[] expected) + public void Aux_SteeringPumpLookupValues(MissionType mission, VehicleClass hdvClass, double expected, string axle1, + string axle2, string axle3, string axle4) { - var sp = DeclarationData.SteeringPump; + // mk remark: made the test call with 4 axle params, so that the test name is clear in the test explorer. + AssertHelper.AreRelativeEqual(expected, + SteeringPump.Lookup(mission, hdvClass, + new[] { axle1, axle2, axle3, axle4 }.TakeWhile(a => a != null).ToArray())); + } - for (var i = 0; i < Missions.Length; i++) { - var value = sp.Lookup(Missions[i], hdvClass, new[] { technology }); - Assert.AreEqual(expected[i], value.Value(), Tolerance); - } + [TestCase(MissionType.LongHaul, VehicleClass.Class1, "Dual displacement", + TestName = "Aux_SteeringPumpLookupFail( No Value )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Super displacement", + TestName = "Aux_SteeringPumpLookupFail( Wrong Tech )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, "Dual displacement", "Dual displacement", + "Dual displacement", "Dual displacement", "Dual displacement", TestName = "Aux_SteeringPumpLookupFail( >4 Techs )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, TestName = "Aux_SteeringPumpLookupFail( Null Techs )"), + TestCase(MissionType.RegionalDelivery, VehicleClass.Class2, new string[0], + TestName = "Aux_SteeringPumpLookupFail( 0 Techs )"), + ] + public void Aux_SteeringPumpLookupFail(MissionType mission, VehicleClass hdvClass, params string[] tech) + { + AssertHelper.Exception<VectoException>(() => SteeringPump.Lookup(mission, hdvClass, tech)); } [ diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs index be8e383a3074892fa92f77447ac1c69a880d0408..8c53d55d328ced122c12edb188c2583b994bce6a 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -79,7 +79,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation DeclarationData.Fan.Lookup(MissionType.LongHaul, "Hydraulic driven - Constant displacement pump")); aux.AddConstant("PS", DeclarationData.PneumaticSystem.Lookup(mission, hdvClass)); aux.AddConstant("STP", - DeclarationData.SteeringPump.Lookup(MissionType.LongHaul, hdvClass, + SteeringPump.Lookup(MissionType.LongHaul, hdvClass, new[] { "Variable displacement mech. controlled" })); aux.AddConstant("ES", DeclarationData.ElectricSystem.Lookup(mission, null)); aux.AddConstant("AC",