From 280cfab839271c3d545b87e0f18dd6da605bbfa6 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Wed, 23 Mar 2022 10:07:22 +0100 Subject: [PATCH] move calculation of overload buffer, continuous torque etc. from EM to data adapter --- VECTO/GUI/XMLExportJobDialog.Designer.vb | 76 +++++++++---------- .../ComponentData/ElectricMotorMapReader.cs | 4 +- .../EngineeringDataAdapter.cs | 73 +++++++++++++++--- .../EngineeringModeVectoRunDataFactory.cs | 52 +++++++++---- .../Data/ElectricMotor/ElectricMotorData.cs | 33 ++++---- .../SimulationComponent/Impl/ElectricMotor.cs | 36 +++------ .../Impl/PEVAMTShiftStrategy.cs | 8 +- .../Strategies/GensetPreprocessor.cs | 2 +- .../Strategies/SerialHybridStrategy.cs | 4 +- .../FileIO/JsonReadHybridTest.cs | 2 +- .../Models/Declaration/ShiftPolygonTest.cs | 12 +-- .../SimulationComponent/ElectricMotorTest.cs | 18 ++--- .../Utils/MockSimulationDataFactory.cs | 2 +- 13 files changed, 189 insertions(+), 133 deletions(-) diff --git a/VECTO/GUI/XMLExportJobDialog.Designer.vb b/VECTO/GUI/XMLExportJobDialog.Designer.vb index fc21f135f3..6972a2fe18 100644 --- a/VECTO/GUI/XMLExportJobDialog.Designer.vb +++ b/VECTO/GUI/XMLExportJobDialog.Designer.vb @@ -1,27 +1,27 @@ -<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ -Partial Class XMLExportJobDialog - Inherits System.Windows.Forms.Form - - 'Form overrides dispose to clean up the component list. - <System.Diagnostics.DebuggerNonUserCode()> _ - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - Try - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - Finally - MyBase.Dispose(disposing) - End Try - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - <System.Diagnostics.DebuggerStepThrough()> _ - Private Sub InitializeComponent() +<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ +Partial Class XMLExportJobDialog + Inherits System.Windows.Forms.Form + + 'Form overrides dispose to clean up the component list. + <System.Diagnostics.DebuggerNonUserCode()> _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + <System.Diagnostics.DebuggerStepThrough()> _ + Private Sub InitializeComponent() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(XMLExportJobDialog)) Me.lbVendor = New System.Windows.Forms.Label() Me.tbVendor = New System.Windows.Forms.TextBox() @@ -173,18 +173,18 @@ Partial Class XMLExportJobDialog Me.ResumeLayout(false) Me.PerformLayout -End Sub - Private WithEvents lbVendor As System.Windows.Forms.Label - Private WithEvents tbVendor As System.Windows.Forms.TextBox - Private WithEvents btnExport As System.Windows.Forms.Button - Private WithEvents cbSingleFile As System.Windows.Forms.CheckBox - Private WithEvents label1 As System.Windows.Forms.Label - Private WithEvents tbJobfile As System.Windows.Forms.TextBox - Private WithEvents tbMode As System.Windows.Forms.TextBox - Private WithEvents lblJobfile As System.Windows.Forms.Label - Private WithEvents lblDstDir As System.Windows.Forms.Label - Private WithEvents tbDestination As System.Windows.Forms.TextBox - Private WithEvents lblMode As System.Windows.Forms.Label - Private WithEvents btnCancel As System.Windows.Forms.Button +End Sub + Private WithEvents lbVendor As System.Windows.Forms.Label + Private WithEvents tbVendor As System.Windows.Forms.TextBox + Private WithEvents btnExport As System.Windows.Forms.Button + Private WithEvents cbSingleFile As System.Windows.Forms.CheckBox + Private WithEvents label1 As System.Windows.Forms.Label + Private WithEvents tbJobfile As System.Windows.Forms.TextBox + Private WithEvents tbMode As System.Windows.Forms.TextBox + Private WithEvents lblJobfile As System.Windows.Forms.Label + Private WithEvents lblDstDir As System.Windows.Forms.Label + Private WithEvents tbDestination As System.Windows.Forms.TextBox + Private WithEvents lblMode As System.Windows.Forms.Label + Private WithEvents btnCancel As System.Windows.Forms.Button Friend WithEvents BtTCfileBrowse As System.Windows.Forms.Button -End Class +End Class diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs index b664b31c50..9f3ad4bd25 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs @@ -82,7 +82,9 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData { var torquesMinRpm = entries.Where(x => x.MotorSpeed.IsBetween(lowerSpeed, upperSpeed)).OrderBy(x => x.Torque).ToList(); // entries at 0 rpm grid point var torquesZeroRpm = entries.Where(x => x.MotorSpeed.IsEqual(0)).OrderBy(x => x.Torque).ToList(); - + if (torquesZeroRpm.Count == 0) { + throw new VectoException("Electric Motor PowerMap contains no entries at 0 rpm!"); + } var entriesZero = new List<EfficiencyMap.Entry>(); var avgSpeed = torquesMinRpm.Average(x => x.MotorSpeed.Value()).SI<PerSecond>(); diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index 142f3cdf27..e7e13c95ba 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -865,7 +865,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } public List<Tuple<PowertrainPosition, ElectricMotorData>> CreateElectricMachines( - IElectricMachinesEngineeringInputData electricMachines, Dictionary<PowertrainPosition, List<Tuple<Volt, TableData>>> torqueLimits) + IElectricMachinesEngineeringInputData electricMachines, + Dictionary<PowertrainPosition, List<Tuple<Volt, TableData>>> torqueLimits, Volt averageVoltage) { if (electricMachines == null) { return null; @@ -882,11 +883,12 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter return electricMachines.Entries .Select(x => Tuple.Create(x.Position, CreateElectricMachine(x.ElectricMachine, x.Count, x.RatioADC, x.RatioPerGear, x.MechanicalTransmissionEfficiency, - x.MechanicalTransmissionLossMap, torqueLimits?.First(t =>t.Key == x.Position).Value))).ToList(); + x.MechanicalTransmissionLossMap, torqueLimits?.First(t =>t.Key == x.Position).Value, averageVoltage))).ToList(); } private ElectricMotorData CreateElectricMachine(IElectricMotorEngineeringInputData motorData, int count, - double ratio, double[] ratioPerGear, double efficiency, TableData adcLossMap, List<Tuple<Volt, TableData>> torqueLimits) + double ratio, double[] ratioPerGear, double efficiency, TableData adcLossMap, + List<Tuple<Volt, TableData>> torqueLimits, Volt averageVoltage) { var voltageLevels = new List<ElectricMotorVoltageLevelData>(); @@ -901,23 +903,23 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter voltageLevels.Add(new ElectricMotorVoltageLevelData() { Voltage = entry.VoltageLevel, - ContinuousTorque = entry.ContinuousTorque * count, - ContinuousTorqueSpeed = entry.ContinuousTorqueSpeed, - OverloadTorque = (entry.OverloadTorque ?? 0.SI<NewtonMeter>()) * count, - OverloadTestSpeed = entry.OverloadTestSpeed ?? 0.RPMtoRad(), - OverloadTime = entry.OverloadTime, + FullLoadCurve = fullLoadCurveCombined, // DragCurve = ElectricMotorDragCurveReader.Create(entry.DragCurve, count), EfficiencyMap = ElectricMotorMapReader.Create(entry.PowerMap.First().PowerMap, count), //PowerMap }); } + if (averageVoltage == null) { + // if no average voltage is provided (e.g. for supercap) use mean value of measured voltage maps + averageVoltage = (voltageLevels.Min(x => x.Voltage) + voltageLevels.Max(x => x.Voltage)) / 2.0; + } var lossMap = adcLossMap != null ? TransmissionLossMapReader.CreateEmADCLossMap(adcLossMap, ratio, "EM ADC LossMap") : TransmissionLossMapReader.CreateEmADCLossMap(efficiency, ratio, "EM ADC LossMap Eff"); - return new ElectricMotorData() { + var retVal = new ElectricMotorData() { EfficiencyData = new VoltageLevelData() { VoltageLevels = voltageLevels}, DragCurve = ElectricMotorDragCurveReader.Create(motorData.DragCurve, count), Inertia = motorData.Inertia * count, @@ -925,7 +927,58 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter RatioADC = ratio, RatioPerGear = ratioPerGear, TransmissionLossMap = lossMap, - ContinuousTorque = voltageLevels.First().ContinuousTorque, + }; + retVal.Overload = CalculateOverloadData(motorData, count, retVal.EfficiencyData, averageVoltage); + return retVal; + } + + private OverloadData CalculateOverloadData(IElectricMotorEngineeringInputData motorData, int count, VoltageLevelData voltageLevels, Volt averageVoltage) + { + + // if average voltage is outside of the voltage-level range, do not extrapolate but take the min voltage entry, or max voltage entry + if (averageVoltage < motorData.VoltageLevels.Min(x => x.VoltageLevel)) { + return CalculateOverloadBuffer(motorData.VoltageLevels.First(), count, voltageLevels); + } + if (averageVoltage > motorData.VoltageLevels.Max(x => x.VoltageLevel)) { + return CalculateOverloadBuffer(motorData.VoltageLevels.Last(), count, voltageLevels); + } + + var (vLow, vHigh) = motorData.VoltageLevels.OrderBy(x => x.VoltageLevel).GetSection(x => x.VoltageLevel < averageVoltage); + var ovlLo = CalculateOverloadBuffer(vLow, count, voltageLevels); + var ovlHi = CalculateOverloadBuffer(vHigh, count, voltageLevels); + + var retVal = new OverloadData() { + OverloadBuffer = VectoMath.Interpolate(vLow.VoltageLevel, vHigh.VoltageLevel, ovlLo.OverloadBuffer, ovlHi.OverloadBuffer, averageVoltage), + ContinuousTorque = VectoMath.Interpolate(vLow.VoltageLevel, vHigh.VoltageLevel, ovlLo.ContinuousTorque, ovlHi.ContinuousTorque, averageVoltage), + ContinuousPowerLoss = VectoMath.Interpolate(vLow.VoltageLevel, vHigh.VoltageLevel, ovlLo.ContinuousPowerLoss, ovlHi.ContinuousPowerLoss, averageVoltage) + }; + return retVal; + } + + private OverloadData CalculateOverloadBuffer(IElectricMotorVoltageLevel voltageEntry, + int count, VoltageLevelData voltageLevels) + { + var continuousTorque = voltageEntry.ContinuousTorque * count; + var continuousTorqueSpeed = voltageEntry.ContinuousTorqueSpeed; + var overloadTorque = (voltageEntry.OverloadTorque ?? 0.SI<NewtonMeter>()) * count; + var overloadTestSpeed = voltageEntry.OverloadTestSpeed ?? 0.RPMtoRad(); + + + var peakElPwr = voltageLevels.LookupElectricPower(voltageEntry.VoltageLevel, overloadTestSpeed, -overloadTorque, true) + .ElectricalPower; + var peakPwrLoss = -peakElPwr - overloadTorque * overloadTestSpeed; // losses need to be positive + + var contElPwr = voltageLevels.LookupElectricPower(voltageEntry.VoltageLevel, continuousTorqueSpeed, + -continuousTorque).ElectricalPower ?? + voltageLevels.LookupElectricPower(voltageEntry.VoltageLevel, continuousTorqueSpeed, + voltageLevels.FullLoadDriveTorque(voltageEntry.VoltageLevel, continuousTorqueSpeed), + true).ElectricalPower; + var continuousPowerLoss = -contElPwr - continuousTorque * continuousTorqueSpeed; // loss needs to be positive + var overloadBuffer = (peakPwrLoss - continuousPowerLoss) * voltageEntry.OverloadTime; + return new OverloadData() { + OverloadBuffer = overloadBuffer, + ContinuousTorque = continuousTorque, + ContinuousPowerLoss = continuousPowerLoss }; } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs index 76db0e47e8..e40b9957e2 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs @@ -35,12 +35,14 @@ using System.Linq; using System.Runtime.CompilerServices; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery; using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.Utils; @@ -98,11 +100,18 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl var vehicle = InputDataProvider.JobInputData.Vehicle; var engineData = dao.CreateEngineData(vehicle, engineMode); engineData.FuelMode = modeIdx; - + + var battery = dao.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + var superCap = dao.CreateSuperCapData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + + var averageVoltage = battery != null + ? CalculateAverageVoltage(battery) + : null; + var axlegearData = vehicle.Components.AxleGearInputData != null ? dao.CreateAxleGearData(vehicle.Components.AxleGearInputData) : null; - var electricMachinesData = dao.CreateElectricMachines(vehicle.Components.ElectricMachines, vehicle.ElectricMotorTorqueLimits); + var electricMachinesData = dao.CreateElectricMachines(vehicle.Components.ElectricMachines, vehicle.ElectricMotorTorqueLimits, averageVoltage); GearboxData gearboxData = null; ShiftStrategyParameters gearshiftParams = null; @@ -175,12 +184,9 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl var electricMachines = dao.CreateElectricMachines(vehicle.Components.ElectricMachines, - vehicle.ElectricMotorTorqueLimits) ?? + vehicle.ElectricMotorTorqueLimits, averageVoltage) ?? new List<Tuple<PowertrainPosition, ElectricMotorData>>(); - var battery = dao.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); - var superCap = dao.CreateSuperCapData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); - - + var jobType = VectoSimulationJobType.SerialHybridVehicle; var vehicleData = dao.CreateVehicleData(vehicle); @@ -233,7 +239,11 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl ? dao.CreateAxleGearData(vehicle.Components.AxleGearInputData) : null; - var electricMachinesData = dao.CreateElectricMachines(vehicle.Components.ElectricMachines, vehicle.ElectricMotorTorqueLimits); + var batteryData = dao.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + var supercapData = dao.CreateSuperCapData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + + var averageVoltage = batteryData != null ? CalculateAverageVoltage(batteryData) : null; + var electricMachinesData = dao.CreateElectricMachines(vehicle.Components.ElectricMachines, vehicle.ElectricMotorTorqueLimits, averageVoltage); GearboxData gearboxData = null; ShiftStrategyParameters gearshiftParams = null; @@ -297,8 +307,8 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl ExecutionMode = ExecutionMode.Engineering, ElectricMachinesData = electricMachinesData, //HybridStrategyParameters = dao.CreateHybridStrategyParameters(InputDataProvider.JobInputData.HybridStrategyParameters), - BatteryData = dao.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.InitialSOC), - SuperCapData = dao.CreateSuperCapData(vehicle.Components.ElectricStorage, vehicle.InitialSOC), + BatteryData = batteryData, + SuperCapData = supercapData, SimulationType = SimulationType.DistanceCycle | SimulationType.MeasuredSpeedCycle | SimulationType.PWheel, GearshiftParameters = gearshiftParams, ElectricAuxDemand = InputDataProvider.JobInputData.Vehicle.Components.AuxiliaryInputData.Auxiliaries.ElectricPowerDemand, @@ -369,12 +379,15 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl var drivingCycle = CyclesCache.GetOrAdd(cycle.CycleData.Source, _=> DrivingCycleDataReader.ReadFromDataTable(cycle.CycleData, cycle.Name, crossWindRequired)); + var battery = dao.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + var superCap = dao.CreateSuperCapData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + var averageVoltage = battery != null ? CalculateAverageVoltage(battery): null; + var electricMachines = dao.CreateElectricMachines(vehicle.Components.ElectricMachines, - vehicle.ElectricMotorTorqueLimits) ?? + vehicle.ElectricMotorTorqueLimits, averageVoltage) ?? new List<Tuple<PowertrainPosition, ElectricMotorData>>(); - var battery = dao.CreateBatteryData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); - var superCap = dao.CreateSuperCapData(vehicle.Components.ElectricStorage, vehicle.InitialSOC); + var jobType = electricMachines.Count > 0 && (battery != null || superCap != null) @@ -434,5 +447,18 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl } } } + + private Volt CalculateAverageVoltage(BatterySystemData batteryData) + { + // use the battery system to get min/max SoC of the whole battery system (multiple batteries in series/parallel) + // the battery system already contains all necessary models, no need to duplicate here the rather complex calculations + var tmpBattery = new BatterySystem(null, batteryData); + var min = tmpBattery.MinSoC; + var max = tmpBattery.MaxSoC; + var averageSoC = (min + max) / 2.0; + + tmpBattery.Initialize(averageSoC); + return tmpBattery.InternalVoltage; + } } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs index 0563309743..9d0ac85e97 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs @@ -26,10 +26,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [ValidateObject] public VoltageLevelData EfficiencyData { get; internal set; } - // not read direcly from input but calculated in a pre-processing step - public NewtonMeter ContinuousTorque { get; internal set; } - public DragCurve DragCurve { get; internal set; } + + // not read direcly from input but calculated in a pre-processing step + public OverloadData Overload { get; internal set; } } public class VoltageLevelData @@ -146,23 +146,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data { [SIRange(0, double.MaxValue)] public Volt Voltage { get; internal set; } - - [SIRange(double.MinValue, double.MaxValue)] - public NewtonMeter ContinuousTorque { get; internal set; } - - [SIRange(0, double.MaxValue)] - public PerSecond ContinuousTorqueSpeed { get; internal set; } - - [SIRange(double.MinValue, double.MaxValue)] - public NewtonMeter OverloadTorque { get; set; } - - [SIRange(0, double.MaxValue)] - public PerSecond OverloadTestSpeed { get; set; } - - - [SIRange(0, double.MaxValue)] - public Second OverloadTime { get; internal set; } - + [ValidateObject] public ElectricMotorFullLoadCurve FullLoadCurve { get; internal set; } @@ -171,4 +155,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data } + + public class OverloadData + { + public NewtonMeter ContinuousTorque { get; internal set; } + + public Joule OverloadBuffer { get; internal set; } + + public Watt ContinuousPowerLoss { get; internal set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 5cb6d4c91f..630f2da8bb 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -27,11 +27,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public bool DeRatingActive { get; protected internal set; } - public Joule OverloadBuffer { get; } - public NewtonMeter ContinuousTorque { get; } - - public Watt ContinuousPowerLoss { get; } - public BusAuxiliariesAdapter BusAux { protected get; set; } public ElectricMotor(IVehicleContainer container, ElectricMotorData data, IElectricMotorControl control, PowertrainPosition position) : base(container) @@ -50,20 +45,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl container.AddComponent(this); // We have to do this again because in the base class the position is unknown! - var vLevel = ModelData.EfficiencyData.VoltageLevels.First(); - ContinuousTorque = vLevel.ContinuousTorque; - var voltage = ModelData.EfficiencyData.VoltageLevels.First().Voltage; - var contElPwr = - ModelData.EfficiencyData.LookupElectricPower(voltage, vLevel.ContinuousTorqueSpeed, -ContinuousTorque).ElectricalPower ?? - ModelData.EfficiencyData.LookupElectricPower(voltage, vLevel.ContinuousTorqueSpeed, ModelData.EfficiencyData.FullLoadDriveTorque(voltage, vLevel.ContinuousTorqueSpeed), true).ElectricalPower; - ContinuousPowerLoss = -contElPwr - ContinuousTorque * vLevel.ContinuousTorqueSpeed; // loss needs to be positive - - var peakElPwr = ModelData.EfficiencyData.LookupElectricPower(voltage, vLevel.OverloadTestSpeed, -vLevel.OverloadTorque, true) - .ElectricalPower; - var peakPwrLoss = -peakElPwr - vLevel.OverloadTorque * vLevel.OverloadTestSpeed; // losses need to be positive - - OverloadBuffer = (peakPwrLoss - ContinuousPowerLoss) * vLevel.OverloadTime; - if (OverloadBuffer.IsSmallerOrEqual(0) && !(container is SimplePowertrainContainer)) { + if (ModelData.Overload.OverloadBuffer.IsSmallerOrEqual(0) && !(container is SimplePowertrainContainer)) { Log.Error("Overload buffer for thermal de-rating is zero or negative! Please check electric motor data!"); } } @@ -399,7 +381,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private NewtonMeter GetMaxRecuperationTorque(Volt volt, Second dt, PerSecond avgSpeed) { - var tqContinuousPwr = DeRatingActive ? ContinuousTorque : null; + var tqContinuousPwr = DeRatingActive ? ModelData.Overload.ContinuousTorque : null; var maxEmTorque = VectoMath.Min(tqContinuousPwr, ModelData.EfficiencyData.FullGenerationTorque(volt, avgSpeed)); var electricSystemResponse = ElectricPower.Request(0.SI<Second>(), dt, 0.SI<Watt>(), true); @@ -427,7 +409,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private NewtonMeter GetMaxDriveTorque(Volt volt, Second dt, PerSecond avgSpeed) { - var tqContinuousPwr = DeRatingActive ? -ContinuousTorque : null; + var tqContinuousPwr = DeRatingActive ? -ModelData.Overload.ContinuousTorque : null; var maxEmTorque = VectoMath.Max(tqContinuousPwr ,ModelData.EfficiencyData.FullLoadDriveTorque(volt, avgSpeed)); var electricSystemResponse = ElectricPower.Request(0.SI<Second>(), dt, 0.SI<Watt>(), true); @@ -522,9 +504,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl container[ModalResultField.EM_Off_, Position] = CurrentState.EMTorque == null ? 1.SI<Scalar>() : 0.SI<Scalar>(); var losses = (CurrentState.EmTorqueMap ?? 0.SI<NewtonMeter>()) * avgEMSpeed - CurrentState.ElectricPowerToBattery; - var contribution = (losses - ContinuousPowerLoss) * simulationInterval; - if (OverloadBuffer.Value() != 0) { // mk2021-08-03 overloadbuffer was 0 in Test Case: "ADASTestPEV.TestPCCEngineeringSampleCases G5Eng PCC12 Case A" - container[ModalResultField.ElectricMotor_OvlBuffer_, Position] = VectoMath.Max(0, (ThermalBuffer + contribution) / OverloadBuffer); + var contribution = (losses - ModelData.Overload.ContinuousPowerLoss) * simulationInterval; + if (ModelData.Overload.OverloadBuffer.Value() != 0) { // mk2021-08-03 overloadbuffer was 0 in Test Case: "ADASTestPEV.TestPCCEngineeringSampleCases G5Eng PCC12 Case A" + container[ModalResultField.ElectricMotor_OvlBuffer_, Position] = VectoMath.Max(0, (ThermalBuffer + contribution) / ModelData.Overload.OverloadBuffer); } if (NextComponent == null && BusAux != null) { @@ -536,17 +518,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { var avgSpeed = (PreviousState.EMSpeed + CurrentState.EMSpeed) / 2; var losses = (CurrentState.EMTorque ?? 0.SI<NewtonMeter>()) * avgSpeed - CurrentState.ElectricPowerToBattery; - ThermalBuffer += (losses - ContinuousPowerLoss) * simulationInterval; + ThermalBuffer += (losses - ModelData.Overload.ContinuousPowerLoss) * simulationInterval; if (ThermalBuffer < 0) { ThermalBuffer = 0.SI<Joule>(); } if (DeRatingActive) { - if (ThermalBuffer.IsSmallerOrEqual(OverloadBuffer * ModelData.OverloadRegenerationFactor)) { + if (ThermalBuffer.IsSmallerOrEqual(ModelData.Overload.OverloadBuffer * ModelData.OverloadRegenerationFactor)) { DeRatingActive = false; } } else { - if (ThermalBuffer.IsGreater(OverloadBuffer)) { + if (ThermalBuffer.IsGreater(ModelData.Overload.OverloadBuffer)) { DeRatingActive = true; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs index 9505ec1ede..f15e669cb1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs @@ -161,13 +161,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var contTqFld = new ElectricMotorFullLoadCurve(new List<ElectricMotorFullLoadCurve.FullLoadEntry>() { new ElectricMotorFullLoadCurve.FullLoadEntry() { MotorSpeed = 0.RPMtoRad(), - FullDriveTorque = -em.ContinuousTorque, - FullGenerationTorque = em.ContinuousTorque + FullDriveTorque = -em.Overload.ContinuousTorque, + FullGenerationTorque = em.Overload.ContinuousTorque }, new ElectricMotorFullLoadCurve.FullLoadEntry() { MotorSpeed = 1.1 * emFld.MaxSpeed, - FullDriveTorque = -em.ContinuousTorque, - FullGenerationTorque = em.ContinuousTorque + FullDriveTorque = -em.Overload.ContinuousTorque, + FullGenerationTorque = em.Overload.ContinuousTorque } }); var limitedFld = AbstractSimulationDataAdapter.IntersectEMFullLoadCurves(emFld, contTqFld); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/GensetPreprocessor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/GensetPreprocessor.cs index 7f6ba0eaee..dce109a26a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/GensetPreprocessor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/GensetPreprocessor.cs @@ -47,7 +47,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies private void MaxElectricPower(Volt voltage, bool emDerated) { - var continuousTq = emDerated ? Genset.ElectricMotor.ContinuousTorque : double.MaxValue.SI<NewtonMeter>(); + var continuousTq = emDerated ? EmData.Overload.ContinuousTorque : double.MaxValue.SI<NewtonMeter>(); var maxSpeed = VectoMath.Min(EmData.EfficiencyData.MaxSpeed, IceData.FullLoadCurves[0].FullLoadEntries.Select(x => x.EngineSpeed).Max()); var emFldDrivetrain = new ElectricMotorFullLoadCurve(EmData.EfficiencyData.VoltageLevels[0].FullLoadCurve diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/SerialHybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/SerialHybridStrategy.cs index 3ba4c0729c..f64706e76e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/SerialHybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/SerialHybridStrategy.cs @@ -294,8 +294,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies retVal.MechanicalAssistPower[em.Item1] = null; } - GenSetCharacteristics.ContinuousTorque = - (DataBus.ElectricMotorInfo(PowertrainPosition.GEN) as ElectricMotor).ContinuousTorque; + GenSetCharacteristics.ContinuousTorque = ModelData.ElectricMachinesData + .FirstOrDefault(x => x.Item1 == EmPosition)?.Item2.Overload.ContinuousTorque ?? 0.SI<NewtonMeter>(); PreviousState.AngularVelocity = outAngularVelocity; PreviousState.SMState = DataBus.BatteryInfo.StateOfCharge > StrategyParameters.TargetSoC diff --git a/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs b/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs index 0859bde7a6..2e0bf3c6ed 100644 --- a/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs +++ b/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs @@ -145,7 +145,7 @@ namespace TUGraz.VectoCore.Tests.FileIO new JSONComponentInputData(@"TestData\Hybrids\ElectricMotor\GenericEMotorV3.vem", null, false); var daa = new EngineeringDataAdapter(); - var emData = daa.CreateElectricMachines(inputProvider.ElectricMachines, null).First().Item2; + var emData = daa.CreateElectricMachines(inputProvider.ElectricMachines, null, null).First().Item2; Assert.AreEqual(26, emData.DragCurve.Lookup(2000.RPMtoRad()).Value()); diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs index cc0bc9807e..89c56a1bfa 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs @@ -938,7 +938,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var gearboxData = inputData.JobInputData.Vehicle.Components.GearboxInputData; var dao = new EngineeringDataAdapter(); var emData = dao.CreateElectricMachines(inputData.JobInputData.Vehicle.Components.ElectricMachines, - null).FirstOrDefault()?.Item2; + null, null).FirstOrDefault()?.Item2; var axlegearRatio = inputData.JobInputData.Vehicle.Components.AxleGearInputData.Ratio; var vehicleData = dao.CreateVehicleData(inputData.JobInputData.Vehicle); var r_dyn = vehicleData.DynamicTyreRadius; @@ -989,7 +989,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var gearboxData = inputData.JobInputData.Vehicle.Components.GearboxInputData; var dao = new EngineeringDataAdapter(); var emData = dao.CreateElectricMachines(inputData.JobInputData.Vehicle.Components.ElectricMachines, - null).FirstOrDefault()?.Item2; + null, null).FirstOrDefault()?.Item2; var axlegearRatio = inputData.JobInputData.Vehicle.Components.AxleGearInputData.Ratio; var vehicleData = dao.CreateVehicleData(inputData.JobInputData.Vehicle); @@ -999,13 +999,13 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var contTqFld = new ElectricMotorFullLoadCurve(new List<ElectricMotorFullLoadCurve.FullLoadEntry>() { new ElectricMotorFullLoadCurve.FullLoadEntry() { MotorSpeed = 0.RPMtoRad(), - FullDriveTorque = -emData.ContinuousTorque, - FullGenerationTorque = emData.ContinuousTorque + FullDriveTorque = -emData.Overload.ContinuousTorque, + FullGenerationTorque = emData.Overload.ContinuousTorque }, new ElectricMotorFullLoadCurve.FullLoadEntry() { MotorSpeed = 1.1 * emData.EfficiencyData.VoltageLevels.First().FullLoadCurve.MaxSpeed, - FullDriveTorque = -emData.ContinuousTorque, - FullGenerationTorque = emData.ContinuousTorque + FullDriveTorque = -emData.Overload.ContinuousTorque, + FullGenerationTorque = emData.Overload.ContinuousTorque } }); var limitedFld = AbstractSimulationDataAdapter.IntersectEMFullLoadCurves(emData.EfficiencyData.VoltageLevels.First().FullLoadCurve, contTqFld); diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs index a955efe4cf..bbe9cd9cb8 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/ElectricMotorTest.cs @@ -55,13 +55,13 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var emModelData = data.First().Item2; Assert.AreEqual(0.15 * count, emModelData.Inertia.Value(), 1e-3); //Assert.AreEqual(2000, emModelData.ContinuousTorqueSpeed.AsRPM, 1e-3); - Assert.AreEqual(238.7323 * count, emModelData.ContinuousTorque.Value(), 1e-3); + Assert.AreEqual(238.7323 * count, emModelData.Overload.ContinuousTorque.Value(), 1e-3); Assert.AreEqual(334.23 * count, -emModelData.EfficiencyData.VoltageLevels.First().FullLoadCurve.FullLoadDriveTorque(2000.RPMtoRad()).Value(), 1e-3); Assert.AreEqual(-334.23 * count, -emModelData.EfficiencyData.VoltageLevels.First().FullLoadCurve.FullGenerationTorque(2000.RPMtoRad()).Value(), 1e-3); @@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var battery = new MockBattery(); @@ -146,7 +146,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var battery = new MockBattery(); @@ -193,7 +193,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var battery = new MockBattery(); @@ -243,7 +243,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var battery = new MockBattery(); @@ -288,7 +288,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var batInput = JSONInputDataFactory.ReadREESSData(BatFile, false); @@ -352,7 +352,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var tmp = new MockBatteryInputData() @@ -407,7 +407,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent } } }; - var data = dao.CreateElectricMachines(electricMachine, null); + var data = dao.CreateElectricMachines(electricMachine, null, null); var strategy = new MockHybridControl(); var tmp = new MockBatteryInputData() diff --git a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs index 8d7345564e..3c89b0fe24 100644 --- a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs +++ b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs @@ -190,7 +190,7 @@ namespace TUGraz.VectoCore.Tests.Utils Count = count, ElectricMachine = inputData, Position = pos, RatioADC = ratio, MechanicalTransmissionEfficiency = efficiency, } } - }, null); + }, null, null); } -- GitLab