From 680d184c1ee30d31a2c9c0044573987b3edf6b1e Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Mon, 22 Jun 2020 21:17:16 +0200 Subject: [PATCH] more work on hybrid strategy --- .../Models/Declaration/DeclarationData.cs | 3 + .../Simulation/Impl/PowertrainBuilder.cs | 24 +- .../SimulationComponent/IHybridController.cs | 2 +- .../Impl/AMTShiftStrategy.cs | 8 +- .../Impl/AMTShiftStrategyOptimized.cs | 40 +-- .../SimulationComponent/Impl/Battery.cs | 2 +- .../SimulationComponent/Impl/Gearbox.cs | 4 +- .../Impl/HybridController.cs | 20 +- .../Impl/SimpleHybridController.cs | 12 +- .../Impl/StopStartCombustionEngine.cs | 9 + .../Strategies/HybridStrategy.cs | 287 +++++++++++++----- .../Integration/Hybrid/ParallelHybridTest.cs | 186 +++++++++++- 12 files changed, 466 insertions(+), 131 deletions(-) diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 15ea2fb218..c86439a6fb 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -452,6 +452,9 @@ namespace TUGraz.VectoCore.Models.Declaration public static class GearboxTCU { + + public static readonly MeterPerSecond MIN_SPEED_AFTER_TRACTION_INTERRUPTION = 5.KMPHtoMeterPerSecond(); + public const double TorqueReserve = 0; public const double TorqueReserveStart = 0.2; diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 23a8b92bc3..954c55c70b 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -39,6 +39,8 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; @@ -493,7 +495,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (gbx == null) { throw new VectoException("Gearbox can not be used for parallel hybrid"); } - var engine = new CombustionEngine(container, data.EngineData); + var engine = new StopStartCombustionEngine(container, data.EngineData); var ctl = new SimpleHybridController(container, es, clutch); @@ -501,9 +503,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl 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( + 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)) @@ -734,6 +738,22 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } } + //public class DummyFvOutPort : IFvOutPort { + // #region Implementation of IFvOutPort + + // public IResponse Request(Second absTime, Second dt, Newton force, MeterPerSecond velocity, bool dryRun) + // { + // return new ResponseSuccess(this); + // } + + // public IResponse Initialize(Newton vehicleForce, MeterPerSecond vehicleSpeed) + // { + // return new ResponseSuccess(this); + // } + + // #endregion + //} + internal class DummyDriverInfo : VectoSimulationComponent, IDriverInfo { public DummyDriverInfo(VehicleContainer container) : base(container) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs index 4fb7c26f19..2be5d30ce2 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs @@ -12,6 +12,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { IElectricMotorControl ElectricMotorControl(PowertrainPosition pos); void AddElectricMotor(PowertrainPosition pos, ElectricMotorData motorDataItem2); - ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse strategySettings); + //ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse strategySettings); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs index 515ab13e53..50e7027162 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs @@ -117,10 +117,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { - return InitStartGear(outTorque, outAngularVelocity); + return InitStartGear(absTime, outTorque, outAngularVelocity); } for (var gear = (uint)ModelData.Gears.Count; gear > 1; gear--) { - var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); + var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; @@ -150,7 +150,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return 1; } - private uint InitStartGear(NewtonMeter outTorque, PerSecond outAngularVelocity) + private uint InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity) { for (var gear = MaxStartGear; gear > 1; gear--) { var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; @@ -160,7 +160,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl continue; } - var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); + var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); var fullLoadPower = response.Engine.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad; var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs index 11f494e2d6..265cf8f686 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs @@ -31,7 +31,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private Kilogram vehicleMass; protected internal ResponseDryRun minFCResponse; - public static readonly MeterPerSecond MIN_SPEED_AFTER_TRACTION_INTERRUPTION = 5.KMPHtoMeterPerSecond(); + public AMTShiftStrategyOptimized(VectoRunData runData, IVehicleContainer dataBus) : base(runData, dataBus) { @@ -91,7 +91,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); - if (!estimatedVelocityPostShift.IsGreater(MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { + if (!estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { return currentGear; } @@ -234,7 +234,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fcCurrent = double.NaN; var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); - if (!estimatedVelocityPostShift.IsGreater(MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { + if (!estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { return currentGear; } @@ -286,23 +286,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #endregion - protected ResponseDryRun RequestDryRunWithGear( - Second absTime, Second dt, MeterPerSecond vehicleSpeed, MeterPerSquareSecond acceleration, uint tryNextGear) - { - LogEnabled = false; - TestContainerGbx.Disengaged = false; - TestContainerGbx.Gear = tryNextGear; - - //TestContainer.GearboxOutPort.Initialize(outTorque, outAngularVelocity); - TestContainer.VehiclePort.Initialize(vehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient); - var response = (ResponseDryRun)TestContainer.VehiclePort.Request( - 0.SI<Second>(), dt, acceleration, DataBus.DrivingCycleInfo.RoadGradient, true); - - //var response = (ResponseDryRun)TestContainer.GearboxOutPort.Request( - // 0.SI<Second>(), dt, outTorque, outAngularVelocity, true); - LogEnabled = true; - return response; - } + //protected ResponseDryRun RequestDryRunWithGear( + // Second absTime, Second dt, MeterPerSecond vehicleSpeed, MeterPerSquareSecond acceleration, uint tryNextGear) + //{ + // LogEnabled = false; + // TestContainerGbx.Disengaged = false; + // TestContainerGbx.Gear = tryNextGear; + + // //TestContainer.GearboxOutPort.Initialize(outTorque, outAngularVelocity); + // TestContainer.VehiclePort.Initialize(vehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient); + // var response = (ResponseDryRun)TestContainer.VehiclePort.Request( + // 0.SI<Second>(), dt, acceleration, DataBus.DrivingCycleInfo.RoadGradient, true); + + // //var response = (ResponseDryRun)TestContainer.GearboxOutPort.Request( + // // 0.SI<Second>(), dt, outTorque, outAngularVelocity, true); + // LogEnabled = true; + // return response; + //} protected override ResponseDryRun RequestDryRunWithGear( Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint tryNextGear) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs index 2afbaa5e43..3e78dd9d2d 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs @@ -34,7 +34,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public void Initialize(double initialSoC) { - if (initialSoC < ModelData.MinSOC || initialSoC > ModelData.MaxSOC) + if (initialSoC.IsSmaller(ModelData.MinSOC) || initialSoC.IsGreater(ModelData.MaxSOC)) { throw new VectoException("SoC must be between {0} and {1}", ModelData.MinSOC, ModelData.MaxSOC); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 9b1b8f4b28..017dcdc51e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -127,7 +127,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl get { return true; } } - internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity) + internal ResponseDryRun Initialize(Second absTime, uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity) { var oldGear = Gear; Gear = gear; @@ -148,7 +148,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var response = (ResponseDryRun) - NextComponent.Request(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, inTorque, + NextComponent.Request(absTime, Constants.SimulationSettings.TargetTimeInterval, inTorque, inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity); //response.Switch(). // Case<ResponseSuccess>(). diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index f06fd82d6e..4b1789c3f7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -55,13 +55,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _electricMotorCtl[pos] = new ElectricMotorController(this, motorData); } - public ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse strategySettings) - { - ApplyStrategySettings(strategySettings); - var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); + //public ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse strategySettings) + //{ + // ApplyStrategySettings(strategySettings); + // var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); - return retVal as ResponseDryRun; - } + // return retVal as ResponseDryRun; + //} private void ApplyStrategySettings(HybridStrategyResponse strategySettings) { @@ -242,11 +242,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl PerSecond outAngularVelocity) { if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { - return InitStartGear(outTorque, outAngularVelocity); + return InitStartGear(absTime, outTorque, outAngularVelocity); } for (var gear = (uint)ModelData.Gears.Count; gear > 1; gear--) { - var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); + var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; @@ -279,7 +279,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return 1; } - protected uint InitStartGear(NewtonMeter outTorque, PerSecond outAngularVelocity) + protected uint InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity) { for (var gear = MaxStartGear; gear > 1; gear--) { var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio; @@ -289,7 +289,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl continue; } - var response = _gearbox.Initialize(gear, outTorque, outAngularVelocity); + var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); var fullLoadPower = response.Engine.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs index fc55b43ae9..0d54cb86e1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/SimpleHybridController.cs @@ -85,12 +85,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { _electricMotorCtl[pos] = new ElectricMotorController(this, motorData); } - public ResponseDryRun RequestDryRun( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - HybridStrategyResponse strategySettings) - { - throw new System.NotImplementedException(); - } + //public ResponseDryRun RequestDryRun( + // Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + // HybridStrategyResponse strategySettings) + //{ + // throw new System.NotImplementedException(); + //} #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs index 514ce4b6c8..fba8022dcb 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs @@ -172,4 +172,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { container[ModalResultField.P_WHR_mech_corr] = (1 - EngineStopStartUtilityFactor) * pWHRmechCorr; } } + + public class SimplePowerrtrainCombustionEngine : StopStartCombustionEngine + { + public SimplePowerrtrainCombustionEngine( + IVehicleContainer container, CombustionEngineData modelData, bool pt1Disabled = false) : base( + container, modelData, pt1Disabled) { } + + public EngineState EnginePreviousState { get { return PreviousState; } } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index 571750f250..da91b3aa31 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.InteropServices; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; @@ -17,8 +18,45 @@ using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { + public class TestPowertrain + { + public SimplePowertrainContainer Container; + public Gearbox Gearbox; + public SimpleHybridController HybridController; + public Battery Battery; + public Clutch Clutch; + + public StopStartCombustionEngine CombustionEngine; + + public TestPowertrain(SimplePowertrainContainer container) + { + Container = container; + Gearbox = Container.GearboxCtl as Gearbox; + HybridController = Container.HybridController as SimpleHybridController; + Battery = Container.BatteryInfo as Battery; + Clutch = Container.ClutchInfo as Clutch; + CombustionEngine = Container.EngineInfo as StopStartCombustionEngine; + if (Gearbox == null) { + throw new VectoException("Unknown gearboxtype in TestContainer: {0}", Container.GearboxCtl.GetType().FullName); + } + + if (HybridController == null) { + throw new VectoException("Unknown HybridController in TestContainer: {0}", Container.HybridController.GetType().FullName); + } + } + } + public class HybridStrategy : LoggingObject, IHybridControlStrategy { + public class StrategyState + { + public HybridStrategyResponse Response { get; set; } + public List<HybridResultEntry> Evaluations; + public HybridResultEntry Solution { get; set; } + + public bool GearboxEngaged; + } + private VectoRunData ModelData; private IDataBus DataBus; @@ -27,15 +65,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies private bool ElectricMotorCanPropellDuringTractionInterruption; //private Second lastShiftTime; - private Gearbox TestContainerGbx; - private SimplePowertrainContainer TestContainer; + + + private TestPowertrain TestPoweretrain; + protected readonly VelocityRollingLookup VelocityDropData; - private SimpleHybridController TestContainerHybCtl; - public Battery TestContainerBattery; - private Clutch TestContainerClutch; - protected HybridStrategyResponse Response { get; set; } + protected StrategyState CurrentState = new StrategyState(); + protected StrategyState PreviousState = new StrategyState(); public HybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer) { @@ -54,20 +92,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies 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); - } + var testContainer = new SimplePowertrainContainer(runData); + builder.BuildSimpleHybridPowertrain(runData, testContainer); + TestPoweretrain = new TestPowertrain(testContainer); + // register pre-processors var maxG = runData.Cycle.Entries.Max(x => Math.Abs(x.RoadGradientPercent.Value())) + 1; var grad = Convert.ToInt32(maxG / 2) * 2; @@ -77,7 +106,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies VelocityDropData = new VelocityRollingLookup(); vehicleContainer.AddPreprocessor( - new VelocitySpeedGearshiftPreprocessor(VelocityDropData, runData.GearboxData.TractionInterruption, TestContainer, -grad, grad, 2)); + new VelocitySpeedGearshiftPreprocessor(VelocityDropData, runData.GearboxData.TractionInterruption, testContainer, -grad, grad, 2)); var shiftStrategyParameters = runData.GearshiftParameters; if (shiftStrategyParameters == null) { @@ -100,16 +129,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } - HybridResultEntry tmp = null; - Tuple<bool, uint> gs = null; + var eval = new List<HybridResultEntry>(); + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate || DataBus.DriverInfo.DrivingAction == DrivingAction.Brake) { if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { - tmp = FindSolution(absTime, dt, outTorque, outAngularVelocity); - if (tmp != null) { - gs = HandleGearshift(absTime, tmp.Response); - } + eval = FindSolution(absTime, dt, outTorque, outAngularVelocity); } else { - tmp = new HybridResultEntry { + eval.Add(new HybridResultEntry { U = double.NaN, Response = null, Setting = new HybridStrategyResponse() { @@ -118,11 +144,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies MechanicalAssistPower = ElectricMotorsOff }, FuelCosts = double.NaN - }; + }); } } if (DataBus.DriverInfo.DrivingAction == DrivingAction.Roll || DataBus.DriverInfo.DrivingAction == DrivingAction.Coast) { - tmp = new HybridResultEntry { + eval.Add(new HybridResultEntry { U = double.NaN, Response = null, Setting = new HybridStrategyResponse() { @@ -131,29 +157,38 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies MechanicalAssistPower = ElectricMotorsOff }, FuelCosts = double.NaN - }; + }); } - if (DataBus.DriverInfo.DrivingAction == DrivingAction.Brake && tmp == null) { - tmp = MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity); - gs = HandleGearshift(absTime, tmp.Response); + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Brake && eval.Count == 0) { + eval.Add(MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity)); } + var best = eval.Where(x => !double.IsNaN(x.Score)).OrderBy(x => x.Score).FirstOrDefault() ?? eval.FirstOrDefault(); + if (best == null) { + // TODO! + } + Tuple<bool, uint> gs = null; + if (best?.Response != null) { + gs = HandleGearshift(absTime, best); + } var retVal = new HybridStrategyResponse() { - CombustionEngineOn = tmp.Setting.CombustionEngineOn, - GearboxInNeutral = tmp.Setting.GearboxInNeutral, - MechanicalAssistPower = tmp.Setting.MechanicalAssistPower, + CombustionEngineOn = best.Setting.CombustionEngineOn, + GearboxInNeutral = best.Setting.GearboxInNeutral, + MechanicalAssistPower = best.Setting.MechanicalAssistPower, ShiftRequired = gs?.Item1 ?? false, NextGear = gs?.Item2 ?? 0, }; - Response = dryRun ? null : retVal; + CurrentState.Response = dryRun ? null : retVal; if (!dryRun) { - Solution = tmp; + CurrentState.Solution = best; + CurrentState.Evaluations = eval; + CurrentState.GearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); } return retVal; } - public HybridResultEntry Solution { get; set; } + private HybridResultEntry MaxRecuperationSetting(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { @@ -162,22 +197,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies GearboxInNeutral = false, // DataBus.GearboxInfo.GearEngaged(absTime), MechanicalAssistPower = ElectricMotorsOff }; - var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, first); + var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, first); var emPos = ModelData.ElectricMachinesData.First().Item1; var emTorque = firstResponse.ElectricMotor.MaxRecuperationTorque; - return TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorque, double.NaN); + return TryConfiguration(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, emPos, emTorque, double.NaN); } - private HybridResultEntry FindSolution(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + private List<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 firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, first); //var gearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime); var emPos = ModelData.ElectricMachinesData.First().Item1; @@ -188,14 +223,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies U = double.NaN, Response = firstResponse, Setting = first, - + Gear = DataBus.GearboxInfo.Gear, //Score = CalcualteCosts(firstResponse, dt) }; CalcualteCosts(firstResponse, dt, entry); responses.Add(entry); if (firstResponse.Gearbox.Gear == 0 && !ElectricMotorCanPropellDuringTractionInterruption) { - return responses.First(); + return responses; } var minimumShiftTimePassed = (DataBus.GearboxInfo.LastShift + ModelData.GearboxData.ShiftTime).IsSmallerOrEqual(absTime); @@ -210,27 +245,35 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var gear = DataBus.GearboxInfo.Gear; var numGears = ModelData.GearboxData.Gears.Count; - for (var nextGear = Math.Max(1, gear - gearRangeDownshift); + for (uint nextGear = (uint)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 - } - IterateEMTorque(absTime, dt, outTorque, outAngularVelocity, firstResponse, emTqReq, emPos, responses); - } + nextGear++) { + var baseResponse = firstResponse; - if (responses.All(x => double.IsNaN(x.Score))) { - return null; + //if (!ElectricMotorCanPropellDuringTractionInterruption) { + // em is at gearbox input side - angular speed is different so get new + baseResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, first); + + //} + if (baseResponse == null) { + continue; + } + + var gearEntry = new HybridResultEntry() { + U = double.NaN, + Response = baseResponse, + Setting = first, + Gear = nextGear + }; + CalcualteCosts(baseResponse, dt, gearEntry); + responses.Add(gearEntry); + IterateEMTorque(absTime, dt, outTorque, outAngularVelocity, nextGear, baseResponse, emTqReq, emPos, responses); } - var best = responses.Where(x => !double.IsNaN(x.Score)).OrderBy(x => x.Score).First(); - return best; + return responses; } - private void IterateEMTorque( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, ResponseDryRun firstResponse, - NewtonMeter emTqReq, PowertrainPosition emPos, List<HybridResultEntry> responses) + private void IterateEMTorque(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, ResponseDryRun firstResponse, NewtonMeter emTqReq, PowertrainPosition emPos, List<HybridResultEntry> responses) { const double stepSize = 0.1; @@ -244,7 +287,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies continue; } - var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorque, u); + var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorque, u); responses.Add(tmp); } @@ -252,11 +295,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var emTorqueM = emTqReq * maxU; if (emTorqueM.IsBetween( 0.SI<NewtonMeter>(), firstResponse.ElectricMotor.MaxDriveTorque)) { - var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorqueM, maxU); + var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, 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) { @@ -266,15 +309,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies continue; } - var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, emPos, emTorque, u); + var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorque, u); responses.Add(tmp); } } } - private HybridResultEntry TryConfiguration( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, PowertrainPosition emPos, - NewtonMeter emTorque, double u) + private HybridResultEntry TryConfiguration(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, PowertrainPosition emPos, NewtonMeter emTorque, double u) { var cfg = new HybridStrategyResponse() { CombustionEngineOn = true, @@ -283,35 +324,87 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { emPos, emTorque } } }; - var resp = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, cfg); + var resp = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, cfg); var tmp = new HybridResultEntry { U = u, Setting = cfg, Response = resp, - //Score = cost + Gear = nextGear, }; CalcualteCosts(resp, dt, tmp); return tmp; } - private ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, HybridStrategyResponse cfg) + private ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, 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); + TestPoweretrain.Gearbox.Gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear; + TestPoweretrain.Container.VehiclePort.Initialize(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); + TestPoweretrain.HybridController.ApplyStrategySettings(cfg); + TestPoweretrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); + TestPoweretrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses); + TestPoweretrain.Battery.Initialize(DataBus.BatteryInfo.StateOfCharge); + + TestPoweretrain.CombustionEngine.PreviousState.EnginePower = (DataBus.EngineInfo as CombustionEngine).PreviousState.EnginePower; + TestPoweretrain.CombustionEngine.PreviousState.dt = (DataBus.EngineInfo as CombustionEngine).PreviousState.dt; + TestPoweretrain.CombustionEngine.PreviousState.EngineSpeed = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed; + TestPoweretrain.CombustionEngine.PreviousState.EngineTorque = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorque; + TestPoweretrain.CombustionEngine.PreviousState.EngineTorqueOut = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorqueOut; + TestPoweretrain.CombustionEngine.PreviousState.DynamicFullLoadTorque = (DataBus.EngineInfo as CombustionEngine).PreviousState.DynamicFullLoadTorque; + + if (nextGear != DataBus.GearboxInfo.Gear) { + if (ModelData.GearboxData.Gears[nextGear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) { + return null; + } + + if (ModelData.GearboxData.Gears[nextGear].Ratio >= ModelData.GearshiftParameters.RatioEarlyDownshiftFC) { + return null; + } + + var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); + if (!estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) { + return null; + } + + + var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift; + var vehicleSpeedPostShift = DataBus.VehicleInfo.VehicleSpeed - vDrop * ModelData.GearshiftParameters.VelocityDropFactor; + TestPoweretrain.Gearbox.Gear = nextGear; + TestPoweretrain.Container.VehiclePort.Initialize( + vehicleSpeedPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); + } + + // AMT EffShift: estimatedVelocityPostShift < MIN_SPEED => no shift + + // AMT EffShift: engine torqueOut close to dragCurve => no shift + + // AMT EffShift: Ratio EarlyUpshift / Ratio RealyDownshift + + // initialize with new vehicle speed + // set gear + + var retVal = TestPoweretrain.HybridController.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true); + + if (nextGear != DataBus.GearboxInfo.Gear) { + if (retVal.Engine.TorqueOutDemand.IsSmaller(DeclarationData.GearboxTCU.DragMarginFactor * retVal.Engine.DragTorque)) { + return null; + } + } + + //var retVal2 = Controller.RequestDryRun(absTime, dt, outTorque, outAngularVelocity, cfg); return retVal as ResponseDryRun; } private void CalcualteCosts(ResponseDryRun resp, Second dt, HybridResultEntry tmp) { + if (resp == null) { + tmp.FuelCosts = double.NaN; + return; + } if (!resp.Engine.TotalTorqueDemand.IsBetween( resp.Engine.DragTorque, resp.Engine.DynamicFullLoadTorque)) { tmp.FuelCosts = double.NaN; + return; } tmp.FuelCosts = ModelData.EngineData.Fuels.Sum( @@ -321,10 +414,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies tmp.SoCPenalty = 1 - Math.Pow((DataBus.BatteryInfo.StateOfCharge - ModelData.BatteryData.TargetSoC) / (0.5 * (ModelData.BatteryData.MaxSOC - ModelData.BatteryData.MinSOC)), 5); tmp.EqualityFactor = 2.5; + tmp.GearshiftPenalty = resp.Gearbox.Gear != DataBus.GearboxInfo.Gear + ? ModelData.GearshiftParameters.RatingFactorCurrentGear + : 1; } - private Tuple<bool, uint> HandleGearshift(Second absTime, ResponseDryRun response) + private Tuple<bool, uint> HandleGearshift(Second absTime, HybridResultEntry config) { + // search for EM operating point already selected another gear + if (config.Gear != DataBus.GearboxInfo.Gear) { + return Tuple.Create(true, config.Gear); + } + var response = config.Response; var retVal = Tuple.Create(false, response.Gearbox.Gear); var gear = DataBus.GearboxInfo.Gear; @@ -384,7 +485,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies GearboxInNeutral = false, MechanicalAssistPower = ElectricMotorsOff }; - Response = dryRun ? null : tmp; + CurrentState.Response = dryRun ? null : tmp; return tmp; } @@ -402,16 +503,30 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public virtual void CommitSimulationStep(Second time, Second simulationInterval) { - + PreviousState = CurrentState; + CurrentState = new StrategyState(); } public void WriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) { - container[ModalResultField.HybridStrategyScore] = Solution?.Score ?? 0; - container[ModalResultField.HybridStrategySolution] = Solution?.U ?? -100; + container[ModalResultField.HybridStrategyScore] = CurrentState.Solution?.Score ?? 0; + container[ModalResultField.HybridStrategySolution] = CurrentState.Solution?.U ?? -100; + + if (CurrentState.Evaluations != null) { + container.SetDataValue( + "HybridStrategyEvaluation", + string.Join( + " | ", CurrentState.Evaluations.Select( + x => { + var foo = string.Join(" ", x.Setting.MechanicalAssistPower.Select(e => $"{e.Key.GetName()}: {e.Value}")); + return $"{x.U}: G{x.Gear} ({x.FuelCosts} + {x.EqualityFactor} * {x.BatCosts} * {x.SoCPenalty} = {x.Score}) * {x.GearshiftPenalty} ({foo})"; + }) + ) + ); + } } - [DebuggerDisplay("{U}: {Score} {Setting.MechanicalAssistPower}")] + [DebuggerDisplay("{U}: {Score} {Gear} {Setting.MechanicalAssistPower}")] public class HybridResultEntry { public double U { get; set; } @@ -420,7 +535,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public ResponseDryRun Response { get; set; } - public double Score { get { return FuelCosts + EqualityFactor * BatCosts * SoCPenalty; } } + public double Score { get { return (FuelCosts + EqualityFactor * BatCosts * SoCPenalty) / GearshiftPenalty; } } public double FuelCosts { get; set; } @@ -429,6 +544,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public double SoCPenalty { get; set; } public double EqualityFactor { get; set; } + + public double GearshiftPenalty { get; set; } + + public uint Gear { get; set; } } } diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs index 5c9f3ceeaa..f5fe4fe535 100644 --- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs @@ -82,7 +82,9 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid // Assert.IsTrue(modData.Rows.Count > 0); //} - [TestCase(30, 0.7, 0, TestName = "P2 Hybrid DriveOff 30km/h SoC: 0.7, level"), + [ + TestCase(30, 0.7, 0, TestName = "P2 Hybrid DriveOff 30km/h SoC: 0.7, level"), + TestCase(80, 0.7, 0, TestName = "P2 Hybrid DriveOff 80km/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) @@ -110,6 +112,88 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + + Assert.IsTrue(modData.Rows.Count > 0); + } + + [ + TestCase(30, 0.7, 0, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.7, level"), + TestCase(50, 0.7, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.7, level"), + TestCase(80, 0.7, 0, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.7, level"), + + TestCase(30, 0.2, 0, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.2, level"), + TestCase(50, 0.2, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.2, level"), + TestCase(80, 0.2, 0, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.2, level"), + + TestCase(30, 0.5, 5, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.5, UH 5%"), + TestCase(50, 0.5, 5, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.5, UH 5%"), + TestCase(80, 0.5, 5, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.5, UH 5%"), + + TestCase(30, 0.5, -5, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.5, DH 5%"), + TestCase(50, 0.5, -5, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.5, DH 5%"), + TestCase(80, 0.5, -5, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.5, DH 5%"), + ] + public void P2HybridConstantSpeed(double vmax, double initialSoC, double slope) + { + var cycleData = string.Format( + @" 0, {0}, {1}, 0 + 5000, {0}, {1}, 0", vmax, slope); + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + const bool largeMotor = true; + + const PowertrainPosition pos = PowertrainPosition.HybridP2; + var run = CreateEngineeringRun( + cycle, string.Format("SimpleParallelHybrid_constant_{0}-{1}_{2}.vmod", vmax, initialSoC, slope), initialSoC, pos, largeMotor: true); + + 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(80, 0, TestName = "Conventional DriveOff 80km/h level"), + ] + public void ConventionalVehicleDriveOff(double vmax, double slope) + { + var cycleData = string.Format( + @" 0, 0, {1}, 3 + 700, {0}, {1}, 0", vmax, slope); + var cycle = SimpleDrivingCycles.CreateCycleData(cycleData); + + //const bool largeMotor = true; + + //const PowertrainPosition pos = PowertrainPosition.HybridP2; + var run = CreateConventionalEngineeringRun( + cycle, string.Format("ConventionalVehicle_acc_{0}_{1}.vmod", vmax, slope)); + + //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); @@ -170,6 +254,14 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid return new DistanceRun(container); } + public static VectoRun CreateConventionalEngineeringRun(DrivingCycleData cycleData, string modFileName, + SummaryDataContainer sumData = null, double pAuxEl = 0) + { + var container = CreateConventionalPowerTrain( + cycleData, Path.GetFileNameWithoutExtension(modFileName), sumData, pAuxEl); + return new DistanceRun(container); + } + public static VehicleContainer CreateParallelHybridPowerTrain(DrivingCycleData cycleData, string modFileName, double initialBatCharge, bool largeMotor, SummaryDataContainer sumData, double pAuxEl, PowertrainPosition pos) { @@ -278,6 +370,98 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid return container; } + + public static VehicleContainer CreateConventionalPowerTrain(DrivingCycleData cycleData, string modFileName, + SummaryDataContainer sumData, double pAuxEl) + { + //var strategySettings = GetHybridStrategyParameters(largeMotor); + + //strategySettings.StrategyName = "SimpleParallelHybridStrategy"; + + var fileWriter = new FileOutputWriter(modFileName); + var modDataFilter = new IModalDataFilter[] { }; //new IModalDataFilter[] { new ActualModalDataFilter(), }; + var modData = new ModalDataContainer( + modFileName, new IFuelProperties[] { FuelData.Diesel }, fileWriter, + filters: modDataFilter) { + WriteModalResults = true, + }; + + var gearboxData = CreateGearboxData(); + var axleGearData = CreateAxleGearData(); + + var vehicleData = CreateVehicleData(3300.SI<Kilogram>()); + var airdragData = CreateAirdragData(); + var driverData = CreateDriverData(AccelerationFile, true); + + 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, + DriverData = driverData, + AxleGearData = axleGearData, + GearboxData = gearboxData, + VehicleData = vehicleData, + AirdragData = airdragData, + JobName = modFileName, + Cycle = cycleData, + Retarder = new RetarderData() { Type = RetarderType.None }, + Aux = new List<VectoRunData.AuxData>(), + //ElectricMachinesData = electricMotorData, + 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); }); + container.RunData = runData; + + + var clutch = new SwitchableClutch(container, runData.EngineData); + + var gbxStrategy = new AMTShiftStrategyOptimized(runData,container); + + var gearbox = new Gearbox(container, gbxStrategy, runData); + + var engine = new StopStartCombustionEngine(container, runData.EngineData); + var idleController = engine.IdleController; + var cycle = new DistanceBasedDrivingCycle(container, cycleData); + + var aux = new ElectricAuxiliary(container); + aux.AddConstant("P_aux_el", pAuxEl.SI<Watt>()); + cycle + .AddComponent(new Driver(container, runData.DriverData, new DefaultDriverStrategy(container))) + .AddComponent(new Vehicle(container, runData.VehicleData, runData.AirdragData)) + .AddComponent(new Wheels(container, runData.VehicleData.DynamicTyreRadius, + runData.VehicleData.WheelsInertia)) + .AddComponent(new Brakes(container)) + //.AddComponent(ctl) + //.AddComponent(GetElectricMachine(PowertrainPosition.HybridP4, runData.ElectricMachinesData, container, + // es, ctl)) + .AddComponent(new AxleGear(container, runData.AxleGearData)) + //.AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, runData.ElectricMachinesData, container, + // es, ctl)) + .AddComponent(runData.AngledriveData != null ? new Angledrive(container, runData.AngledriveData) : null) + .AddComponent(gearbox, runData.Retarder, container) + //.AddComponent(GetElectricMachine(PowertrainPosition.HybridP2, runData.ElectricMachinesData, container, + // es, ctl)) + .AddComponent(clutch) + //.AddComponent(GetElectricMachine(PowertrainPosition.HybridP1, runData.ElectricMachinesData, container, + // es, ctl)) + .AddComponent(engine, idleController) + .AddAuxiliaries(container, runData); + + return container; + } + public static ShiftStrategyParameters CreateGearshiftData(GearboxData gbx, double axleRatio, PerSecond engineIdlingSpeed) { var retVal = new ShiftStrategyParameters { -- GitLab