From 5d24e38b932336b6cc152b38539c51862c371b38 Mon Sep 17 00:00:00 2001 From: "VKMTHD\\haraldmartini" <harald.martini@student.tugraz.at> Date: Wed, 8 Feb 2023 14:40:21 +0100 Subject: [PATCH] implemented s-hev strategy parameters for vehicles with supercap --- .../HybridStrategyParameterDataAdapter.cs | 119 +++++++++++++----- .../SimulationComponent/Impl/SuperCap.cs | 7 ++ .../HybridStrategyDataAdapterTest.cs | 37 +++++- 3 files changed, 131 insertions(+), 32 deletions(-) diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/StrategyDataAdapter/HybridStrategyParameterDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/StrategyDataAdapter/HybridStrategyParameterDataAdapter.cs index 1beed0b120..b4fb1e23dc 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/StrategyDataAdapter/HybridStrategyParameterDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/StrategyDataAdapter/HybridStrategyParameterDataAdapter.cs @@ -9,6 +9,7 @@ using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Battery; using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents.StrategyDataAdapter { @@ -80,12 +81,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen SuperCapData superCapData, Kilogram vehicleMass, VectoRunData.OvcHevMode ovcMode) { if (batterySystemData == null && superCapData == null) { - return null; + throw new VectoException("Either Battery or SuperCap must be set"); } - if (superCapData != null) { - throw new VectoException("Super cap for serial hybrid is not implemented"); - } + var result = new HybridStrategyParameters(); result.AuxReserveTime = null; @@ -99,47 +98,79 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen result.EquivalenceFactorDischarge = double.NaN; result.CostFactorSOCExponent = double.NaN; - - SetGenericParameters(result, batterySystemData, superCapData, vehicleMass, out var deltaSoc, out var tmpSystem); - switch (ovcMode) { - case VectoRunData.OvcHevMode.ChargeSustaining: - result.InitialSoc = result.MinSoC + deltaSoc; - break; - case VectoRunData.OvcHevMode.ChargeDepleting: - result.InitialSoc = (tmpSystem.MaxSoC + tmpSystem.MinSoC) / 2; - result.TargetSoC = result.InitialSoc - 1; - break; - default: - throw new ArgumentOutOfRangeException(nameof(ovcMode), ovcMode, null); + if (batterySystemData != null) { + SetGenericParameters(ref result, batterySystemData, vehicleMass, ovcMode); } + if (superCapData != null) { + SetGenericParameters(ref result, superCapData, vehicleMass, ovcMode); + } + return result; } - private void SetGenericParameters(HybridStrategyParameters result, BatterySystemData batterySystemData, - SuperCapData superCapData, Kilogram vehicleMass, out double deltaSoc, out BatterySystem tmpSystem) + private void SetGenericParameters(ref HybridStrategyParameters result, SuperCapData superCapData, Kilogram vehicleMass, VectoRunData.OvcHevMode ovcMode) { - tmpSystem = null; - if (batterySystemData != null) { - tmpSystem = new BatterySystem(null, batterySystemData); + + + SetSuperCapParameters(result, superCapData, vehicleMass, 70.KMPHtoMeterPerSecond()); + if (result.MinSoC >= result.TargetSoC) { + SetSuperCapParameters(result, superCapData, vehicleMass, 30.KMPHtoMeterPerSecond()); + } + + + + + + + + + + if (result.MinSoC >= result.TargetSoC || result.TargetSoC >= 1) { + throw new VectoException("Min SOC higher than Target SOC"); } + } + + private void SetSuperCapParameters(HybridStrategyParameters result, SuperCapData superCapData, Kilogram vehicleMass, MeterPerSecond velocity) + { + var min_sc_energy = SC_Energy(superCapData.MinVoltage, superCapData.Capacity); + var max_sc_energy = SC_Energy(superCapData.MaxVoltage, superCapData.Capacity); + + var kin_energy = KineticEnergy(vehicleMass, velocity); - deltaSoc = CalculatedDeltaSocSHev(vehicleMass, tmpSystem, superCapData); + var min_hs_energy = min_sc_energy + kin_energy; + var target_hs_energy = max_sc_energy - kin_energy; - var reessMinSoc = tmpSystem?.MinSoC ?? (superCapData.MinVoltage / superCapData.MaxVoltage); - var reessMaxSoc = tmpSystem?.MaxSoC ?? 1; + var u_min = SC_Voltage(min_hs_energy, superCapData.Capacity); + var u_target = SC_Voltage(target_hs_energy, superCapData.Capacity); + result.MinSoC = u_min / superCapData.MaxVoltage; + result.TargetSoC = u_target / superCapData.MaxVoltage; + result.InitialSoc = + Math.Sqrt(((Math.Pow(superCapData.MaxVoltage.Value(),2) + Math.Pow(superCapData.MinVoltage.Value(),2)) / 2.0)) / + superCapData.MaxVoltage.Value(); + result.MaxSoC = 1; + } + private void SetGenericParameters(ref HybridStrategyParameters result, + BatterySystemData batterySystemData, + Kilogram vehicleMass, + VectoRunData.OvcHevMode ovcMode) + { + var tmpSystem = new BatterySystem(null, batterySystemData); + var deltaSoc = CalculateDeltaSocSHev(vehicleMass, tmpSystem, 100.KMPHtoMeterPerSecond()); + + var reessMinSoc = tmpSystem.MinSoC; + var reessMaxSoc = tmpSystem.MaxSoC; result.MinSoC = reessMinSoc + 2 * deltaSoc; result.TargetSoC = tmpSystem.MaxSoC - 5 * deltaSoc; result.MaxSoC = double.NaN; - if (result.MinSoC >= result.TargetSoC) { - deltaSoc = CalculatedDeltaSocSHev(vehicleMass, tmpSystem, superCapData, 50); + deltaSoc = CalculateDeltaSocSHev(vehicleMass, tmpSystem, 50.KMPHtoMeterPerSecond()); //Small battery result.TargetSoC = reessMaxSoc - 1 * deltaSoc; result.MinSoC = reessMinSoc + 2 * deltaSoc; @@ -147,18 +178,44 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen throw new VectoException("Min SOC higher than Target SOC"); } } + + switch (ovcMode) + { + case VectoRunData.OvcHevMode.ChargeSustaining: + result.InitialSoc = result.MinSoC + deltaSoc; + break; + case VectoRunData.OvcHevMode.ChargeDepleting: + result.InitialSoc = (tmpSystem.MaxSoC + tmpSystem.MinSoC) / 2; + result.TargetSoC = result.InitialSoc - 1; + break; + default: + throw new ArgumentOutOfRangeException(nameof(ovcMode), ovcMode, null); + } } - private double CalculatedDeltaSocSHev(Kilogram vehicleMass, - BatterySystem tmpSystem, SuperCapData superCap, double kmph = 100) + private double CalculateDeltaSocSHev(Kilogram vehicleMass, + BatterySystem tmpSystem, MeterPerSecond v) { - var v_nom = tmpSystem?.NominalVoltage ?? (superCap.MaxVoltage + superCap.MinVoltage)/2; + var v_nom = tmpSystem.NominalVoltage; var c_nom = tmpSystem.Capacity.AsAmpHour; - var v = kmph.KMPHtoMeterPerSecond(); - var result = ((vehicleMass / 2 * v * v) / 3600) * (1 / v_nom) * (1 / c_nom); + var result = KineticEnergy(vehicleMass, v).ConvertToWattHour() / v_nom / c_nom; return result.Value(); } + private static WattSecond KineticEnergy(Kilogram vehicleMass, MeterPerSecond v) + { + return ((vehicleMass / 2.0) * v * v).Cast<WattSecond>(); + } + + private static Volt SC_Voltage(WattSecond energy, Farad capacity) + { + return Math.Sqrt((2.0 * energy / capacity).Value()).SI<Volt>(); + } + + private static Joule SC_Energy(Volt voltage, Farad capacity) + { + return 0.5 * capacity * voltage * voltage; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs index 0f22bd36d8..5279712b60 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs @@ -56,7 +56,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public double MinSoC => ModelData.MinVoltage / ModelData.MaxVoltage; public double MaxSoC => 1; + + /// <summary> + /// [Warning("Not implemented in super cap, returns null")] + /// </summary> public AmpereSecond Capacity => null; + /// <summary> + /// [Warning("Not implemented in super cap, returns null")] + /// </summary> public Volt NominalVoltage => null; public void Initialize(double initialSoC) diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/HybridStrategyDataAdapterTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/HybridStrategyDataAdapterTest.cs index a9de4c7dd9..40a14f5808 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/HybridStrategyDataAdapterTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DataAdapter/HybridStrategyDataAdapterTest.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using Castle.Components.DictionaryAdapter; using Moq; using NUnit.Framework; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents.StrategyDataAdapter; @@ -22,7 +23,6 @@ public class HybridStrategyDataAdapterTest [TestCase(0.7375, 0.2625, 11273.9176, 778.61, 247500, false, 0.624646591, 0.307641364)] [TestCase(0.6, 0.2, 11000, 778.61, 80000, false, 0.582967134, 0.234065732)] [TestCase(0.6, 0.2, 11000, 778.61, 5000, true, 0.268131464, 0.634065732)] - public void SerialHybridStrategyTest(double bat_soc_max, double bat_soc_min, double vehicle_mass, double nominalVoltage, double nominalCapacity, bool exception, double expected_target_soc, double expected_min_soc) { var mass = vehicle_mass.SI<Kilogram>(); @@ -83,5 +83,40 @@ public class HybridStrategyDataAdapterTest } + [TestCase(1000.00000000000000 ,10.00000000000000 ,1000.00000000000000 ,1.00000000000000 ,0.61496863314570 ,0.78861497592102 ,0.70714213564177 ,1.00000000000000 ,false)] + //[TestCase(40000.00000000000000 ,10.00000000000000 ,1000.00000000000000 ,25.00000000000000, 0.77784206083558, 0.62853936105471, 0.70714213564177, 1.00000000000000, true)] //fallback 30 kmh + [TestCase(1000.00000000000000 ,10.00000000000000 ,1000.00000000000000 ,25.00000000000000, 0.12338337323207, 0.99240946348263, 0.70714213564177, 1.00000000000000, false)] + [TestCase(40000.00000000000000 ,10.00000000000000 ,1000.00000000000000 ,25.00000000000000, 0.33348329959851, 0.94280904158206, 0.70714213564177, 1.00000000000000, false)] + [TestCase(40000.00000000000000 ,10.00000000000000 ,1000.00000000000000 ,3.00000000000000 ,0.96230240877072 ,0.27216552697591 ,0.70714213564177 ,1.00000000000000 ,true)] + public void SerialHybridSuperCapTest(double mass_kg, double U_min_V, double U_max_V, double C_F, double exp_soc_min, double exp_soc_target, double exp_soc_initial, double exp_soc_max, bool exception = false) + { + var dataAdapter = new SerialHybridStrategyParameterDataAdapter(); + + var mass = mass_kg.SI<Kilogram>(); + var Umin_sc = U_min_V.SI<Volt>(); + var Umax_sc = U_max_V.SI<Volt>(); + var Cap_sc = C_F.SI<Farad>(); + + + var scData = new SuperCapData() { + Capacity = Cap_sc, + MaxVoltage = Umax_sc, + MinVoltage = Umin_sc, + }; + if (exception) { + Assert.Throws<VectoException>(() => + dataAdapter.CreateHybridStrategyParameters(null, scData, mass, + VectoRunData.OvcHevMode.ChargeSustaining)); + Assert.Pass(); + } + var parameter = dataAdapter.CreateHybridStrategyParameters(null, scData, mass, VectoRunData.OvcHevMode.ChargeSustaining); + + Assert.AreEqual(exp_soc_target, parameter.TargetSoC, 1E-3); + Assert.AreEqual(exp_soc_min, parameter.MinSoC, 1E-3); + Assert.AreEqual(exp_soc_max, parameter.MaxSoC, 1E-3); + + + Assert.AreEqual(exp_soc_initial, parameter.InitialSoc, 1E-3); + } } \ No newline at end of file -- GitLab