From 401f1418b21bc9bd060aebc3c987559202128281 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Fri, 19 Jun 2020 08:40:05 +0200 Subject: [PATCH] using test-powertrain to calculate rating for certain em configurations --- VectoCommon/VectoCommon/Models/IResponse.cs | 12 +- .../Models/Connector/Ports/Impl/Response.cs | 20 ++ .../Simulation/Data/ModalResultField.cs | 4 + .../Models/Simulation/DataBus/IClutchInfo.cs | 2 + .../Simulation/DataBus/IElectricMotorInfo.cs | 2 +- .../Models/Simulation/DataBus/IGearboxInfo.cs | 4 + .../Simulation/Impl/PowertrainBuilder.cs | 78 ++++- .../Data/Battery/BatteryData.cs | 2 + .../Models/SimulationComponent/IBattery.cs | 2 +- .../IElectricMotorControl.cs | 35 +- .../IHybridControlStrategy.cs | 2 + .../SimulationComponent/IHybridController.cs | 2 + .../Impl/AMTShiftStrategyACEA.cs | 12 +- .../Impl/AMTShiftStrategyOptimized.cs | 12 +- .../SimulationComponent/Impl/ATClutchInfo.cs | 5 + .../SimulationComponent/Impl/ATGearbox.cs | 12 + .../Impl/ATShiftStrategy.cs | 2 +- .../Impl/ATShiftStrategyOptimized.cs | 14 +- .../Impl/ATShiftStrategyVoith.cs | 2 +- .../Impl/AbstractGearbox.cs | 4 + .../SimulationComponent/Impl/Angledrive.cs | 2 +- .../SimulationComponent/Impl/AxleGear.cs | 4 +- .../Models/SimulationComponent/Impl/Clutch.cs | 13 +- .../Impl/CombustionEngine.cs | 37 +- .../SimulationComponent/Impl/CycleGearbox.cs | 12 + .../Impl/DefaultDriverStrategy.cs | 2 +- .../SimulationComponent/Impl/ElectricMotor.cs | 39 ++- .../SimulationComponent/Impl/Gearbox.cs | 13 +- .../Impl/HybridController.cs | 53 +-- .../Impl/MaxCardanTorquePreprocessor.cs | 8 +- .../Impl/SimpleHybridController.cs | 181 ++++++++++ .../Impl/StopStartCombustionEngine.cs | 4 +- .../Impl/TorqueConverter.cs | 4 +- .../Impl/TransmissionComponent.cs | 4 +- .../Strategies/HybridStrategy.cs | 315 +++++++++++++++--- .../OutputData/ModalDataContainer.cs | 2 +- VectoCore/VectoCore/VectoCore.csproj | 1 + .../Integration/Hybrid/ParallelHybridTest.cs | 150 +++++++-- .../ShiftStrategy/ShiftStrategyTest.cs | 8 +- VectoCore/VectoCoreTest/Utils/MockGearbox.cs | 15 + .../Utils/MockVehicleContainer.cs | 15 + 41 files changed, 922 insertions(+), 188 deletions(-) create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs diff --git a/VectoCommon/VectoCommon/Models/IResponse.cs b/VectoCommon/VectoCommon/Models/IResponse.cs index 1cb6301a40..8c830e8518 100644 --- a/VectoCommon/VectoCommon/Models/IResponse.cs +++ b/VectoCommon/VectoCommon/Models/IResponse.cs @@ -61,21 +61,23 @@ namespace TUGraz.VectoCommon.Models } - [DebuggerDisplay("n_ice: {EngineSpeed.AsRPM}; T_out: {EngineTorqueDemand}; T_ice: {EngineTorqueDemandTotal}; T_full_dyn: {EngineDynamicFullLoadTorque}; P_full_dyn: {DynamicFullLoadPower}; P_drag: {DragPower}; P_aux: {AuxiliariesPowerDemand}")] + [DebuggerDisplay("n_ice: {EngineSpeed.AsRPM}; T_out: {TorqueOutDemand}; T_ice: {TotalTorqueDemand}; T_full_dyn: {DynamicFullLoadTorque}; P_full_dyn: {DynamicFullLoadPower}; P_drag: {DragPower}; P_aux: {AuxiliariesPowerDemand}")] public class EngineResponse : AbstractPowertrainComponentResponse { public PerSecond EngineSpeed { get; set; } - public NewtonMeter EngineTorqueDemand { get; set; } - public NewtonMeter EngineTorqueDemandTotal { get; set; } - public NewtonMeter EngineDynamicFullLoadTorque { get; set; } + public NewtonMeter TorqueOutDemand { get; set; } + public NewtonMeter TotalTorqueDemand { get; set; } + public NewtonMeter DynamicFullLoadTorque { get; set; } - public NewtonMeter EngineStationaryFullLoadTorque { get; set; } + public NewtonMeter StationaryFullLoadTorque { get; set; } public Watt DynamicFullLoadPower { get; set; } public Watt DragPower { get; set; } + public NewtonMeter DragTorque { get; set; } + public Watt AuxiliariesPowerDemand { get; set; } } diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs index bd6e9cd885..7e4049b402 100644 --- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs +++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs @@ -55,9 +55,27 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl Vehicle = new VehicleResponse(); Brakes = new BrakesResponse(); ElectricMotor = new ElectricMotorResponse(); + //ElectricSystem = new TorqueConverter = new TorqueConverterResponse(); } + public AbstractResponse(object source, IResponse subResponse) + { + Source = source; + Driver = subResponse.Driver; + Engine = subResponse.Engine; + Clutch = subResponse.Clutch; + Gearbox = subResponse.Gearbox; + Axlegear = subResponse.Axlegear; + Angledrive = subResponse.Angledrive; + Wheels = subResponse.Wheels; + Vehicle = subResponse.Vehicle; + Brakes = subResponse.Brakes; + ElectricMotor = subResponse.ElectricMotor; + ElectricSystem = subResponse.ElectricSystem; + TorqueConverter = subResponse.TorqueConverter; + } + public Second AbsTime { get; set; } public Second SimulationInterval { get; set; } public Meter SimulationDistance { get; set; } @@ -153,6 +171,8 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl { public ResponseDryRun(object source) : base(source) { } + public ResponseDryRun(object source, IResponse subResponse) : base(source, subResponse) { } + public Watt DeltaFullLoad { get; set; } public Watt DeltaDragLoad { get; set; } public PerSecond DeltaEngineSpeed { get; set; } diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs index ec8244206d..54419692ce 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs @@ -349,6 +349,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Data [ModalResultField(typeof(DrivingBehavior))] drivingBehavior, + [ModalResultField(typeof(double))] HybridStrategyScore, + + [ModalResultField(typeof(double))]HybridStrategySolution, + //[ModalResultField(typeof(double), caption: "AA_NonSmartAlternatorsEfficiency [%]")] AA_NonSmartAlternatorsEfficiency, //[ModalResultField(typeof(SI), caption: "AA_SmartIdleCurrent_Amps [A]")] AA_SmartIdleCurrent_Amps, //[ModalResultField(typeof(double), caption: "AA_SmartIdleAlternatorsEfficiency [%]")] AA_SmartIdleAlternatorsEfficiency, diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IClutchInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IClutchInfo.cs index a1853577cb..a5958c8257 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IClutchInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IClutchInfo.cs @@ -39,5 +39,7 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus /// Returns if the clutch is closed in the current interval. /// </summary> bool ClutchClosed(Second absTime); + + Watt ClutchLosses { get; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs index c0182a4aa7..75bf5cfab8 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs @@ -5,7 +5,7 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus { public interface IElectricMotorInfo { - NewtonMeter ElectricDragTorque(PerSecond electricMotorSpeed, Second simulationInterval, DrivingBehavior drivingBehavior); + //NewtonMeter ElectricDragTorque(PerSecond electricMotorSpeed, Second simulationInterval, DrivingBehavior drivingBehavior); PerSecond ElectricMotorSpeed { get; } PowertrainPosition Position { get; } diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs index e95bd10ee4..48254bf68a 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs @@ -60,6 +60,10 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus Second LastShift { get; } + Second LastUpshift { get; } + + Second LastDownshift { get; } + GearData GetGearData(uint gear); /// <summary> diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index ed2bf3a46f..23a8b92bc3 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -384,7 +384,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl ctl.Gearbox = gbx; ctl.Engine = engine; - + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); @@ -423,7 +423,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return null; } - container.ModData.AddElectricMotor(pos); + container.ModData?.AddElectricMotor(pos); ctl.AddElectricMotor(pos, motorData.Item2); var motor = new ElectricMotor(container, motorData.Item2, ctl.ElectricMotorControl(pos), pos); motor.Connect(es); @@ -474,6 +474,70 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .AddAuxiliaries(container, data); } + public void BuildSimpleHybridPowertrain(VectoRunData data, VehicleContainer container) + { + //if (data.Cycle.CycleType != CycleType.DistanceBased) { + // throw new VectoException("CycleType must be DistanceBased"); + //} + + var battery = new Battery(container, data.BatteryData); + battery.Initialize(data.BatteryData.InitialSoC); + + var es = new ElectricSystem(container); + es.Connect(battery); + + var clutch = data.GearboxData.Type.ManualTransmission() ? new SwitchableClutch(container, data.EngineData) : null; + + var gearbox = GetSimpleGearbox(container, data); + var gbx = gearbox as IHybridControlledGearbox; + if (gbx == null) { + throw new VectoException("Gearbox can not be used for parallel hybrid"); + } + var engine = new CombustionEngine(container, data.EngineData); + + var ctl = new SimpleHybridController(container, es, clutch); + + ctl.Gearbox = gbx; + ctl.Engine = engine; + + var vehicle = new Vehicle(container, data.VehicleData, data.AirdragData); + //var dummyDriver = new Driver(container, data.DriverData, new DefaultDriverStrategy(container)); + var powertrain = vehicle + .AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)) + .AddComponent(ctl) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP4, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(new AxleGear(container, data.AxleGearData)) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(data.AngledriveData != null ? new Angledrive(container, data.AngledriveData) : null) + .AddComponent(gearbox, data.Retarder, container) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP2, data.ElectricMachinesData, container, es, ctl)) + .AddComponent(clutch) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP1, data.ElectricMachinesData, container, es, ctl)); + + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels + // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux + + // TODO: MQ 2018-11-19: engineering mode needs AUX power from cycle, use face cycle... + // should be a reference/proxy to the main driving cyle. but how to access it? + switch (data.Cycle.CycleType) { + case CycleType.DistanceBased: + container.AddComponent(new DistanceBasedDrivingCycle(container, data.Cycle)); + break; + case CycleType.MeasuredSpeed: + var dummyData = GetMeasuredSpeedDummnCycle(); + var msCycle = new MeasuredSpeedDrivingCycle(container, dummyData); + msCycle.AddComponent(vehicle); + break; + case CycleType.EngineOnly: break; + default: throw new VectoException("Wrong CycleType for SimplePowertrain"); + } + + var idleController = GetIdleController(data.PTO, engine, container); + //cycle.IdleController = idleController as IdleControllerSwitcher; + + powertrain.AddComponent(engine, idleController) + .AddAuxiliaries(container, data); + } private DrivingCycleData GetMeasuredSpeedDummnCycle() { @@ -769,6 +833,16 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl get { throw new VectoException("No Gearbox available."); } } + public Second LastUpshift + { + get { throw new VectoException("No Gearbox available."); } + } + + public Second LastDownshift + { + get { throw new VectoException("No Gearbox available."); } + } + public GearData GetGearData(uint gear) { throw new VectoException("No Gearbox available."); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs index 852b7b7fc2..e8391a1b93 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs @@ -24,6 +24,8 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData { public Ampere MaxCurrent { get; internal set; } public double InitialSoC { get; internal set; } + + public double TargetSoC { get; internal set; } } public class SOCMap diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IBattery.cs b/VectoCore/VectoCore/Models/SimulationComponent/IBattery.cs index bea010f6ae..ffc18e5481 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IBattery.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IBattery.cs @@ -5,7 +5,7 @@ using TUGraz.VectoCore.Models.Simulation.DataBus; namespace TUGraz.VectoCore.Models.SimulationComponent { - public interface IElectricSystemInfo : IBatteryInfo + public interface IElectricSystemInfo { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs b/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs index faa305349b..6f13b1a493 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotorControl.cs @@ -22,22 +22,25 @@ namespace TUGraz.VectoCore.Models.SimulationComponent PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, PowertrainPosition position, bool dryRun); - /// <summary> - /// required for electric-only powertrain (i.e., serial hybrids) - /// returns the maximum power the engine may provide (i.e., full-load) - /// </summary> - /// <param name="avgSpeed"></param> - /// <param name="dt"></param> - /// <returns>power at full drive, has to be less than 0! </returns> - NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt); - /// <summary> - /// required for electric-only powertrain (i.e., serial hybrids) - /// returns the maximum power the engine may apply during retardation (i.e., drag-load) - /// </summary> - /// <param name="avgSpeed"></param> - /// <param name="dt"></param> - /// <returns>power at full retardation (for current driving situation), has to be greater than 0!</returns> - NewtonMeter MaxDragTorque(PerSecond avgSpeed, Second dt); + // TODO: MQ 2020-0618 - still needed? + + ///// <summary> + ///// required for electric-only powertrain (i.e., serial hybrids) + ///// returns the maximum power the engine may provide (i.e., full-load) + ///// </summary> + ///// <param name="avgSpeed"></param> + ///// <param name="dt"></param> + ///// <returns>power at full drive, has to be less than 0! </returns> + //NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt); + + ///// <summary> + ///// required for electric-only powertrain (i.e., serial hybrids) + ///// returns the maximum power the engine may apply during retardation (i.e., drag-load) + ///// </summary> + ///// <param name="avgSpeed"></param> + ///// <param name="dt"></param> + ///// <returns>power at full retardation (for current driving situation), has to be greater than 0!</returns> + //NewtonMeter MaxDragTorque(PerSecond avgSpeed, Second dt); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs index e61b13f292..9d2802bf11 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs @@ -3,6 +3,7 @@ using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Strategies; +using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent { @@ -21,5 +22,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent HybridStrategyResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity); void CommitSimulationStep(Second time, Second simulationInterval); IHybridController Controller { set; } + void WriteModalResults(Second time, Second simulationInterval, IModalDataContainer container); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs index 2d5ae8f3e7..4fb7c26f19 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs @@ -8,6 +8,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { { IShiftStrategy ShiftStrategy { get; } + SimpleComponentState PreviousState { get; } + IElectricMotorControl ElectricMotorControl(PowertrainPosition pos); void AddElectricMotor(PowertrainPosition pos, ElectricMotorData motorDataItem2); ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse strategySettings); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyACEA.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyACEA.cs index ff7c068bf8..28e8124b85 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyACEA.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyACEA.cs @@ -364,11 +364,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } ResponseDryRun respDriverDemand = null; - if (respAccRsv.Engine.EngineTorqueDemandTotal <= respAccRsv.Engine.EngineDynamicFullLoadTorque) { + if (respAccRsv.Engine.TotalTorqueDemand <= respAccRsv.Engine.DynamicFullLoadTorque) { respDriverDemand = DriverDemandResponse(gradient, driverAccelerationAvg); var fc = PowertrainConfig.EngineData.Fuels.First().ConsumptionMap.GetFuelConsumption( - respDriverDemand.Engine.EngineTorqueDemandTotal.LimitTo( + respDriverDemand.Engine.TotalTorqueDemand.LimitTo( PowertrainConfig.EngineData.FullLoadCurves[0].DragLoadStationaryTorque(respAccRsv.Engine.EngineSpeed), PowertrainConfig.EngineData.FullLoadCurves[0].FullLoadStationaryTorque(respAccRsv.Engine.EngineSpeed)), respAccRsv.Engine.EngineSpeed); @@ -661,19 +661,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } var averageAccelerationTorque = AverageAccelerationTorqueLookup.Interpolate( - responseDriverDemand.Engine.EngineSpeed, responseDriverDemand.Engine.EngineTorqueDemand); + responseDriverDemand.Engine.EngineSpeed, responseDriverDemand.Engine.TorqueOutDemand); TestContainerGbx.Gear = gear; var initResponse = TestContainer.VehiclePort.Initialize(vehicleSpeed, estimatedGradient); - var delta = initResponse.Engine.EngineTorqueDemand - averageAccelerationTorque; + var delta = initResponse.Engine.TorqueOutDemand - averageAccelerationTorque; var acceleration = SearchAlgorithm.Search( 0.SI<MeterPerSquareSecond>(), delta, 0.1.SI<MeterPerSquareSecond>(), - getYValue: r => { return (r as AbstractResponse).Engine.EngineTorqueDemand - averageAccelerationTorque; }, + getYValue: r => { return (r as AbstractResponse).Engine.TorqueOutDemand - averageAccelerationTorque; }, evaluateFunction: a => { return TestContainer.VehiclePort.Request( 0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, a, estimatedGradient, true); }, - criterion: r => { return ((r as AbstractResponse).Engine.EngineTorqueDemand - averageAccelerationTorque).Value(); } + criterion: r => { return ((r as AbstractResponse).Engine.TorqueOutDemand - averageAccelerationTorque).Value(); } ); var engineAcceleration = (acceleration / ratio).Cast<PerSquareSecond>(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs index 6bc1808f1c..11f494e2d6 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs @@ -86,7 +86,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fcUpshiftPossible = true; - if (response1.Engine.EngineTorqueDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { + if (response1.Engine.TorqueOutDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { return currentGear; } @@ -169,12 +169,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (double.IsNaN(fcCurrent)) { //var responseCurrent = RequestDryRunWithGear(absTime, dt, DataBus.VehicleSpeed, DataBus.DriverAcceleration, currentGear); var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear); - var tqCurrent = responseCurrent.Engine.EngineTorqueDemandTotal.LimitTo( + var tqCurrent = responseCurrent.Engine.TotalTorqueDemand.LimitTo( fld[currentGear].DragLoadStationaryTorque(responseCurrent.Engine.EngineSpeed), fld[currentGear].FullLoadStationaryTorque(responseCurrent.Engine.EngineSpeed)); fcCurrent = GetFCRating(responseCurrent.Engine.EngineSpeed, tqCurrent); } - var tqNext = response.Engine.EngineTorqueDemandTotal.LimitTo( + var tqNext = response.Engine.TotalTorqueDemand.LimitTo( fld[tryNextGear].DragLoadStationaryTorque(response.Engine.EngineSpeed), fld[tryNextGear].FullLoadStationaryTorque(response.Engine.EngineSpeed)); var fcNext = GetFCRating(response.Engine.EngineSpeed, tqNext); @@ -238,7 +238,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return currentGear; } - if (response1.Engine.EngineTorqueDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { + if (response1.Engine.TorqueOutDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { return currentGear; } @@ -264,11 +264,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear); //var responseCurrent = RequestDryRunWithGear(absTime, dt, DataBus.VehicleSpeed, DataBus.DriverAcceleration, currentGear); - fcCurrent = GetFCRating(responseCurrent.Engine.EngineSpeed, responseCurrent.Engine.EngineTorqueDemand.LimitTo( + fcCurrent = GetFCRating(responseCurrent.Engine.EngineSpeed, responseCurrent.Engine.TorqueOutDemand.LimitTo( fld[currentGear].DragLoadStationaryTorque(responseCurrent.Engine.EngineSpeed), fld[currentGear].FullLoadStationaryTorque(responseCurrent.Engine.EngineSpeed))); } - var fcNext = GetFCRating(response.Engine.EngineSpeed, response.Engine.EngineTorqueDemand.LimitTo( + var fcNext = GetFCRating(response.Engine.EngineSpeed, response.Engine.TorqueOutDemand.LimitTo( fld[tryNextGear].DragLoadStationaryTorque(response.Engine.EngineSpeed), fld[tryNextGear].FullLoadStationaryTorque(response.Engine.EngineSpeed))); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATClutchInfo.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATClutchInfo.cs index 4612e885a1..b003e1917a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATClutchInfo.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATClutchInfo.cs @@ -31,6 +31,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { return true; } + public Watt ClutchLosses + { + get { return 0.SI<Watt>(); } + } + #endregion } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs index f152a22007..fdbe493f5b 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs @@ -103,6 +103,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl TorqueConverter.NextComponent = other; } + public override Second LastUpshift + { + get { throw new System.NotImplementedException(); } + protected internal set { throw new System.NotImplementedException(); } + } + + public override Second LastDownshift + { + get { throw new System.NotImplementedException(); } + protected internal set { throw new System.NotImplementedException(); } + } + public override GearInfo NextGear { get { return _strategy.NextGear; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index 9783694270..4f1356b705 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -514,7 +514,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var nextTcOutSpeed = gbxOutSpeed * ModelData.Gears[currentGear + 1].TorqueConverterRatio; var tcNext = ModelData.TorqueConverterData.LookupOperatingPointOut( - nextTcOutSpeed, response.Engine.EngineSpeed, response.Engine.EngineTorqueDemand); + nextTcOutSpeed, response.Engine.EngineSpeed, response.Engine.TorqueOutDemand); var tcLossesNextGear = tcNext.InAngularVelocity * tcNext.InTorque - tcNext.OutAngularVelocity * tcNext.OutTorque; var deltaTcLosses = tcLossesNextGear - tcLossesCurrentGear; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs index 83e0781c99..442a3b2d61 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs @@ -187,7 +187,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var _accMin = (accPower / DataBus.VehicleInfo.VehicleSpeed / (MaxMass + DataBus.WheelsInfo.ReducedMassWheels)).Cast<MeterPerSquareSecond>(); var _accMax = (accPower / DataBus.VehicleInfo.VehicleSpeed / (MinMass + DataBus.WheelsInfo.ReducedMassWheels)).Cast<MeterPerSquareSecond>(); - var engineLoadPercent = inTorque / response.Engine.EngineDynamicFullLoadTorque; + var engineLoadPercent = inTorque / response.Engine.DynamicFullLoadTorque; var _loadStage = GetLoadStage(engineLoadPercent); var shiftSpeed = UpshiftLineTCLocked.LookupShiftSpeed( @@ -239,7 +239,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (DataBus.DriverInfo.DriverAcceleration < 0) { return null; } - if (response1.Engine.EngineTorqueDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { + if (response1.Engine.TorqueOutDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { return null; } @@ -331,12 +331,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // absTime, dt, vehicleSpeedForGearRating, DataBus.DriverAcceleration, current); //var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, current); var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorqueEst, outAngularVelocityEst, current); - var tqCurrent = responseCurrent.Engine.EngineTorqueDemand.LimitTo( + var tqCurrent = responseCurrent.Engine.TorqueOutDemand.LimitTo( fld[currentGear].DragLoadStationaryTorque(responseCurrent.Engine.EngineSpeed), fld[currentGear].FullLoadStationaryTorque(responseCurrent.Engine.EngineSpeed)); fcCurrent = GetFCRating(responseCurrent.Engine.EngineSpeed, tqCurrent); } - var tqNext = response.Engine.EngineTorqueDemand.LimitTo( + var tqNext = response.Engine.TorqueOutDemand.LimitTo( fld[next.Gear].DragLoadStationaryTorque(response.Engine.EngineSpeed), fld[next.Gear].FullLoadStationaryTorque(response.Engine.EngineSpeed)); var fcNext = GetFCRating(response.Engine.EngineSpeed, tqNext); @@ -379,7 +379,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque, PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response1) { - if (response1.Engine.EngineTorqueDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { + if (response1.Engine.TorqueOutDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * fld[currentGear].DragLoadStationaryTorque(response1.Engine.EngineSpeed))) { return null; } @@ -417,11 +417,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (!IsAboveUpShiftCurve(next.Gear, inTorque, inAngularVelocity, next.TorqueConverterLocked.Value)) { if (double.IsNaN(fcCurrent)) { var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, current); - fcCurrent = GetFCRating(responseCurrent.Engine.EngineSpeed, responseCurrent.Engine.EngineTorqueDemand.LimitTo( + fcCurrent = GetFCRating(responseCurrent.Engine.EngineSpeed, responseCurrent.Engine.TorqueOutDemand.LimitTo( fld[currentGear].DragLoadStationaryTorque(responseCurrent.Engine.EngineSpeed), fld[currentGear].FullLoadStationaryTorque(responseCurrent.Engine.EngineSpeed))); } - var fcNext = GetFCRating(response.Engine.EngineSpeed, response.Engine.EngineTorqueDemand.LimitTo( + var fcNext = GetFCRating(response.Engine.EngineSpeed, response.Engine.TorqueOutDemand.LimitTo( fld[next.Gear].DragLoadStationaryTorque(response.Engine.EngineSpeed), fld[next.Gear].FullLoadStationaryTorque(response.Engine.EngineSpeed))); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs index 218d3cc175..65c05d55d1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs @@ -173,7 +173,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _accMax = (accPower / DataBus.VehicleInfo.VehicleSpeed / (MinMass + DataBus.WheelsInfo.ReducedMassWheels)).Cast<MeterPerSquareSecond>(); //var engineLoadPercent = inTorque / FullLoadCurve.FullLoadStationaryTorque(inAngularVelocity); - var engineLoadPercent = inTorque / response.Engine.EngineDynamicFullLoadTorque; + var engineLoadPercent = inTorque / response.Engine.DynamicFullLoadTorque; _loadStage = GetLoadStage(engineLoadPercent); return base.ShiftRequired( diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs index e890079a94..fe08d6b0d8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs @@ -110,6 +110,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public virtual Second LastShift { get; protected set; } + public abstract Second LastUpshift { get; protected internal set; } + + public abstract Second LastDownshift { get; protected internal set; } + public GearData GetGearData(uint gear) { return ModelData.Gears[gear]; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs index 7c9a1d017e..f780dddc7b 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Angledrive.cs @@ -46,7 +46,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl bool dryRun = false) { var retVal = base.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); - retVal.Angledrive.PowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; + retVal.Angledrive.PowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; return retVal; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs index 720c808f16..c5c88be82f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs @@ -56,8 +56,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl bool dryRun = false) { var retVal = base.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); - retVal.Axlegear.PowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0; - retVal.Axlegear.CardanTorque = CurrentState.InTorque; + retVal.Axlegear.PowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + retVal.Axlegear.CardanTorque = InTorque; return retVal; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index cd05b8335f..df474ac2a1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -93,6 +93,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return retVal; } + public virtual void Initialize(Watt clutchLoss) + { + PreviousState.ClutchLoss = clutchLoss; + } + + public virtual IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun = false) { @@ -157,7 +163,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl NewtonMeter torqueIn; PerSecond angularVelocityIn; - var startClutch = DataBus.VehicleInfo.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0) || (PreviousState.ClutchLoss.IsEqual(0) && outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed)); + var startClutch = DataBus.VehicleInfo.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0); // || (PreviousState.ClutchLoss.IsEqual(0) && outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed)); var slippingClutchWhenDriving = (DataBus.GearboxInfo.Gear <= 2 && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Braking); var slippingClutchDuringBraking = DataBus.GearboxInfo.Gear == 1 && DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking && outTorque > 0 && DataBus.Brakes.BrakePower.IsEqual(0); //var slippingClutchWhenDriving = (DataBus.Gear == 1 && outTorque > 0); @@ -224,6 +230,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return DataBus.GearboxInfo.GearEngaged(absTime); } + public Watt ClutchLosses + { + get { return PreviousState.ClutchLoss; } + } + public class ClutchState : SimpleComponentState { public Watt ClutchLoss = 0.SI<Watt>(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index baa412b47a..511ea303b6 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -235,12 +235,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Engine = { EngineSpeed = angularVelocity, PowerRequest = torqueOut * avgEngineSpeed, + TorqueOutDemand = torqueOut, + TotalTorqueDemand = totalTorqueDemand, DynamicFullLoadPower = dynamicFullLoadPower, - EngineTorqueDemand = torqueOut, - EngineTorqueDemandTotal = totalTorqueDemand, - EngineDynamicFullLoadTorque = dynamicFullLoadTorque, - EngineStationaryFullLoadTorque = stationaryFullLoadTorque, + DynamicFullLoadTorque = dynamicFullLoadTorque, + StationaryFullLoadTorque = stationaryFullLoadTorque, DragPower = fullDragTorque * avgEngineSpeed, + DragTorque = fullDragTorque, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, }, }; @@ -283,10 +284,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl EngineSpeed = angularVelocity, PowerRequest = totalTorqueDemand * avgEngineSpeed, DynamicFullLoadPower = dynamicFullLoadPower, - EngineTorqueDemand = torqueOut, - EngineTorqueDemandTotal = totalTorqueDemand, - EngineStationaryFullLoadTorque = stationaryFullLoadTorque, - EngineDynamicFullLoadTorque = dynamicFullLoadTorque, + TorqueOutDemand = torqueOut, + TotalTorqueDemand = totalTorqueDemand, + StationaryFullLoadTorque = stationaryFullLoadTorque, + DynamicFullLoadTorque = dynamicFullLoadTorque, DragPower = CurrentState.FullDragTorque * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, }, @@ -302,10 +303,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Engine = { PowerRequest = totalTorqueDemand * avgEngineSpeed, DynamicFullLoadPower = dynamicFullLoadPower, - EngineTorqueDemand = torqueOut, - EngineTorqueDemandTotal = totalTorqueDemand, - EngineStationaryFullLoadTorque = stationaryFullLoadTorque, - EngineDynamicFullLoadTorque = dynamicFullLoadTorque, + TorqueOutDemand = torqueOut, + TotalTorqueDemand = totalTorqueDemand, + StationaryFullLoadTorque = stationaryFullLoadTorque, + DynamicFullLoadTorque = dynamicFullLoadTorque, DragPower = CurrentState.FullDragTorque * avgEngineSpeed, EngineSpeed = angularVelocity, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, @@ -318,10 +319,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseSuccess(this) { Engine = { PowerRequest = totalTorqueDemand * avgEngineSpeed, - EngineTorqueDemand = torqueOut, - EngineTorqueDemandTotal = totalTorqueDemand, - EngineStationaryFullLoadTorque = stationaryFullLoadTorque, - EngineDynamicFullLoadTorque = dynamicFullLoadTorque, + TorqueOutDemand = torqueOut, + TotalTorqueDemand = totalTorqueDemand, + StationaryFullLoadTorque = stationaryFullLoadTorque, + DynamicFullLoadTorque = dynamicFullLoadTorque, DynamicFullLoadPower = dynamicFullLoadPower, DragPower = CurrentState.FullDragTorque * avgEngineSpeed, EngineSpeed = angularVelocity, @@ -366,8 +367,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl PowerRequest = PreviousState.EnginePower, DynamicFullLoadPower = PreviousState.DynamicFullLoadTorque * PreviousState.EngineSpeed, EngineSpeed = outAngularVelocity, - EngineTorqueDemand = outTorque, - EngineTorqueDemandTotal = outTorque + auxDemand + TorqueOutDemand = outTorque, + TotalTorqueDemand = outTorque + auxDemand } }; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs index e4fe9a6e75..18e01c8ec7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs @@ -437,6 +437,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ICluchInfo + public override Second LastUpshift + { + get { throw new System.NotImplementedException(); } + protected internal set { throw new System.NotImplementedException(); } + } + + public override Second LastDownshift + { + get { throw new System.NotImplementedException(); } + protected internal set { throw new System.NotImplementedException(); } + } + public override GearInfo NextGear { get { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index c2e2068410..b551eb0b66 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -134,7 +134,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (retVal.Source is ICombustionEngine) { var success = retVal as ResponseSuccess; var avgEngineSpeed = (success.Engine.EngineSpeed + Driver.DataBus.EngineInfo.EngineSpeed) / 2.0; - EcoRollState.AcceleratorPedalIdle = success.Engine.DragPower.IsEqual(success.Engine.EngineTorqueDemandTotal * avgEngineSpeed, 10.SI<Watt>()); + EcoRollState.AcceleratorPedalIdle = success.Engine.DragPower.IsEqual(success.Engine.TotalTorqueDemand * avgEngineSpeed, 10.SI<Watt>()); } else { EcoRollState.AcceleratorPedalIdle = false; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index f0869658b9..e19b76527c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -68,8 +68,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { var avgSpeed = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2; var maxDriveTorque = GetMaxDriveTorque(absTime, dt, avgSpeed); - var maxRecuperationTorque = ModelData.FullLoadCurve.FullGenerationTorque(avgSpeed); - + var maxRecuperationTorque = GetMaxRecuperationTorque(absTime, dt, avgSpeed); + var retVal = HandleRequest(absTime, dt, outTorque, outAngularVelocity, dryRun, maxDriveTorque, maxRecuperationTorque); retVal.ElectricMotor.MaxDriveTorque = maxDriveTorque; @@ -84,6 +84,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return retVal; } + private NewtonMeter GetMaxRecuperationTorque(Second absTime, Second dt, PerSecond avgSpeed) + { + var maxEmTorque = ModelData.FullLoadCurve.FullGenerationTorque(avgSpeed); + var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), true); + var maxBatPower = electricSystemResponse.BatteryResponse.MaxBatteryLoadCharge; + + var maxBatRecuperationTorque = ModelData.EfficiencyMap.LookupTorque(maxBatPower, avgSpeed, maxEmTorque); + var maxTorqueRecuperate = VectoMath.Max(maxEmTorque, maxBatRecuperationTorque); + return maxTorqueRecuperate < 0 ? null : maxTorqueRecuperate; + } + private NewtonMeter GetMaxDriveTorque(Second absTime, Second dt, PerSecond avgSpeed) { var maxEmTorque = ModelData.FullLoadCurve.FullLoadDriveTorque(avgSpeed); @@ -91,7 +102,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var maxBatPower = electricSystemResponse.BatteryResponse.MaxBatteryLoadDischarge; var maxBatDriveTorque = ModelData.EfficiencyMap.LookupTorque(maxBatPower, avgSpeed, maxEmTorque); - return VectoMath.Max(maxEmTorque, maxBatDriveTorque); + var maxTorqueDrive = VectoMath.Max(maxEmTorque, maxBatDriveTorque); + return maxTorqueDrive > 0 ? null : maxTorqueDrive; } @@ -122,6 +134,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl throw new VectoSimulationException("electric motor cannot provide torque when gearbox and clutch are disengaged"); } var electricSystemResponse = ElectricPower.Request(absTime, dt, 0.SI<Watt>(), dryRun); + if (!dryRun) { + SetState(inTorque, outAngularVelocity); + } var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); retVal.ElectricMotor.ElectricMotorPowerMech = 0.SI<Watt>(); retVal.ElectricSystem = electricSystemResponse; @@ -144,7 +159,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // return retVal; //} - if (!eMotorTorque.IsBetween(maxDriveTorque, maxRecuperationTorque)) { + if (!eMotorTorque.IsBetween(maxDriveTorque ?? 0.SI<NewtonMeter>(), maxRecuperationTorque ?? 0.SI<NewtonMeter>())) { throw new VectoException("Invalid operating point provided by strategy! SupportPower: {0}, max Power: {1}, min Power: {2}", eMotorTorque, maxDriveTorque, maxRecuperationTorque); } @@ -213,8 +228,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var remainingPower = inTorque * avgSpeed; if (dryRun) { - var driveTorque = Control.MaxDriveTorque(avgSpeed, dt); - var dragTorque = Control.MaxDragTorque(avgSpeed, dt); + //var driveTorque = Control.MaxDriveTorque(avgSpeed, dt); + var dragTorque = 0.SI<NewtonMeter>(); //Control.MaxDragTorque(avgSpeed, dt); var powerDemand = outTorque * avgSpeed; return new ResponseDryRun(this) { Engine = { @@ -275,16 +290,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl 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_drag_max_, Position] = CurrentState.DragMax * avgSpeed; - container[ModalResultField.P_electricMotor_drive_max_, Position] = CurrentState.DriveMax * avgSpeed; + container[ModalResultField.P_electricMotor_drag_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 + CurrentState.ElectricBrakePower); container[ModalResultField.P_electricMotorInertiaLoss_, Position] = CurrentState.InertiaTorqueLoss * avgSpeed; } - public NewtonMeter ElectricDragTorque(PerSecond electricMotorSpeed, Second dt, DrivingBehavior drivingBehavior) - { - return Control.MaxDragTorque(electricMotorSpeed, dt); - } + //public NewtonMeter ElectricDragTorque(PerSecond electricMotorSpeed, Second dt, DrivingBehavior drivingBehavior) + //{ + // return Control.MaxDragTorque(electricMotorSpeed, dt); + //} diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index c8330810c8..9b1b8f4b28 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -63,9 +63,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected internal GearInfo _nextGear; private Second _overrideDisengage; - public Second LastUpshift { get; protected internal set; } + public override Second LastUpshift { get; protected internal set; } - public Second LastDownshift { get; protected internal set; } + public override Second LastDownshift { get; protected internal set; } public override GearInfo NextGear { @@ -291,7 +291,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (dryRun) { // if gearbox is disengaged the 0[W]-line is the limit for drag and full load. var delta = inTorque * avgInAngularVelocity; - return new ResponseDryRun(this) { + var remainingPowerTrain = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), inAngularVelocity, true); + return new ResponseDryRun(this, remainingPowerTrain) { Gearbox = { PowerRequest = delta, Gear = 0, @@ -369,10 +370,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl dryRunResponse.Gearbox.PowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; dryRunResponse.Gearbox.Gear = Gear; + //dryRunResponse.Gearbox.GearboxInputSpeed = inAngularVelocity; return dryRunResponse; } var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, false); + response.Gearbox.GearboxInputSpeed = inAngularVelocity; var shiftAllowed = !inAngularVelocity.IsEqual(0) && !DataBus.VehicleInfo.VehicleSpeed.IsEqual(0); if (response is ResponseSuccess && shiftAllowed) { @@ -406,8 +409,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }, Engine = { EngineSpeed = response.Engine.EngineSpeed, - EngineTorqueDemand = response.Engine.EngineTorqueDemand, - EngineTorqueDemandTotal = response.Engine.EngineTorqueDemandTotal, + TorqueOutDemand = response.Engine.TorqueOutDemand, + TotalTorqueDemand = response.Engine.TotalTorqueDemand, PowerRequest = response.Engine.PowerRequest } }; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index e1cb37c050..f06fd82d6e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -70,6 +70,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _electricMotorTorque = strategySettings.MechanicalAssistPower; } + SimpleComponentState IHybridController.PreviousState + { + get { return PreviousState; } + } + public virtual IElectricMotorControl ElectricMotorControl(PowertrainPosition pos) { return _electricMotorCtl[pos]; @@ -86,6 +91,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var strategySettings = Strategy.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); ApplyStrategySettings(strategySettings); if (!dryRun) { + CurrentState.SetState(outTorque, outAngularVelocity, outTorque, outAngularVelocity); CurrentState.StrategyResponse = strategySettings; } return NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); @@ -93,6 +99,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) { + PreviousState.SetState(outTorque, outAngularVelocity, outTorque, outAngularVelocity); PreviousState.StrategyResponse = Strategy.Initialize(outTorque, outAngularVelocity); _electricMotorTorque = PreviousState.StrategyResponse.MechanicalAssistPower; return NextComponent.Initialize(outTorque, outAngularVelocity); @@ -104,8 +111,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Strategy.CommitSimulationStep(time, simulationInterval); } - protected override void DoWriteModalResults(Second time, Second simulationInterval, - IModalDataContainer container) { } + protected override void DoWriteModalResults( + Second time, Second simulationInterval, + IModalDataContainer container) + { + Strategy.WriteModalResults(time, simulationInterval, container); + } private NewtonMeter MechanicalAssistPower(PowertrainPosition pos, Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, bool dryRun) @@ -129,7 +140,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public ICombustionEngine Engine { protected get; set; } ///======================================================================================= - public class HybridControllerState + public class HybridControllerState : SimpleComponentState { public HybridStrategyResponse StrategyResponse; } @@ -154,24 +165,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl currOutAngularVelocity, dryRun); } - public NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt) - { - var driveTorque = ElectricMotorData.FullLoadCurve.FullLoadDriveTorque(avgSpeed); - var drivePowerElectric = ElectricMotorData.EfficiencyMap.LookupElectricPower(avgSpeed, driveTorque).ElectricalPower; - if (drivePowerElectric >= _controller.ElectricSystem.MaxDischargePower(dt)) - { - return driveTorque; - } - - drivePowerElectric = _controller.ElectricSystem.MaxDischargePower(dt); - driveTorque = ElectricMotorData.EfficiencyMap.SearchMechanicalPower(drivePowerElectric, avgSpeed).Torque; - return driveTorque; - } - - public NewtonMeter MaxDragTorque(PerSecond avgSpeed, Second dt) - { - return 0.SI<NewtonMeter>(); - } + //public NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt) + //{ + // var driveTorque = ElectricMotorData.FullLoadCurve.FullLoadDriveTorque(avgSpeed); + // var drivePowerElectric = ElectricMotorData.EfficiencyMap.LookupElectricPower(avgSpeed, driveTorque).ElectricalPower; + // if (drivePowerElectric >= _controller.ElectricSystem.MaxDischargePower(dt)) + // { + // return driveTorque; + // } + + // drivePowerElectric = _controller.ElectricSystem.MaxDischargePower(dt); + // driveTorque = ElectricMotorData.EfficiencyMap.SearchMechanicalPower(drivePowerElectric, avgSpeed).Torque; + // return driveTorque; + //} + + //public NewtonMeter MaxDragTorque(PerSecond avgSpeed, Second dt) + //{ + // return 0.SI<NewtonMeter>(); + //} } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxCardanTorquePreprocessor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxCardanTorquePreprocessor.cs index 9635598633..0c5b2ec46f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxCardanTorquePreprocessor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MaxCardanTorquePreprocessor.cs @@ -49,20 +49,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { var grad = VectoMath.InclinationToAngle(1); var max = TestContainer.VehiclePort.Initialize(vehicleSpeed, grad); - if ((max.Engine.EngineTorqueDemandTotal - maxTorque).IsGreater(0)) { + if ((max.Engine.TotalTorqueDemand - maxTorque).IsGreater(0)) { var first = TestContainer.VehiclePort.Initialize(vehicleSpeed, 0.SI<Radian>()); - var delta = first.Engine.EngineTorqueDemandTotal - maxTorque; + var delta = first.Engine.TotalTorqueDemand - maxTorque; grad = SearchAlgorithm.Search( 0.SI<Radian>(), delta, 0.1.SI<Radian>(), getYValue: r => { - return ((r as AbstractResponse).Engine.EngineTorqueDemandTotal - maxTorque); + return ((r as AbstractResponse).Engine.TotalTorqueDemand - maxTorque); }, evaluateFunction: g => { return TestContainer.VehiclePort.Initialize(vehicleSpeed, g); }, criterion: r => { - return ((r as AbstractResponse).Engine.EngineTorqueDemandTotal - maxTorque).Value() / 1e5; + return ((r as AbstractResponse).Engine.TotalTorqueDemand - maxTorque).Value() / 1e5; } ); max = TestContainer.VehiclePort.Initialize(vehicleSpeed, grad); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs new file mode 100644 index 0000000000..fc55b43ae9 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs @@ -0,0 +1,181 @@ +using System.Collections.Generic; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { + public class SimpleHybridController : VectoSimulationComponent, IHybridController, ITnInPort, ITnOutPort + { + + //private SwitchableClutch clutch; + private ElectricSystem ElectricSystem; + + protected readonly Dictionary<PowertrainPosition, ElectricMotorController> _electricMotorCtl = new Dictionary<PowertrainPosition, ElectricMotorController>(); + public ITnOutPort NextComponent; + + private Dictionary<PowertrainPosition, NewtonMeter> _electricMotorTorque = new Dictionary<PowertrainPosition, NewtonMeter>(); + + public SimpleHybridController(VehicleContainer container, ElectricSystem es, SwitchableClutch clutch) : base(container) + { + this.ElectricSystem = es; + //this.clutch = clutch; + } + + #region Overrides of VectoSimulationComponent + + protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) + { + // nothgin to write - this is only used in test-container + } + + protected override void DoCommitSimulationStep(Second time, Second simulationInterval) + { + // nothing to write - this is only used in test-container + } + + #endregion + + #region Implementation of ITnInProvider + + public ITnInPort InPort() + { + return this; + } + + #endregion + + #region Implementation of ITnOutProvider + + public ITnOutPort OutPort() + { + return this; + } + + #endregion + + #region Implementation of IHybridController + + public IShiftStrategy ShiftStrategy + { + get { return null; } + } + + public SimpleComponentState PreviousState + { + get { throw new System.NotImplementedException(); } + } + + public IElectricMotorControl ElectricMotorControl(PowertrainPosition pos) + { + return _electricMotorCtl[pos]; + } + + public void AddElectricMotor(PowertrainPosition pos, ElectricMotorData motorData) + { + if (_electricMotorCtl.ContainsKey(pos)) { + throw new VectoException("Electric motor already registered as position {0}", pos); + } + + _electricMotorCtl[pos] = new ElectricMotorController(this, motorData); + } + + public ResponseDryRun RequestDryRun( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + HybridStrategyResponse strategySettings) + { + throw new System.NotImplementedException(); + } + + #endregion + + #region Implementation of ITnInPort + + public void Connect(ITnOutPort other) + { + NextComponent = other; + } + + #endregion + + #region Implementation of ITnOutPort + + public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) + { + return NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); + } + + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + //PreviousState.StrategyResponse = Strategy.Initialize(outTorque, outAngularVelocity); + //_electricMotorTorque = PreviousState.StrategyResponse.MechanicalAssistPower; + return NextComponent.Initialize(outTorque, outAngularVelocity); + } + + #endregion + + public void ApplyStrategySettings(HybridStrategyResponse strategySettings) + { + Gearbox.SwitchToNeutral = strategySettings.GearboxInNeutral; + Engine.CombustionEngineOn = strategySettings.CombustionEngineOn; + _electricMotorTorque = strategySettings.MechanicalAssistPower; + } + + public IHybridControlledGearbox Gearbox { protected get; set; } + public ICombustionEngine Engine { protected get; set; } + + private NewtonMeter MechanicalAssistPower(PowertrainPosition pos, Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, bool dryRun) + { + return _electricMotorTorque.ContainsKey(pos) ? _electricMotorTorque[pos] : null; + } + + ///======================================================================================= + public class ElectricMotorController : IElectricMotorControl + { + private SimpleHybridController _controller; + private ElectricMotorData ElectricMotorData; + + public ElectricMotorController(SimpleHybridController controller, ElectricMotorData motorData) + { + _controller = controller; + ElectricMotorData = motorData; + } + #region Implementation of IElectricMotorControl + + public NewtonMeter MechanicalAssistPower( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond prevOutAngularVelocity, PerSecond currOutAngularVelocity, + PowertrainPosition position, bool dryRun) + { + return _controller.MechanicalAssistPower(position, absTime, dt, outTorque, prevOutAngularVelocity, + currOutAngularVelocity, dryRun); + } + + //public NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt) + //{ + // var driveTorque = ElectricMotorData.FullLoadCurve.FullLoadDriveTorque(avgSpeed); + // var drivePowerElectric = ElectricMotorData.EfficiencyMap.LookupElectricPower(avgSpeed, driveTorque).ElectricalPower; + // if (drivePowerElectric >= _controller.ElectricSystem.MaxDischargePower(dt)) { + // return driveTorque; + // } + + // drivePowerElectric = _controller.ElectricSystem.MaxDischargePower(dt); + // driveTorque = ElectricMotorData.EfficiencyMap.SearchMechanicalPower(drivePowerElectric, avgSpeed).Torque; + // return driveTorque; + //} + + //public NewtonMeter MaxDragTorque(PerSecond avgSpeed, Second dt) + //{ + // return 0.SI<NewtonMeter>(); + //} + + #endregion + } + + + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs index 5bf4dad306..514ce4b6c8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs @@ -64,7 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { DeltaFullLoad = 0.SI<Watt>(), DeltaDragLoad = 0.SI<Watt>(), Engine = { - EngineTorqueDemandTotal = 0.SI<NewtonMeter>(), + TotalTorqueDemand = 0.SI<NewtonMeter>(), PowerRequest = 0.SI<Watt>(), DynamicFullLoadPower = 0.SI<Watt>(), DragPower = 0.SI<Watt>(), @@ -79,7 +79,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { Engine = { PowerRequest = 0.SI<Watt>(), DynamicFullLoadPower = 0.SI<Watt>(), - EngineTorqueDemandTotal = 0.SI<NewtonMeter>(), + TotalTorqueDemand = 0.SI<NewtonMeter>(), DragPower = 0.SI<Watt>(), EngineSpeed = 0.RPMtoRad(), AuxiliariesPowerDemand = 0.SI<Watt>(), diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs index 9b36aaf1b7..5ba2826e17 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs @@ -177,7 +177,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DeltaEngineSpeed = operatingPoint.InAngularVelocity - maxEngineSpeed, TorqueConverter = { TorqueConverterOperatingPoint = operatingPoint}, Engine = { - EngineTorqueDemand = inTorque, + TorqueOutDemand = inTorque, EngineSpeed = engineResponse.Engine.EngineSpeed, PowerRequest = engineResponse.Engine.PowerRequest } @@ -208,7 +208,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DeltaEngineSpeed = dryOperatingPointMax.InAngularVelocity - maxEngineSpeed, TorqueConverter = { TorqueConverterOperatingPoint = dryOperatingPointMax}, Engine = { - EngineTorqueDemand = inTorque, + TorqueOutDemand = inTorque, EngineSpeed = dryOperatingPointMax?.InAngularVelocity ?? dryOperatingPointMin?.InAngularVelocity ?? 0.RPMtoRad(), PowerRequest = engineResponse.Engine.PowerRequest diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TransmissionComponent.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TransmissionComponent.cs index f371fa11cf..adf81d3165 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TransmissionComponent.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TransmissionComponent.cs @@ -89,11 +89,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); CurrentState.TorqueLossResult = torqueLossResult; } - + InTorque = inTorque; var retVal = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, dryRun); return retVal; } + protected NewtonMeter InTorque { get; private set; } + public virtual IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) { var inAngularVelocity = outAngularVelocity * ModelData.Ratio; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index 64530c5923..571750f250 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -1,18 +1,23 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { - public class HybridStrategy : IHybridControlStrategy + public class HybridStrategy : LoggingObject, IHybridControlStrategy { private VectoRunData ModelData; private IDataBus DataBus; @@ -22,6 +27,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies private bool ElectricMotorCanPropellDuringTractionInterruption; //private Second lastShiftTime; + private Gearbox TestContainerGbx; + private SimplePowertrainContainer TestContainer; + protected readonly VelocityRollingLookup VelocityDropData; + private SimpleHybridController TestContainerHybCtl; + public Battery TestContainerBattery; + private Clutch TestContainerClutch; + protected HybridStrategyResponse Response { get; set; } @@ -39,9 +51,47 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var emPos = ModelData.ElectricMachinesData.First().Item1; ElectricMotorCanPropellDuringTractionInterruption = emPos == PowertrainPosition.HybridP4 || emPos == PowertrainPosition.HybridP3; + + var modData = new ModalDataContainer(runData, null, new[] { FuelData.Diesel }, null, false); + var builder = new PowertrainBuilder(modData); + TestContainer = new SimplePowertrainContainer(runData); + builder.BuildSimpleHybridPowertrain(runData, TestContainer); + TestContainerGbx = TestContainer.GearboxCtl as Gearbox; + TestContainerHybCtl = TestContainer.HybridController as SimpleHybridController; + TestContainerBattery = TestContainer.BatteryInfo as Battery; + TestContainerClutch = TestContainer.ClutchInfo as Clutch; + if (TestContainerGbx == null) { + throw new VectoException("Unknown gearboxtype in TestContainer: {0}", TestContainer.GearboxCtl.GetType().FullName); + } + + if (TestContainerHybCtl == null) { + throw new VectoException("Unknown HybridController in TestContainer: {0}", TestContainer.HybridController.GetType().FullName); + } + + // register pre-processors + var maxG = runData.Cycle.Entries.Max(x => Math.Abs(x.RoadGradientPercent.Value())) + 1; + var grad = Convert.ToInt32(maxG / 2) * 2; + if (grad == 0) { + grad = 2; + } + + VelocityDropData = new VelocityRollingLookup(); + vehicleContainer.AddPreprocessor( + new VelocitySpeedGearshiftPreprocessor(VelocityDropData, runData.GearboxData.TractionInterruption, TestContainer, -grad, grad, 2)); + + var shiftStrategyParameters = runData.GearshiftParameters; + if (shiftStrategyParameters == null) { + throw new VectoException("Parameters for shift strategy missing!"); + } + if (shiftStrategyParameters.AllowedGearRangeFC > 2 || shiftStrategyParameters.AllowedGearRangeFC < 1) { + Log.Warn("Gear-range for FC-based gearshift must be either 1 or 2!"); + shiftStrategyParameters.AllowedGearRangeFC = shiftStrategyParameters.AllowedGearRangeFC.LimitTo(1, 2); + } } + public virtual IHybridController Controller { protected get; set; } + public virtual HybridStrategyResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) { @@ -49,85 +99,228 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return HandleHaltAction(absTime, dt, outTorque, outAngularVelocity, dryRun); } - Tuple<double, ResponseDryRun, HybridStrategyResponse, double> tmp = null; + + HybridResultEntry tmp = null; Tuple<bool, uint> gs = null; - if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate) { - if (DataBus.GearboxInfo.GearEngaged(absTime)) { + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate || DataBus.DriverInfo.DrivingAction == DrivingAction.Brake) { + if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { tmp = FindSolution(absTime, dt, outTorque, outAngularVelocity); - gs = HandleGearshift(absTime, tmp.Item2); + if (tmp != null) { + gs = HandleGearshift(absTime, tmp.Response); + } } else { - tmp = new Tuple<double, ResponseDryRun, HybridStrategyResponse, double>(double.NaN, null, new HybridStrategyResponse() { + tmp = new HybridResultEntry { + U = double.NaN, + Response = null, + Setting = new HybridStrategyResponse() { + GearboxInNeutral = false, + CombustionEngineOn = true, + MechanicalAssistPower = ElectricMotorsOff + }, + FuelCosts = double.NaN + }; + } + } + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Roll || DataBus.DriverInfo.DrivingAction == DrivingAction.Coast) { + tmp = new HybridResultEntry { + U = double.NaN, + Response = null, + Setting = new HybridStrategyResponse() { GearboxInNeutral = false, CombustionEngineOn = true, MechanicalAssistPower = ElectricMotorsOff - }, double.NaN); - } + }, + FuelCosts = double.NaN + }; } - if (DataBus.DriverInfo.DrivingAction == DrivingAction.Roll || DataBus.DriverInfo.DrivingAction == DrivingAction.Coast) { - tmp = new Tuple<double, ResponseDryRun, HybridStrategyResponse, double>(double.NaN, null, new HybridStrategyResponse() { - GearboxInNeutral = false, - CombustionEngineOn = true, - MechanicalAssistPower = ElectricMotorsOff - }, double.NaN); + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Brake && tmp == null) { + tmp = MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity); + gs = HandleGearshift(absTime, tmp.Response); } var retVal = new HybridStrategyResponse() { - CombustionEngineOn = tmp.Item3.CombustionEngineOn, - GearboxInNeutral = tmp.Item3.GearboxInNeutral, - MechanicalAssistPower = tmp.Item3.MechanicalAssistPower, + CombustionEngineOn = tmp.Setting.CombustionEngineOn, + GearboxInNeutral = tmp.Setting.GearboxInNeutral, + MechanicalAssistPower = tmp.Setting.MechanicalAssistPower, ShiftRequired = gs?.Item1 ?? false, NextGear = gs?.Item2 ?? 0, }; Response = dryRun ? null : retVal; + if (!dryRun) { + Solution = tmp; + } return retVal; } - private Tuple<double, ResponseDryRun, HybridStrategyResponse, double> FindSolution(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + public HybridResultEntry Solution { get; set; } + + private HybridResultEntry MaxRecuperationSetting(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { var first = new HybridStrategyResponse() { CombustionEngineOn = true, //DataBus.EngineCtl.CombustionEngineOn, GearboxInNeutral = false, // DataBus.GearboxInfo.GearEngaged(absTime), MechanicalAssistPower = ElectricMotorsOff }; - var firstResponse = Controller.RequestDryRun(absTime, dt, outTorque, outAngularVelocity, first); + var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, first); - var gearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); + + var emPos = ModelData.ElectricMachinesData.First().Item1; + var emTorque = firstResponse.ElectricMotor.MaxRecuperationTorque; + return TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorque, double.NaN); + } + + private HybridResultEntry FindSolution(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var first = new HybridStrategyResponse() { + CombustionEngineOn = true, //DataBus.EngineCtl.CombustionEngineOn, + GearboxInNeutral = false, // DataBus.GearboxInfo.GearEngaged(absTime), + MechanicalAssistPower = ElectricMotorsOff + }; + var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, first); + + //var gearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); var emPos = ModelData.ElectricMachinesData.First().Item1; var emTqReq = (firstResponse.ElectricMotor.PowerRequest + firstResponse.ElectricMotor.InertiaPowerDemand) / firstResponse.ElectricMotor.AngularVelocity; - var responses = new List<Tuple<double, ResponseDryRun, HybridStrategyResponse, double>>(); - for (var u = -1.0; u <= 1; u += 2.0 / 20) { - if (!(emTqReq * u).IsBetween( - firstResponse.ElectricMotor.MaxRecuperationTorque, firstResponse.ElectricMotor.MaxDriveTorque)) { - continue; - } - var cfg = new HybridStrategyResponse() { - CombustionEngineOn = true, - GearboxInNeutral = false, - MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() { - {emPos, emTqReq * u} + var responses = new List<HybridResultEntry>(); + + var entry = new HybridResultEntry() { + U = double.NaN, + Response = firstResponse, + Setting = first, + + //Score = CalcualteCosts(firstResponse, dt) + }; + CalcualteCosts(firstResponse, dt, entry); + responses.Add(entry); + + if (firstResponse.Gearbox.Gear == 0 && !ElectricMotorCanPropellDuringTractionInterruption) { + return responses.First(); + } + + var minimumShiftTimePassed = (DataBus.GearboxInfo.LastShift + ModelData.GearboxData.ShiftTime).IsSmallerOrEqual(absTime); + var gearRangeUpshift = ModelData.GearshiftParameters.AllowedGearRangeUp; + var gearRangeDownshift = ModelData.GearshiftParameters.AllowedGearRangeDown; + if (!minimumShiftTimePassed || (absTime - DataBus.GearboxInfo.LastUpshift).IsSmaller(ModelData.GearboxData.DownshiftAfterUpshiftDelay)) { + gearRangeDownshift = 0; + } + if (!minimumShiftTimePassed || (absTime - DataBus.GearboxInfo.LastDownshift).IsSmaller(ModelData.GearboxData.UpshiftAfterDownshiftDelay)) { + gearRangeUpshift = 0; + } + + var gear = DataBus.GearboxInfo.Gear; + var numGears = ModelData.GearboxData.Gears.Count; + for (var nextGear = Math.Max(1, gear - gearRangeDownshift); + nextGear <= Math.Min(numGears, gear + gearRangeUpshift); + nextGear++) + { + if (!ElectricMotorCanPropellDuringTractionInterruption) { + // em is at gearbox input side - angular speed is different so get new } - }; - var resp = Controller.RequestDryRun(absTime, dt, outTorque, outAngularVelocity, cfg); - var cost = CalcualteCosts(resp, dt); - responses.Add(Tuple.Create(u, resp, cfg, cost)); + IterateEMTorque(absTime, dt, outTorque, outAngularVelocity, firstResponse, emTqReq, emPos, responses); } - var best = responses.OrderBy(x => x.Item4).First(); + if (responses.All(x => double.IsNaN(x.Score))) { + return null; + } + + var best = responses.Where(x => !double.IsNaN(x.Score)).OrderBy(x => x.Score).First(); return best; } - private double CalcualteCosts(ResponseDryRun resp, Second dt) + private void IterateEMTorque( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, ResponseDryRun firstResponse, + NewtonMeter emTqReq, PowertrainPosition emPos, List<HybridResultEntry> responses) + { + const double stepSize = 0.1; + + // iterate over 'EM provides torque'. allow EM to provide more torque in order to overcome ICE inertia + var maxU = Math.Min((firstResponse.ElectricMotor.MaxDriveTorque ?? 0.SI<NewtonMeter>()) / emTqReq, -1.0); + if (firstResponse.ElectricMotor.MaxDriveTorque != null) { + for (var u = 0.0; u >= maxU; u -= stepSize * (u < -4 ? 10 : (u < -2 ? 5 : 1))) { + var emTorque = emTqReq.Abs() * u; + if (!emTorque.IsBetween( + 0.SI<NewtonMeter>(), firstResponse.ElectricMotor.MaxDriveTorque)) { + continue; + } + + var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorque, u); + responses.Add(tmp); + } + + // make sure the max drive point is also covered. + var emTorqueM = emTqReq * maxU; + if (emTorqueM.IsBetween( + 0.SI<NewtonMeter>(), firstResponse.ElectricMotor.MaxDriveTorque)) { + var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorqueM, maxU); + responses.Add(tmp); + } + } + + // iterate over 'EM recuperates' up to max available recuperation potential + if (firstResponse.ElectricMotor.MaxRecuperationTorque != null) { + for (var u = stepSize; u <= 1.0; u += stepSize) { + var emTorque = firstResponse.ElectricMotor.MaxRecuperationTorque * u; + if (!(emTorque).IsBetween( + firstResponse.ElectricMotor.MaxRecuperationTorque, 0.SI<NewtonMeter>())) { + continue; + } + + var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorque, u); + responses.Add(tmp); + } + } + } + + private HybridResultEntry TryConfiguration( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, PowertrainPosition emPos, + NewtonMeter emTorque, double u) + { + var cfg = new HybridStrategyResponse() { + CombustionEngineOn = true, + GearboxInNeutral = false, + MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() { + { emPos, emTorque } + } + }; + var resp = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, cfg); + + var tmp = new HybridResultEntry { + U = u, + Setting = cfg, + Response = resp, + //Score = cost + }; + CalcualteCosts(resp, dt, tmp); + return tmp; + } + + private ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse cfg) + { + TestContainerHybCtl.ApplyStrategySettings(cfg); + TestContainerGbx.Gear = DataBus.GearboxInfo.Gear; + TestContainerHybCtl.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); + TestContainerClutch.Initialize(DataBus.ClutchInfo.ClutchLosses); + TestContainerBattery.Initialize(DataBus.BatteryInfo.StateOfCharge); + var retVal = TestContainerHybCtl.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); + var retVal2 = Controller.RequestDryRun(absTime, dt, outTorque, outAngularVelocity, cfg); + return retVal as ResponseDryRun; + } + + private void CalcualteCosts(ResponseDryRun resp, Second dt, HybridResultEntry tmp) { - var fcCost = ModelData.EngineData.Fuels.Sum( - x => (x.ConsumptionMap.GetFuelConsumptionValue(resp.Engine.EngineTorqueDemandTotal, resp.Engine.EngineSpeed) + if (!resp.Engine.TotalTorqueDemand.IsBetween( + resp.Engine.DragTorque, resp.Engine.DynamicFullLoadTorque)) { + tmp.FuelCosts = double.NaN; + } + + tmp.FuelCosts = ModelData.EngineData.Fuels.Sum( + x => (x.ConsumptionMap.GetFuelConsumptionValue(resp.Engine.TotalTorqueDemand, resp.Engine.EngineSpeed) * x.FuelData.LowerHeatingValueVecto * dt).Value()); - var eqnFactor = 2.5; - var batCost = (resp.ElectricSystem.ConsumerPower * dt).Value(); - var socPenalty = 1 - Math.Pow((resp.ElectricSystem.BatteryResponse.StateOfCharge - DataBus.BatteryInfo.StateOfCharge) / (0.5 * (ModelData.BatteryData.MaxSOC - ModelData.BatteryData.MinSOC)), 5); + tmp.BatCosts = -(resp.ElectricSystem.ConsumerPower * dt).Value(); + tmp.SoCPenalty = 1 - Math.Pow((DataBus.BatteryInfo.StateOfCharge - ModelData.BatteryData.TargetSoC) / (0.5 * (ModelData.BatteryData.MaxSOC - ModelData.BatteryData.MinSOC)), 5); - var cost = fcCost + eqnFactor * batCost * socPenalty; - return cost; + tmp.EqualityFactor = 2.5; } private Tuple<bool, uint> HandleGearshift(Second absTime, ResponseDryRun response) @@ -136,7 +329,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var gear = DataBus.GearboxInfo.Gear; var _nextGear = gear; - var outSpeed = response.Engine.EngineSpeed / ModelData.GearboxData.Gears[gear].Ratio; + var outSpeed = (response.Gearbox.GearboxInputSpeed ?? response.Engine.EngineSpeed ) / ModelData.GearboxData.Gears[gear].Ratio; // emergency shift to not stall the engine ------------------------ if (gear == 1 && SpeedTooLowForEngine(_nextGear, outSpeed)) { retVal = Tuple.Create(true, 0u); @@ -160,10 +353,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return retVal; } - if (response.Engine.EngineSpeed != null && response.Engine.EngineSpeed.IsGreaterOrEqual(1600.RPMtoRad())) { + if (response.Engine.EngineSpeed != null && gear < ModelData.GearboxData.Gears.Count && ModelData.GearboxData.Gears[gear].ShiftPolygon.IsAboveUpshiftCurve(response.Engine.TorqueOutDemand, response.Engine.EngineSpeed)) { //lastShiftTime = absTime; retVal = Tuple.Create(true, response.Gearbox.Gear + 1); } + if (response.Engine.EngineSpeed != null && gear > 0 && ModelData.GearboxData.Gears[gear].ShiftPolygon.IsBelowDownshiftCurve(response.Engine.TorqueOutDemand, response.Engine.EngineSpeed)) { + //lastShiftTime = absTime; + retVal = Tuple.Create(true, response.Gearbox.Gear - 1); + } return retVal; } @@ -208,6 +405,32 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } + public void WriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) + { + container[ModalResultField.HybridStrategyScore] = Solution?.Score ?? 0; + container[ModalResultField.HybridStrategySolution] = Solution?.U ?? -100; + } + + [DebuggerDisplay("{U}: {Score} {Setting.MechanicalAssistPower}")] + public class HybridResultEntry + { + public double U { get; set; } + + public HybridStrategyResponse Setting { get; set; } + + public ResponseDryRun Response { get; set; } + + public double Score { get { return FuelCosts + EqualityFactor * BatCosts * SoCPenalty; } } + + public double FuelCosts { get; set; } + + public double BatCosts { get; set; } + + public double SoCPenalty { get; set; } + + public double EqualityFactor { get; set; } + } + } diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index c381d3b187..a4d15ba37e 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -503,7 +503,7 @@ namespace TUGraz.VectoCore.OutputData } } //if (!_writeEngineOnly && WriteAdvancedAux) { - + dataColumns.AddRange(new [] {ModalResultField.HybridStrategyScore, ModalResultField.HybridStrategySolution}.Select(x => x.GetName())); //} return dataColumns; } diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 256926fe2a..cef7da6259 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -401,6 +401,7 @@ <Compile Include="Models\SimulationComponent\Impl\ElectricMotor.cs" /> <Compile Include="Models\SimulationComponent\Impl\HybridController.cs" /> <Compile Include="Models\SimulationComponent\IHybridController.cs" /> + <Compile Include="Models\SimulationComponent\Impl\SimpleHybridController.cs" /> <Compile Include="Models\SimulationComponent\Impl\StopStartCombustionEngine.cs" /> <Compile Include="Models\SimulationComponent\Strategies\DelegateParallelHybridStrategy.cs" /> <Compile Include="Models\SimulationComponent\Strategies\HybridStrategy.cs" /> diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs index 600dbcdc5b..5c9f3ceeaa 100644 --- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs @@ -7,7 +7,9 @@ using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Impl; using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.InputData.Reader.ShiftStrategy; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; @@ -44,23 +46,57 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); } - [TestCase(30, 0.8, 200), - TestCase(30, 0.3, 200), - TestCase(30, 0.8, -200), - TestCase(30, 0.8, 0), - ] - public void P2HybridDirveOff_ElectricAndICE(double vmax, double initialSoC, double electricTorque) + //[TestCase(30, 0.8, 200), + //TestCase(30, 0.3, 200), + //TestCase(30, 0.8, -200), + //TestCase(30, 0.8, 0), + //] + //public void P2HybridDirveOff_ElectricAndICE(double vmax, double initialSoC, double electricTorque) + //{ + // var cycleData = string.Format( + // @" 0, 0, 0, 3 + // 700, {0}, 0, 0", vmax); + // var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + // const bool largeMotor = true; + // var electricTq = electricTorque.SI<NewtonMeter>(); + // var run = CreateEngineeringRun( + // cycle, string.Format("SimpleParallelHybrid_acc_{0}_{2}-{1}.vmod", vmax, initialSoC, electricTq.Value()), + // initialSoC, PowertrainPosition.HybridP2); + + // var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; + // Assert.NotNull(hybridController); + // //var strategy = (DelegateParallelHybridStrategy)hybridController.Strategy; + // //Assert.NotNull(strategy); + + // var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; + + // var nextState = new StrategyState(); + // var currentState = new StrategyState(); + + + + // run.Run(); + // Assert.IsTrue(run.FinishedWithoutErrors); + + // Assert.IsTrue(modData.Rows.Count > 0); + //} + + [TestCase(30, 0.7, 0, TestName = "P2 Hybrid DriveOff 30km/h SoC: 0.7, level"), + TestCase(30, 0.22, 0, TestName = "P2 Hybrid DriveOff 30km/h SoC: 0.22, level") + ] + public void P2HybridDriveOff(double vmax, double initialSoC, double slope) { var cycleData = string.Format( - @" 0, 0, 0, 3 - 700, {0}, 0, 0", vmax); + @" 0, 0, {1}, 3 + 700, {0}, {1}, 0", vmax, slope); var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); const bool largeMotor = true; - var electricTq = electricTorque.SI<NewtonMeter>(); + + const PowertrainPosition pos = PowertrainPosition.HybridP2; var run = CreateEngineeringRun( - cycle, string.Format("SimpleParallelHybrid_acc_{0}_{2}-{1}.vmod", vmax, initialSoC, electricTq.Value()), - initialSoC, PowertrainPosition.HybridP2); + cycle, string.Format("SimpleParallelHybrid_acc_{0}-{1}_{2}.vmod", vmax, initialSoC, slope), initialSoC, pos, largeMotor: true); var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; Assert.NotNull(hybridController); @@ -80,21 +116,24 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid Assert.IsTrue(modData.Rows.Count > 0); } - [TestCase(30, 0.7), - TestCase(30, 0.22) - ] - public void P2HybridDriveOff_ElectricOnly(double vmax, double initialSoC) + + [TestCase(50, 0.79, 0, TestName = "P2 Hybrid Brake Standstill 50km/h SoC: 0.79, level"), + TestCase(50, 0.25, 0, TestName = "P2 Hybrid Brake Standstill 50km/h SoC: 0.25, level"), + TestCase(50, 0.65, 0, TestName = "P2 Hybrid Brake Standstill 50km/h SoC: 0.65, level") + ] + public void P2HybridBrakeStandstill(double vmax, double initialSoC, double slope) { + //var dst = var cycleData = string.Format( - @" 0, 0, 0, 3 - 700, {0}, 0, 0", vmax); + @" 0, {0}, {1}, 0 + 100, 0, {1}, 3", vmax, slope); var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); const bool largeMotor = true; const PowertrainPosition pos = PowertrainPosition.HybridP2; var run = CreateEngineeringRun( - cycle, string.Format("SimpleParallelHybrid_ICE-off-acc_{0}-{1}.vmod", vmax, initialSoC), initialSoC, pos, largeMotor: true); + cycle, string.Format("SimpleParallelHybrid_stop_{0}-{1}_{2}.vmod", vmax, initialSoC, slope), initialSoC, pos, largeMotor: true); var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; Assert.NotNull(hybridController); @@ -106,7 +145,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid var nextState = new StrategyState(); var currentState = new StrategyState(); - + run.Run(); Assert.IsTrue(run.FinishedWithoutErrors); @@ -114,7 +153,6 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid Assert.IsTrue(modData.Rows.Count > 0); } - public class StrategyState { public Second lastGearShift = -double.MaxValue.SI<Second>(); @@ -158,10 +196,17 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid MockSimulationDataFactory.CreateElectricMotorData(largeMotor ? MotorFile240kW : MotorFile, pos); var batteryData = MockSimulationDataFactory.CreateBatteryData(BatFile, initialBatCharge); + batteryData.TargetSoC = 0.5; var engineData = MockSimulationDataFactory.CreateEngineDataFromFile( Truck40tPowerTrain.EngineFile, gearboxData.Gears.Count); + foreach (var entry in gearboxData.Gears) { + entry.Value.ShiftPolygon = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon( + (int)entry.Key, engineData.FullLoadCurves[entry.Key], new TransmissionInputData().Repeat(gearboxData.Gears.Count + 1).Cast<ITransmissionInputData>().ToList(), engineData, axleGearData.AxleGear.Ratio, + vehicleData.DynamicTyreRadius); + } + var runData = new VectoRunData() { //PowertrainConfiguration = PowertrainConfiguration.ParallelHybrid, JobRunId = 0, @@ -178,6 +223,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid EngineData = engineData, BatteryData = batteryData, //HybridStrategy = strategySettings + GearshiftParameters = CreateGearshiftData(gearboxData, axleGearData.AxleGear.Ratio, engineData.IdleSpeed) }; var container = new VehicleContainer( ExecutionMode.Engineering, modData, x => { sumData?.Write(x, 1, 1, runData); }); @@ -232,6 +278,68 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid return container; } + public static ShiftStrategyParameters CreateGearshiftData(GearboxData gbx, double axleRatio, PerSecond engineIdlingSpeed) + { + var retVal = new ShiftStrategyParameters { + StartVelocity = DeclarationData.GearboxTCU.StartSpeed, + StartAcceleration = DeclarationData.GearboxTCU.StartAcceleration, + GearResidenceTime = DeclarationData.GearboxTCU.GearResidenceTime, + DnT99L_highMin1 = DeclarationData.GearboxTCU.DnT99L_highMin1, + DnT99L_highMin2 = DeclarationData.GearboxTCU.DnT99L_highMin2, + AllowedGearRangeUp = DeclarationData.GearboxTCU.AllowedGearRangeUp, + AllowedGearRangeDown = DeclarationData.GearboxTCU.AllowedGearRangeDown, + LookBackInterval = DeclarationData.GearboxTCU.LookBackInterval, + DriverAccelerationLookBackInterval = DeclarationData.GearboxTCU.DriverAccelerationLookBackInterval, + DriverAccelerationThresholdLow = DeclarationData.GearboxTCU.DriverAccelerationThresholdLow, + AverageCardanPowerThresholdPropulsion = DeclarationData.GearboxTCU.AverageCardanPowerThresholdPropulsion, + CurrentCardanPowerThresholdPropulsion = DeclarationData.GearboxTCU.CurrentCardanPowerThresholdPropulsion, + TargetSpeedDeviationFactor = DeclarationData.GearboxTCU.TargetSpeedDeviationFactor, + EngineSpeedHighDriveOffFactor = DeclarationData.GearboxTCU.EngineSpeedHighDriveOffFactor, + RatingFactorCurrentGear = gbx.Type.AutomaticTransmission() + ? DeclarationData.GearboxTCU.RatingFactorCurrentGearAT + : DeclarationData.GearboxTCU.RatingFactorCurrentGear, + //AccelerationReserveLookup = AccelerationReserveLookupReader.ReadFromStream( + // RessourceHelper.ReadStream( + // DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.AccelerationReserveLookup.csv")), + //ShareTorque99L = ShareTorque99lLookupReader.ReadFromStream( + // RessourceHelper.ReadStream( + // DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.ShareTq99L.csv") + //), + //PredictionDurationLookup = PredictionDurationLookupReader.ReadFromStream( + // RessourceHelper.ReadStream( + // DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.PredictionTimeLookup.csv") + //), + //ShareIdleLow = ShareIdleLowReader.ReadFromStream( + // RessourceHelper.ReadStream( + // DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.ShareIdleLow.csv") + //), + //ShareEngineHigh = EngineSpeedHighLookupReader.ReadFromStream( + // RessourceHelper.ReadStream( + // DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.ShareEngineSpeedHigh.csv") + //), + + //-------------------- + RatioEarlyUpshiftFC = DeclarationData.GearboxTCU.RatioEarlyUpshiftFC / axleRatio, + RatioEarlyDownshiftFC = DeclarationData.GearboxTCU.RatioEarlyDownshiftFC / axleRatio, + AllowedGearRangeFC = gbx.Type.AutomaticTransmission() + ? (gbx.Gears.Count > DeclarationData.GearboxTCU.ATSkipGearsThreshold + ? DeclarationData.GearboxTCU.AllowedGearRangeFCATSkipGear + : DeclarationData.GearboxTCU.AllowedGearRangeFCAT) + : DeclarationData.GearboxTCU.AllowedGearRangeFCAMT, + VelocityDropFactor = DeclarationData.GearboxTCU.VelocityDropFactor, + AccelerationFactor = DeclarationData.GearboxTCU.AccelerationFactor, + MinEngineSpeedPostUpshift = 0.RPMtoRad(), + ATLookAheadTime = DeclarationData.GearboxTCU.ATLookAheadTime, + + LoadStageThresoldsUp = DeclarationData.GearboxTCU.LoadStageThresholdsUp, + LoadStageThresoldsDown = DeclarationData.GearboxTCU.LoadStageThresoldsDown, + ShiftSpeedsTCToLocked = DeclarationData.GearboxTCU.ShiftSpeedsTCToLocked + .Select(x => x.Select(y => y + engineIdlingSpeed.AsRPM).ToArray()).ToArray(), + }; + + return retVal; + } + private static IElectricMotor GetElectricMachine(PowertrainPosition pos, IList<Tuple<PowertrainPosition, ElectricMotorData>> electricMachinesData, VehicleContainer container, IElectricSystem es, IHybridController ctl) @@ -262,7 +370,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid ratio.IsEqual(1) ? GearboxIndirectLoss : GearboxDirectLoss, ratio, string.Format("Gear {0}", i)), Ratio = ratio, - //ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile) + //ShiftPolygon = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon(i,) })).ToDictionary(k => k.Item1 + 1, v => v.Item2), ShiftTime = 2.SI<Second>(), Inertia = 0.SI<KilogramSquareMeter>(), diff --git a/VectoCore/VectoCoreTest/Integration/ShiftStrategy/ShiftStrategyTest.cs b/VectoCore/VectoCoreTest/Integration/ShiftStrategy/ShiftStrategyTest.cs index 1bd79f2b21..ccc8b3302b 100644 --- a/VectoCore/VectoCoreTest/Integration/ShiftStrategy/ShiftStrategyTest.cs +++ b/VectoCore/VectoCoreTest/Integration/ShiftStrategy/ShiftStrategyTest.cs @@ -152,19 +152,19 @@ namespace TUGraz.VectoCore.Tests.Integration.ShiftStrategy var r = tuple.Item2; var s = tuple.Item3; var fc = r.Engine.EngineSpeed != null - ? container.RunData.EngineData.Fuels.First().ConsumptionMap.GetFuelConsumption(r.Engine.EngineTorqueDemandTotal, r.Engine.EngineSpeed).Value + ? container.RunData.EngineData.Fuels.First().ConsumptionMap.GetFuelConsumption(r.Engine.TotalTorqueDemand, r.Engine.EngineSpeed).Value .ConvertToGrammPerHour().Value : 0; var fc2 = s?.Engine.EngineSpeed != null - ? container.RunData.EngineData.Fuels.First().ConsumptionMap.GetFuelConsumption(s.Engine.EngineTorqueDemandTotal, s.Engine.EngineSpeed).Value + ? container.RunData.EngineData.Fuels.First().ConsumptionMap.GetFuelConsumption(s.Engine.TotalTorqueDemand, s.Engine.EngineSpeed).Value .ConvertToGrammPerHour().Value : 0; Console.WriteLine( "{0}; {1}; {2}; {3}; {4}; {5}; {6}; {7}", tuple.Item1, tuple.Item2 is ResponseGearShift ? "1" : "0", r.Engine.EngineSpeed?.AsRPM ?? 0, - r.Engine.EngineTorqueDemand?.Value() ?? 0, fc, + r.Engine.TorqueOutDemand?.Value() ?? 0, fc, s?.Engine.EngineSpeed?.AsRPM ?? 0, - s?.Engine.EngineTorqueDemand?.Value() ?? 0, fc2 + s?.Engine.TorqueOutDemand?.Value() ?? 0, fc2 ); } } diff --git a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs index 400b727464..172ba27c88 100644 --- a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs +++ b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs @@ -95,6 +95,16 @@ namespace TUGraz.VectoCore.Tests.Utils public Second LastShift { get; private set; } + public Second LastUpshift + { + get { throw new NotImplementedException(); } + } + + public Second LastDownshift + { + get { throw new NotImplementedException(); } + } + public GearData GetGearData(uint gear) { return new GearData(); @@ -142,6 +152,11 @@ namespace TUGraz.VectoCore.Tests.Utils return _clutchClosed; } + public Watt ClutchLosses + { + get { throw new NotImplementedException(); } + } + public void SetClutch(bool closed) { _clutchClosed = closed; diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index 8ac5cb92fc..098457ef40 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -56,6 +56,7 @@ namespace TUGraz.VectoCore.Tests.Utils private Watt _axlegearLoss = 0.SI<Watt>(); private bool _clutchClosed = true; private ITorqueConverterControl _torqueConverter; + private IGearboxInfo _gearboxInfoImplementation; public IAxlegearInfo AxlegearInfo { @@ -159,6 +160,15 @@ namespace TUGraz.VectoCore.Tests.Utils } public Second LastShift { get; set; } + public Second LastUpshift + { + get { return _gearboxInfoImplementation.LastUpshift; } + } + + public Second LastDownshift + { + get { return _gearboxInfoImplementation.LastDownshift; } + } public GearData GetGearData(uint gear) { @@ -243,6 +253,11 @@ namespace TUGraz.VectoCore.Tests.Utils return _clutchClosed; } + public Watt ClutchLosses + { + get { throw new NotImplementedException(); } + } + public Watt BrakePower { get; set; } public Radian RoadGradient { get; set; } public MeterPerSecond TargetSpeed { get; set; } -- GitLab