diff --git a/VectoCore/VectoCore/Configuration/Constants.cs b/VectoCore/VectoCore/Configuration/Constants.cs index 5c659f02e6a0b8d5d5a888f03d4b8894929c2a21..041f88d0445dbe460689117370d8c34ac0ad6390 100644 --- a/VectoCore/VectoCore/Configuration/Constants.cs +++ b/VectoCore/VectoCore/Configuration/Constants.cs @@ -60,6 +60,7 @@ namespace TUGraz.VectoCore.Configuration public const string ElectricSystem = "ES"; public const string HeatingVentilationAirCondition = "AC"; public const string PneumaticSystem = "PS"; + public const string Cond = "COND"; public const string PTOConsumer = "PTO_CONSUM"; public const string ENG_AUX_MECH_BASE = "ENG_AUX_BASE"; diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs index 01a86deb2b9e9410f9794a35670775b5a40891f8..70451885b9466be886d939e629b9a386b3ba6c9a 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs @@ -180,9 +180,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen AddConditioning(mission, jobType, retVal, hdvClass); } - - - return retVal; } @@ -195,13 +192,18 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen IsFullyElectric = true, MissionType = mission, DemandType = AuxiliaryDemandType.Dynamic, - ID = "Cond", + ID = Constants.Auxiliaries.IDs.Cond, ConnectToREESS = true, }; - Func<IDataBus, Watt> parallelHybridPowerDemand = (dataBus) => { + VectoRunData.AuxData.PowerDemandFunc parallelHybridPowerDemand = (dataBus, mechPower) => { double xFactor = 0; + if (mechPower == true) + { + throw new NotImplementedException( + "Conditioning only applies to xEVs and should be connected to the DCDC system"); + } var elInfo = dataBus.ElectricMotorInfo(dataBus.PowertrainInfo.ElectricMotorPositions.Single()); if (!elInfo.EmOff) { var iceInfo = dataBus.EngineInfo; @@ -214,8 +216,12 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen return DeclarationData.Conditioning.LookupPowerDemand(hdv, mission) * xFactor; }; - Func<IDataBus, Watt> powerDemandFunc = (dataBus) => { + VectoRunData.AuxData.PowerDemandFunc powerDemandFunc = (dataBus, mechPower) => { var elInfo = dataBus.ElectricMotorInfo(dataBus.PowertrainInfo.ElectricMotorPositions.Single()); + if (mechPower == true) { + throw new NotImplementedException( + "Conditioning only applies to xEVs and should be connected to the DCDC system"); + } if (elInfo.EmOff) { return 0.SI<Watt>(); @@ -233,10 +239,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen throw new VectoException("Should not be created for conventional vehicles"); case VectoSimulationJobType.BatteryElectricVehicle: case VectoSimulationJobType.SerialHybridVehicle: - aux.PowerDemandElectricDataBusFunc = powerDemandFunc; + aux.PowerDemandDataBusFunc = powerDemandFunc; break; case VectoSimulationJobType.ParallelHybridVehicle: - aux.PowerDemandElectricDataBusFunc = parallelHybridPowerDemand; + aux.PowerDemandDataBusFunc = parallelHybridPowerDemand; break; case VectoSimulationJobType.EngineOnlySimulation: case VectoSimulationJobType.IEPC_E: @@ -335,41 +341,44 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen IsFullyElectric = false, ID = Constants.Auxiliaries.IDs.SteeringPump, PowerDemandMech = powerDemand.mechanicalPumps, + MissionType = mission, }; - if (jobType == VectoSimulationJobType.ConventionalVehicle) { - //Add to mechanical steering pump aux - spMech.PowerDemandMech += powerDemand.electricPumps; - } else { - //Create separate auxiliary component for connection to REESS via DC/DC converter - if (powerDemand.electricPumps.IsGreater(0)) + + + if (powerDemand.electricPumps.IsGreater(0)) + { + var spElectric = new VectoRunData.AuxData { - var spElectric = new VectoRunData.AuxData - { - DemandType = AuxiliaryDemandType.Dynamic, - Technology = auxData.Technology.Where(tech => DeclarationData.SteeringPump.IsFullyElectric(tech)) - .ToList(), - IsFullyElectric = true, - ConnectToREESS = true, - ID = Constants.Auxiliaries.IDs.SteeringPump_el, - PowerDemandElectric = powerDemand.electricPumps * alternatorEfficiency, - PowerDemandMech = powerDemand.electricPumps, - - PowerDemandElectricDataBusFunc = (db) => { - if (db.VehicleInfo.VehicleStopped) { - return 0.SI<Watt>(); - } else { - return powerDemand.electricPumps; - } - }, - MissionType = mission, - }; - - auxDataList.Add(spElectric); + DemandType = AuxiliaryDemandType.Constant, + Technology = auxData.Technology.Where(tech => DeclarationData.SteeringPump.IsFullyElectric(tech)) + .ToList(), + IsFullyElectric = true, + ConnectToREESS = true, + ID = Constants.Auxiliaries.IDs.SteeringPump_el, + PowerDemandElectric = powerDemand.electricPumps * alternatorEfficiency, + PowerDemandMech = powerDemand.electricPumps, + + //PowerDemandElectricDataBusFunc = (db, mech) => { + // if (db.VehicleInfo.VehicleStopped) { + // return 0.SI<Watt>(); + // } else { + // return powerDemand.electricPumps; + // } + //}, + MissionType = mission, + }; + + auxDataList.Add(spElectric); + + if (jobType.IsOneOf(VectoSimulationJobType.ConventionalVehicle, + VectoSimulationJobType.EngineOnlySimulation)) { + spElectric.ConnectToREESS = false; } } + if (spMech.PowerDemandMech.IsGreater(0)) { diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs index 3928f2ba0ff4aeebe5992029abe0a7264004bd0e..ad008eab161350a66f210787944bcbcd26b620bc 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -179,6 +179,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public class AuxData { + public delegate Watt PowerDemandFunc(IDataBus dataBus, bool mechPower = true); // ReSharper disable once InconsistentNaming public string ID; @@ -190,7 +191,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data [JsonIgnore] public Func<DrivingCycleData.DrivingCycleEntry, Watt> PowerDemandMechCycleFunc; - [JsonIgnore] public Func<IDataBus, Watt> PowerDemandElectricDataBusFunc; + [JsonIgnore] public PowerDemandFunc PowerDemandDataBusFunc; diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 15a99effe095a7d369e40ebe6056be2f6b85a7d6..a6f947b1992d0332fb893e39f54b054e8f43afb6 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -49,6 +49,7 @@ using TUGraz.VectoCore.Models.SimulationComponent; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Impl.Auxiliaries; using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies; using TUGraz.VectoCore.Models.SimulationComponent.Strategies; using TUGraz.VectoCore.OutputData; @@ -769,8 +770,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl es.Connect(dcdc); var elAux = new ElectricAuxiliaries(container); - elAux.AddAuxiliaries(data.Aux.Where(x => x.ConnectToREESS)); - + + elAux.AddAuxiliaries(data.Aux.Where(x => x.ConnectToREESS && x.ID != Constants.Auxiliaries.IDs.SteeringPump)); + elAux.AddAuxiliary(new SteeringPumpSystem(data.Aux.Where(aux => aux.ID == Constants.Auxiliaries.IDs.SteeringPump).ToArray())); dcdc.Connect(elAux); dcdc.Initialize(); } @@ -1490,6 +1492,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl (nEng, absTime, dt, dryRun) => ptoDrive.PowerDemand(nEng, absTime, dt, dryRun), Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTODuringDrive); } + if (data.PTO != null) { aux.AddConstant(Constants.Auxiliaries.IDs.PTOTransmission, DeclarationData.PTOTransmission.Lookup(data.PTO.TransmissionType).PowerDemand, Constants.Auxiliaries.PowerPrefix + Constants.Auxiliaries.IDs.PTOTransmission); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/DCDCConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/DCDCConverter.cs index 1b308554adfd582f86f249cc9a6bb6ac667d7331..8e5438aa9848389e7d14db6d3368aada1fddab81 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/DCDCConverter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/DCDCConverter.cs @@ -87,7 +87,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent container[ModalResultField.P_DCDC_Out] = consumedEnergy; - + container[ModalResultField.P_DCDC_missing] = 0.SI<Watt>(); + } else { container[ModalResultField.P_DCDC_In] = 0.SI<Watt>(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/Conditioning.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/Conditioning.cs new file mode 100644 index 0000000000000000000000000000000000000000..64950d5d0e52bdec11835a8bd765acfa360a1edd --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/Conditioning.cs @@ -0,0 +1,31 @@ +using System; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Auxiliaries +{ + public class Conditioning + { + + + public Conditioning(VectoRunData.AuxData auxData) + { + if (!auxData.ID.Contains(Constants.Auxiliaries.IDs.Cond)) { + throw new ArgumentException(); + } + + + + + + + + + + + + + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/ElectricAuxiliaries.cs similarity index 69% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/ElectricAuxiliaries.cs index 52b5d7285487afb7bdca9ac28d784237ee146835..ea204b3f6cbce2587faba6ec4bb7e9c1ec96d7c9 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/ElectricAuxiliaries.cs @@ -9,6 +9,8 @@ using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.PrimaryBus; using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Impl.Auxiliaries; using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl @@ -19,8 +21,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// </summary> public class ElectricAuxiliaries : VectoSimulationComponent, IElectricAuxPort { - private IList<VectoRunData.AuxData> _auxData = new List<VectoRunData.AuxData>(4); - + private IDictionary<string, Func<IDataBus, Watt>> _auxData = new Dictionary<string, Func<IDataBus, Watt>>(); private IDictionary<string, string> _auxColumnName = new Dictionary<string, string>(); private IDictionary<string, Watt> _powerDemands = new Dictionary<string, Watt>(); @@ -42,18 +43,28 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Watt Initialize() { - foreach (var auxData in _auxData) { - var name = $"P_{auxData.ID}_el"; - _auxColumnName.Add(auxData.ID, name); //use column name as ID + foreach (var auxId in _auxData.Keys) { + var name = $"P_{auxId}_el"; + _auxColumnName.Add(auxId, name); //use column name as ID VehicleContainer.AddAuxiliary(name, name); } + return 0.SI<Watt>(); } public void AddAuxiliary(VectoRunData.AuxData aux) { - _auxData.Add(aux); + if (aux.DemandType == AuxiliaryDemandType.Constant) { + _auxData.Add(aux.ID, (dataBus) => aux.PowerDemandElectric); + }else if (aux.DemandType == AuxiliaryDemandType.Dynamic) { + _auxData.Add(aux.ID, (dataBus) => aux.PowerDemandDataBusFunc(dataBus, false)); + } + } + + public void AddAuxiliary(IAuxDemand aux) + { + _auxData.Add(aux.AuxID, aux.PowerDemand); } public void AddAuxiliaries(IEnumerable<VectoRunData.AuxData> auxData) @@ -69,16 +80,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var sum = 0.SI<Watt>(); foreach (var aux in _auxData) { - var powerDemand = 0.SI<Watt>(); - if (aux.DemandType == AuxiliaryDemandType.Constant) { - powerDemand = aux.PowerDemandElectric; - } else if(aux.DemandType == AuxiliaryDemandType.Dynamic) { - powerDemand = aux.PowerDemandElectricDataBusFunc(DataBus); - } + var powerDemand = 0.SI<Watt>(); + powerDemand += aux.Value(DataBus); if (!dryRun) { - _powerDemands[aux.ID] = powerDemand; + _powerDemands[aux.Key] = powerDemand; } sum += powerDemand; @@ -98,7 +105,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl foreach (var aux in _auxData) { - container[_auxColumnName[aux.ID]] = _powerDemands[aux.ID]; + container[_auxColumnName[aux.Key]] = _powerDemands[aux.Key]; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/SteeringPump.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/SteeringPump.cs new file mode 100644 index 0000000000000000000000000000000000000000..843172b0756c62c702f46cc14ab7bc5648f2fcde --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Auxiliaries/SteeringPump.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel.Syndication; +using System.Text; +using System.Threading.Tasks; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Auxiliaries +{ + public class SteeringPumpSystem : IAuxDemand + { + private bool ConnectedToREESS = false; + + private List<VectoRunData.AuxData> fullyElectricSp = new List<VectoRunData.AuxData>(); + private List<VectoRunData.AuxData> mechanicalSp = new List<VectoRunData.AuxData>(); + + + + + public SteeringPumpSystem(VectoRunData.AuxData[] spAuxData) + { + if (spAuxData.Any(aux => aux.ID != Constants.Auxiliaries.IDs.SteeringPump)) { + throw new VectoException($"Only steering pumps can be used in {nameof(SteeringPumpSystem)}"); + } + + ConnectedToREESS = spAuxData.All(aux => aux.ConnectToREESS); + if (spAuxData.Any(aux => aux.ConnectToREESS != ConnectedToREESS)) { + throw new VectoException("All steering pumps must be connected to either REESS or Engine"); + } + + if (spAuxData.Any(auxData => auxData.DemandType != AuxiliaryDemandType.Constant)) { + throw new VectoException("Only constant auxiliaries supported"); + } + + if (ConnectedToREESS && spAuxData.Any(aux => !aux.IsFullyElectric)) { + throw new VectoException("Only fully electric steering pumps can be connected to REESS"); + } + + foreach (var aux in spAuxData) { + if (aux.IsFullyElectric) { + fullyElectricSp.Add(aux); + } else { + mechanicalSp.Add(aux); + } + } + } + + + #region Implementation of IAuxDemand + /// <summary> + /// Returns electrical power demand if the SteeringPumpSystem is connected to REESS + /// </summary> + /// <param name="dataBus"></param> + /// <returns></returns> + public Watt PowerDemand(IDataBus dataBus) + { + var powerDemand = 0.SI<Watt>(); + if (!dataBus.VehicleInfo.VehicleStopped) { + powerDemand += fullyElectricSp + .Sum(aux => ConnectedToREESS ? aux.PowerDemandElectric : aux.PowerDemandMech).DefaultIfNull(0); + } + + powerDemand += mechanicalSp.Sum(aux => ConnectedToREESS ? aux.PowerDemandElectric : aux.PowerDemandMech).DefaultIfNull(0); + return powerDemand; + } + + public string AuxID => Constants.Auxiliaries.IDs.SteeringPump; + + #endregion + } + + public interface IAuxDemand + { + Watt PowerDemand(IDataBus dataBus); + + string AuxID { get; } + } +} diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs index 2cc4505bd9d9a7905ba09c52ccc134ccf615e4d6..e3a2ca416a5298d3282f3fde0f8ee7b1b9508a30 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs @@ -91,6 +91,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } + /// <summary> /// Adds an auxiliary with a function returning the power demand based on the engine speed. /// </summary> @@ -144,9 +145,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { var auxiliarieIgnoredDuringVehicleStop = new[] { - Constants.Auxiliaries.IDs.SteeringPump, Constants.Auxiliaries.IDs.Fan, - Constants.Auxiliaries.IDs.PTOConsumer, Constants.Auxiliaries.IDs.PTOTransmission, - Constants.Auxiliaries.IDs.ENG_AUX_MECH_FAN, Constants.Auxiliaries.IDs.ENG_AUX_MECH_STP + Constants.Auxiliaries.IDs.SteeringPump, + Constants.Auxiliaries.IDs.Fan, + Constants.Auxiliaries.IDs.PTOConsumer, + Constants.Auxiliaries.IDs.PTOTransmission, + Constants.Auxiliaries.IDs.ENG_AUX_MECH_FAN, + Constants.Auxiliaries.IDs.ENG_AUX_MECH_STP }; var auxiliarieIgnoredDuringDrive = new[] { Constants.Auxiliaries.IDs.Fan,