diff --git a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs index 192b32070ca9d8a3f66054078d150bea42e3794a..1f6a5d165ea3b7b30ba8099c4376519793a4303f 100644 --- a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs +++ b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; @@ -10,5 +12,53 @@ namespace TUGraz.VectoCommon.Models { public uint NextGear { get; set; } public bool GearboxInNeutral { get; set; } public bool CombustionEngineOn { get; set; } + + public HybridResultEntry EvaluatedSolution { get; set; } + } + + [DebuggerDisplay("{U}: {Score} - G{Gear}")] + public class HybridResultEntry + { + public double U { get; set; } + + public HybridStrategyResponse Setting { get; set; } + + public IResponse Response { get; set; } + + public double Score { get { return (FuelCosts + EqualityFactor * (BatCosts + ICEStartPenalty1) * SoCPenalty + ICEStartPenalty2) / GearshiftPenalty; } } + + public double FuelCosts { get; set; } + + public double BatCosts { get; set; } + + public double SoCPenalty { get; set; } + + public double EqualityFactor { get; set; } + + public double GearshiftPenalty { get; set; } + + public double ICEStartPenalty1 { get; set; } + + public double ICEStartPenalty2 { get; set; } + + public uint Gear { get; set; } + + public bool ICEOff { get; set; } + + public HybridConfigurationIgnoreReason IgnoreReason { get; set; } + } + + [Flags] + public enum HybridConfigurationIgnoreReason + { + NotEvaluated = 0, + EngineSpeedTooLow = 1 << 2, + EngineSpeedTooHigh = 1 << 3, + EngineTorqueDemandTooHigh = 1 << 4, + EngineTorqueDemandTooLow = 1 << 5, + EngineSpeedAboveUpshift = 1 << 6, + EngineSpeedBelowDownshift = 1 << 7, + NoResponseAvailable = 1 << 8, + Evaluated = 1 << 9, } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 36491db598242fa0c482fa02ba6ea140bd157dc3..35c1863f1395b849e246e89da3ac3dc2dc862608 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -295,6 +295,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DynamicFullLoadTorque = dynamicFullLoadTorque, DragPower = CurrentState.FullDragTorque * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, + DragTorque = fullDragTorque, }, }; } @@ -315,6 +316,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DragPower = CurrentState.FullDragTorque * avgEngineSpeed, EngineSpeed = angularVelocity, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, + DragTorque = fullDragTorque, }, }; } @@ -332,6 +334,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DragPower = CurrentState.FullDragTorque * avgEngineSpeed, EngineSpeed = angularVelocity, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, + DragTorque = fullDragTorque, }, }; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 5b8d18338ce1820c3fe71860954240db8b7a6a97..307702310fb09ed4ca511114aea31ae6a8787fcb 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -162,7 +162,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // return retVal; //} - if (!eMotorTorque.IsBetween(maxDriveTorque ?? 0.SI<NewtonMeter>(), maxRecuperationTorque ?? 0.SI<NewtonMeter>())) { + if (!dryRun && !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); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs index 057464681db82ce4ba2f3e7d423e15b574a0f0b3..619abb2cae69a0b231071062ab1e7c77ab7c8c90 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs @@ -20,203 +20,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { - public class TestPowertrain - { - public SimplePowertrainContainer Container; - public Gearbox Gearbox; - public SimpleHybridController HybridController; - public Battery Battery; - public Clutch Clutch; - public IBrakes Brakes; - - public IDriverInfo Driver; - public IDrivingCycleInfo DrivingCycle; - - public StopStartCombustionEngine CombustionEngine; - public ElectricMotor ElectricMotorP2; - - public TestPowertrain(SimplePowertrainContainer container, IDataBus realContainer) - { - Container = container; - Gearbox = Container.GearboxCtl as Gearbox; - HybridController = Container.HybridController as SimpleHybridController; - Battery = Container.BatteryInfo as Battery; - Clutch = Container.ClutchInfo as Clutch; - CombustionEngine = Container.EngineInfo as StopStartCombustionEngine; - ElectricMotorP2 = container.ElectricMotors.ContainsKey(PowertrainPosition.HybridP2) - ? container.ElectricMotors[PowertrainPosition.HybridP2] as ElectricMotor - : null; - if (Gearbox == null) { - throw new VectoException("Unknown gearboxtype in TestContainer: {0}", Container.GearboxCtl.GetType().FullName); - } - - if (HybridController == null) { - throw new VectoException("Unknown HybridController in TestContainer: {0}", Container.HybridController.GetType().FullName); - } - - Driver = new MockDriver(container, realContainer); - DrivingCycle = new MockDrivingCycle(container, realContainer); - Brakes = new MockBrakes(container); - } - } - - public class MockBrakes : VectoSimulationComponent, IBrakes - { - public MockBrakes(IVehicleContainer container) : base(container) - { - BrakePower = 0.SI<Watt>(); - } - - #region Overrides of VectoSimulationComponent - - protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) - { - - } - - protected override void DoCommitSimulationStep(Second time, Second simulationInterval) - { - - } - - #endregion - - #region Implementation of IBrakes - - public Watt BrakePower { get; set; } - - #endregion - } - - public class MockDrivingCycle : VectoSimulationComponent, IDrivingCycleInfo - { - private IDataBus realContainer; - - public MockDrivingCycle(VehicleContainer container, IDataBus rcontainer) : base(container) - { - realContainer = rcontainer; - } - - #region Implementation of IDrivingCycleInfo - - public CycleData CycleData - { - get { return realContainer.DrivingCycleInfo.CycleData; } - } - - public bool PTOActive - { - get { return realContainer.DrivingCycleInfo.PTOActive; } - } - - public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) - { - return realContainer.DrivingCycleInfo.CycleLookAhead(distance); - } - - public Meter Altitude - { - get { return realContainer.DrivingCycleInfo.Altitude; } - } - - public Radian RoadGradient - { - get { return realContainer.DrivingCycleInfo.RoadGradient; } - } - - public MeterPerSecond TargetSpeed - { - get { return realContainer.DrivingCycleInfo.TargetSpeed; } - } - - public Second StopTime - { - get { return realContainer.DrivingCycleInfo.StopTime; } - } - - public Meter CycleStartDistance - { - get { return realContainer?.DrivingCycleInfo?.CycleStartDistance ?? 0.SI<Meter>(); } - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) - { - return realContainer.DrivingCycleInfo.LookAhead(lookaheadDistance); - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) - { - return realContainer.DrivingCycleInfo.LookAhead(time); - } - - public SpeedChangeEntry LastTargetspeedChange - { - get { return realContainer.DrivingCycleInfo.LastTargetspeedChange; } - } - - public void FinishSimulation() - { - } - - #endregion - - #region Overrides of VectoSimulationComponent - - protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) - { - - } - - protected override void DoCommitSimulationStep(Second time, Second simulationInterval) - { - - } - - #endregion - } - - public class MockDriver : VectoSimulationComponent, IDriverInfo - { - private IDataBus realContainer; - - public MockDriver(VehicleContainer container, IDataBus rcontainer) : base(container) - { - realContainer = rcontainer; - } - - #region Implementation of IDriverInfo - - public DrivingBehavior DriverBehavior - { - get { return realContainer?.DriverInfo?.DriverBehavior ?? DrivingBehavior.Accelerating; } - } - - public DrivingAction DrivingAction - { - get { return realContainer?.DriverInfo?.DrivingAction ?? DrivingAction.Accelerate; } - } - - public MeterPerSquareSecond DriverAcceleration - { - get { return realContainer?.DriverInfo.DriverAcceleration; } - } - - #endregion - - #region Overrides of VectoSimulationComponent - - protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) - { - - } - - protected override void DoCommitSimulationStep(Second time, Second simulationInterval) - { - - } - - #endregion - } + public class HybridStrategy : LoggingObject, IHybridControlStrategy { @@ -241,7 +45,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies private bool ElectricMotorCanPropellDuringTractionInterruption; //private Second lastShiftTime; - private TestPowertrain TestPowertrain; @@ -255,6 +58,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies protected HybridStrategyParameters StrategyParameters; + protected DebugData DebugData = new DebugData(); + + protected DrivingAction? DryRunAction = null; + protected HybridResultEntry DryRunResult = null; + public HybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer) { DataBus = vehicleContainer; @@ -323,28 +131,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return HandleHaltAction(absTime, dt, outTorque, outAngularVelocity, dryRun); } - - var eval = new List<HybridResultEntry>(); - - if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate || DataBus.DriverInfo.DrivingAction == DrivingAction.Brake) { - if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { - eval = FindSolution(absTime, dt, outTorque, outAngularVelocity, dryRun); - } else { - eval.Add(new HybridResultEntry { - U = double.NaN, - Response = null, - Setting = new HybridStrategyResponse() { - GearboxInNeutral = false, - CombustionEngineOn = true, - MechanicalAssistPower = ElectricMotorsOff - }, - FuelCosts = double.NaN, - Gear = 0, - }); - } + var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear; + + if (!dryRun && DryRunAction.HasValue && DryRunAction == DataBus.DriverInfo.DrivingAction && DryRunResult != null) { + return CreateResponse(DryRunResult, currentGear); } - if (DataBus.DriverInfo.DrivingAction == DrivingAction.Roll || DataBus.DriverInfo.DrivingAction == DrivingAction.Coast) { - eval.Add(new HybridResultEntry { + + var responseEmOff = + new HybridResultEntry { U = double.NaN, Response = null, Setting = new HybridStrategyResponse() { @@ -354,9 +148,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies }, FuelCosts = double.NaN, ICEOff = !DataBus.EngineInfo.EngineOn, - Gear = 0 , - }); + Gear = 0, + }; + var eval = new List<HybridResultEntry>(); + + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate || DataBus.DriverInfo.DrivingAction == DrivingAction.Brake) { + if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) { + eval = FindSolution(absTime, dt, outTorque, outAngularVelocity, dryRun); + } else { + eval.Add(responseEmOff); + } + } + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Roll) { + if (ElectricMotorCanPropellDuringTractionInterruption) { + //eval = FindSolutionDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun); + eval.Add(responseEmOff); + } else { + eval.Add(responseEmOff); + } + } + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Coast) { + eval.Add(responseEmOff); } + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Brake && (eval.Count == 0 )) { eval.Add(MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity)); } @@ -391,17 +205,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies best = eval.MaxBy(x => x.Setting.MechanicalAssistPower.Sum(e => e.Value ?? 0.SI<NewtonMeter>())); } } + if (DataBus.DriverInfo.DrivingAction == DrivingAction.Brake && dryRun) { + best = MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity); + } } - var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear; + - var retVal = new HybridStrategyResponse() { - CombustionEngineOn = !best.ICEOff, - GearboxInNeutral = best.Setting.GearboxInNeutral, - MechanicalAssistPower = best.Setting.MechanicalAssistPower, - ShiftRequired = best.Gear != 0 && best.Gear != currentGear, // gs?.Item1 ?? false, - NextGear = best.Gear // gs?.Item2 ?? 0, - }; + var retVal = CreateResponse(best, currentGear); if (!DataBus.EngineInfo.EngineOn && !best.ICEOff && retVal.ShiftRequired) { CurrentState.ICEStartTStmp = absTime + dt; } @@ -414,10 +225,28 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies CurrentState.ICEStartTStmp = absTime; } } + if (dryRun) { + DryRunAction = DataBus.DriverInfo.DrivingAction; + DryRunResult = best; + } + + DebugData.Add(new { Evaluations = eval, Best = best, RetVal = retVal, DryRun = dryRun }); + return retVal; + } + + private static HybridStrategyResponse CreateResponse(HybridResultEntry best, uint currentGear) + { + var retVal = new HybridStrategyResponse() { + CombustionEngineOn = !best.ICEOff, + GearboxInNeutral = best.Setting.GearboxInNeutral, + MechanicalAssistPower = best.Setting.MechanicalAssistPower, + ShiftRequired = best.Gear != 0 && best.Gear != currentGear, // gs?.Item1 ?? false, + NextGear = best.Gear, // gs?.Item2 ?? 0, + EvaluatedSolution = best, + }; return retVal; } - private HybridResultEntry MaxRecuperationSetting(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { @@ -488,6 +317,40 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return responses; } + private List<HybridResultEntry> FindSolutionDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) + { + const bool allowICEOff = false; + + var emPos = ModelData.ElectricMachinesData.First().Item1; + var responses = new List<HybridResultEntry>(); + var gear = 0u; + + var emOffSetting = new HybridStrategyResponse() { + CombustionEngineOn = true, + GearboxInNeutral = false, + MechanicalAssistPower = ElectricMotorsOff + }; + var emOffResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, gear, emOffSetting); + + if (emOffResponse == null) { + return responses; + } + var emTqReq = (emOffResponse.ElectricMotor.PowerRequest + emOffResponse.ElectricMotor.InertiaPowerDemand) / emOffResponse.ElectricMotor.AngularVelocity; + + var entry = new HybridResultEntry() { + U = double.NaN, + Response = emOffResponse, + Setting = emOffSetting, + Gear = gear + }; + CalcualteCosts(emOffResponse, dt, entry, allowICEOff); + responses.Add(entry); + + IterateEMTorque(absTime, dt, outTorque, outAngularVelocity, gear, allowICEOff, emOffResponse, emTqReq, emPos, responses); + + return responses; + } + private void IterateEMTorque(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, bool allowIceOff, ResponseDryRun firstResponse, NewtonMeter emTqReq, PowertrainPosition emPos, List<HybridResultEntry> responses) { const double stepSize = 0.1; @@ -520,6 +383,44 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, maxEmTorque, maxEmTorque / emTqReq, allowIceOff); responses.Add(tmp); } + if (ElectricMotorCanPropellDuringTractionInterruption && allowIceOff && DataBus.DriverInfo.DrivingAction != DrivingAction.Brake) { + // this means that the EM is between wheels and transmission + // search EM Torque that results in 0 torque at ICE out + try { + var emTorqueICEOff = SearchAlgorithm.Search( + firstResponse.ElectricMotor.ElectricMotorPowerMech / firstResponse.ElectricMotor.AngularVelocity, + firstResponse.Engine.TorqueOutDemand, firstResponse.ElectricMotor.MaxDriveTorque * 0.1, + getYValue: r => { + var response = r as ResponseDryRun; + return response.Engine.TorqueOutDemand; + }, + evaluateFunction: emTq => { + var cfg = new HybridStrategyResponse() { + CombustionEngineOn = true, + GearboxInNeutral = false, + MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() { + { emPos, emTq } + } + }; + return RequestDryRun(absTime, dt, outTorque, outAngularVelocity, nextGear, cfg); + }, + criterion: r => { + var response = r as ResponseDryRun; + return response.Engine.TorqueOutDemand.Value(); + } + ); + if (emTorqueICEOff.IsBetween( + firstResponse.ElectricMotor.MaxDriveTorque, 0.SI<NewtonMeter>())) { + // only consider where EM is propelling + var tmp = TryConfiguration( + absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorqueICEOff, emTorqueICEOff / emTqReq, + allowIceOff); + responses.Add(tmp); + } + } catch (Exception ) { + Log.Debug("Failed to find EM torque to compensate drag losses of next components."); + } + } } // iterate over 'EM recuperates' up to max available recuperation potential @@ -561,13 +462,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies private ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, HybridStrategyResponse cfg) { TestPowertrain.Gearbox.Gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear; + TestPowertrain.Gearbox.DisengageGearbox = nextGear == 0; TestPowertrain.Container.VehiclePort.Initialize(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); TestPowertrain.HybridController.ApplyStrategySettings(cfg); TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity); TestPowertrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses); TestPowertrain.Battery.Initialize(DataBus.BatteryInfo.StateOfCharge); - if (nextGear != DataBus.GearboxInfo.Gear) { + var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear; + + if (nextGear != 0 && nextGear != currentGear) { if (ModelData.GearboxData.Gears[nextGear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) { return null; } @@ -589,6 +493,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies vehicleSpeedPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>()); } + if (nextGear == 0) { + TestPowertrain.Gearbox._nextGear = Controller.ShiftStrategy.NextGear; + } + TestPowertrain.CombustionEngine.PreviousState.EngineOn = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineOn; TestPowertrain.CombustionEngine.PreviousState.EnginePower = (DataBus.EngineInfo as CombustionEngine).PreviousState.EnginePower; TestPowertrain.CombustionEngine.PreviousState.dt = (DataBus.EngineInfo as CombustionEngine).PreviousState.dt; @@ -675,6 +583,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies tmp.ICEStartPenalty1 = 0; tmp.ICEStartPenalty2 = 0; } + if (!double.IsNaN(tmp.FuelCosts) && tmp.IgnoreReason == 0) { + tmp.IgnoreReason = HybridConfigurationIgnoreReason.Evaluated; + } } private Tuple<bool, uint> HandleGearshift(Second absTime, HybridResultEntry config) @@ -712,6 +623,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies MechanicalAssistPower = ElectricMotorsOff }; CurrentState.Response = dryRun ? null : tmp; + + DebugData.Add(new { RetVal = tmp, DryRun = dryRun }); return tmp; } @@ -732,6 +645,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies PreviousState = CurrentState; CurrentState = new StrategyState(); CurrentState.ICEStartTStmp = PreviousState.ICEStartTStmp; + DebugData = new DebugData(); + DryRunAction = null; + DryRunResult = null; } public void WriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) @@ -759,51 +675,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies } } - [DebuggerDisplay("{U}: {Score} - G{Gear}")] - 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 + ICEStartPenalty1) * SoCPenalty + ICEStartPenalty2) / GearshiftPenalty; } } - - public double FuelCosts { get; set; } - - public double BatCosts { get; set; } - public double SoCPenalty { get; set; } - - public double EqualityFactor { get; set; } - - public double GearshiftPenalty { get; set; } - - public double ICEStartPenalty1 { get; set; } - - public double ICEStartPenalty2 { get; set; } - - public uint Gear { get; set; } - - public bool ICEOff { get; set; } - - public HybridConfigurationIgnoreReason IgnoreReason { get; set; } - } - - [Flags] - public enum HybridConfigurationIgnoreReason - { - NotEvaluated = 0, - EngineSpeedTooLow = 1<<2, - EngineSpeedTooHigh = 1<<3, - EngineTorqueDemandTooHigh = 1<<4, - EngineTorqueDemandTooLow = 1<<5, - EngineSpeedAboveUpshift = 1<<6, - EngineSpeedBelowDownshift = 1<<7, - NoResponseAvailable = 1<<8, - Evaluated = 1<<9, - } @@ -811,32 +683,35 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies public static class HybridConfigurationIgnoreReasonHelper { - public static string HumanReadable(this HybridStrategy.HybridConfigurationIgnoreReason x) + public static string HumanReadable(this HybridConfigurationIgnoreReason x) { var retVal = new List<string>(); - foreach (var entry in EnumHelper.GetValues<HybridStrategy.HybridConfigurationIgnoreReason>()) { + foreach (var entry in EnumHelper.GetValues<HybridConfigurationIgnoreReason>()) { var tmp = x & entry; switch (tmp) { - case HybridStrategy.HybridConfigurationIgnoreReason.Evaluated: break; - case HybridStrategy.HybridConfigurationIgnoreReason.NotEvaluated: retVal.Add("not evaluated"); + case HybridConfigurationIgnoreReason.Evaluated: + retVal.Add("OK"); + break; + case HybridConfigurationIgnoreReason.NotEvaluated: + //retVal.Add("not evaluated"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedTooLow: retVal.Add("engine speed too low"); + case HybridConfigurationIgnoreReason.EngineSpeedTooLow: retVal.Add("engine speed too low"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedTooHigh: retVal.Add("engine speed too high"); + case HybridConfigurationIgnoreReason.EngineSpeedTooHigh: retVal.Add("engine speed too high"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.EngineTorqueDemandTooHigh: + case HybridConfigurationIgnoreReason.EngineTorqueDemandTooHigh: retVal.Add("engine torque demand too high"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.EngineTorqueDemandTooLow: + case HybridConfigurationIgnoreReason.EngineTorqueDemandTooLow: retVal.Add("engine torque demand too low"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedAboveUpshift: retVal.Add("engine speed above upshift"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedBelowDownshift: + case HybridConfigurationIgnoreReason.EngineSpeedAboveUpshift: retVal.Add("engine speed above upshift"); break; + case HybridConfigurationIgnoreReason.EngineSpeedBelowDownshift: retVal.Add("engine speed below downshift"); break; - case HybridStrategy.HybridConfigurationIgnoreReason.NoResponseAvailable: return "no response available"; + case HybridConfigurationIgnoreReason.NoResponseAvailable: return "no response available"; default: throw new ArgumentOutOfRangeException(nameof(x), x, null); } } @@ -844,12 +719,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies return string.Join("/", retVal); } - public static bool InvalidEngineSpeed(this HybridStrategy.HybridConfigurationIgnoreReason x) + public static bool InvalidEngineSpeed(this HybridConfigurationIgnoreReason x) { - return (x & (HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedTooLow | - HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedTooHigh | - HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedBelowDownshift | - HybridStrategy.HybridConfigurationIgnoreReason.EngineSpeedAboveUpshift)) != 0; + return (x & (HybridConfigurationIgnoreReason.EngineSpeedTooLow | + HybridConfigurationIgnoreReason.EngineSpeedTooHigh | + HybridConfigurationIgnoreReason.EngineSpeedBelowDownshift | + HybridConfigurationIgnoreReason.EngineSpeedAboveUpshift)) != 0; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs new file mode 100644 index 0000000000000000000000000000000000000000..bf5115604393b2ebd5c7ac75f3457a8a92fa95d5 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs @@ -0,0 +1,210 @@ +using System.Collections.Generic; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies { + public class TestPowertrain + { + public SimplePowertrainContainer Container; + public Gearbox Gearbox; + public SimpleHybridController HybridController; + public Battery Battery; + public Clutch Clutch; + public IBrakes Brakes; + + public IDriverInfo Driver; + public IDrivingCycleInfo DrivingCycle; + + public StopStartCombustionEngine CombustionEngine; + public ElectricMotor ElectricMotorP2; + + public TestPowertrain(SimplePowertrainContainer container, IDataBus realContainer) + { + Container = container; + Gearbox = Container.GearboxCtl as Gearbox; + HybridController = Container.HybridController as SimpleHybridController; + Battery = Container.BatteryInfo as Battery; + Clutch = Container.ClutchInfo as Clutch; + CombustionEngine = Container.EngineInfo as StopStartCombustionEngine; + ElectricMotorP2 = container.ElectricMotors.ContainsKey(PowertrainPosition.HybridP2) + ? container.ElectricMotors[PowertrainPosition.HybridP2] as ElectricMotor + : null; + if (Gearbox == null) { + throw new VectoException("Unknown gearboxtype in TestContainer: {0}", Container.GearboxCtl.GetType().FullName); + } + + if (HybridController == null) { + throw new VectoException("Unknown HybridController in TestContainer: {0}", Container.HybridController.GetType().FullName); + } + + Driver = new MockDriver(container, realContainer); + DrivingCycle = new MockDrivingCycle(container, realContainer); + Brakes = new MockBrakes(container); + } + } + + public class MockBrakes : VectoSimulationComponent, IBrakes + { + public MockBrakes(IVehicleContainer container) : base(container) + { + BrakePower = 0.SI<Watt>(); + } + + #region Overrides of VectoSimulationComponent + + protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) + { + + } + + protected override void DoCommitSimulationStep(Second time, Second simulationInterval) + { + + } + + #endregion + + #region Implementation of IBrakes + + public Watt BrakePower { get; set; } + + #endregion + } + + public class MockDrivingCycle : VectoSimulationComponent, IDrivingCycleInfo + { + private IDataBus realContainer; + + public MockDrivingCycle(VehicleContainer container, IDataBus rcontainer) : base(container) + { + realContainer = rcontainer; + } + + #region Implementation of IDrivingCycleInfo + + public CycleData CycleData + { + get { return realContainer.DrivingCycleInfo.CycleData; } + } + + public bool PTOActive + { + get { return realContainer.DrivingCycleInfo.PTOActive; } + } + + public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) + { + return realContainer.DrivingCycleInfo.CycleLookAhead(distance); + } + + public Meter Altitude + { + get { return realContainer.DrivingCycleInfo.Altitude; } + } + + public Radian RoadGradient + { + get { return realContainer.DrivingCycleInfo.RoadGradient; } + } + + public MeterPerSecond TargetSpeed + { + get { return realContainer.DrivingCycleInfo.TargetSpeed; } + } + + public Second StopTime + { + get { return realContainer.DrivingCycleInfo.StopTime; } + } + + public Meter CycleStartDistance + { + get { return realContainer?.DrivingCycleInfo?.CycleStartDistance ?? 0.SI<Meter>(); } + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) + { + return realContainer.DrivingCycleInfo.LookAhead(lookaheadDistance); + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) + { + return realContainer.DrivingCycleInfo.LookAhead(time); + } + + public SpeedChangeEntry LastTargetspeedChange + { + get { return realContainer.DrivingCycleInfo.LastTargetspeedChange; } + } + + public void FinishSimulation() + { + } + + #endregion + + #region Overrides of VectoSimulationComponent + + protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) + { + + } + + protected override void DoCommitSimulationStep(Second time, Second simulationInterval) + { + + } + + #endregion + } + + public class MockDriver : VectoSimulationComponent, IDriverInfo + { + private IDataBus realContainer; + + public MockDriver(VehicleContainer container, IDataBus rcontainer) : base(container) + { + realContainer = rcontainer; + } + + #region Implementation of IDriverInfo + + public DrivingBehavior DriverBehavior + { + get { return realContainer?.DriverInfo?.DriverBehavior ?? DrivingBehavior.Accelerating; } + } + + public DrivingAction DrivingAction + { + get { return realContainer?.DriverInfo?.DrivingAction ?? DrivingAction.Accelerate; } + } + + public MeterPerSquareSecond DriverAcceleration + { + get { return realContainer?.DriverInfo.DriverAcceleration; } + } + + #endregion + + #region Overrides of VectoSimulationComponent + + protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) + { + + } + + protected override void DoCommitSimulationStep(Second time, Second simulationInterval) + { + + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index a9895d19205ed3672e4798a2b11d88d020f1729e..264729c31bc6fa40655bb09d8d5be3e748b64e44 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -406,6 +406,7 @@ <Compile Include="Models\SimulationComponent\Impl\StopStartCombustionEngine.cs" /> <Compile Include="Models\SimulationComponent\Strategies\DelegateParallelHybridStrategy.cs" /> <Compile Include="Models\SimulationComponent\Strategies\HybridStrategy.cs" /> + <Compile Include="Models\SimulationComponent\Strategies\TestPowertrain.cs" /> <Compile Include="Models\SimulationComponent\SwitchableClutch.cs" /> <Compile Include="Models\Simulation\DataBus\IBatteryInfo.cs" /> <Compile Include="Models\Simulation\DataBus\IElectricMotorInfo.cs" />