diff --git a/Documentation/User Manual/3-simulation-models/Electric_Motor.md b/Documentation/User Manual/3-simulation-models/Electric_Motor.md index b193137cd5666a7f8d83fd7f99e24fe1661fe787..0c2444186e1e61bf2f1fbb227f0024965f08bb68 100644 --- a/Documentation/User Manual/3-simulation-models/Electric_Motor.md +++ b/Documentation/User Manual/3-simulation-models/Electric_Motor.md @@ -14,9 +14,32 @@ The first two curves are read from a single .vemp file (see [Electric Motor Max The convention for all input files is that positive torque values drive the vehicle while negative torque values apply additional drag and generate electric power. +The follwing picture shows the signals used in VECTO and provided in the .vmod file. The VECTO convention is that positive torque adds additional drag to the drivetrain. Thus, if the electric motor propells the vehicle it applies negative torque.  +###Electric Motor Model + +The VECTO component for the electric motor contains the electric motor itself which is connected via a transmission stage to the drivetrain. The ratio and efficiency of the transmission stage can be defined in the vehicle model. + + + +The naming convention for the signals is that 'X' denotes the position of the EM in the powertrain. P_X_... denotes signals related to the drivetrain speed while P_X-em_... denotes signals to the electric motor shaft. + +P_X_in = P_X_out + P_X_mech + +P_X_mech = P_X-em_mech + P_X_transm_loss + +P_X-em_mech = P_X-em_mech_elmap + P_X-em_inertia + +P_X-em_mech_elmap = P_X-em_el + P_X-em_loss + +P_X-em_mech_elmap = n_X-em * T_X-em_map + +P_X-em_el = PowerMap(n_X-em, T_X-em_map) + +P_X_loss = P_X_mech - P_X-em_el + ###Thermal De-Rating @@ -27,13 +50,14 @@ The basic principal of the thermal de-rating is as follows: based on the continu $E_\textrm{th,buf} = P_\textrm{loss,cont} * t_\textrm{ovl}$ -$P_\textrm{loss,cont} = P_\textrm{map, el}(\frac{P_\textrm{cont}}{n_\textrm{P, cont}}, n_\textrm{P, cont}) - P_\textrm{cont}$ +$P_\textrm{loss,cont} = P_\textrm{cont} - P_\textrm{map, el}(\frac{P_\textrm{cont}}{n_\textrm{P, cont}}, n_\textrm{P, cont})$ In every simulation step the losses of the electric machine are accumulated: -$E_{\textrm{ovl,} i + 1} = E_{\textrm{ovl,} i} + P_\textrm{loss, i} * dt$ +$E_{\textrm{ovl,} i + 1} = E_{\textrm{ovl,} i} + (P_\textrm{loss, i} - P_\textrm{loss,cont}) * dt$ $P_\textrm{loss, i} = T_\textrm{em, mech} * n_\textrm{em} - P_\textrm{map, el}(T_\textrm{em, mech}, n_\textrm{em})$ + If $E_\textrm{ovl, i}$ reaches the overload capacity $E_\textrm{th,buf}$ the power of the electric machine is limited to the continuous power until $E_\textrm{ovl,i}$ goes below the overload capacity multiplied by a certain factor. Then the maximum torque is available again. diff --git a/Documentation/User Manual/5-input-and-output-files/VMOD.md b/Documentation/User Manual/5-input-and-output-files/VMOD.md index 65e207e96b249638aa7c9d693943d389cd8a1e0b..5b98fd21e62d036b4d38b62ac37d69d42694119c 100644 --- a/Documentation/User Manual/5-input-and-output-files/VMOD.md +++ b/Documentation/User Manual/5-input-and-output-files/VMOD.md @@ -97,18 +97,26 @@ $P_{avg} = \frac{1}{simulation interval} \int{P(t) dt}$. | PCCSegment | | 1 if a PCC segment was identified in the pre-processing (gradient below threshold where vehicle accelerates on its own without engine power) , 0 otherwise | | PCCState | | 0: not inside PCC segment, 1: inside PCC segment, 2: PCC use-case 1 active, 3: PCC use-case 2 active | | ICE On | | 0 if the combustion engine is switched off (either during stand-still or eco-roll), 1 otherwise | -| n_em<\_POS> | [rpm] | Angular speed of the electric motor at position *POS* | -| T_em<\_POS> | [Nm] | Torque applied by the electric motor at position *POS*.Positive values mean that the electric motor acts as generator, negative torque values mean that the electric motor propels the vehicle | -| T_em<\_POS>\_mot_max | [Nm] | Maximum torque the electric machine can apply to propel the vehicle. This already considers the maximum current the battery can provide | -| T_em<\_POS>\_gen_max | [Nm] | Maximum torque the electric machine can apply to generate electric power. This already considers the maximum charge current the battery can handle. | -| P_em<\_POS>\_in | [kW] | Power at the electric machine's input shaft | -| P_em<\_POS>\_out | [kW] | Power at the electric machine's output shaft | -| P_em<\_POS>\_mech | [kW] | Mechanical power the electric machine applies to the drivetrain. Positive values mean that electric energy is generated while negative values mean that the electric machine drives the vehicle. | -| P_em<\_POS>\_el | [kW] | Electric power generated or consumed by the elctric machine | -| P_em<\_POS>\_drive_max | [kW] | Maximum power the electric motor can provide to drive the vehicle. This already considers the maximum electric power the battery can provide. | -| P_em<\_POS>\_gen_max | [kW] | Maximum power the electric machine can generate. This already considers the maximum charge power the battery can handle. | -| P_em<\_POS>\_loss | [kW] | Losses in the electric machine due to converting electric power to mechanical power | -| P_em<\_POS>\_inertia_loss | [kW] | Inertia loses of the electric machine | +| i\_<POS}-em | [-] | Ratio between drivetrain and electric motor shaft +| n\_<POS>-em_avg | [rpm] | Angular speed of the electric motor at position *POS* | +| T\_<POS>-em | [Nm] | Torque at the shaft of electric motor at position *POS*. Positive values mean that the electric motor acts as generator, negative torque values mean that the electric motor propels the vehicle | +| T\_<POS>-em_map | [Nm] | Torque internal torque of the electric motor at posision *POS*. Takes into account the electric motor's intertia. Positive values mean that the electric motor acts as generator, negative torque values mean that the electric motor propels the vehicle | +| T\_<POS>-em_drive_max | [Nm] | Maximum torque the electric machine can apply to propel the vehicle. This already considers the maximum current the battery can provide | +| T\_<POS>-em_gen_max | [Nm] | Maximum torque the electric machine can apply to generate electric power. This already considers the maximum charge current the battery can handle. | +| P\_<POS>-em_drive_max | [kW] | Maximum power the electric motor can provide to drive the vehicle. This already considers the maximum electric power the battery can provide. | +| P\_<POS>-em_gen_max | [kW] | Maximum power the electric machine can generate. This already considers the maximum charge power the battery can handle. | +| P\_<POS>-em_mech | [kW] | Power at the shaft of the electric motor at position *POS* | +| P\_<POS>-em_mech_map | [kW] | Mechanical powerthe electric motor at position *POS* applies for driving or recuperation, including the electric motor's inertia | +| P\_<POS>-em_el | [kW] | Electric power generated or consumed by the elctric machine | +| P\_<POS>-em_loss | [kW] | Losses in the electric machine due to converting electric power to mechanical power | +| P\_<POS>-em_inertia_loss | [kW] | Inertia loses of the electric machine | +| P\_<POS>\_in | [kW] | Power at the electric machine's input shaft (drivetrain) | +| P\_<POS>\_out | [kW] | Power at the electric machine's output shaft (drivetrain) | +| P\_<POS>\_mech | [kW] | Mechanical power the electric machine applies to the drivetrain. Positive values mean that electric energy is generated while negative values mean that the electric machine drives the vehicle. | +| P\_<POS>\_loss | [kW] | The total sum of losses of the electric motor at position *POS*. Calcualted as the difference of mecanical power applied at the drivetrain and the electrical power drawn from the REESS. | +| P\_<POS>\_transm_loss | [kW] | Losses of the transmission stage inside the electric motor component | +| EM_OVL-<POS>-em | [%] | Used capacity of the thermal overload buffer of the thermal derating model | +| EM_<POS>_off | [-] | Indicates if the electric motor at position *POS* is energized or not. | | P_bat_T | [kW] | Electric power provided at the battery's connector | | P_bat_int | [kW] | Internal battery power | | P_bat_loss | [kW] | Losses of the battery due to its internal resistance. | diff --git a/Documentation/User Manual/5-input-and-output-files/VSUM.md b/Documentation/User Manual/5-input-and-output-files/VSUM.md index cb0b2366ad5f968fa23ffdea4ac61833a71f3a6f..bb5ceeccc23376c9a193ae6edc98e019622376fe 100644 --- a/Documentation/User Manual/5-input-and-output-files/VSUM.md +++ b/Documentation/User Manual/5-input-and-output-files/VSUM.md @@ -79,12 +79,19 @@ The .vsum file includes total / average results for each calculation run in one | DecelerationTimeShare | [%] | Time share of deceleration phases (a~3s~ \< 0.125 \[m/s^2^\], a~3s~ = 3-seconds-averaged acceleration) | | CruiseTimeShare | [%] | Time share of cruise phases (-0.125 ≤ a~3s~ ≤ 0.125 \[m/s^2^\]) | | StopTimeShare | [%] | Time share of stop phases (v \< 0.1 \[m/s\]) | -| E_EM_<\_POS>\_drive | [kWh] | Mechanical energy applied by the electric machine at position *POS* to drive the vehicle | -| E_EM_<\_POS>\_gen | [kWh] | Mechanical energy recuperated by the electric machine at position *POS* | -| n_EM_<\_POS>\_avg | [rpm] | Average angular speed of the electric machine | -| η_EM_<\_POS>\_mot | [-] | Average efficiency of the electric machine when the electric machine drives the vehicle | -| η_EM_<\_POS>\_gen | [-] | Average efficiency of the electric machine when the electric machine generates electric energy | -| E_EM_<\_POS>\_off_loss | [kWh] | Total losses added by the electric machine when the electric machine is not energized (i.e., the electric machine's drag losses) | +| E_EM_<POS>\_drive | [kWh] | Mechanical energy applied at the drivetrain by the electric machine at position *POS* to drive the vehicle | +| E_EM_<POS>\_gen | [kWh] | Mechanical energy at the drivetrain recuperated by the electric machine at position *POS* | +| η_EM_<POS>\_drive | [-] | Average efficiency at the drivetrain of the electric machine when the electric machine drives the vehicle. Based on the mechanical energy at the drivetrain and the electric power. | +| η_EM_<POS>\_gen | [-] | Average efficiency at the drivetrain of the electric machine when the electric machine generates electric energy. Based on the mechanical energy at the drivetrain and the electric power | +| E_EM_<POS>-em_drive | [kWh] | Mechanical energy at the electric motor shaft applied by the electric machine at position *POS* to drive the vehicle | +| E_EM_<POS>-em_gen | [kWh] | Mechanical energy at the electric motor shaft recuperated by the electric machine at position *POS* | +| η_EM_<POS>-em_drive | [-] | Average efficiency of the electric machine when the electric machine drives the vehicle. Based on the mechanical energy at the electric motor shaft and the electric energy. | +| η_EM_<POS>-em_gen | [-] | Average efficiency of the electric machine when the electric machine generates electric energy. Based on the mechanical energy at the electric motor shaft and the electric energy. | +| n_EM_<POS>\_avg | [rpm] | Average angular speed of the electric machine | +| E_EM_<POS>\_off_loss | [kWh] | Total losses added by the electric machine when the electric machine is not energized (i.e., the electric machine's drag losses) | +| E_EM_<POS>\_transm_loss | [kWh] | Losses of the transmission stage in the electric motor component. | +| E_EM_<POS>-em_loss | [kWh] | Total losses of the electric motor component. Calculated from P_<POS>-em_loss | +| E_EM_<POS>\_loss | [kWh] | Losses of the electric machine. Calculated from P_<POS>_loss | | Battery Start SoC | [%] | Battery state of charge at the beginning of the simulation run | | Battery End SoC | [%] | Battery state of charge at the end of the simulation run | | Battery Delta SoC | [kWh] | Difference of the energy stored in the battery between the beginning and end of the simulation run | diff --git a/Documentation/User Manual/OriginalPictures/EM_Model.png b/Documentation/User Manual/OriginalPictures/EM_Model.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc51b583bcd8f71fbe070a28f8523bc62cfdced Binary files /dev/null and b/Documentation/User Manual/OriginalPictures/EM_Model.png differ diff --git a/Documentation/User Manual/pics/EM_Model_scaled.png b/Documentation/User Manual/pics/EM_Model_scaled.png new file mode 100644 index 0000000000000000000000000000000000000000..bece268af3058d7659c76a46592cf8080c4f8162 Binary files /dev/null and b/Documentation/User Manual/pics/EM_Model_scaled.png differ diff --git a/VECTO/GUI/ElectricMotorForm.vb b/VECTO/GUI/ElectricMotorForm.vb index 8b4ae442683cce4b45c79a3d0fce330ba418debe..4708d71435d91e877e0d11679754dd7536587cc9 100644 --- a/VECTO/GUI/ElectricMotorForm.vb +++ b/VECTO/GUI/ElectricMotorForm.vb @@ -360,21 +360,21 @@ Public Class ElectricMotorForm Dim fldFile As String = If(Not String.IsNullOrWhiteSpace(_emFile), Path.Combine(Path.GetDirectoryName(_emFile), tbMaxTorque.Text), tbDragTorque.Text) If File.Exists(fldFile) Then _ - fullLoadCurve = ElectricFullLoadCurveReader.Create(VectoCSVFile.Read(fldFile), 1.0, 1, 1.0) + fullLoadCurve = ElectricFullLoadCurveReader.Create(VectoCSVFile.Read(fldFile), 1) Catch ex As Exception End Try Try Dim fcFile As String = If(Not String.IsNullOrWhiteSpace(_emFile), Path.Combine(Path.GetDirectoryName(_emFile), tbMap.Text), tbMap.Text) - If File.Exists(fcFile) Then fcMap = ElectricMotorMapReader.Create(VectoCSVFile.Read(fcFile), 1.0, 1, 1.0) + If File.Exists(fcFile) Then fcMap = ElectricMotorMapReader.Create(VectoCSVFile.Read(fcFile), 1) Catch ex As Exception End Try Try Dim dragFile As String = If(Not String.IsNullOrWhiteSpace(_emFile), Path.Combine(Path.GetDirectoryName(_emFile), tbDragTorque.Text), tbMap.Text) - If File.Exists(dragFile) Then dragCurve = ElectricMotorDragCurveReader.Create(VectoCSVFile.Read(dragFile), 1.0, 1, 1.0) + If File.Exists(dragFile) Then dragCurve = ElectricMotorDragCurveReader.Create(VectoCSVFile.Read(dragFile), 1) Catch ex As Exception End Try diff --git a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs index 31645d5c81d8555ce5d44921c4b6ded8df891754..c886e3319d5d0131518520fe40ed468360f28795 100644 --- a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs +++ b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs @@ -18,7 +18,9 @@ namespace TUGraz.VectoCommon.Models { public class HybridStrategyResponse : AbstractComponentResponse, IHybridStrategyResponse { public Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> MechanicalAssistPower; - public bool ShiftRequired { get; set; } + + public Second SimulationInterval; + public bool ShiftRequired { get; set; } public uint NextGear { get; set; } public bool GearboxInNeutral { get; set; } public bool CombustionEngineOn { get; set; } @@ -30,6 +32,8 @@ namespace TUGraz.VectoCommon.Models { [DebuggerDisplay("{U}: {Score} - G{Gear}")] public class HybridResultEntry { + public Second SimulationInterval + ; public double U { get; set; } public HybridStrategyResponse Setting { get; set; } diff --git a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs index e16fbf0189cfe682fc373b15e1dec7334b34374b..203705d3cb20006867e3817104ba310ee427efd6 100644 --- a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs +++ b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs @@ -12,9 +12,9 @@ namespace TUGraz.VectoCommon.InputData { HybridP3, HybridP4, - BatteryElectricB4, - BatteryElectricB3, - BatteryElectricB2, + BatteryElectricE4, + BatteryElectricE3, + BatteryElectricE2, } public static class PowertrainPositionHelper @@ -29,6 +29,9 @@ namespace TUGraz.VectoCommon.InputData { } if (pos.StartsWith("B", StringComparison.InvariantCultureIgnoreCase)) { + return (BatteryElectriPrefix + pos.Replace("B", "E")).ParseEnum<PowertrainPosition>(); + } + if (pos.StartsWith("E", StringComparison.InvariantCultureIgnoreCase)) { return (BatteryElectriPrefix + pos).ParseEnum<PowertrainPosition>(); } throw new VectoException("invalid powertrain position {0}", pos); @@ -54,8 +57,8 @@ namespace TUGraz.VectoCommon.InputData { public static bool IsBatteryElectric(this PowertrainPosition pos) { - return pos == PowertrainPosition.BatteryElectricB2 || pos == PowertrainPosition.BatteryElectricB3 || - pos == PowertrainPosition.BatteryElectricB4; + return pos == PowertrainPosition.BatteryElectricE2 || pos == PowertrainPosition.BatteryElectricE3 || + pos == PowertrainPosition.BatteryElectricE4; } public static bool IsParallelHybrid(this PowertrainPosition pos) diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricFullLoadCurveReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricFullLoadCurveReader.cs index 06990cb404a896066fce82d589daa85044574a75..d242372c60bb8693b4cce593d4ceba5b7e8708cb 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricFullLoadCurveReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricFullLoadCurveReader.cs @@ -9,7 +9,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData { public static class ElectricFullLoadCurveReader { - public static ElectricMotorFullLoadCurve Create(DataTable data, double ratio, int count, double efficiency) + public static ElectricMotorFullLoadCurve Create(DataTable data, int count) { if (data.Columns.Count < 3) { throw new VectoException("Motor FullLoadCurve Data must contain at least 3 columns"); @@ -27,9 +27,9 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData return new ElectricMotorFullLoadCurve( (from DataRow row in data.Rows select new ElectricMotorFullLoadCurve.FullLoadEntry { - MotorSpeed = row.ParseDouble(Fields.MotorSpeed).RPMtoRad() / ratio, - FullDriveTorque = -row.ParseDouble(Fields.DrivingTorque).SI<NewtonMeter>() * count * ratio * efficiency, - FullGenerationTorque = -row.ParseDouble(Fields.GenerationTorque).SI<NewtonMeter>() * count * ratio / efficiency + MotorSpeed = row.ParseDouble(Fields.MotorSpeed).RPMtoRad(), // / ratio, + FullDriveTorque = -row.ParseDouble(Fields.DrivingTorque).SI<NewtonMeter>() * count, // * ratio * efficiency, + FullGenerationTorque = -row.ParseDouble(Fields.GenerationTorque).SI<NewtonMeter>() * count, //* ratio / efficiency }).ToList()); } @@ -51,7 +51,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData public static class ElectricMotorDragCurveReader { - public static DragCurve Create(DataTable data, double ratio, int count, double efficiency) + public static DragCurve Create(DataTable data, int count) { if (data.Columns.Count < 2) { throw new VectoException("Drag Curve must contain at least 2 columns"); @@ -66,8 +66,8 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData data.Columns[1].ColumnName = Fields.DragTorque; } return new DragCurve(data.AsEnumerable().Cast<DataRow>().Select(x => new DragCurve.DragLoadEntry() { - MotorSpeed = x.ParseDouble(Fields.MotorSpeed).RPMtoRad() / ratio, - DragTorque = -x.ParseDouble(Fields.DragTorque).SI<NewtonMeter>() * ratio * count / efficiency + MotorSpeed = x.ParseDouble(Fields.MotorSpeed).RPMtoRad(), // / ratio, + DragTorque = -x.ParseDouble(Fields.DragTorque).SI<NewtonMeter>() * count, // * ratio / efficiency }).ToList()); } diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs index 27bb374a263e2bdf05db403e1b5e691739602a16..73cf6ca8ad478501e41d69565ce4a34181faab48 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs @@ -12,12 +12,12 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.InputData.Reader.ComponentData { public static class ElectricMotorMapReader { - public static EfficiencyMap Create(Stream data, double ratio, int count, double efficiency) + public static EfficiencyMap Create(Stream data, int count) { - return Create(VectoCSVFile.ReadStream(data), ratio, count, efficiency); + return Create(VectoCSVFile.ReadStream(data), count); } - public static EfficiencyMap Create(DataTable data, double ratio, int count, double efficiency) + public static EfficiencyMap Create(DataTable data, int count) { var headerValid = HeaderIsValid(data.Columns); if (!headerValid) @@ -37,12 +37,12 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData { { var entry = CreateEntry(row); if (entry.Torque.IsGreaterOrEqual(0)) { - delaunayMap.AddPoint(-entry.Torque.Value() * count * ratio * efficiency, - entry.MotorSpeed.Value() / ratio, + delaunayMap.AddPoint(-entry.Torque.Value() * count, // * ratio * efficiency, + entry.MotorSpeed.Value(), // / ratio, -entry.PowerElectrical.Value() * count); } else { - delaunayMap.AddPoint(-entry.Torque.Value() * count * ratio / efficiency, - entry.MotorSpeed.Value() / ratio, + delaunayMap.AddPoint(-entry.Torque.Value() * count, // * ratio / efficiency, + entry.MotorSpeed.Value(), // / ratio, -entry.PowerElectrical.Value() * count); } } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index 488da9e14cd1612a433d8d14a64ba7d92ce58c51..f41a99b7755e68e48764700393593299ecd2a17f 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -680,14 +680,16 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter double ratio, double efficiency) { return new ElectricMotorData() { - FullLoadCurve = ElectricFullLoadCurveReader.Create(motorData.FullLoadCurve, ratio, count, efficiency), - DragCurve = ElectricMotorDragCurveReader.Create(motorData.DragCurve, ratio, count, efficiency), - EfficiencyMap = ElectricMotorMapReader.Create(motorData.EfficiencyMap, ratio, count, efficiency), + FullLoadCurve = ElectricFullLoadCurveReader.Create(motorData.FullLoadCurve, count), + DragCurve = ElectricMotorDragCurveReader.Create(motorData.DragCurve, count), + EfficiencyMap = ElectricMotorMapReader.Create(motorData.EfficiencyMap, count), Inertia = motorData.Inertia, ContinuousPower = motorData.ContinuousPower * count, ContinuousPowerSpeed = motorData.ContinuousPowerSpeed, OverloadTime = motorData.OverloadTime, OverloadRegenerationFactor = motorData.OverloadRecoveryFactor, + Ratio = ratio, + TransmissionEfficiency = efficiency }; } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs index bc03c0e2b584748a7b24422d1bf0543f1bb73b84..5d1b932354fe85a23550bd1be8f888b2c3fb0106 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs @@ -93,7 +93,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl GearboxData gearboxData = null; ShiftStrategyParameters gearshiftParams = null; AngledriveData angledriveData = null; - if (electricMachinesData.Any(x => x.Item1 == PowertrainPosition.BatteryElectricB2)) { + if (electricMachinesData.Any(x => x.Item1 == PowertrainPosition.BatteryElectricE2)) { // gearbox required! var tmpRunData = new VectoRunData() { JobType = VectoSimulationJobType.BatteryElectricVehicle, diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 9ddc1f14dd9f6c240045176430f56acb9791e9a8..0833e78d6e58da38f2f829238ad86513fab18413 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -639,7 +639,7 @@ namespace TUGraz.VectoCore.Models.Declaration } public static ShiftPolygon ComputeElectricMotorShiftPolygon(int gearIdx, - ElectricMotorFullLoadCurve fullLoadCurve, IList<ITransmissionInputData> gears, + ElectricMotorFullLoadCurve fullLoadCurve, double emRatio, IList<ITransmissionInputData> gears, double axlegearRatio, Meter dynamicTyreRadius) { if (gears.Count < 2) { @@ -649,16 +649,16 @@ namespace TUGraz.VectoCore.Models.Declaration var downShift = new List<ShiftPolygon.ShiftPolygonEntry>(); var upShift = new List<ShiftPolygon.ShiftPolygonEntry>(); if (gearIdx > 0) { - downShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxGenerationTorque * 1.1, 0.RPMtoRad())); - downShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDriveTorque * 1.1, 0.RPMtoRad())); + downShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxGenerationTorque * emRatio * 1.1, 0.RPMtoRad())); + downShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDriveTorque * emRatio * 1.1, 0.RPMtoRad())); } if (gearIdx >= gears.Count - 1) { return new ShiftPolygon(downShift, upShift); } - upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxGenerationTorque * 1.1, fullLoadCurve.MaxSpeed * 0.9)); - upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDriveTorque * 1.1, fullLoadCurve.MaxSpeed * 0.9)); + upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxGenerationTorque * emRatio * 1.1, fullLoadCurve.MaxSpeed / emRatio * 0.9)); + upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDriveTorque * emRatio * 1.1, fullLoadCurve.MaxSpeed / emRatio * 0.9)); return new ShiftPolygon(downShift, upShift); } diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs index 2bc2cc74bd0b2f55a0f82ddb770bfeb8634a7636..bd64deffcbce45f302914033871229458b072be3 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs @@ -378,37 +378,49 @@ namespace TUGraz.VectoCore.Models.Simulation.Data [ModalResultField(typeof(SI), "P_WHR_mech [kW]", outputFactor: 1e-3)] P_WHR_mech_map, [ModalResultField(typeof(SI), "P_WHR_mech_corr [kW]", outputFactor: 1e-3)] P_WHR_mech_corr, - [ModalResultField(typeof(SI), caption: "n_em-{0}_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_electricMotor_, - [ModalResultField(typeof(SI), caption: "T_em-{0} [Nm]")] T_electricMotor_, - [ModalResultField(typeof(SI), caption: "T_em-{0}_drive_max [Nm]")] T_electricMotor_drive_max_, - [ModalResultField(typeof(SI), caption: "T_em-{0}_gen_max [Nm]")] T_electricMotor_gen_max_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_in [kW]", outputFactor: 1e-3)] P_electricMotor_in_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_out [kW]", outputFactor: 1e-3)] P_electricMotor_out_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_el [kW]", outputFactor: 1e-3)] P_electricMotor_el_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_gen_max_ [kW]", outputFactor: 1e-3)] P_electricMotor_gen_max_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_drive_max [kW]", outputFactor: 1e-3)] P_electricMotor_drive_max_, - //[ModalResultField(typeof(SI), caption: "P_em-{0}_brake [kW]", outputFactor: 1e-3)] P_electricMotor_brake_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_loss [kW]", outputFactor: 1e-3)] P_electricMotorLoss_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_transm_loss [kW]", outputFactor: 1e-3)] P_electricMotorTransmissionLoss_, - [ModalResultField(typeof(SI), caption: "P_em-{0}_inertia_loss [kW]", outputFactor: 1e-3)] P_electricMotorInertiaLoss_, - [ModalResultField(typeof(SI), caption: "EM-{0}_OverloadBuffer [%]", outputFactor: 100)] ElectricMotor_OvlBuffer_, + [ModalResultField(typeof(SI), caption: "i_{0}-em [-]")] EM_ratio_, + [ModalResultField(typeof(SI), caption: "n_{0}-em_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_EM_electricMotor_, + [ModalResultField(typeof(SI), caption: "T_{0}-em [Nm]")] T_EM_electricMotor_, + [ModalResultField(typeof(SI), caption: "T_{0}-em_map [Nm]")] T_EM_electricMotor_map_, + + [ModalResultField(typeof(SI), caption: "T_{0}-em_drive_max [Nm]")] T_EM_electricMotor_drive_max_, + [ModalResultField(typeof(SI), caption: "T_{0}-em_gen_max [Nm]")] T_EM_electricMotor_gen_max_, + [ModalResultField(typeof(SI), caption: "P_{0}-em_gen_max_ [kW]", outputFactor: 1e-3)] P_EM_electricMotor_gen_max_, + [ModalResultField(typeof(SI), caption: "P_{0}-em_drive_max [kW]", outputFactor: 1e-3)] P_EM_electricMotor_drive_max_, + + [ModalResultField(typeof(SI), caption: "P_{0}-em_mech [kW]", outputFactor: 1e-3)] P_EM_electricMotor_em_mech_, + [ModalResultField(typeof(SI), caption: "P_{0}-em_mech_map [kW]", outputFactor: 1e-3)] P_EM_electricMotor_em_mech_map_, + [ModalResultField(typeof(SI), caption: "P_{0}-em_el [kW]", outputFactor: 1e-3)] P_EM_electricMotor_el_, + [ModalResultField(typeof(SI), caption: "P_{0}-em_loss [kW]", outputFactor: 1e-3)] P_EM_electricMotorLoss_, + [ModalResultField(typeof(SI), caption: "P_{0}-em_inertia_loss [kW]", outputFactor: 1e-3)] P_EM_electricMotorInertiaLoss_, + + [ModalResultField(typeof(SI), caption: "P_{0}_in [kW]", outputFactor: 1e-3)] P_EM_in_, + [ModalResultField(typeof(SI), caption: "P_{0}_out [kW]", outputFactor: 1e-3)] P_EM_out_, + [ModalResultField(typeof(SI), caption: "P_{0}_mech [kW]", outputFactor: 1e-3)] P_EM_mech_, + [ModalResultField(typeof(SI), caption: "P_{0}_loss [kW]", outputFactor: 1e-3)] P_EM_loss_, + + [ModalResultField(typeof(SI), caption: "P_{0}_transm_loss [kW]", outputFactor: 1e-3)] P_EM_TransmissionLoss_, + + [ModalResultField(typeof(SI), caption: "EM_OVL-{0}-em [%]", outputFactor: 100)] ElectricMotor_OvlBuffer_, + + [ModalResultField(typeof(SI), caption: "EM_{0}_off")] EM_Off_, + // only for graphDrawing Testcase - [ModalResultField(typeof(SI), caption: "P_em-P2_mech [kW]", outputFactor: 1e-3)] + [ModalResultField(typeof(SI), caption: "P_P2_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_P2, - [ModalResultField(typeof(SI), caption: "P_em-P3_mech [kW]", outputFactor: 1e-3)] + [ModalResultField(typeof(SI), caption: "P_P3_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_P3, - [ModalResultField(typeof(SI), caption: "P_em-P4_mech [kW]", outputFactor: 1e-3)] + [ModalResultField(typeof(SI), caption: "P_P4_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_P4, - [ModalResultField(typeof(SI), caption: "P_em-B4_mech [kW]", outputFactor: 1e-3)] + [ModalResultField(typeof(SI), caption: "P_E4_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_B4, - [ModalResultField(typeof(SI), caption: "P_em-B3_mech [kW]", outputFactor: 1e-3)] + [ModalResultField(typeof(SI), caption: "P_E3_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_B3, - [ModalResultField(typeof(SI), caption: "P_em-B2_mech [kW]", outputFactor: 1e-3)] + [ModalResultField(typeof(SI), caption: "P_E2_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_B2, // --> @@ -421,9 +433,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data [ModalResultField(typeof(SI), caption: "U_reess_terminal [V]")] U_reess_terminal, [ModalResultField(typeof(SI), caption: "U_0_reess [V]")] U0_reess, [ModalResultField(typeof(SI), caption: "I_reess [A]")] I_reess, - - [ModalResultField(typeof(SI), caption: "E_reess [kWh]", outputFactor: 1/3600e3)] E_RESS, - } + } [AttributeUsage(AttributeTargets.Field)] public class ModalResultFieldAttribute : Attribute diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IAxlegearInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IAxlegearInfo.cs index 2677b92dcbe28c92038db5390198935af4d72ec3..fdaf27c16e6f4b4a70fdf16dd600da9f29ca0d07 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IAxlegearInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IAxlegearInfo.cs @@ -39,5 +39,12 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus Watt AxlegearLoss(); Tuple<PerSecond, NewtonMeter> CurrentAxleDemand { get; } + + double Ratio { get; } + } + + public interface IAngledriveInfo + { + double Ratio { get; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs index 6ab1f6c29145d7dc775954d17457d16e6728da40..729be51228375f377546f4cb49dcedcc89786dab 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs @@ -80,6 +80,7 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus IHybridControllerInfo HybridControllerInfo { get; } IHybridControllerCtl HybridControllerCtl { get; } + IAngledriveInfo AngledriveInfo { get; } } public interface IPowertainInfo diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs index 0415b9820d02db501612265910b34f488cb342a1..1980ad7b06e350bf00d8ae9b26bbec66c1ae23ad 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs @@ -12,5 +12,6 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus PerSecond MaxSpeed { get; } Watt DragPower(PerSecond electricMotorSpeed); Watt MaxPowerDrive(PerSecond inAngularVelocity); + NewtonMeter GetTorqueForElectricPower(Watt electricPower, PerSecond avgEmSpeed, Second dt); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IHybridControllerInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IHybridControllerInfo.cs index e9f029be4a7886f495668e8cc3092bf1ccd01bfa..bfc5f43bb930441f6e57035f8e128ad430f16eed 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IHybridControllerInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IHybridControllerInfo.cs @@ -10,6 +10,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent PerSecond ICESpeed { get; } bool GearboxEngaged { get; } + + Second SimulationInterval { get; } + PerSecond ElectricMotorSpeed(PowertrainPosition pos); //IList<PowertrainPosition> ElectricMotors { get; } diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IWheelsInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IWheelsInfo.cs index eba2f5092d716cd561515725f3bf6eef59f98ea4..a9bf31e94b1d1d9fc28e4c0d7e722a55196e6edc 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IWheelsInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IWheelsInfo.cs @@ -36,5 +36,6 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus public interface IWheelsInfo { Kilogram ReducedMassWheels { get; } + Meter DynamicTyreRadius { get; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 95d8e9dff105e97282e5fbc602781b8fc33c0d4c..d2bd40e5b1fea3b548d0357b7fc06f88df7dbada 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -488,27 +488,27 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl case PowertrainPosition.HybridP3: case PowertrainPosition.HybridP4: throw new VectoException("testcase does not support parallel powertrain configurations"); - case PowertrainPosition.BatteryElectricB4: + case PowertrainPosition.BatteryElectricE4: powertrain.AddComponent( - GetElectricMachine(PowertrainPosition.BatteryElectricB4, data.ElectricMachinesData, container, es, ctl)); + GetElectricMachine(PowertrainPosition.BatteryElectricE4, data.ElectricMachinesData, container, es, ctl)); new DummyGearboxInfo(container); //new MockEngineInfo(container); new ATClutchInfo(container); break; - case PowertrainPosition.BatteryElectricB3: + case PowertrainPosition.BatteryElectricE3: powertrain.AddComponent(new AxleGear(container, data.AxleGearData)) .AddComponent( - GetElectricMachine(PowertrainPosition.BatteryElectricB3, data.ElectricMachinesData, container, es, ctl)); + GetElectricMachine(PowertrainPosition.BatteryElectricE3, data.ElectricMachinesData, container, es, ctl)); new DummyGearboxInfo(container); //new MockEngineInfo(container); new ATClutchInfo(container); break; - case PowertrainPosition.BatteryElectricB2: + case PowertrainPosition.BatteryElectricE2: var strategy = new PEVAMTShiftStrategy(container); powertrain.AddComponent(new AxleGear(container, data.AxleGearData)) .AddComponent(new PEVGearbox(container, strategy)) .AddComponent( - GetElectricMachine(PowertrainPosition.BatteryElectricB2, data.ElectricMachinesData, container, es, ctl)); + GetElectricMachine(PowertrainPosition.BatteryElectricE2, data.ElectricMachinesData, container, es, ctl)); new ATClutchInfo(container); break; default: throw new ArgumentOutOfRangeException(nameof(pos), pos, null); @@ -713,7 +713,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddComponent(new AxleGear(container, data.AxleGearData)) .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) .AddComponent(GetSimpleGearbox(container, data), data.Retarder, container) - .AddComponent(GetElectricMachine(PowertrainPosition.BatteryElectricB2, data.ElectricMachinesData, container, es, ctl)); + .AddComponent(GetElectricMachine(PowertrainPosition.BatteryElectricE2, data.ElectricMachinesData, container, es, ctl)); // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 6b119919345bf536eb4873cb5b84f2e862dd78e6..d6ac7800998326f41ee230daa9e5d2fbc346aca4 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -60,6 +60,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public virtual IGearboxInfo GearboxInfo { get; protected set; } public virtual IGearboxControl GearboxCtl { get; protected set; } public virtual IAxlegearInfo AxlegearInfo { get; protected set; } + public virtual IAngledriveInfo AngledriveInfo { get; protected set; } public virtual IVehicleInfo VehicleInfo { get; protected set; } public virtual IBrakes Brakes { get; protected set; } public virtual IWheelsInfo WheelsInfo { get; protected set; } @@ -132,6 +133,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl get { return HybridController; } } + + public virtual void AddComponent(VectoSimulationComponent component) { var commitPriority = 0; @@ -152,6 +155,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .If<IGearboxControl>(c => GearboxCtl = c) .If<ITorqueConverterControl>(c => TorqueConverterCtl = c) .If<IAxlegearInfo>(c => AxlegearInfo = c) + .If<IAngledriveInfo>(c => AngledriveInfo = c) .If<IWheelsInfo>(c => WheelsInfo = c) .If<IVehicleInfo>(c => { VehicleInfo = c; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs index fe6417b85e93c2eece27cd0a159934df4bd59343..4e00de495a107acfcdbe72211a2f7ac92b96e23e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/ElectricMotorData.cs @@ -27,5 +27,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [SIRange(0, 1)] public double OverloadRegenerationFactor { get; internal set; } + + public double Ratio { get; internal set; } + public double TransmissionEfficiency { get; internal set; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IAxlegear.cs b/VectoCore/VectoCore/Models/SimulationComponent/IAxlegear.cs index 38eaa2abd18dba31cb3bb68bf656f1d776545694..98e3df2cf3f9c2c3c94aad3ef94be61eecc07770 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IAxlegear.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IAxlegear.cs @@ -34,4 +34,6 @@ using TUGraz.VectoCore.Models.Simulation.DataBus; namespace TUGraz.VectoCore.Models.SimulationComponent { public interface IAxlegear : IPowerTrainComponent, IAxlegearInfo {} + + public interface IAngledrive : IPowerTrainComponent, IAngledriveInfo {} } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs index f780dddc7b06b5cdca6db8eb1d533eaee491e6cb..539a029abbb25fd2c949d44c14b72fb7485781fc 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs @@ -38,7 +38,7 @@ using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { - public class Angledrive : TransmissionComponent + public class Angledrive : TransmissionComponent, IAngledrive { public Angledrive(IVehicleContainer container, AngledriveData modelData) : base(container, modelData.Angledrive) {} @@ -57,5 +57,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl avgAngularVelocity; container[ModalResultField.P_angle_in] = CurrentState.InTorque * avgAngularVelocity; } + + public double Ratio + { + get { return ModelData.Ratio; } + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs index c5c88be82f21acd51ce2550c9f4a755a010c51ba..61ea47843b03a2ad8acbd2da9391eef556799539 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs @@ -81,5 +81,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0, CurrentState.InTorque); } } + + public double Ratio + { + get { return ModelData.Ratio; } + } } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs index 6c97bcff2cc269ee8ca54c63bda755dd9499bf41..98c95a97d4103d5d78fc822c78735e623c5faf9d 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs @@ -157,9 +157,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl container[ModalResultField.P_reess_loss] = CurrentState.BatteryLoss; container[ModalResultField.P_reess_charge_max] = CurrentState.MaxChargePower; container[ModalResultField.P_reess_discharge_max] = CurrentState.MaxDischargePower; - - container[ModalResultField.E_RESS] = CurrentState.StateOfCharge * cellVoltage * ModelData.Capacity; - } protected override void DoCommitSimulationStep(Second time, Second simulationInterval) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index ab22a687b2069257d470c7b66e14b69e3557840c..6ff1f6bc7971fc6ede31e8f5ceb9ce7c173c3db8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -769,6 +769,25 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Log.Debug("Gear changed after a valid operating point was found - braking is no longer applicable due to overload"); return null; } + + if (DataBus.HybridControllerCtl != null && response is ResponseEngineSpeedTooHigh && + !(retVal is ResponseSuccess)) { + // search brakingpower found a solution but request resulted in non-success - try again + DataBus.Brakes.BrakePower = 0.SI<Watt>(); + try { + operatingPoint = SearchBrakingPower( + absTime, operatingPoint.SimulationDistance, gradient, + operatingPoint.Acceleration, response); + } catch (VectoSearchAbortedException vsa) { + Log.Warn("Search braking power aborted {0}", vsa); + if (DataBus.GearboxInfo.GearboxType.AutomaticTransmission()) { + operatingPoint = SetTCOperatingPointATGbxBraking(absTime, gradient, operatingPoint, response); + } + } + retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, + gradient, false); + } + retVal.Switch(). Case<ResponseSuccess>(). Case<ResponseGearShift>(). diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 1ab7d3136da925d5cda659777bdb32d094cf3d09..156332e54cb77fb4cfa8cc73adbfd1fb5399f17d 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -1,4 +1,7 @@ -using TUGraz.VectoCommon.Exceptions; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Security.Cryptography; +using NLog.LayoutRenderers; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; @@ -14,6 +17,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { + public class ElectricMotor : StatefulProviderComponent<ElectricMotorState, ITnOutPort, ITnInPort, ITnOutPort>, IPowerTrainComponent, IElectricMotor, ITnOutPort, ITnInPort { @@ -52,7 +56,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public PowertrainPosition Position { get; } public PerSecond MaxSpeed { - get { return _maxSpeed ?? (_maxSpeed = ModelData.FullLoadCurve.FullLoadEntries.MaxBy(x => x.MotorSpeed).MotorSpeed); } + get { return _maxSpeed ?? (_maxSpeed = (ModelData.FullLoadCurve.FullLoadEntries.MaxBy(x => x.MotorSpeed).MotorSpeed) / ModelData.Ratio); } } public Watt DragPower(PerSecond electricMotorSpeed) @@ -65,26 +69,50 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return ModelData.FullLoadCurve.FullLoadDriveTorque(electricMotorSpeed) * electricMotorSpeed; } + public NewtonMeter GetTorqueForElectricPower(Watt electricPower, PerSecond avgEmSpeed, Second dt) + { + var maxTorque = electricPower > 0 + ? GetMaxRecuperationTorque(dt, avgEmSpeed) + : GetMaxDriveTorque(dt, avgEmSpeed); + var tqEmMap = ModelData.EfficiencyMap.LookupTorque(electricPower, avgEmSpeed, maxTorque); + if (tqEmMap == null) { + return null; + } + + var emSpeed = avgEmSpeed * 2 - PreviousState.EMSpeed; + + var tqInertia = Formulas.InertiaPower(emSpeed, PreviousState.EMSpeed, ModelData.Inertia, dt) / avgEmSpeed; + var tqEm = tqEmMap + tqInertia; + var tqDt = ConvertEmTorqueToDrivetrain(tqEm); + return tqDt; + + } + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) { - PreviousState.OutAngularVelocity = outAngularVelocity; - PreviousState.OutTorque = outTorque; - PreviousState.InAngularVelocity = outAngularVelocity; - PreviousState.InTorque = outTorque; + var emOutAngularVelocity = outAngularVelocity * ModelData.Ratio; + var emOutTorque = outTorque / ModelData.Ratio; + + PreviousState.EMSpeed = emOutAngularVelocity; + PreviousState.EMTorque = 0.SI<NewtonMeter>(); + + PreviousState.DrivetrainSpeed = outAngularVelocity; + PreviousState.DrivetrainOutTorque = outTorque; + if (NextComponent == null) { return new ResponseSuccess(this) { Engine = { - PowerRequest = outTorque * outAngularVelocity, - EngineSpeed = outAngularVelocity + PowerRequest = emOutTorque * emOutAngularVelocity, + EngineSpeed = emOutAngularVelocity } }; } - if (!DataBus.EngineCtl.CombustionEngineOn) - { - PreviousState.InTorque = 0.SI<NewtonMeter>(); - PreviousState.InAngularVelocity = outAngularVelocity; + if (!DataBus.EngineCtl.CombustionEngineOn) { + PreviousState.DrivetrainInTorque = 0.SI<NewtonMeter>(); + //PreviousState.InAngularVelocity = emOutAngularVelocity; } - return NextComponent.Initialize(PreviousState.InTorque, PreviousState.InAngularVelocity); + return NextComponent.Initialize(outTorque, outAngularVelocity); + //return NextComponent.Initialize(PreviousState.InTorque, PreviousState.InAngularVelocity); } /// <summary> @@ -100,91 +128,58 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public IResponse Request( Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun = false) { - var avgSpeed = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; - var maxDriveTorque = GetMaxDriveTorque(absTime, dt, avgSpeed); - var maxRecuperationTorque = GetMaxRecuperationTorque(absTime, dt, avgSpeed); - - var retVal = HandleRequest(absTime, dt, outTorque, outAngularVelocity, dryRun, maxDriveTorque, maxRecuperationTorque); - - retVal.ElectricMotor.MaxDriveTorque = maxDriveTorque; - retVal.ElectricMotor.MaxRecuperationTorque = maxRecuperationTorque; - retVal.ElectricMotor.AngularVelocity = avgSpeed; - retVal.ElectricMotor.PowerRequest = outTorque * avgSpeed; - if (!dryRun) { - CurrentState.DragMax = maxRecuperationTorque; - CurrentState.DriveMax = maxDriveTorque; - CurrentState.ElectricPowerToBattery = retVal.ElectricSystem?.ConsumerPower; - } - return retVal; - } - - private NewtonMeter GetMaxRecuperationTorque(Second absTime, Second dt, PerSecond avgSpeed) - { - var tqContinuousPwr = DeRatingActive ? ContinuousTorque : null; - if (!avgSpeed.IsEqual(0)) { - tqContinuousPwr = DeRatingActive ? ModelData.ContinuousPower / avgSpeed : null; - } - var maxEmTorque = VectoMath.Min(tqContinuousPwr, ModelData.FullLoadCurve.FullGenerationTorque(avgSpeed)); - var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), true); - var maxBatPower = electricSystemResponse.MaxPowerDrag; - - var maxBatRecuperationTorque = maxBatPower.IsEqual(0) ? ModelData.DragCurve.Lookup(avgSpeed) : ModelData.EfficiencyMap.LookupTorque(maxBatPower, avgSpeed, maxEmTorque); - var maxTorqueRecuperate = VectoMath.Min(maxEmTorque, maxBatRecuperationTorque); - return maxTorqueRecuperate < 0 ? null : maxTorqueRecuperate; - } + var avgDtSpeed = (PreviousState.DrivetrainSpeed + outAngularVelocity) / 2; + var emSpeed = outAngularVelocity * ModelData.Ratio; - private NewtonMeter GetMaxDriveTorque(Second absTime, Second dt, PerSecond avgSpeed) - { - var tqContinuousPwr = DeRatingActive ? -ContinuousTorque : null; - if (!avgSpeed.IsEqual(0)) { - tqContinuousPwr = DeRatingActive ? -ModelData.ContinuousPower / avgSpeed : null; - } - var maxEmTorque = VectoMath.Max(tqContinuousPwr ,ModelData.FullLoadCurve.FullLoadDriveTorque(avgSpeed)); - var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), true); - var maxBatPower = electricSystemResponse.MaxPowerDrive; - - var maxBatDriveTorque = maxBatPower.IsEqual(0) ? ModelData.DragCurve.Lookup(avgSpeed) : ModelData.EfficiencyMap.LookupTorque(maxBatPower, avgSpeed, maxEmTorque); - //if (maxBatDriveTorque == null) { - // return ModelData.DragCurve.Lookup(avgSpeed); - //} - var maxTorqueDrive = VectoMath.Max(maxEmTorque, maxBatDriveTorque); - return maxTorqueDrive > 0 ? null : maxTorqueDrive; - } - - - protected virtual IResponse HandleRequest( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun, - NewtonMeter maxDriveTorque, NewtonMeter maxRecuperationTorque) - { - - var avgSpeed = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; - var inertiaTorqueLoss = avgSpeed.IsEqual(0) + var avgEmSpeed = (PreviousState.EMSpeed + emSpeed) / 2; + var inertiaTorqueEm = avgEmSpeed.IsEqual(0) ? 0.SI<NewtonMeter>() - : Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / avgSpeed; - var inTorque = outTorque + inertiaTorqueLoss; + : Formulas.InertiaPower(avgEmSpeed, PreviousState.EMSpeed, ModelData.Inertia, dt) / avgEmSpeed; - //var maxDriveTorque = ModelData.FullLoadCurve.FullLoadDriveTorque(avgSpeed); - //var maxDragTorque = ModelData.FullLoadCurve.FullGenerationTorque(avgSpeed); - if (!dryRun) { - CurrentState.InertiaTorqueLoss = inertiaTorqueLoss; - CurrentState.OutTorque = outTorque; - } + var maxDriveTorqueEmMap = GetMaxDriveTorque(dt, avgEmSpeed); + var maxRecuperationTorqueEmMap = GetMaxRecuperationTorque(dt, avgEmSpeed); + + // inertia has to be added here. drive torque is negative, when accelerating inertia is positive and thus 'reduces' drive torque, i.e 'less negative' + var maxDriveTorqueEm = maxDriveTorqueEmMap == null ? null : maxDriveTorqueEmMap + inertiaTorqueEm; + // inertia has to be added here. recuperation torque is positive, when accelerating inertia is positive and adds more drag to the drivetrain, + var maxRecuperationTorqueEm = maxRecuperationTorqueEmMap == null ? null : maxRecuperationTorqueEmMap + inertiaTorqueEm; - if (ElectricPower == null) { - var retVal = ForwardRequest(absTime, dt, inTorque, inTorque, outAngularVelocity, null, dryRun); - return retVal; + var maxDriveTorqueDt = maxDriveTorqueEm == null ? null : ConvertEmTorqueToDrivetrain(maxDriveTorqueEm); + var maxRecuperationTorqueDt = maxRecuperationTorqueEm == null ? null : ConvertEmTorqueToDrivetrain(maxRecuperationTorqueEm); + + // control returns torque that shall be applied on the drivetrain. calculate backward to the EM + var emTorqueDt = Control.MechanicalAssistPower(absTime, dt, outTorque, + PreviousState.DrivetrainSpeed, outAngularVelocity, maxDriveTorqueDt, maxRecuperationTorqueDt, Position, dryRun); + + var emTorque = emTorqueDt == null ? null : ConvertDrivetrainTorqueToEm(emTorqueDt); + var emOff = emTorqueDt == null; + + if (!dryRun && emTorqueDt != null && ((emTorque).IsSmaller(maxDriveTorqueEm ?? 0.SI<NewtonMeter>(), 1e-3) || + (emTorque).IsGreater(maxRecuperationTorqueEm ?? 0.SI<NewtonMeter>(), 1e-3))) { + // check if provided EM torque (drivetrain) is valid) + if (DataBus.HybridControllerInfo != null && (!avgDtSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position)) || + !dt.IsEqual(DataBus.HybridControllerInfo.SimulationInterval))) { + return new ResponseInvalidOperatingPoint(this); + } + throw new VectoException( + "Invalid operating point provided by strategy! SupportPower: {0}, max Power: {1}, min Power: {2}", + emTorqueDt, maxDriveTorqueDt, maxRecuperationTorqueDt); } - var eMotorTorque = Control.MechanicalAssistPower( - absTime, dt, inTorque, PreviousState.OutAngularVelocity, outAngularVelocity, maxDriveTorque, maxRecuperationTorque, - Position, dryRun); - if (Position == PowertrainPosition.HybridP2 && - !DataBus.GearboxInfo.GearEngaged(absTime) /* && !DataBus.ClutchInfo.ClutchClosed(absTime)*/) { + + if (Position == PowertrainPosition.HybridP2 && !DataBus.GearboxInfo.GearEngaged(absTime)) { // electric motor is between gearbox and clutch, but no gear is engaged... - if (eMotorTorque != null) { + if (emTorque != null) { if (!DataBus.HybridControllerInfo.GearboxEngaged) { - return new ResponseInvalidOperatingPoint(this); + return new ResponseInvalidOperatingPoint(this) { + ElectricMotor = { + MaxDriveTorque = maxDriveTorqueDt, + MaxRecuperationTorque = maxRecuperationTorqueDt, + AngularVelocity = avgDtSpeed, + PowerRequest = outTorque * avgDtSpeed + } + }; } if (!dryRun) { @@ -192,248 +187,234 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl "electric motor cannot provide torque when gearbox and clutch are disengaged"); } } + // gearbox is disengaged - ignore em inertia and drag... + emTorqueDt = 0.SI<NewtonMeter>(); + emTorque = 0.SI<NewtonMeter>(); + } - var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), dryRun); - if (!dryRun) { - if (!(electricSystemResponse is ElectricSystemResponseSuccess)) { - throw new VectoException("unexpected response from electric system: {0}", electricSystemResponse); - } - - SetState(inTorque, outAngularVelocity); - } - - var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); - retVal.ElectricMotor.ElectricMotorPowerMech = 0.SI<Watt>(); - retVal.ElectricSystem = electricSystemResponse; - retVal.ElectricMotor.InertiaPowerDemand = 0.SI<Watt>(); // inertiaTorqueLoss * avgSpeed; - return retVal; + if (Position == PowertrainPosition.BatteryElectricE2 && !DataBus.GearboxInfo.GearEngaged(absTime)) { + // electric motor is after the gearbox but no gear engaged - ignore inertia and drag... + emTorqueDt = 0.SI<NewtonMeter>(); + emTorque = 0.SI<NewtonMeter>(); } - if (eMotorTorque == null) { - var retVal = ElectricMotorOff(absTime, dt, outTorque, outAngularVelocity, dryRun); - retVal.ElectricMotor.InertiaPowerDemand = inertiaTorqueLoss * avgSpeed; - return retVal; + if (ElectricPower == null || emTorqueDt == null) { + // no electric system or EM shall be off - apply drag only + // if EM is off, calculate EM drag torque 'forward' to be applied on drivetrain + // add inertia, drag is positive + emTorque = ModelData.DragCurve.Lookup(avgEmSpeed) + inertiaTorqueEm; + emTorqueDt = ConvertEmTorqueToDrivetrain(emTorque); + emOff = true; } - //if (eMotorTorque.IsEqual(0, 1e-3)) - //{ - // var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), dryRun); + // inertia torque 'brakes' - electric motor has to provide this torque in addition (T_inertia > 0 when angular speed increases) + // emTorque < 0 when propelling, emTorqueMap needs to be 'more negative' to provide torque for inertia + // emTorque > 0 when recuperating, inertia 'brakes' in addition, emTorqueMap is decreased + var emTorqueMap = emTorque - inertiaTorqueEm ; + if (emOff) { + // not used later + emTorqueMap = null; + } - // var retVal = ForwardRequest(absTime, dt, inTorque, inTorque, outAngularVelocity, dryRun); - // retVal.ElectricSystem = electricSystemResponse; - // retVal.ElectricMotor.ElectricMotorPowerMech = 0.SI<Watt>(); - // return retVal; - //} + var electricPower = emOff || (ModelData.DragCurve.Lookup(avgEmSpeed) + inertiaTorqueEm).IsEqual(emTorque) + ? 0.SI<Watt>() + : ModelData.EfficiencyMap + .LookupElectricPower(avgEmSpeed, emTorqueMap, DataBus.ExecutionMode != ExecutionMode.Declaration) + .ElectricalPower; - if (!dryRun && (eMotorTorque.IsSmaller(maxDriveTorque ?? 0.SI<NewtonMeter>(), 1e-3) || - eMotorTorque.IsGreater(maxRecuperationTorque ?? 0.SI<NewtonMeter>(), 1e-3))) { - if (DataBus.HybridControllerInfo != null && !avgSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position))) { + var electricSupplyResponse = + ElectricPower.Request(absTime, dt, electricPower, dryRun); + if (!dryRun && !emOff && !(electricSupplyResponse is ElectricSystemResponseSuccess)) { + if (DataBus.HybridControllerInfo != null && !avgEmSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position))) { return new ResponseInvalidOperatingPoint(this); } throw new VectoException( - "Invalid operating point provided by strategy! SupportPower: {0}, max Power: {1}, min Power: {2}", - eMotorTorque, - maxDriveTorque, maxRecuperationTorque); + "Invalid operating point provided by strategy! EM Torque: {0}, req. electric Power: {1}, battery demand motor: {3}, max Power from Battery: {2}", + emTorque, electricPower, + emTorque < 0 ? electricSupplyResponse.MaxPowerDrive : electricSupplyResponse.MaxPowerDrag, electricSupplyResponse.ConsumerPower); } + var inTorqueDt = outTorque + emTorqueDt; - var electricPower = ModelData.EfficiencyMap - .LookupElectricPower(avgSpeed, eMotorTorque, DataBus.ExecutionMode != ExecutionMode.Declaration) - .ElectricalPower; - - if (ModelData.DragCurve.Lookup(avgSpeed).IsEqual(eMotorTorque)) { - electricPower = 0.SI<Watt>(); - } - - - var electricSupplyResponse = ElectricPower.Request(absTime, dt, electricPower, dryRun); - //if (!dryRun && !(electricSupplyResponse is ElectricSystemResponseSuccess) && - // electricPower > electricSupplyResponse.MaxPowerDrag) { - // // can't charge all power into the battery - probably it's full - // // dissipate remaining power - // electricSupplyResponse = ElectricPower.Request(absTime, dt, electricSupplyResponse.MaxPowerDrag); - // CurrentState.ElectricBrakePower = electricPower - electricSupplyResponse.MaxPowerDrag; - //} - if (!dryRun && !(electricSupplyResponse is ElectricSystemResponseSuccess)) { - if (DataBus.HybridControllerInfo != null && !avgSpeed.IsEqual(DataBus.HybridControllerInfo.ElectricMotorSpeed(Position))) { - return new ResponseInvalidOperatingPoint(this); + IResponse retVal = null; + if (NextComponent == null) { + // electric motor only + var remainingPower = inTorqueDt * avgDtSpeed; + if (dryRun) { + retVal = new ResponseDryRun(this) { + Engine = { EngineSpeed = avgDtSpeed}, + ElectricMotor = { + ElectricMotorPowerMech = (inTorqueDt - outTorque) * avgDtSpeed, + TotalTorqueDemand = inTorqueDt, + }, + DeltaFullLoad = remainingPower, + DeltaDragLoad = remainingPower, + }; + } else { + + if (remainingPower.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) { + if (electricSupplyResponse.MaxPowerDrive.IsGreaterOrEqual(0)) { + retVal = new ResponseBatteryEmpty(this); + } else { + retVal = new ResponseSuccess(this) { + ElectricMotor = { + ElectricMotorPowerMech = (inTorqueDt - outTorque) * avgDtSpeed, + TotalTorqueDemand = inTorqueDt + }, + Engine = { + PowerRequest = 0.SI<Watt>(), + EngineSpeed = outAngularVelocity + }, + }; + } + } else { + if (remainingPower > 0) { + retVal = new ResponseOverload(this) { Delta = remainingPower }; + } else { + retVal = new ResponseUnderload(this) { Delta = remainingPower }; + } + + retVal.Engine.EngineSpeed = avgDtSpeed; + } } - throw new VectoException( - "Invalid operating point provided by strategy! SupportPower: {0}, req. electric Power: {1}, battery demand motor: {3}, max Power from Battery: {2}", - eMotorTorque, electricPower, - eMotorTorque < 0 ? electricSupplyResponse.MaxPowerDrive : electricSupplyResponse.MaxPowerDrag, electricSupplyResponse.ConsumerPower); + } else { + retVal = NextComponent.Request(absTime, dt, inTorqueDt, outAngularVelocity, dryRun); + retVal.ElectricMotor.ElectricMotorPowerMech = (inTorqueDt - outTorque) * avgDtSpeed; + retVal.ElectricMotor.TotalTorqueDemand = inTorqueDt; } - var response = ForwardRequest(absTime, dt, inTorque, inTorque + eMotorTorque, outAngularVelocity, electricSupplyResponse, dryRun); + retVal.ElectricMotor.MaxDriveTorque = maxDriveTorqueDt; + retVal.ElectricMotor.MaxRecuperationTorque = maxRecuperationTorqueDt; + retVal.ElectricMotor.AngularVelocity = avgEmSpeed; + + retVal.ElectricMotor.PowerRequest = outTorque * outAngularVelocity; + retVal.ElectricMotor.InertiaPowerDemand = inertiaTorqueEm * avgEmSpeed; + retVal.ElectricSystem = electricSupplyResponse; + + if (!dryRun) { + CurrentState.EMSpeed = emSpeed; + CurrentState.EMTorque = emTorque; + CurrentState.EmTorqueMap = emTorqueMap; + CurrentState.DragMax = maxRecuperationTorqueEmMap; + CurrentState.DriveMax = maxDriveTorqueEmMap; - response.ElectricSystem = electricSupplyResponse; - response.ElectricMotor.InertiaPowerDemand = inertiaTorqueLoss * avgSpeed; + CurrentState.InertiaTorqueLoss = inertiaTorqueEm; - return response; - } + CurrentState.DrivetrainSpeed = outAngularVelocity; + CurrentState.DrivetrainInTorque = inTorqueDt; + CurrentState.DrivetrainOutTorque = outTorque; - private IResponse ElectricMotorOff(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) - { - var avgSpeed = (PreviousState.InAngularVelocity + outAngularVelocity) / 2.0; - var torqueLoss = ModelData.DragCurve.Lookup(avgSpeed); - var inTorque = outTorque + torqueLoss; + CurrentState.TransmissionTorqueLoss = avgDtSpeed.IsEqual(0) ? 0.SI<NewtonMeter>() : + ((inTorqueDt - outTorque) * avgDtSpeed - emTorque * avgEmSpeed) / avgDtSpeed; - if (!dryRun) { - SetState(inTorque, outAngularVelocity); - } - var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), dryRun); + CurrentState.ElectricPowerToBattery = retVal.ElectricSystem?.ConsumerPower; - var retVal = NextComponent == null - ? RequestElectricMotorOnly(absTime, dt, outTorque, inTorque, outAngularVelocity, dryRun, avgSpeed, electricSystemResponse) - : NextComponent.Request(absTime, dt, inTorque, outAngularVelocity, dryRun); - retVal.ElectricMotor.ElectricMotorPowerMech = (inTorque - outTorque) * avgSpeed; - retVal.ElectricSystem = electricSystemResponse; + } return retVal; } - public IResponse ForwardRequest(Second absTime, Second dt, NewtonMeter outTorque, NewtonMeter inTorque, PerSecond outAngularVelocity, - IElectricSystemResponse electricSystemResponse, bool dryRun = false) + private NewtonMeter GetMaxRecuperationTorque(Second dt, PerSecond avgSpeed) { - var avgSpeed = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; - if (NextComponent == null) - { - return RequestElectricMotorOnly(absTime, dt, outTorque, inTorque, outAngularVelocity, dryRun, avgSpeed, electricSystemResponse); + var tqContinuousPwr = DeRatingActive ? ContinuousTorque : null; + if (!avgSpeed.IsEqual(0)) { + tqContinuousPwr = DeRatingActive ? ModelData.ContinuousPower / avgSpeed : null; } + var maxEmTorque = VectoMath.Min(tqContinuousPwr, ModelData.FullLoadCurve.FullGenerationTorque(avgSpeed)); + var electricSystemResponse = ElectricPower.Request(0.SI<Second>(), dt, 0.SI<Watt>(), true); + var maxBatPower = electricSystemResponse.MaxPowerDrag; - if (!dryRun) { - SetState(inTorque, outAngularVelocity); + if (maxBatPower.IsSmaller(0, 1e-3)) { + // has to be positive for recuperation - battery is full + return null; } - var retVal = NextComponent.Request(absTime, dt, inTorque, outAngularVelocity, dryRun); - retVal.ElectricMotor.ElectricMotorPowerMech = (inTorque - outTorque) * avgSpeed; - retVal.ElectricMotor.TotalTorqueDemand = inTorque; - return retVal; + + var maxBatRecuperationTorque = maxBatPower.IsEqual(0, 1e-3) ? ModelData.DragCurve.Lookup(avgSpeed) : ModelData.EfficiencyMap.LookupTorque(maxBatPower, avgSpeed, maxEmTorque); + var maxTorqueRecuperate = VectoMath.Min(maxEmTorque, maxBatRecuperationTorque); + return maxTorqueRecuperate < 0 ? null : maxTorqueRecuperate; } - private IResponse RequestElectricMotorOnly(Second absTime, Second dt, NewtonMeter outTorque, - NewtonMeter inTorque, PerSecond outAngularVelocity, bool dryRun, PerSecond avgSpeed, - IElectricSystemResponse electricSystemResponse) + private NewtonMeter GetMaxDriveTorque(Second dt, PerSecond avgSpeed) { - var remainingPower = inTorque * avgSpeed; - if (dryRun) { - //var driveTorque = Control.MaxDriveTorque(avgSpeed, dt); - var dragTorque = 0.SI<NewtonMeter>(); //Control.MaxDragTorque(avgSpeed, dt); - var powerDemand = outTorque * avgSpeed; - return new ResponseDryRun(this) { - Engine = { - EngineSpeed = avgSpeed, - }, - ElectricMotor = { - ElectricMotorPowerMech = (inTorque - outTorque) * avgSpeed, - TotalTorqueDemand = inTorque, - }, - DeltaFullLoad = remainingPower, //powerDemand + driveTorque * avgSpeed, - DeltaDragLoad = remainingPower, // powerDemand + dragTorque * avgSpeed, - }; - } - - //if (!DataBus.GearboxInfo.GearEngaged(absTime)) { - // return RequestDisengagedElectricMotorOnly(absTime, dt, outTorque, inTorque, outAngularVelocity, dryRun, - // avgSpeed, electricSystemResponse); - //} - - if ((inTorque * avgSpeed).IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) { - SetState(inTorque, outAngularVelocity); - if (electricSystemResponse.MaxPowerDrive.IsGreaterOrEqual(0)) { - return new ResponseBatteryEmpty(this); - } - - return new ResponseSuccess(this) { - ElectricMotor = { - ElectricMotorPowerMech = (inTorque - outTorque) * avgSpeed, - TotalTorqueDemand = inTorque - }, - Engine = { - PowerRequest = 0.SI<Watt>(), - EngineSpeed = outAngularVelocity - }, - }; + var tqContinuousPwr = DeRatingActive ? -ContinuousTorque : null; + if (!avgSpeed.IsEqual(0)) { + tqContinuousPwr = DeRatingActive ? -ModelData.ContinuousPower / avgSpeed : null; } + var maxEmTorque = VectoMath.Max(tqContinuousPwr ,ModelData.FullLoadCurve.FullLoadDriveTorque(avgSpeed)); + var electricSystemResponse = ElectricPower.Request(0.SI<Second>(), dt, 0.SI<Watt>(), true); + var maxBatPower = electricSystemResponse.MaxPowerDrive; - AbstractResponse response; - - if (remainingPower > 0) { - response = new ResponseOverload(this) { Delta = remainingPower }; - } else { - response = new ResponseUnderload(this) { Delta = remainingPower }; + if (maxBatPower.IsGreater(0, 1e-3)) { + // has to be negative for propelling - so battery is below min SoC + return null; } - response.Engine.EngineSpeed = avgSpeed; - return response; + var maxBatDriveTorque = maxBatPower.IsEqual(0, 1e-3) ? ModelData.DragCurve.Lookup(avgSpeed) : ModelData.EfficiencyMap.LookupTorque(maxBatPower, avgSpeed, maxEmTorque); + //if (maxBatDriveTorque == null) { + // return ModelData.DragCurve.Lookup(avgSpeed); + //} + var maxTorqueDrive = VectoMath.Max(maxEmTorque, maxBatDriveTorque); + return maxTorqueDrive > 0 ? null : maxTorqueDrive; } - //private IResponse RequestDisengagedElectricMotorOnly(Second absTime, Second dt, NewtonMeter outTorque, - // NewtonMeter inTorque, PerSecond outAngularVelocity, bool dryRun, PerSecond avgSpeed, - // IElectricSystemResponse electricSystemResponse) - //{ - // var angularSpeed = SearchAlgorithm.Search(outAngularVelocity, inTorque, - // Constants.SimulationSettings.EngineIdlingSearchInterval, - // getYValue: t => (NewtonMeter)t, - // evaluateFunction: n => { - // var avg = (PreviousState.InAngularVelocity + n) / 2.0; - // var tDrag = ModelData.DragCurve.Lookup(avg); - // var tInert = Formulas.InertiaPower(n, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / avg; - // return tDrag + tInert; - // }, - // criterion: t => ((NewtonMeter)t).Value()); - // Log.Debug("Found operating point for idling. absTime: {0}, dt: {1}, torque: {2}, angularSpeed: {3}", absTime, dt, - // 0.SI<NewtonMeter>(), angularSpeed); - // SetState(inTorque, angularSpeed); - // return new ResponseSuccess(this) { - // ElectricMotor = { - // ElectricMotorPowerMech = (inTorque - outTorque) * (PreviousState.InAngularVelocity + angularSpeed) / 2.0, - // TotalTorqueDemand = inTorque - // }, - // Engine = { - // PowerRequest = 0.SI<Watt>(), - // EngineSpeed = outAngularVelocity - // }, - // }; - //} - private void SetState(NewtonMeter inTorque, PerSecond outAngularVelocity) + protected NewtonMeter ConvertEmTorqueToDrivetrain(NewtonMeter emTorque) { - CurrentState.OutAngularVelocity = outAngularVelocity; - CurrentState.InAngularVelocity = outAngularVelocity; - //CurrentState.OutTorque = outTorque; - CurrentState.InTorque = inTorque; + return emTorque * ModelData.Ratio * + (emTorque < 0 ? ModelData.TransmissionEfficiency : 1 / ModelData.TransmissionEfficiency); } - + protected NewtonMeter ConvertDrivetrainTorqueToEm(NewtonMeter dtTorque) + { + return dtTorque / ModelData.Ratio * + (dtTorque < 0 ? 1 / ModelData.TransmissionEfficiency : ModelData.TransmissionEfficiency); + } protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) { - var avgSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2; - container[ModalResultField.n_electricMotor_, Position] = avgSpeed; - container[ModalResultField.T_electricMotor_, Position] = CurrentState.InTorque - CurrentState.OutTorque; - container[ModalResultField.T_electricMotor_drive_max_, Position] = CurrentState.DriveMax; - container[ModalResultField.T_electricMotor_gen_max_, Position] = CurrentState.DragMax; - container[ModalResultField.P_electricMotor_mech_, Position] = (CurrentState.InTorque - CurrentState.OutTorque) * avgSpeed; - container[ModalResultField.P_electricMotor_out_, Position] = CurrentState.OutTorque * avgSpeed; - container[ModalResultField.P_electricMotor_in_, Position] = CurrentState.InTorque * avgSpeed; - container[ModalResultField.P_electricMotor_el_, Position] = CurrentState.ElectricPowerToBattery; - //container[ModalResultField.P_electricMotor_brake_, Position] = CurrentState.ElectricBrakePower; - container[ModalResultField.P_electricMotor_gen_max_, Position] = (CurrentState.DragMax ?? 0.SI<NewtonMeter>()) * avgSpeed; - container[ModalResultField.P_electricMotor_drive_max_, Position] = (CurrentState.DriveMax ?? 0.SI<NewtonMeter>()) * avgSpeed; - container[ModalResultField.P_electricMotorLoss_, Position] = (CurrentState.InTorque - CurrentState.OutTorque) * avgSpeed - (CurrentState.ElectricPowerToBattery); - container[ModalResultField.P_electricMotorTransmissionLoss_, Position] = 0.SI<Watt>(); - container[ModalResultField.P_electricMotorInertiaLoss_, Position] = CurrentState.InertiaTorqueLoss * avgSpeed; - - var contribution = - (((CurrentState.InTorque - CurrentState.OutTorque) * avgSpeed - - CurrentState.ElectricPowerToBattery) - ContinuousPowerLoss) * simulationInterval; + var avgEMSpeed = (PreviousState.EMSpeed + CurrentState.EMSpeed) / 2; + var avgDTSpeed = (PreviousState.DrivetrainSpeed + CurrentState.DrivetrainSpeed) / 2; + + container[ModalResultField.EM_ratio_, Position] = ModelData.Ratio.SI<Scalar>(); + container[ModalResultField.n_EM_electricMotor_, Position] = avgEMSpeed; + container[ModalResultField.T_EM_electricMotor_, Position] = CurrentState.EMTorque; + container[ModalResultField.T_EM_electricMotor_map_, Position] = CurrentState.EmTorqueMap; + + container[ModalResultField.T_EM_electricMotor_drive_max_, Position] = CurrentState.DriveMax; + container[ModalResultField.T_EM_electricMotor_gen_max_, Position] = CurrentState.DragMax; + + container[ModalResultField.P_EM_electricMotor_gen_max_, Position] = (CurrentState.DragMax ?? 0.SI<NewtonMeter>()) * avgEMSpeed; + container[ModalResultField.P_EM_electricMotor_drive_max_, Position] = (CurrentState.DriveMax ?? 0.SI<NewtonMeter>()) * avgEMSpeed; + + container[ModalResultField.P_EM_electricMotor_em_mech_, Position] = CurrentState.EMTorque * avgEMSpeed; + container[ModalResultField.P_EM_electricMotor_em_mech_map_, Position] = (CurrentState.EmTorqueMap ?? 0.SI<NewtonMeter>()) * avgEMSpeed; + + + container[ModalResultField.P_EM_in_, Position] = CurrentState.DrivetrainInTorque * avgDTSpeed; + container[ModalResultField.P_EM_out_, Position] = CurrentState.DrivetrainOutTorque * avgDTSpeed; + container[ModalResultField.P_EM_mech_, Position] = (CurrentState.DrivetrainInTorque - CurrentState.DrivetrainOutTorque) * avgDTSpeed; + + container[ModalResultField.P_EM_electricMotor_el_, Position] = CurrentState.ElectricPowerToBattery; + + container[ModalResultField.P_EM_electricMotorLoss_, Position] = (CurrentState.EmTorqueMap ?? 0.SI<NewtonMeter>()) * avgEMSpeed - CurrentState.ElectricPowerToBattery; + + container[ModalResultField.P_EM_TransmissionLoss_, Position] = CurrentState.TransmissionTorqueLoss * avgDTSpeed; + + container[ModalResultField.P_EM_electricMotorInertiaLoss_, Position] = CurrentState.InertiaTorqueLoss * avgEMSpeed; + + container[ModalResultField.P_EM_loss_, Position] = (CurrentState.DrivetrainInTorque - CurrentState.DrivetrainOutTorque) * avgDTSpeed - CurrentState.ElectricPowerToBattery; + + 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; container[ModalResultField.ElectricMotor_OvlBuffer_, Position] = VectoMath.Max(0, (ThermalBuffer + contribution) / OverloadBuffer); } protected override void DoCommitSimulationStep(Second time, Second simulationInterval) { - var avgSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2; - var losses = (CurrentState.InTorque - CurrentState.OutTorque) * avgSpeed - (CurrentState.ElectricPowerToBattery); + var avgSpeed = (PreviousState.EMSpeed + CurrentState.EMSpeed) / 2; + var losses = CurrentState.EMTorque * avgSpeed - CurrentState.ElectricPowerToBattery; ThermalBuffer += (losses - ContinuousPowerLoss) * simulationInterval; if (ThermalBuffer < 0) { ThermalBuffer = 0.SI<Joule>(); @@ -461,7 +442,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public PerSecond ElectricMotorSpeed { - get { return PreviousState.InAngularVelocity; } + get { return PreviousState.EMSpeed; } } public void Connect(IElectricSystem powersupply) @@ -470,12 +451,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - public class ElectricMotorState : SimpleComponentState + public class ElectricMotorState // : SimpleComponentState { + + public PerSecond DrivetrainSpeed = 0.RPMtoRad(); + public NewtonMeter DrivetrainInTorque = 0.SI<NewtonMeter>(); + public NewtonMeter DrivetrainOutTorque = 0.SI<NewtonMeter>(); + public NewtonMeter TransmissionTorqueLoss; + + public PerSecond EMSpeed = 0.RPMtoRad(); + public NewtonMeter EMTorque; + public NewtonMeter EmTorqueMap; + public NewtonMeter DriveMax; public NewtonMeter DragMax; - public Watt ElectricPowerToBattery; - //public Watt ElectricBrakePower = 0.SI<Watt>(); public NewtonMeter InertiaTorqueLoss; + + + public Watt ElectricPowerToBattery; } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 9ac3583b321c89f04f896cf89b1b85fd6c206ec7..3ec161f24875911a97f12d452d7603f9c687f4f2 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -563,7 +563,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl NextComponent.Request(absTime, Constants.SimulationSettings.TargetTimeInterval, inTorque, inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity); - var fullLoad = -DataBus.ElectricMotorInfo(PowertrainPosition.BatteryElectricB2).MaxPowerDrive(inAngularVelocity); + var fullLoad = -DataBus.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2).MaxPowerDrive(inAngularVelocity); Gear = oldGear; return new ResponseDryRun(this, response) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index 004f7b072e0a83f1dd4150ce60b65a7dec0bb306..3f407110f8f979a6d961d97761b97bfe4ae2469c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -105,6 +105,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return CurrentStrategySettings.MechanicalAssistPower[pos].Item1; } + public Second SimulationInterval + { + get + { + return CurrentStrategySettings.SimulationInterval; + } + } + public PerSecond ICESpeed { get { return CurrentStrategySettings.EvaluatedSolution.Response?.Engine.EngineSpeed; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs index 98469d1461e9b971d7273b006a963a2443a91414..0dacb252248e2c695df4e7b8a0cb513aa69065f7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs @@ -53,9 +53,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } ModelData = dataBus.RunData.GearboxData; PowerMap = dataBus.RunData.ElectricMachinesData - .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricB2)?.Item2.EfficiencyMap; + .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricE2)?.Item2.EfficiencyMap; FullLoadCurve = dataBus.RunData.ElectricMachinesData - .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricB2)?.Item2.FullLoadCurve; + .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricE2)?.Item2.FullLoadCurve; DataBus = dataBus; EarlyShiftUp = true; @@ -240,7 +240,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift; var vehicleSpeedPostShift = DataBus.VehicleInfo.VehicleSpeed - vDrop * shiftStrategyParameters.VelocityDropFactor; - var totalTransmissionRatio = DataBus.ElectricMotorInfo(PowertrainPosition.BatteryElectricB2).ElectricMotorSpeed / DataBus.VehicleInfo.VehicleSpeed; + var totalTransmissionRatio = DataBus.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2).ElectricMotorSpeed / DataBus.VehicleInfo.VehicleSpeed; //var totalTransmissionRatio = outAngularVelocity / DataBus.VehicleSpeed; var results = new List<Tuple<uint, double>>(); @@ -607,7 +607,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { return (outAngularSpeed * ModelData.Gears[gear].Ratio).IsGreaterOrEqual(VectoMath.Min(ModelData.Gears[gear].MaxSpeed, - DataBus.ElectricMotorInfo(PowertrainPosition.BatteryElectricB2).MaxSpeed)); + DataBus.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2).MaxSpeed)); } public void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { } @@ -634,10 +634,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public void WriteModalResults(IModalDataContainer container) { } - public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData) { - return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, electricMotorData.FullLoadCurve, gearboxGears, axlegearRatio, dynamicTyreRadius); + return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, electricMotorData.FullLoadCurve, electricMotorData.Ratio, gearboxGears, axlegearRatio, dynamicTyreRadius); } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs index 52b20ef3246b34fb7a5be0f8ca38ab138d98df38..838cf675c3d6122e54208223b63e1d496efee630 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs @@ -182,6 +182,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { public GearInfo SelectedGear { get; } public PerSecond ICESpeed { get; } public bool GearboxEngaged { get; } + public Second SimulationInterval { get; } public PerSecond ElectricMotorSpeed(PowertrainPosition pos) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs index ab26393427fde4811816a5f9bdb222ce3daf94f5..621be6e2a44d38fe28677393286b092a6f5f1f6f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SuperCap.cs @@ -191,8 +191,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl container[ModalResultField.P_reess_loss] = CurrentState.InternalLoss; container[ModalResultField.P_reess_charge_max] = CurrentState.MaxChargePower; container[ModalResultField.P_reess_discharge_max] = CurrentState.MaxDischargePower; - - container[ModalResultField.E_RESS] = CurrentState.Charge * CurrentState.Charge / ModelData.Capacity / 2.0; } protected override void DoCommitSimulationStep(Second time, Second simulationInterval) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs index 41e65280e586493b3d71cc78815e93a780589f46..6b21ee7b7553413764741235027b7abcbd55ef9a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs @@ -64,44 +64,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } var model = container.RunData; - if (container.PowertrainInfo.HasCombustionEngine) { - if (model?.GearboxData == null || model.AxleGearData == null) { - return; - } - MaxVehicleSpeed = model.EngineData.FullLoadCurves[0].N95hSpeed / - model.GearboxData.Gears[model.GearboxData.Gears.Keys.Max()].Ratio / - model.AxleGearData.AxleGear.Ratio / - (model.AngledriveData?.Angledrive.Ratio - ?? 1.0) * model.VehicleData.DynamicTyreRadius * 0.995; - } - - if (model.ElectricMachinesData.Count > 0) { - var positions = model.ElectricMachinesData.Select(x => x.Item1).ToArray(); - if (positions.Length > 1) { - throw new VectoException("Multiple electrical machines are currently not supported"); - } - - var pos = positions.First(); - if (pos.IsBatteryElectric()) { - var maxEMSpeed = model.ElectricMachinesData.Find(x => x.Item1 == pos).Item2.FullLoadCurve.MaxSpeed; - var ratio = 1.0; - if (pos == PowertrainPosition.BatteryElectricB3) { - ratio = model.AxleGearData.AxleGear.Ratio; - } - - if (pos == PowertrainPosition.BatteryElectricB2) { - ratio = model.GearboxData.Gears[model.GearboxData.Gears.Keys.Max()].Ratio * - model.AxleGearData.AxleGear.Ratio * - (model.AngledriveData?.Angledrive.Ratio ?? 1.0); - } - MaxVehicleSpeed = maxEMSpeed / ratio * model.VehicleData.DynamicTyreRadius * 0.995; - } - } + } public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) { + SetMaxVehicleSpeed(); PreviousState = new VehicleState { Distance = DataBus.DrivingCycleInfo.CycleStartDistance, Velocity = vehicleSpeed, @@ -116,6 +85,46 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return NextComponent?.Initialize(PreviousState.VehicleTractionForce, vehicleSpeed); } + protected virtual void SetMaxVehicleSpeed() + { + if (DataBus.PowertrainInfo.HasCombustionEngine) { + if (DataBus.GearboxInfo == null || DataBus.AxlegearInfo == null) { + throw new VectoException("Powertrain with combustion engine requires gearbox and axlegear!"); + //return; + } + MaxVehicleSpeed = DataBus.EngineInfo.EngineN95hSpeed / + DataBus.GearboxInfo.GetGearData(DataBus.GearboxInfo.NumGears).Ratio / + DataBus.AxlegearInfo.Ratio / + (DataBus.AngledriveInfo?.Ratio ?? 1.0) * + DataBus.WheelsInfo.DynamicTyreRadius * 0.995; + } + + + if (DataBus.PowertrainInfo.HasElectricMotor) { + var positions = DataBus.PowertrainInfo.ElectricMotorPositions; + if (positions.Length > 1) { + throw new VectoException("Multiple electrical machines are currently not supported"); + } + + var pos = positions.First(); + if (pos.IsBatteryElectric()) { + var maxEMSpeed = DataBus.ElectricMotorInfo(pos).MaxSpeed; + + var ratio = 1.0; + if (pos == PowertrainPosition.BatteryElectricE3) { + ratio = DataBus.AxlegearInfo.Ratio; + } + + if (pos == PowertrainPosition.BatteryElectricE2) { + ratio = DataBus.GearboxInfo.GetGearData(DataBus.GearboxInfo.NumGears).Ratio * + DataBus.AxlegearInfo.Ratio * + (DataBus.AngledriveInfo?.Ratio ?? 1.0); + } + MaxVehicleSpeed = maxEMSpeed / ratio * DataBus.WheelsInfo.DynamicTyreRadius * 0.995; + } + } + } + public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient, MeterPerSquareSecond startAcceleration) { //CurrentState.Velocity = vehicleSpeed + startAcceleration * Constants.SimulationSettings.TargetTimeInterval; @@ -216,7 +225,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return retVal; } - public MeterPerSecond MaxVehicleSpeed { get; } + public MeterPerSecond MaxVehicleSpeed { get; set; } public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs index 040cc1f1bb761a265009239fa8faa2e57fa1ae5d..45b4997ec43d587610e45e4bc39a6d6cf292ead0 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs @@ -204,14 +204,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected override PerSecond GetMotorTargetSpeed(VectoRunData runData) { return 0.5 * runData.ElectricMachinesData - .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricB2)?.Item2.FullLoadCurve + .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricE2)?.Item2.FullLoadCurve .MaxSpeed; } protected override PerSecond GetMaxMotorspeed(VectoRunData runData) { return runData.ElectricMachinesData - .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricB2)?.Item2.FullLoadCurve + .FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricE2)?.Item2.FullLoadCurve .MaxSpeed; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Wheels.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Wheels.cs index 73e3312961abc7ac7c99f11219a5e47d5bd699cc..9e9b33c285ea43ae32ed9a46b72b4107d2bcfd48 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Wheels.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Wheels.cs @@ -42,7 +42,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public class Wheels : StatefulProviderComponent<Wheels.WheelsState, IFvOutPort, ITnInPort, ITnOutPort>, IWheels, IFvOutPort, ITnInPort { - private readonly Meter _dynamicWheelRadius; private readonly KilogramSquareMeter _totalWheelsInertia; public class WheelsState @@ -55,14 +54,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Wheels(IVehicleContainer cockpit, Meter rdyn, KilogramSquareMeter totalWheelsInertia) : base(cockpit) { - _dynamicWheelRadius = rdyn; + DynamicTyreRadius = rdyn; _totalWheelsInertia = totalWheelsInertia; } public IResponse Initialize(Newton force, MeterPerSecond velocity) { - PreviousState.TorqueIn = force * _dynamicWheelRadius; - PreviousState.AngularVelocity = velocity / _dynamicWheelRadius; + PreviousState.TorqueIn = force * DynamicTyreRadius; + PreviousState.AngularVelocity = velocity / DynamicTyreRadius; PreviousState.InertiaTorqueLoss = 0.SI<NewtonMeter>(); return NextComponent.Initialize(PreviousState.TorqueIn, PreviousState.AngularVelocity); @@ -72,13 +71,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { Log.Debug("request: force: {0}, velocity: {1}", force, velocity); - CurrentState.AngularVelocity = velocity / _dynamicWheelRadius; + CurrentState.AngularVelocity = velocity / DynamicTyreRadius; var avgAngularSpeed = (CurrentState.AngularVelocity + PreviousState.AngularVelocity) / 2.0; CurrentState.InertiaTorqueLoss = avgAngularSpeed.IsEqual(0.SI<PerSecond>()) ? 0.SI<NewtonMeter>() : Formulas.InertiaPower(CurrentState.AngularVelocity, PreviousState.AngularVelocity, _totalWheelsInertia, dt) / avgAngularSpeed; //(_totalWheelsInertia * avgAngularSpeed / dt).Cast<NewtonMeter>(); - CurrentState.TorqueIn = force * _dynamicWheelRadius + CurrentState.InertiaTorqueLoss; + CurrentState.TorqueIn = force * DynamicTyreRadius + CurrentState.InertiaTorqueLoss; var retVal = NextComponent.Request(absTime, dt, CurrentState.TorqueIn, CurrentState.AngularVelocity, dryRun); @@ -96,7 +95,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Kilogram ReducedMassWheels { - get { return (_totalWheelsInertia / _dynamicWheelRadius / _dynamicWheelRadius).Cast<Kilogram>(); } + get { return (_totalWheelsInertia / DynamicTyreRadius / DynamicTyreRadius).Cast<Kilogram>(); } } + + public Meter DynamicTyreRadius { get; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index d385888f124364ee8a107ba0d569b3000f0deb92..a496aa7f0415d79e5a5f43c76b298c5f77fe9148 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -183,7 +183,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } if (DryRunSolution != null && DryRunSolution.DrivingAction == DataBus.DriverInfo.DrivingAction) { - return CreateResponse(DryRunSolution.Solution, currentGear); + var tmp = CreateResponse(DryRunSolution.Solution, currentGear); + return tmp; } @@ -220,7 +221,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies // Log.Debug("best: {0}, origBest: {1}", best.ToString(), origBest.ToString()); //} + //best.SimulationInterval = dt; var retVal = CreateResponse(best, currentGear); + retVal.GearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); if (!DataBus.EngineInfo.EngineOn && !best.ICEOff && retVal.ShiftRequired) { CurrentState.ICEStartTStmp = absTime + dt; @@ -623,6 +626,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var best = DoSelectBestOption(eval, absTime, dt, outTorque, outAngularVelocity, dryRun, currentGear); if (best == null || !best.IgnoreReason.InvalidEngineSpeed() || best.ICEOff || eval.Select(x => x.Gear).Distinct().Count() <= 1) { + best.SimulationInterval = dt; return best; } @@ -647,6 +651,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies best = DoSelectBestOption(newEval, absTime, dt, outTorque, outAngularVelocity, dryRun, currentGear); } } + + best.SimulationInterval = dt; return best; } @@ -847,7 +853,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies ShiftRequired = best.Gear != 0 && best.Gear != currentGear, // gs?.Item1 ?? false, NextGear = best.Gear, // gs?.Item2 ?? 0, EvaluatedSolution = best, - }; + SimulationInterval = best.SimulationInterval + }; + //var pos = retVal.MechanicalAssistPower.Keys.First(); + //if (retVal.MechanicalAssistPower[pos].Item1 == null) { + // retVal.MechanicalAssistPower[pos] = Tuple.Create(best.Response.ElectricMotor.AngularVelocity, retVal.MechanicalAssistPower[pos].Item2); + //} if (best.IgnoreReason.EngineSpeedTooHigh() && !DataBus.EngineInfo.EngineOn) { // ICE is off, selected solution has a too low or too high engine speed - keep ICE off retVal.CombustionEngineOn = false; @@ -1056,10 +1067,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies // if battery is getting empty try to set EM-torque to discharge battery to lower SoC boundary if (maxEmTorque.IsSmaller(0) && (-emDrivePower).IsGreaterOrEqual(maxEmTorque * firstResponse.ElectricMotor.AngularVelocity)) { - // maxEmTorque < 0 ==> EM can still propell + // maxEmTorque < 0 ==> EM can still propel // (-emDrivePower).IsGreaterOrEqual(maxEmTorque * firstResponse.ElectricMotor.AngularVelocity) ==> power available from battery for driving does not exceed max EM power (otherwise torque lookup may fail) - var emDriveTorque = ModelData.ElectricMachinesData.Where(x => x.Item1 == emPos).First().Item2.EfficiencyMap - .LookupTorque(emDrivePower, firstResponse.ElectricMotor.AngularVelocity, maxEmTorque); + //var emDriveTorque = ModelData.ElectricMachinesData.Where(x => x.Item1 == emPos).First().Item2.EfficiencyMap + // .LookupTorque(emDrivePower, firstResponse.ElectricMotor.AngularVelocity, maxEmTorque); + + var emDriveTorque = DataBus.ElectricMotorInfo(emPos).GetTorqueForElectricPower(emDrivePower, firstResponse.ElectricMotor.AngularVelocity, dt); var emDragTorque = ModelData.ElectricMachinesData.Where(x => x.Item1 == emPos).First().Item2 .DragCurve.Lookup(firstResponse.ElectricMotor.AngularVelocity); if (emDriveTorque != null && @@ -1279,11 +1292,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies (DataBus.ElectricMotorInfo(pos) as ElectricMotor).DeRatingActive; if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP2 != null) { - TestPowertrain.ElectricMotorP2.PreviousState.OutAngularVelocity = + TestPowertrain.ElectricMotorP2.PreviousState.EMSpeed = DataBus.ElectricMotorInfo(PowertrainPosition.HybridP2).ElectricMotorSpeed; } if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP3 != null) { - TestPowertrain.ElectricMotorP3.PreviousState.OutAngularVelocity = + TestPowertrain.ElectricMotorP3.PreviousState.EMSpeed = DataBus.ElectricMotorInfo(PowertrainPosition.HybridP3).ElectricMotorSpeed; } diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index fad3bc204a1c5253fbb8bfb8e1977d2d6d74374c..2f40b5daf46e3205956588d7466a891f0acc42b4 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -126,18 +126,21 @@ namespace TUGraz.VectoCore.OutputData bool HasCombustionEngine { get; } WattSecond TotalElectricMotorWorkDrive(PowertrainPosition emPos); WattSecond TotalElectricMotorWorkRecuperate(PowertrainPosition emPos); + WattSecond TotalElectricMotorMotWorkDrive(PowertrainPosition emPos); + WattSecond TotalElectricMotorMotWorkRecuperate(PowertrainPosition emPos); PerSecond ElectricMotorAverageSpeed(PowertrainPosition emPos); double ElectricMotorEfficiencyDrive(PowertrainPosition emPos); double ElectricMotorEfficiencyGenerate(PowertrainPosition emPos); + double ElectricMotorMotEfficiencyDrive(PowertrainPosition emPos); + double ElectricMotorMotEfficiencyGenerate(PowertrainPosition emPos); WattSecond ElectricMotorOffLosses(PowertrainPosition emPos); WattSecond ElectricMotorLosses(PowertrainPosition emPos); + WattSecond ElectricMotorMotLosses(PowertrainPosition emPos); WattSecond ElectricMotorTransmissionLosses(PowertrainPosition emPos); double BatteryStartSoC(); double REESSEndSoC(); WattSecond REESSLoss(); - WattSecond REESSEnergyEnd(); - } public static class ModalDataContainerExtensions diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 82aed0a0618891cd4b7f9efa91d6dafe326ff321..8288dae00fd355e5786325498b7c6fcb5b2f4f46 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -65,14 +65,32 @@ namespace TUGraz.VectoCore.OutputData private Meter _distance; private readonly ModalResultField[] _electricMotorColumns = new[] { - ModalResultField.n_electricMotor_, ModalResultField.T_electricMotor_, - ModalResultField.T_electricMotor_drive_max_, ModalResultField.T_electricMotor_gen_max_, - ModalResultField.P_electricMotor_in_, ModalResultField.P_electricMotor_out_, - ModalResultField.P_electricMotor_mech_, ModalResultField.P_electricMotor_el_, - ModalResultField.P_electricMotorLoss_, ModalResultField.P_electricMotorInertiaLoss_, - ModalResultField.P_electricMotorTransmissionLoss_, - /*ModalResultField.P_electricMotor_brake_,*/ ModalResultField.P_electricMotor_drive_max_, - ModalResultField.P_electricMotor_gen_max_, ModalResultField.ElectricMotor_OvlBuffer_ + ModalResultField.EM_ratio_, + ModalResultField.P_EM_out_, + ModalResultField.P_EM_mech_, + ModalResultField.P_EM_in_, + + ModalResultField.P_EM_TransmissionLoss_, + ModalResultField.P_EM_electricMotor_em_mech_, + ModalResultField.P_EM_electricMotorInertiaLoss_, + ModalResultField.P_EM_electricMotor_em_mech_map_, + ModalResultField.P_EM_electricMotorLoss_, + ModalResultField.P_EM_electricMotor_el_, + + ModalResultField.P_EM_loss_, + + ModalResultField.n_EM_electricMotor_, + ModalResultField.T_EM_electricMotor_, + ModalResultField.T_EM_electricMotor_map_, + + ModalResultField.T_EM_electricMotor_drive_max_, + ModalResultField.T_EM_electricMotor_gen_max_, + + ModalResultField.P_EM_electricMotor_drive_max_, + ModalResultField.P_EM_electricMotor_gen_max_, + + ModalResultField.ElectricMotor_OvlBuffer_, + ModalResultField.EM_Off_, }; public static readonly IList<ModalResultField> FuelConsumptionSignals = new[] { @@ -258,7 +276,21 @@ namespace TUGraz.VectoCore.OutputData if (!_eEmDrive.ContainsKey(emPos)) { _eEmDrive[emPos] = TimeIntegral<WattSecond>( - string.Format(ModalResultField.P_electricMotor_mech_.GetCaption(), emPos.GetName()), x => x < 0); + string.Format(ModalResultField.P_EM_mech_.GetCaption(), emPos.GetName()), x => x < 0); + } + + return -_eEmDrive[emPos]; + } + + public WattSecond TotalElectricMotorMotWorkDrive(PowertrainPosition emPos) + { + if (!ElectricMotors.Contains(emPos)) { + return null; + } + + if (!_eEmDrive.ContainsKey(emPos)) { + _eEmDrive[emPos] = TimeIntegral<WattSecond>( + string.Format(ModalResultField.P_EM_electricMotor_em_mech_.GetCaption(), emPos.GetName()), x => x < 0); } return -_eEmDrive[emPos]; @@ -272,12 +304,28 @@ namespace TUGraz.VectoCore.OutputData if (!_eEmRecuperate.ContainsKey(emPos)) { _eEmRecuperate[emPos] = TimeIntegral<WattSecond>( - string.Format(ModalResultField.P_electricMotor_mech_.GetCaption(), emPos.GetName()), x => x > 0); ; + string.Format(ModalResultField.P_EM_mech_.GetCaption(), emPos.GetName()), x => x > 0); ; } return _eEmRecuperate[emPos]; } + public WattSecond TotalElectricMotorMotWorkRecuperate(PowertrainPosition emPos) + { + if (!ElectricMotors.Contains(emPos)) { + return null; + } + + if (!_eEmRecuperate.ContainsKey(emPos)) { + _eEmRecuperate[emPos] = TimeIntegral<WattSecond>( + string.Format(ModalResultField.P_EM_electricMotor_em_mech_.GetCaption(), emPos.GetName()), x => x > 0); + ; + } + + return _eEmRecuperate[emPos]; + } + + public double ElectricMotorEfficiencyDrive(PowertrainPosition emPos) { if (!ElectricMotors.Contains(emPos)) { @@ -287,11 +335,38 @@ namespace TUGraz.VectoCore.OutputData var selected = Data.AsEnumerable().Cast<DataRow>().Select(r => { var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); return new { - P_em = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_el_.GetCaption(), + P_em = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), + emPos.GetName())), + E_mech = r.Field<Watt>(string.Format(ModalResultField.P_EM_mech_.GetCaption(), + emPos.GetName())) * dt, + E_el = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), + emPos.GetName())) * dt, + }; + }); + var eMech = 0.SI<WattSecond>(); + var eEl = 0.SI<WattSecond>(); + foreach (var entry in selected.Where(x => x.P_em.IsSmaller(0))) { + eMech += entry.E_mech; + eEl += entry.E_el; + } + + return eMech.Value() / eEl.Value(); + } + + public double ElectricMotorMotEfficiencyDrive(PowertrainPosition emPos) + { + if (!ElectricMotors.Contains(emPos)) { + return double.NaN; + } + + var selected = Data.AsEnumerable().Cast<DataRow>().Select(r => { + var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); + return new { + P_em = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), emPos.GetName())), - E_mech = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_mech_.GetCaption(), + E_mech = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_em_mech_.GetCaption(), emPos.GetName())) * dt, - E_el = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_el_.GetCaption(), + E_el = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), emPos.GetName())) * dt, }; }); @@ -305,6 +380,7 @@ namespace TUGraz.VectoCore.OutputData return eMech.Value() / eEl.Value(); } + public double ElectricMotorEfficiencyGenerate(PowertrainPosition emPos) { if (!ElectricMotors.Contains(emPos)) { @@ -314,11 +390,11 @@ namespace TUGraz.VectoCore.OutputData var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); return new { - P_em = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_el_.GetCaption(), + P_em = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), emPos.GetName())), - E_mech = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_mech_.GetCaption(), + E_mech = r.Field<Watt>(string.Format(ModalResultField.P_EM_mech_.GetCaption(), emPos.GetName())) * dt, - E_el = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_el_.GetCaption(), + E_el = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), emPos.GetName())) * dt, }; }); @@ -334,6 +410,33 @@ namespace TUGraz.VectoCore.OutputData return eff; } + public double ElectricMotorMotEfficiencyGenerate(PowertrainPosition emPos) + { + if (!ElectricMotors.Contains(emPos)) { + return double.NaN; + } + var selected = Data.AsEnumerable().Cast<DataRow>().Select(r => { + var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); + return new { + P_em = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), + emPos.GetName())), + E_mech = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_em_mech_.GetCaption(), + emPos.GetName())) * dt, + E_el = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), + emPos.GetName())) * dt, + }; + }); + var eMech = 0.SI<WattSecond>(); + var eEl = 0.SI<WattSecond>(); + foreach (var entry in selected.Where(x => x.P_em.IsGreater(0))) { + eMech += entry.E_mech; + eEl += entry.E_el; + } + + var eff = eEl.Value() / eMech.Value(); + return eff; + } + public WattSecond ElectricMotorOffLosses(PowertrainPosition emPos) { if (!ElectricMotors.Contains(emPos)) { @@ -343,9 +446,9 @@ namespace TUGraz.VectoCore.OutputData var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); return new { - P_em = r.Field<Watt>(string.Format(ModalResultField.P_electricMotor_el_.GetCaption(), + P_em = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), emPos.GetName())), - E_mech = r.Field<Watt>(string.Format(ModalResultField.P_electricMotorLoss_.GetCaption(), + E_mech = r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotorLoss_.GetCaption(), emPos.GetName())) * dt, }; }); @@ -356,7 +459,16 @@ namespace TUGraz.VectoCore.OutputData { return Data.AsEnumerable().Cast<DataRow>().Sum(r => { var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); - return r.Field<Watt>(string.Format(ModalResultField.P_electricMotorLoss_.GetCaption(), + return r.Field<Watt>(string.Format(ModalResultField.P_EM_loss_.GetCaption(), + emPos.GetName())) * dt; + }); + } + + public WattSecond ElectricMotorMotLosses(PowertrainPosition emPos) + { + return Data.AsEnumerable().Cast<DataRow>().Sum(r => { + var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); + return r.Field<Watt>(string.Format(ModalResultField.P_EM_electricMotorLoss_.GetCaption(), emPos.GetName())) * dt; }); } @@ -365,14 +477,14 @@ namespace TUGraz.VectoCore.OutputData { return Data.AsEnumerable().Cast<DataRow>().Sum(r => { var dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()); - return r.Field<Watt>(string.Format(ModalResultField.P_electricMotorTransmissionLoss_.GetCaption(), + return r.Field<Watt>(string.Format(ModalResultField.P_EM_TransmissionLoss_.GetCaption(), emPos.GetName())) * dt; }); } public PerSecond ElectricMotorAverageSpeed(PowertrainPosition emPos) { - var integral = GetValues(x => x.Field<PerSecond>(string.Format(ModalResultField.n_electricMotor_.GetCaption(), emPos.GetName())).Value() * + var integral = GetValues(x => x.Field<PerSecond>(string.Format(ModalResultField.n_EM_electricMotor_.GetCaption(), emPos.GetName())).Value() * x.Field<Second>(ModalResultField.simulationInterval.GetName()).Value()).Sum(); return (integral / Duration.Value()).SI<PerSecond>(); } @@ -392,12 +504,6 @@ namespace TUGraz.VectoCore.OutputData return TimeIntegral<WattSecond>(ModalResultField.P_reess_loss); } - public WattSecond REESSEnergyEnd() - { - return Data.AsEnumerable().Cast<DataRow>().Last().Field<SI>(ModalResultField.E_RESS.GetName()) - .Cast<WattSecond>(); - } - public void CalculateAggregateValues() { var duration = Duration; @@ -602,7 +708,6 @@ namespace TUGraz.VectoCore.OutputData ModalResultField.U_reess_terminal, ModalResultField.U0_reess, ModalResultField.I_reess, - ModalResultField.E_RESS }.Select(x => x.GetName())); foreach (var em in ElectricMotors.OrderBy(x => x).Reverse()) { dataColumns.AddRange(_electricMotorColumns.Select(emCol => diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index 16f553f788a988242c6f67bddf6dab9b414d31cd..e5f8add557861975e1bece57d1fbb0f807bee965 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -724,14 +724,25 @@ namespace TUGraz.VectoCore.OutputData foreach (var em in runData.ElectricMachinesData) { var emColumns = new List<Tuple<string, ConvertedSI>>() { - Tuple.Create(Fields.E_EM_DRIVE_FORMAT, modData.TotalElectricMotorWorkDrive(em.Item1).ConvertToKiloWattHour()), + Tuple.Create(Fields.EM_AVG_SPEED_FORMAT, modData.ElectricMotorAverageSpeed(em.Item1).ConvertToRoundsPerMinute()), + + Tuple.Create(Fields.E_EM_Mot_DRIVE_FORMAT, modData.TotalElectricMotorMotWorkDrive(em.Item1).ConvertToKiloWattHour()), + Tuple.Create(Fields.E_EM_Mot_GENERATE_FORMAT, modData.TotalElectricMotorMotWorkRecuperate(em.Item1).ConvertToKiloWattHour()), + + Tuple.Create(Fields.ETA_EM_Mot_DRIVE_FORMAT, new ConvertedSI(modData.ElectricMotorMotEfficiencyDrive(em.Item1), "")), + Tuple.Create(Fields.ETA_EM_Mot_GEN_FORMAT, new ConvertedSI(modData.ElectricMotorMotEfficiencyGenerate(em.Item1), "")), + + + Tuple.Create(Fields.E_EM_DRIVE_FORMAT, modData.TotalElectricMotorWorkDrive(em.Item1).ConvertToKiloWattHour()), Tuple.Create(Fields.E_EM_GENERATE_FORMAT, modData.TotalElectricMotorWorkRecuperate(em.Item1).ConvertToKiloWattHour()), - Tuple.Create(Fields.E_EM_AVG_SPEED_FORMAT, modData.ElectricMotorAverageSpeed(em.Item1).ConvertToRoundsPerMinute()), - Tuple.Create(Fields.E_EM_ETA_DRIVE_FORMAT, new ConvertedSI(modData.ElectricMotorEfficiencyDrive(em.Item1), "")), - Tuple.Create(Fields.E_EM_ETA_GEN_FORMAT, new ConvertedSI(modData.ElectricMotorEfficiencyGenerate(em.Item1), "")), + + Tuple.Create(Fields.ETA_EM_DRIVE_FORMAT, new ConvertedSI(modData.ElectricMotorEfficiencyDrive(em.Item1), "")), + Tuple.Create(Fields.ETA_EM_GEN_FORMAT, new ConvertedSI(modData.ElectricMotorEfficiencyGenerate(em.Item1), "")), + Tuple.Create(Fields.E_EM_OFF_Loss_Format, modData.ElectricMotorOffLosses(em.Item1).ConvertToKiloWattHour()), - Tuple.Create(Fields.E_EM_LOSS_FORMAT, modData.ElectricMotorLosses(em.Item1).ConvertToKiloWattHour()), - Tuple.Create(Fields.E_EM_LOSS_TRANSM_FORMAT, modData.ElectricMotorTransmissionLosses(em.Item1).ConvertToKiloWattHour()) + Tuple.Create(Fields.E_EM_LOSS_TRANSM_FORMAT, modData.ElectricMotorTransmissionLosses(em.Item1).ConvertToKiloWattHour()), + Tuple.Create(Fields.E_EM_Mot_LOSS_FORMAT, modData.ElectricMotorLosses(em.Item1).ConvertToKiloWattHour()), + Tuple.Create(Fields.E_EM_LOSS_FORMAT, modData.ElectricMotorMotLosses(em.Item1).ConvertToKiloWattHour()), }; emColumns.Reverse(); foreach (var entry in emColumns) { @@ -775,25 +786,15 @@ namespace TUGraz.VectoCore.OutputData if (runData.BatteryData != null) { row[Fields.REESS_StartSoC] = runData.BatteryData.InitialSoC * 100; row[Fields.REESS_EndSoC] = modData.REESSEndSoC(); - var cellVoltage = runData.BatteryData.SOCMap.Lookup(runData.BatteryData.InitialSoC); - row[Fields.REESS_DeltaSoC] = - (modData.REESSEnergyEnd() - - (runData.BatteryData.InitialSoC * runData.BatteryData.Capacity * cellVoltage).Cast<WattSecond>()).ConvertToKiloWattHour(); + row[Fields.REESS_DeltaSoC] = modData.TimeIntegral<WattSecond>(ModalResultField.P_reess_int.GetName()) + .ConvertToKiloWattHour(); - } if (runData.SuperCapData != null) { row[Fields.REESS_StartSoC] = runData.SuperCapData.InitialSoC * 100; row[Fields.REESS_EndSoC] = modData.REESSEndSoC(); - var initialCharge = runData.SuperCapData.Capacity * - ((runData.SuperCapData.MaxVoltage - runData.SuperCapData.MinVoltage) * - runData.SuperCapData.InitialSoC + - runData.SuperCapData.MinVoltage); - row[Fields.REESS_DeltaSoC] = - (modData.REESSEnergyEnd() - - (initialCharge * initialCharge / runData.SuperCapData.Capacity / 2.0).Cast<WattSecond>()).ConvertToKiloWattHour(); - - + row[Fields.REESS_DeltaSoC] = modData.TimeIntegral<WattSecond>(ModalResultField.P_reess_int.GetName()) + .ConvertToKiloWattHour(); } } @@ -1311,18 +1312,26 @@ namespace TUGraz.VectoCore.OutputData public const string E_EM_DRIVE_FORMAT = "E_EM_{0}_drive [kWh]"; public const string E_EM_GENERATE_FORMAT = "E_EM_{0}_gen [kWh]"; - public const string E_EM_AVG_SPEED_FORMAT = "n_EM_{0}_avg [rpm]"; - public const string E_EM_ETA_DRIVE_FORMAT = "η_EM_{0}_drive"; - public const string E_EM_ETA_GEN_FORMAT = "η_EM_{0}_gen"; + public const string ETA_EM_DRIVE_FORMAT = "η_EM_{0}_drive"; + public const string ETA_EM_GEN_FORMAT = "η_EM_{0}_gen"; + + public const string E_EM_Mot_DRIVE_FORMAT = "E_EM_{0}-em_drive [kWh]"; + public const string E_EM_Mot_GENERATE_FORMAT = "E_EM_{0}-em_gen [kWh]"; + public const string ETA_EM_Mot_DRIVE_FORMAT = "η_EM_{0}-em_drive"; + public const string ETA_EM_Mot_GEN_FORMAT = "η_EM_{0}-em_gen"; + + public const string EM_AVG_SPEED_FORMAT = "n_EM_{0}-em_avg [rpm]"; + public const string E_EM_OFF_Loss_Format = "E_EM_{0}_off_loss [kWh]"; - public const string E_EM_LOSS_FORMAT = "E_EM_{0}_loss [kWh]"; public const string E_EM_LOSS_TRANSM_FORMAT = "E_EM_{0}_transm_loss [kWh]"; + public const string E_EM_Mot_LOSS_FORMAT = "E_EM_{0}-em_loss [kWh]"; + public const string E_EM_LOSS_FORMAT = "E_EM_{0}_loss [kWh]"; + public const string REESS_CAPACITY = "REESS Capacity"; public const string REESS_StartSoC = "REESS Start SoC [%]"; public const string REESS_EndSoC = "REESS End SoC [%]"; - public const string REESS_DeltaSoC = "REESS Delta SoC [kWh]"; - public const string REESS_CAPACITY = "REESS Capacity"; + public const string REESS_DeltaSoC = "ΔE_REESS [kWh]"; public const string E_REESS_LOSS = "E_REESS_loss [kWh]"; public const string E_REESS_T_chg = "E_REESS_T_chg [kWh]"; diff --git a/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs b/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs index 1ced8a515277542558590eaf80b5b43f4add0997..a9c6fab0bbeacce32b0cb216070eeacda55ae75a 100644 --- a/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs +++ b/VectoCore/VectoCoreTest/FileIO/JsonReadHybridTest.cs @@ -64,7 +64,7 @@ namespace TUGraz.VectoCore.Tests.FileIO Assert.AreEqual("401.07", fld.Rows[0][ElectricFullLoadCurveReader.Fields.DrivingTorque]); Assert.AreEqual("-401.07", fld.Rows[0][ElectricFullLoadCurveReader.Fields.GenerationTorque]); - var fldMap = ElectricFullLoadCurveReader.Create(fld, 1, 1, 1); + var fldMap = ElectricFullLoadCurveReader.Create(fld, 1); Assert.AreEqual(-401.07, fldMap.FullLoadDriveTorque(0.RPMtoRad()).Value()); Assert.AreEqual(401.07, fldMap.FullGenerationTorque(0.RPMtoRad()).Value()); @@ -73,7 +73,7 @@ namespace TUGraz.VectoCore.Tests.FileIO Assert.AreEqual("-800", pwr.Rows[0][ElectricMotorMapReader.Fields.Torque]); Assert.AreEqual("9.8449", pwr.Rows[0][ElectricMotorMapReader.Fields.PowerElectrical]); - var pwrMap = ElectricMotorMapReader.Create(pwr, 1, 1, 1); + var pwrMap = ElectricMotorMapReader.Create(pwr, 1); Assert.AreEqual(-10171.0, pwrMap.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value()); Assert.AreEqual(-20430.186, pwrMap.LookupElectricPower(120.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3); @@ -93,22 +93,22 @@ namespace TUGraz.VectoCore.Tests.FileIO Assert.AreEqual("401.07", fld.Rows[0][ElectricFullLoadCurveReader.Fields.DrivingTorque]); Assert.AreEqual("-401.07", fld.Rows[0][ElectricFullLoadCurveReader.Fields.GenerationTorque]); - var fldMap = ElectricFullLoadCurveReader.Create(fld, 22.6, 2, 0.97); - Assert.AreEqual(-17584.51308 , fldMap.FullLoadDriveTorque(0.RPMtoRad()).Value(), 1e-3); - Assert.AreEqual(18689.03505, fldMap.FullGenerationTorque(0.RPMtoRad()).Value(), 1e-3); + var fldMap = ElectricFullLoadCurveReader.Create(fld, 2); + Assert.AreEqual(-802.14 , fldMap.FullLoadDriveTorque(0.RPMtoRad()).Value(), 1e-3); + Assert.AreEqual(802.14, fldMap.FullGenerationTorque(0.RPMtoRad()).Value(), 1e-3); - Assert.AreEqual(-17584.51308, fldMap.FullLoadDriveTorque(50.RPMtoRad()).Value(), 1e-3); - Assert.AreEqual(18689.03505, fldMap.FullGenerationTorque(50.RPMtoRad()).Value(), 1e-3); + Assert.AreEqual(-802.14, fldMap.FullLoadDriveTorque(50.RPMtoRad()).Value(), 1e-3); + Assert.AreEqual(802.14, fldMap.FullGenerationTorque(50.RPMtoRad()).Value(), 1e-3); var pwr = inputProvider.EfficiencyMap; Assert.AreEqual("0", pwr.Rows[0][ElectricMotorMapReader.Fields.MotorSpeed]); Assert.AreEqual("-800", pwr.Rows[0][ElectricMotorMapReader.Fields.Torque]); Assert.AreEqual("9.8449", pwr.Rows[0][ElectricMotorMapReader.Fields.PowerElectrical]); - var pwrMap = ElectricMotorMapReader.Create(pwr, 22.6, 2, 0.97); - Assert.AreEqual(-146.469, pwrMap.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3); + var pwrMap = ElectricMotorMapReader.Create(pwr, 2); + Assert.AreEqual(-5816.6, pwrMap.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3); - Assert.AreEqual(-20773.997, pwrMap.LookupElectricPower(120.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3); + Assert.AreEqual(-16170.5166, pwrMap.LookupElectricPower(120.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3); } diff --git a/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs b/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs index 5bae324576b79fb0d3017a530029606bd3523f87..2bb7c1795b0bc85701b38b41b9ed517d296d1069 100644 --- a/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs +++ b/VectoCore/VectoCoreTest/Integration/BatteryElectric/BatteryElectricTest.cs @@ -110,7 +110,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B4_constant_{0}-{1}_{2}_{3}", vmax, initialSoC, slope, pAuxEl); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB4; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE4; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 22.6, largeMotor: true, pAuxEl: pAuxEl); var run = job.Runs.First().Run; @@ -146,7 +146,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B4_acc_{0}-{1}_{2}", vmax, initialSoC, slope); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB4; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE4; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 22.6, largeMotor: true); var run = job.Runs.First().Run; @@ -182,7 +182,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleParallelHybrid-B4_cycle_{0}-{1}_{2}_{3}", declarationMission, initialSoC, payload, pAuxEl); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB4; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE4; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 22.6, largeMotor: true); var run = job.Runs.First().Run; @@ -267,7 +267,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B3_constant_{0}-{1}_{2}_{3}", vmax, initialSoC, slope, pAuxEl); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB3; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE3; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 22.6, largeMotor: true, pAuxEl: pAuxEl); var run = job.Runs.First().Run; @@ -303,7 +303,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B3_acc_{0}-{1}_{2}", vmax, initialSoC, slope); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB3; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE3; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 22.6, largeMotor: true); var run = job.Runs.First().Run; @@ -339,7 +339,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleParallelHybrid-B3_cycle_{0}-{1}_{2}_{3}", declarationMission, initialSoC, payload, pAuxEl); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB3; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE3; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 22.6, largeMotor: true); @@ -393,7 +393,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B2_constant_{0}-{1}_{2}_{3}", vmax, initialSoC, slope, pAuxEl); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB2; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE2; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 2, largeMotor: true, pAuxEl: pAuxEl); var run = job.Runs.First().Run; @@ -431,7 +431,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B2_stop_{0}-{1}_{2}", vmax, initialSoC, slope); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB2; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE2; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 2, largeMotor: true); var run = job.Runs.First().Run; @@ -461,7 +461,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; var modFilename = string.Format("SimpleBatteryElectric-B2_acc_{0}-{1}_{2}", vmax, initialSoC, slope); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB2; + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE2; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 2, largeMotor: true); var run = job.Runs.First().Run; @@ -496,8 +496,8 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric const bool largeMotor = true; - var modFilename = string.Format("SimpleParallelHybrid-B2_cycle_{0}-{1}_{2}_{3}", declarationMission, initialSoC, payload, pAuxEl); - const PowertrainPosition pos = PowertrainPosition.BatteryElectricB2; + var modFilename = string.Format("SimpleBatteryElectric-B2_cycle_{0}-{1}_{2}_{3}", declarationMission, initialSoC, payload, pAuxEl); + const PowertrainPosition pos = PowertrainPosition.BatteryElectricE2; var job = CreateEngineeringRun( cycle, modFilename, initialSoC, pos, 2, 2, largeMotor: true); var run = job.Runs.First().Run; @@ -603,7 +603,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric var driverData = CreateDriverData(AccelerationFile, true); var electricMotorData = - MockSimulationDataFactory.CreateElectricMotorData(MotorFile, count, pos, ratio / (pos == PowertrainPosition.BatteryElectricB3 ? 2.59 : 1.0), 0.97); + MockSimulationDataFactory.CreateElectricMotorData(MotorFile, count, pos, ratio / (pos == PowertrainPosition.BatteryElectricE3 ? 2.59 : 1.0), 0.97); var batteryData = MockSimulationDataFactory.CreateBatteryData(BatFile, initialBatCharge); @@ -636,11 +636,11 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric { WriteModalResults = true, }; - if (pos == PowertrainPosition.BatteryElectricB3) { + if (pos == PowertrainPosition.BatteryElectricE3) { runData.AxleGearData = axleGearData; } - if (pos == PowertrainPosition.BatteryElectricB2) { + if (pos == PowertrainPosition.BatteryElectricE2) { runData.AxleGearData = axleGearData; runData.GearboxData = gearboxData; } @@ -682,22 +682,22 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric case PowertrainPosition.HybridP3: case PowertrainPosition.HybridP4: throw new VectoException("testcase does not support parallel powertrain configurations"); - case PowertrainPosition.BatteryElectricB4: + case PowertrainPosition.BatteryElectricE4: powertrain.AddComponent( - GetElectricMachine(PowertrainPosition.BatteryElectricB4, runData.ElectricMachinesData, container, es, ctl)); + GetElectricMachine(PowertrainPosition.BatteryElectricE4, runData.ElectricMachinesData, container, es, ctl)); new DummyGearboxInfo(container); //new MockEngineInfo(container); new ATClutchInfo(container); break; - case PowertrainPosition.BatteryElectricB3: + case PowertrainPosition.BatteryElectricE3: powertrain.AddComponent(new AxleGear(container, runData.AxleGearData)) .AddComponent( - GetElectricMachine(PowertrainPosition.BatteryElectricB3, runData.ElectricMachinesData, container, es, ctl)); + GetElectricMachine(PowertrainPosition.BatteryElectricE3, runData.ElectricMachinesData, container, es, ctl)); new DummyGearboxInfo(container); //new MockEngineInfo(container); new ATClutchInfo(container); break; - case PowertrainPosition.BatteryElectricB2: + case PowertrainPosition.BatteryElectricE2: var strategy = new PEVAMTShiftStrategy(container); foreach (var entry in gearboxData.Gears) { @@ -708,7 +708,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BatteryElectric powertrain.AddComponent(new AxleGear(container, runData.AxleGearData)) .AddComponent(new PEVGearbox(container, strategy)) .AddComponent( - GetElectricMachine(PowertrainPosition.BatteryElectricB2, runData.ElectricMachinesData, container, es, ctl)); + GetElectricMachine(PowertrainPosition.BatteryElectricE2, runData.ElectricMachinesData, container, es, ctl)); new ATClutchInfo(container); break; //throw new VectoException("Battery Electric configuration B2 currently not supported"); diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ElectricMotorEfficienyMapTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ElectricMotorEfficienyMapTest.cs index d23702ed4098e5c15c25d1fa3a25998730687128..b8b8a666a4bde912cf60b97028a90c7a8ff99e7d 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ElectricMotorEfficienyMapTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ElectricMotorEfficienyMapTest.cs @@ -26,10 +26,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { JSONInputDataFactory.ReadElectricMotorData(@"TestData\Hybrids\ElectricMotor\GenericEMotor.vem", false); var fld = inputProvider.FullLoadCurve; - var fldMap = ElectricFullLoadCurveReader.Create(fld, 1.0, 1, 1.0); + var fldMap = ElectricFullLoadCurveReader.Create(fld, 1); var pwr = inputProvider.EfficiencyMap; - var pwrMap = ElectricMotorMapReader.Create(pwr, 1.0, 1, 1.0); + var pwrMap = ElectricMotorMapReader.Create(pwr, 1); var maxEmPwr = batPwr < 0 ? fldMap.FullLoadDriveTorque(emSpeed.RPMtoRad()) @@ -51,10 +51,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData { JSONInputDataFactory.ReadElectricMotorData(@"TestData\Hybrids\ElectricMotor\GenericEMotor.vem", false); var fld = inputProvider.FullLoadCurve; - var fldMap = ElectricFullLoadCurveReader.Create(fld, 1.0, 1, 1.0); + var fldMap = ElectricFullLoadCurveReader.Create(fld, 1); var pwr = inputProvider.EfficiencyMap; - var pwrMap = ElectricMotorMapReader.Create(pwr, 1.0, 1, 1.0); + var pwrMap = ElectricMotorMapReader.Create(pwr, 1); var maxEmPwr = batPwr < 0 ? fldMap.FullLoadDriveTorque(emSpeed.RPMtoRad()) diff --git a/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_Group2_P2/Class2_RigidTruck_ParHyb_ENG.vecto b/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_Group2_P2/Class2_RigidTruck_ParHyb_ENG.vecto index 44cacce02b03eb55520df746f7b0d8cdfb0d1e04..968cdd304678cad63fe96051bc866f6af8d09ddd 100644 --- a/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_Group2_P2/Class2_RigidTruck_ParHyb_ENG.vecto +++ b/VectoCore/VectoCoreTest/TestData/Hybrids/GenericVehicle_Group2_P2/Class2_RigidTruck_ParHyb_ENG.vecto @@ -19,7 +19,7 @@ "AdvancedAuxiliaryFilePath": "", "Aux": [], "Padd": 3540.0, - "Padd_electric": 3540.0, + "Padd_electric": 0.0, "VACC": "Truck.vacc", "EngineStopStartAtVehicleStopThreshold": 2.0, "EngineStopStartMaxOffTimespan": 120.0, diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 23b5b028849209c2c5516a1395a89a274452b4e4..c1d923b5ebdaecdd6ae8eed407a1b0a9b00c249f 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -281,6 +281,16 @@ namespace TUGraz.VectoCore.Tests.Utils throw new NotImplementedException(); } + public WattSecond TotalElectricMotorMotWorkDrive(PowertrainPosition emPos) + { + throw new NotImplementedException(); + } + + public WattSecond TotalElectricMotorMotWorkRecuperate(PowertrainPosition emPos) + { + throw new NotImplementedException(); + } + public PerSecond ElectricMotorAverageSpeed(PowertrainPosition emPos) { throw new NotImplementedException(); @@ -296,6 +306,16 @@ namespace TUGraz.VectoCore.Tests.Utils throw new NotImplementedException(); } + public double ElectricMotorMotEfficiencyDrive(PowertrainPosition emPos) + { + throw new NotImplementedException(); + } + + public double ElectricMotorMotEfficiencyGenerate(PowertrainPosition emPos) + { + throw new NotImplementedException(); + } + public WattSecond ElectricMotorOffLosses(PowertrainPosition emPos) { throw new NotImplementedException(); @@ -306,6 +326,11 @@ namespace TUGraz.VectoCore.Tests.Utils throw new NotImplementedException(); } + public WattSecond ElectricMotorMotLosses(PowertrainPosition emPos) + { + throw new NotImplementedException(); + } + public WattSecond ElectricMotorTransmissionLosses(PowertrainPosition emPos) { throw new NotImplementedException(); diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index 27db481980908758331753cc155cb8278bb70b42..00b278ec311ef1bababcca710e68886721ec0908 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -161,6 +161,7 @@ namespace TUGraz.VectoCore.Tests.Utils public IHybridControllerInfo HybridControllerInfo { get; } public IHybridControllerCtl HybridControllerCtl { get; } + public IAngledriveInfo AngledriveInfo { get; } public Watt GearboxLoss() { @@ -350,8 +351,10 @@ namespace TUGraz.VectoCore.Tests.Utils } public Tuple<PerSecond, NewtonMeter> CurrentAxleDemand { get; } + public double Ratio { get; } public Kilogram ReducedMassWheels { get; set; } + public Meter DynamicTyreRadius { get; } #region Implementation of IEngineControl