From 70c9f0fef8ac28966bd3fd8d6f6df39880477041 Mon Sep 17 00:00:00 2001 From: "VKMTHD\\haraldmartini" <harald.martini@student.tugraz.at> Date: Wed, 12 Oct 2022 11:45:05 +0200 Subject: [PATCH] implemented generic soc with deterioration for PEV, OVC-HEV, NOVC-HEV --- .../DeclarationDataAdapterHeavyLorry.cs | 10 +- .../IDeclarationDataAdapter.cs | 2 +- .../BatteryDataAdapter.cs | 11 +- ...DeclarationModeHeavyLorryRunDataFactory.cs | 2 +- ...tionModeHeavyLorryRunDataFactory_Hybrid.cs | 2 +- .../Models/Declaration/DeclarationData.cs | 2 + .../Models/Declaration/GenericSOC.cs | 103 +++++++++++++++ .../DataAdapter/BatteryDataAdapterTest.cs | 119 ++++++++++-------- 8 files changed, 187 insertions(+), 64 deletions(-) create mode 100644 VectoCore/VectoCore/Models/Declaration/GenericSOC.cs diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/HeavyLorry/DeclarationDataAdapterHeavyLorry.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/HeavyLorry/DeclarationDataAdapterHeavyLorry.cs index 3ed33b0359..291c245610 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/HeavyLorry/DeclarationDataAdapterHeavyLorry.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/HeavyLorry/DeclarationDataAdapterHeavyLorry.cs @@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.HeavyLorry throw new NotImplementedException(); } - public virtual BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData componentsElectricStorage) + public virtual BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData componentsElectricStorage, VectoSimulationJobType jobType, bool ovc) { throw new NotImplementedException(); } @@ -247,9 +247,9 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.HeavyLorry gears); } - public override BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData batteryInputData) + public override BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData batteryInputData, VectoSimulationJobType jobType, bool ovc) { - return _eletricStorageAdapter.CreateBatteryData(batteryInputData); + return _eletricStorageAdapter.CreateBatteryData(batteryInputData, jobType, ovc); } public override SuperCapData CreateSuperCapData(IElectricStorageSystemDeclarationInputData reessInputData) @@ -380,9 +380,9 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.HeavyLorry return _electricMachineAdapter.CreateElectricMachines(electricMachines, torqueLimits, averageVoltage, gears); } - public override BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData componentsElectricStorage) + public override BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData componentsElectricStorage, VectoSimulationJobType jobType, bool ovc) { - return _electricStorageAdapter.CreateBatteryData(batteryInputData: componentsElectricStorage); + return _electricStorageAdapter.CreateBatteryData(batteryInputData: componentsElectricStorage, jobType: jobType, ovc: ovc); } public override SuperCapData CreateSuperCapData(IElectricStorageSystemDeclarationInputData componentsElectricStorage) diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/IDeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/IDeclarationDataAdapter.cs index 08c27a6ae8..6c72b8f7b6 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/IDeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/IDeclarationDataAdapter.cs @@ -68,7 +68,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter IList<Tuple<PowertrainPosition, ElectricMotorData>> CreateElectricMachines(IElectricMachinesDeclarationInputData electricMachines, IDictionary<PowertrainPosition, IList<Tuple<Volt, TableData>>> torqueLimits, Volt averageVoltage, GearList gears = null); - BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData componentsElectricStorage); + BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData componentsElectricStorage, VectoSimulationJobType jobType, bool ovc); SuperCapData CreateSuperCapData(IElectricStorageSystemDeclarationInputData componentsElectricStorage); HybridStrategyParameters CreateHybridStrategy(BatterySystemData runDataBatteryData, SuperCapData runDataSuperCapData); ShiftStrategyParameters CreateDummyGearshiftStrategy(); diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/BatteryDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/BatteryDataAdapter.cs index df6bf39ddc..82a4a9849d 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/BatteryDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/BatteryDataAdapter.cs @@ -13,7 +13,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen { public class ElectricStorageAdapter { - public BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData batteryInputData) + public BatterySystemData CreateBatteryData(IElectricStorageSystemDeclarationInputData batteryInputData, + VectoSimulationJobType jobType, bool ovc) { if (batteryInputData == null) { @@ -28,6 +29,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen } var retVal = new BatterySystemData(); + var genericSOC = DeclarationData.Battery.GenericSOC.Lookup(jobType, ovc); foreach (var entry in batteries) { var b = entry.REESSPack as IBatteryPackDeclarationInputData; @@ -37,12 +39,13 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen } //for (var i = 0; i < entry.Count; i++) { - var minSoc = DeclarationData.Battery.GetMinSoc(b.BatteryType); + var minSoc = genericSOC.SOCMin; if (b.MinSOC != null && b.MinSOC > minSoc) { minSoc = b.MinSOC.Value; } - var maxSoc = DeclarationData.Battery.GetMaxSoc(b.BatteryType); - if (b.MaxSOC != null && b.MaxSOC < maxSoc) { + + var maxSoc = genericSOC.SOCMax; + if (b.MaxSOC != null && b.MaxSOC < maxSoc && b.MaxSOC > b.MinSOC) { maxSoc = b.MaxSOC.Value; } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs index 32826432c5..0760346b47 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs @@ -333,7 +333,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.HeavyLorryRunDa result.AirdragData = DataAdapter.CreateAirdragData(vehicle.Components.AirdragInputData, mission, _segment); result.DriverData = DataAdapter.CreateDriverData(_segment); - result.BatteryData = DataAdapter.CreateBatteryData(componentsElectricStorage: vehicle.Components.ElectricStorage); + result.BatteryData = DataAdapter.CreateBatteryData(componentsElectricStorage: vehicle.Components.ElectricStorage, vehicle.VehicleType, true); result.SuperCapData = DataAdapter.CreateSuperCapData(componentsElectricStorage: vehicle.Components.ElectricStorage); result.ElectricMachinesData = DataAdapter.CreateElectricMachines(vehicle.Components.ElectricMachines, vehicle.ElectricMotorTorqueLimits, result.BatteryData.CalculateAverageVoltage(), null); result.AngledriveData = DataAdapter.CreateAngledriveData(vehicle.Components.AngledriveInputData); diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory_Hybrid.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory_Hybrid.cs index 8cf5ac751f..abbe21afb9 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory_Hybrid.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory_Hybrid.cs @@ -87,7 +87,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.HeavyLorryRunDa var runData = CreateCommonRunData(vehicle, mission, loading, _segment, engineModes, modeIdx.Value); runData.VehicleData = DataAdapter.CreateVehicleData(vehicle, _segment, mission, loading, _allowVocational); runData.EngineData = DataAdapter.CreateEngineData(vehicle, engineMode, mission); - runData.BatteryData = DataAdapter.CreateBatteryData(vehicle.Components.ElectricStorage); + runData.BatteryData = DataAdapter.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.VehicleType, vehicle.OvcHev); runData.SuperCapData = DataAdapter.CreateSuperCapData(vehicle.Components.ElectricStorage); runData.ElectricMachinesData = DataAdapter.CreateElectricMachines(vehicle.Components.ElectricMachines, vehicle.ElectricMotorTorqueLimits, runData.BatteryData.CalculateAverageVoltage()); runData.GearboxData = _gearboxData; diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 9c19fa28e5..0f24809961 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -1225,6 +1225,8 @@ namespace TUGraz.VectoCore.Models.Declaration public static class Battery { + public static GenericSOC GenericSOC = new GenericSOC(); + /// <summary> /// Percentage of the maximum voltage of the battery /// </summary> diff --git a/VectoCore/VectoCore/Models/Declaration/GenericSOC.cs b/VectoCore/VectoCore/Models/Declaration/GenericSOC.cs new file mode 100644 index 0000000000..3d32cbecfd --- /dev/null +++ b/VectoCore/VectoCore/Models/Declaration/GenericSOC.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader.Impl; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + + public class GenericSOC : LookupData<VectoSimulationJobType, bool, GenericSOC.GenericSOCData> + { + protected override string ResourceId => DeclarationData.DeclarationDataResourcePrefix + ".GenericSOC.csv"; + protected override string ErrorMessage => "GenericSOC Lookup Error: no value found. Key: '{0}'"; + + private double _factor = 1d/100; + public struct GenericSOCData + { + public double SOCMin; + public double SOCMax; + public double GenericDetorioration; + } + + public GenericSOC() + { + } + + #region Overrides of LookupData + + #region Overrides of LookupData<VectoSimulationJobType,bool,GenericSOCData> + + public override GenericSOCData Lookup(VectoSimulationJobType jobType, bool ovc) + { + return base.Lookup(jobType, ovc); + } + + #endregion + + + protected override void ParseData(DataTable table) + { + foreach (DataRow row in table.Rows) { + var architecture = row["architecture"]; + switch (architecture) { + case "PEV": + CreatePEVEntries(row); + break; + case "HEV": + CreateHEVEntries(row); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + #endregion + + + private void CreatePEVEntries(DataRow row) + { + var architectures = new VectoSimulationJobType[] { + VectoSimulationJobType.BatteryElectricVehicle, + VectoSimulationJobType.IEPC_E + }; + var val = GenericSocData(row); + foreach (var archs in architectures) { + Data.Add(new Tuple<VectoSimulationJobType, bool>(archs, row.ParseBoolean("ovc")), val); + } + + } + + private GenericSOCData GenericSocData(DataRow row) + { + var val = new GenericSOCData() { + SOCMin = row.ParseDouble("genericsocmin") * _factor, + SOCMax = row.ParseDouble("genericsocmax") * _factor, + GenericDetorioration = row.ParseDouble("genericdeterioration") * _factor, + }; + return val; + } + + private void CreateHEVEntries(DataRow row) + { + var val = GenericSocData(row); + var architectures = new VectoSimulationJobType[] { + VectoSimulationJobType.ParallelHybridVehicle, + VectoSimulationJobType.SerialHybridVehicle, + VectoSimulationJobType.IHPC, + VectoSimulationJobType.IEPC_S + }; + foreach (var archs in architectures) + { + Data.Add(new Tuple<VectoSimulationJobType, bool>(archs, row.ParseBoolean("ovc")), val); + } + } + + + } +} diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs index c124018e54..95b56f4bc6 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/BatteryDataAdapterTest.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.InteropServices.ComTypes; @@ -6,6 +7,7 @@ using Castle.Core.Resource; using Moq; using NLog.LayoutRenderers; using NUnit.Framework; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider; @@ -27,73 +29,53 @@ public class BatteryDataAdapterTest } - [TestCase(null, null, 0.0725, 0.9275, 0.8550)] - public void PEVBatteryDataAdapterTest( + //PEV + [TestCase(null, null, 0.0725, 0.9275, 0.8550, VectoSimulationJobType.BatteryElectricVehicle, true)] + [TestCase(null, null, 0.0725, 0.9275, 0.8550, VectoSimulationJobType.BatteryElectricVehicle, false)] + + //HEV Ovc + [TestCase(0.23, 0.77, 0.2435, 0.7565, 0.5130, VectoSimulationJobType.SerialHybridVehicle, true)] + [TestCase(null, null, 0.1675, 0.8325, 0.6650, VectoSimulationJobType.SerialHybridVehicle, true)] + [TestCase(0.05, 0.97, 0.1675, 0.8325, 0.6650, VectoSimulationJobType.SerialHybridVehicle, true)] + + //HEV Non Ovc + [TestCase(0.40, 0.60, 0.4050, 0.5950, 0.1900, VectoSimulationJobType.SerialHybridVehicle, false)] + [TestCase(null, null, 0.2625, 0.7375, 0.4750, VectoSimulationJobType.SerialHybridVehicle, false)] + [TestCase(0.15, 0.85, 0.2625, 0.7375, 0.4750, VectoSimulationJobType.SerialHybridVehicle, false)] + + + public void GenericSOCTest( double inputMinSoc, double inputMaxSoc, double expectedMinSoc, double expectedMaxSoc, - double usableSocRange) + double usableSocRange, VectoSimulationJobType vectoSimulationJobType, bool ovc) { - var elStorage = CreateElectricStorage(null, null); - var inputData = CreateElectricStorageSystem(elStorage.Object); + var elStorage = CreateElectricStorage(inputMinSoc, inputMaxSoc); + var inputData = CreateElectricStorageSystem(elStorage.Object); - var batteryData = _electricStorageAdapter.CreateBatteryData(inputData.Object); - Assert.AreEqual(1, batteryData.Batteries.Count); - - var battery = batteryData.Batteries.FirstOrDefault().Item2; - - Assert.IsTrue(battery.MinSOC.IsEqual(expectedMinSoc)); - Assert.IsTrue(battery.MaxSOC.IsEqual(expectedMaxSoc )); - Assert.IsTrue(usableSocRange.IsEqual(battery.GetUsableSocRange()), $"Invalid {nameof(usableSocRange)} expected {usableSocRange} got {battery.GetUsableSocRange()}"); + BatterySystemData batteryData; + if (vectoSimulationJobType == VectoSimulationJobType.BatteryElectricVehicle && !ovc) { - } + Assert.Throws<VectoException>(() => _electricStorageAdapter.CreateBatteryData(inputData.Object, vectoSimulationJobType, ovc)); + Assert.Pass(); + } - private static Mock<IElectricStorageDeclarationInputData> CreateElectricStorage(double? minSoc, double? maxSoc) - { - var elStorage = new Mock<IElectricStorageDeclarationInputData>(); - var ressPack = new Mock<IBatteryPackDeclarationInputData>(); + batteryData = _electricStorageAdapter.CreateBatteryData(inputData.Object, vectoSimulationJobType, ovc); - ressPack.Setup(m => m.Capacity).Returns((1000).SI<AmpereSecond>()); - ressPack.Setup(m => m.MinSOC).Returns(() => minSoc); - ressPack.Setup(m => m.MaxSOC).Returns(() => maxSoc); - ressPack.Setup(m => m.MaxCurrentMap).Returns( - GetMockTableData(new[] { - new[]{"0.0", "0.0", "0.0"}, - new[]{"0.0", "0.0", "0.0"}, - new[]{"0.0", "0.0", "0.0"} - })); - ressPack.Setup(m => m.InternalResistanceCurve).Returns( - GetMockTableData(new[] { - new[]{"0.0", "0.0"}, - new[]{"0.0", "0.0"}, - new[]{"0.0", "0.0"} - })); - ressPack.Setup(m => m.VoltageCurve).Returns( - GetMockTableData(new[] { - new[]{"0.0", "0.0"}, - new[]{"0.0", "0.0"}, - new[]{"0.0", "0.0"} - })); - - elStorage.Setup(m => m.REESSPack).Returns(() => ressPack.Object); - return elStorage; - } - - [TestCase] - public void OVCHevBatteryDataAdapterTest() - { + Assert.AreEqual(1, batteryData.Batteries.Count); - } + var battery = batteryData.Batteries.FirstOrDefault().Item2; - [TestCase] - public void NonOVCHevBatteryDataAdapterTest() - { + Assert.IsTrue(battery.MinSOC.IsEqual(expectedMinSoc), $"Expected: {expectedMinSoc}, Actual{battery.MinSOC}"); + Assert.IsTrue(battery.MaxSOC.IsEqual(expectedMaxSoc), $"Expected: {expectedMaxSoc}, Actual{battery.MaxSOC}"); + Assert.IsTrue(usableSocRange.IsEqual(battery.GetUsableSocRange()), + $"Invalid {nameof(usableSocRange)} expected {usableSocRange} got {battery.GetUsableSocRange()}"); } Mock<IElectricStorageSystemDeclarationInputData> CreateElectricStorageSystem(params IElectricStorageDeclarationInputData[] elStorageInputData) @@ -122,6 +104,39 @@ public class BatteryDataAdapterTest } + private static Mock<IElectricStorageDeclarationInputData> CreateElectricStorage(double? minSoc, double? maxSoc) + { + var elStorage = new Mock<IElectricStorageDeclarationInputData>(); + var ressPack = new Mock<IBatteryPackDeclarationInputData>(); + + ressPack.Setup(m => m.Capacity).Returns((1000).SI<AmpereSecond>()); + + ressPack.Setup(m => m.MinSOC).Returns(() => minSoc); + ressPack.Setup(m => m.MaxSOC).Returns(() => maxSoc); + ressPack.Setup(m => m.MaxCurrentMap).Returns( + GetMockTableData(new[] { + new[]{"0.0", "0.0", "0.0"}, + new[]{"0.0", "0.0", "0.0"}, + new[]{"0.0", "0.0", "0.0"} + })); + + ressPack.Setup(m => m.InternalResistanceCurve).Returns( + GetMockTableData(new[] { + new[]{"0.0", "0.0"}, + new[]{"0.0", "0.0"}, + new[]{"0.0", "0.0"} + })); + ressPack.Setup(m => m.VoltageCurve).Returns( + GetMockTableData(new[] { + new[]{"0.0", "0.0"}, + new[]{"0.0", "0.0"}, + new[]{"0.0", "0.0"} + })); + + elStorage.Setup(m => m.REESSPack).Returns(() => ressPack.Object); + return elStorage; + } + } internal static class BatteryDataExtension -- GitLab