diff --git a/VectoCommon/VectoCommon/Models/IResponse.cs b/VectoCommon/VectoCommon/Models/IResponse.cs index 1cb6301a4099956c80ff452abfc55dda80ca6433..8c830e8518952db3125b9441143744749f5619ae 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 bd6e9cd885b7a25acb1fbe05074b0b915f8227a8..7e4049b40225437f8c6f57e13d12f9daabf106b3 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 ec8244206d1f0bd268b9124f8011b6d68325da17..54419692ce96672412180476ae07141273fa2d1c 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 a1853577cbd1d096301ecb29eb0e09288e7afc85..a5958c8257b1d64d2a0b986c5b386a97989997ff 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 c0182a4aa7bfff5a18ac03383fe92093ec234d2e..75bf5cfab80a5a87fa74e5ad769d2070c6771bbe 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 e95bd10ee40f2c45ff90a1f82f525671e65b8263..48254bf68afc53cb9b389dd4c770f9c0905b055f 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 ed2bf3a46fb205be8725098dccf5877cd4fdb682..23a8b92bc392668e55ad721efd309690f67b2c63 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 852b7b7fc2c3005527ecfb90fff91689b96626f4..e8391a1b9372994eb9c391801da9c61410789377 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 bea010f6ae5435c8e714b0eb0613b70d1f290617..ffc18e54818aaa39c12f345791e6797e7831ae93 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 faa305349b211591fda8c144be0c9519a564b484..6f13b1a493b7532e741b51cf5686f17f81757e22 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 e61b13f29207245f423e719b7e07a60cb5941845..9d2802bf11cf565ea25b3472bf4fc79d256f9fea 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 2d5ae8f3e7821ebf4956e8da14b4c62c52da2668..4fb7c26f191c7c0e840e62c148b3eb4d4c577bda 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 ff7c068bf8b35459240dbd0f7b4cf18d39ccae5b..28e8124b85dcfc82dc550b58a6d6290cd36c391c 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 6bc1808f1c0da1033e880a934a39264447082aae..11f494e2d64a853d0210e194da1f3d632a851431 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 4612e885a18791e9cdbfb41e54b1725fc481b491..b003e1917a6637dfa41572f8c28ad3ac4b506c71 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 f152a220073d6c178d9aed9a7532bc2de1bd38c9..fdbe493f5bf0d755798710f2e7a06e2ef7046f0c 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 9783694270b0582b2db1bde41404bbcdd0af3be4..4f1356b7056a1f82fa86839e30636d5ac1e41c1e 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 83e0781c998277cb267c0034f14ffd3725a49d24..442a3b2d61dda51c0099a8b9978587a4b9f2a2f0 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 218d3cc175b3f2ecf983af42551adcbe2ec14854..65c05d55d1f98fc1b2ed830cba5a01ce8f38e7c3 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 e890079a94e155ba2dfd56dd996b24a077441b29..fe08d6b0d883d85e6b94583570c3580e536645a4 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 7c9a1d017eb265228095d70204475f42f18c9c42..f780dddc7b06b5cdca6db8eb1d533eaee491e6cb 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 720c808f16008ef10a6534f017fa4f31ec78028f..c5c88be82f21acd51ce2550c9f4a755a010c51ba 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 cd05b8335faa6793308283c6b33d7da089843eec..df474ac2a1f8922a7bb06c4c27ab390a05ac9f2b 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 baa412b47aa5215f33f73b96630ae6dc67071e27..511ea303b6d652c08e7f9fccf31751c71090caff 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 e4fe9a6e75cfcb7f2963dd4c409f46ecec48bf2f..18e01c8ec72964c1e59ee2601c0f33a03f1f12cc 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 c2e2068410e211d00c65e390d58ba165eb00a7da..b551eb0b667df1260195a82ce5f64c761da1d684 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 f0869658b9c17c51da5484ac83113ab11de568f9..e19b76527ceec10a13e8c3c9d268e26a962fac76 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 c8330810c87aa3afc1bae6ca31b41454ae1b2439..9b1b8f4b283b3a39616a48a07f3c17c65cd8e7c1 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 e1cb37c0509ed7a8dc1e747e9f25237fb5c105bb..f06fd82d6eea82f8ba7ffadc0e37301517e67f7b 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 9635598633191011e6b0f2bc5e733e27fc642ee1..0c5b2ec46f74314a32d5a456f5b7d80c9b52fd10 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 0000000000000000000000000000000000000000..fc55b43ae9cfa396b8efc0d69f12d741ec301da0 --- /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 5bf4dad306f7d9011171faf88d44b27ac9472d3a..514ce4b6c8895fcfceca4ddf807205b1ded568d2 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 9b36aaf1b716e5b17a57407171552bb2f7f0be3f..5ba2826e17bfa8c6bf752626e05a76b70c5f2601 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 f371fa11cf85644c37f0b6728b298346e7eb6f82..adf81d3165fcf0300cfa043f492587fe38e414da 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 64530c5923750bfd7e026846194919526204b27f..571750f250fd3e8633fa13652c9f1c5067b2e3a2 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 c381d3b1871af33410d4ec2b12ded7ba69a4cda2..a4d15ba37e30c065b063075c2cf7b9b606ae1673 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 256926fe2a34b62865305bfb09184e4a768f9c23..cef7da625952120483a6e7835999db18c3a45cd7 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 600dbcdc5b795da05eec939c9a36d076cb540b0c..5c9f3ceeaa35964a6cca0f7b3ee6b62260128f31 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 1bd79f2b21c8ef11880f698273b84617cc251010..ccc8b3302be76559287296429cc13d74b38212f1 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 400b727464f57f9f0cc73b17c195c0b80dda5692..172ba27c880b84025de219866c13f738d3d5ad56 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 8ac5cb92fcf7f6d622e6ee8327322e30c71052e2..098457ef4010a21404ce0c331568d9f5eaff8297 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; }