diff --git a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs index 1d5f6fb91a4749b58c8a9d4f6d9c5a09e8076ed1..2c36ab7b789fef199140fc9664500c04bbb5183e 100644 --- a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs +++ b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs @@ -3,6 +3,7 @@ namespace TUGraz.VectoCommon.InputData { public enum PowertrainPosition { + HybridPositionNotSet, // this has to be the first entrie so that it is used as default for not initialized fields! HybridP0, HybridP1, HybridP2, diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs index 7448e0f13304e95fe9e61f6e7489deb7a17d7f0f..cd8c10f6faacdd664cf3e2b6905207834f346f73 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.SimulationComponent; @@ -44,7 +45,9 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus ExecutionMode ExecutionMode { get; } Second AbsTime { get; set; } - + + IElectricMotorInfo ElectricMotor(PowertrainPosition pos); + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineControl.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineControl.cs index 0f56669ccf81141aec27a8d5dec44c72daf47efd..abfce7266bfbe5c4682b9e26e76524931baf4679 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineControl.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineControl.cs @@ -1,6 +1,6 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus { public interface IEngineControl { - bool IgnitionOn { get; set; } + bool CombustionEngineOn { get; set; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 51eb58c4848388ed6c992d81b3da60aeb14f5210..24ec688d8e5f665d87588172de4c6138ca8e0ff2 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -331,11 +331,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl throw new VectoException("Gearbox can not be used for parallel hybrid"); } - - var engine = new StopStartCombustionEngine(container, data.EngineData); var idleController = GetIdleController(data.PTO, engine, container); + ctl.Gearbox = gbx; + ctl.Engine = engine; + // DistanceBasedDrivingCycle --> driver --> vehicle --> wheels // --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux var cycle = new DistanceBasedDrivingCycle(container, data.Cycle); @@ -375,7 +376,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } container.ModData.AddElectricMotor(pos); - ctl.AddElectricMotor(pos); + ctl.AddElectricMotor(pos, motorData.Item2); var motor = new ElectricMotor(container, motorData.Item2, ctl.ElectricMotorControl(pos), pos); motor.Connect(es); return motor; diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 7dad584cdf72d03a01f35fda4c7524b193fd41fb..1e588ce5111c5dd7a280f2a5f33993fa475f6026 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -300,6 +300,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public virtual Second AbsTime { get; set; } + public IElectricMotorInfo ElectricMotor(PowertrainPosition pos) + { + return ElectricMotors[pos]; + } public void AddComponent(VectoSimulationComponent component) { @@ -336,8 +340,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl .If<PTOCycleController>(c => { commitPriority = 99; }) .If<VTPCycle>(_ => { commitPriority = 0; }) .If<IElectricMotorInfo>(c => { + if (c.Position == PowertrainPosition.HybridPositionNotSet) { + return; + } if (ElectricMotors.ContainsKey(c.Position)) { - throw new VectoException("There is already an electric machine at position {0}", c.Position); + throw new VectoException("There is already an electric machine at position {0}", + c.Position); } ElectricMotors[c.Position] = c; @@ -546,10 +554,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl #region Implementation of IEngineControl - public bool IgnitionOn + public bool CombustionEngineOn { - get { return EngineCtl.IgnitionOn; } - set { EngineCtl.IgnitionOn = value; } + get { return EngineCtl.CombustionEngineOn; } + set { EngineCtl.CombustionEngineOn = value; } } #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs index 8193d17a1e5dcbda147410b810ba3a2b413f5410..24ffed1a544cc0874e829ce11c57c92636591355 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs @@ -10,6 +10,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent public Dictionary<PowertrainPosition, NewtonMeter> MechanicalAssistPower; public bool ShiftRequired { get; set; } public uint NextGear { get; set; } + public bool GearboxInNeutral { get; set; } + public bool CombustionEngineOn { get; set; } } public interface IHybridControlStrategy diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs index b98cd86b82eba725afe4c8bfb65a8e159938909d..2ff9b366fce6d2655cea7dcc9b173e3fb02119b2 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridController.cs @@ -1,4 +1,5 @@ using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCore.Models.SimulationComponent.Data; namespace TUGraz.VectoCore.Models.SimulationComponent { public interface IHybridController : IPowerTrainComponent @@ -6,6 +7,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { IShiftStrategy ShiftStrategy { get; } IElectricMotorControl ElectricMotorControl(PowertrainPosition pos); - void AddElectricMotor(PowertrainPosition pos); + void AddElectricMotor(PowertrainPosition pos, ElectricMotorData motorDataItem2); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs index 5eda23d79809c4ae6b4f4a4fd1436d8d56b78d67..778b12c790eaaee0de54c04fa9e5ea4b1a35d06b 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs @@ -142,7 +142,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Auxiliaries.CycleStep(CurrentState.dt); var essUtilityFactor = 1.0; - if (!DataBus.IgnitionOn) { + if (!DataBus.CombustionEngineOn) { essUtilityFactor = 1 - EngineStopStartUtilityFactor; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 726eec75bc12f162f8811354fb428b8adb46e2b4..f72f3bebb2cea63ef89f23f57cfde8a15819b188 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -762,7 +762,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region Implementation of IEngineControl - public virtual bool IgnitionOn + public virtual bool CombustionEngineOn { get { return true; } set { } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index c80145de00016731d506128ec7dbfeebe1bdb0f7..c7ab9ac5bd289ef6755e055b8d986a9218b2da4a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -203,7 +203,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (EcoRollState.State != EcoRollStates.EcoRollOn && PCCState != PCCStates.UseCase1 && PCCState != PCCStates.UseCase2) { EngineOffTimestamp = null; - Driver.DataBus.IgnitionOn = true; + Driver.DataBus.CombustionEngineOn = true; } if (CurrentDrivingMode == DrivingMode.DrivingModeBrake) { @@ -294,7 +294,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl break; case EcoRollType.WithEngineStop: (dataBus as IGearboxControl).DisengageGearbox = true; - dataBus.IgnitionOn = false; + dataBus.CombustionEngineOn = false; break; default: throw new ArgumentOutOfRangeException(); } @@ -304,7 +304,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl case PCCStates.WithinSegment: case PCCStates.PCCinterrupt: (dataBus as IGearboxControl).DisengageGearbox = false; - dataBus.IgnitionOn = true; + dataBus.CombustionEngineOn = true; break; default: throw new ArgumentOutOfRangeException(); } @@ -468,19 +468,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl case EcoRollStates.EcoRollOn: (dBus as IGearboxControl).DisengageGearbox = true; if (ADAS.EcoRoll == EcoRollType.WithEngineStop) { - dBus.IgnitionOn = false; + dBus.CombustionEngineOn = false; } return; case EcoRollStates.EcoRollOff: (dBus as IGearboxControl).DisengageGearbox = false; if (ADAS.EcoRoll == EcoRollType.WithEngineStop) { - dBus.IgnitionOn = true; + dBus.CombustionEngineOn = true; } return; } EngineOffTimestamp = null; - dBus.IgnitionOn = true; + dBus.CombustionEngineOn = true; } @@ -499,12 +499,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Driver.DriverData.EngineStopStart.EngineOffStandStillActivationDelay)) { if (EngineOffTimestamp == null) { EngineOffTimestamp = absTime; - Driver.DataBus.IgnitionOn = false; + Driver.DataBus.CombustionEngineOn = false; } } if (EngineOffTimestamp != null && (absTime - EngineOffTimestamp).IsGreaterOrEqual(Driver.DriverData.EngineStopStart.MaxEngineOffTimespan)) { - Driver.DataBus.IgnitionOn = true; + Driver.DataBus.CombustionEngineOn = true; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs index 2e2666269477d3e2be9ea0065924e844deb48a02..c0fd928a9b51dceff7783001eb506cbc20f01d77 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs @@ -26,6 +26,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Control = control; ModelData = data; Position = position; + container.AddComponent(this); // We have to do this again because in the base class the position is unknown! } public PowertrainPosition Position { get; } @@ -44,7 +45,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } }; } - if (!DataBus.IgnitionOn) + if (!DataBus.CombustionEngineOn) { PreviousState.InTorque = 0.SI<NewtonMeter>(); PreviousState.InAngularVelocity = outAngularVelocity; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index 091c1274164013afd31879848a5d99cf12d9d7c7..97502be9bc0fba6f424faa8c5ad4c48a265468c3 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -33,6 +33,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _electricMotorCtl = new Dictionary<PowertrainPosition, ElectricMotorController>(); _shiftStrategy = new HybridCtlShiftStrategy(this, container); _hybridStrategy = strategy; + ElectricSystem = es; } public IHybridControlStrategy Strategy @@ -40,13 +41,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl get { return _hybridStrategy; } } - public virtual void AddElectricMotor(PowertrainPosition pos) + public IElectricSystem ElectricSystem { get; } + + public virtual 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); + _electricMotorCtl[pos] = new ElectricMotorController(this, motorData); } public virtual IElectricMotorControl ElectricMotorControl(PowertrainPosition pos) @@ -63,6 +66,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl bool dryRun = false) { CurrentState.StrategyResponse = Strategy.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); + Gearbox.SwitchToNeutral = CurrentState.StrategyResponse.GearboxInNeutral; + Engine.CombustionEngineOn = CurrentState.StrategyResponse.CombustionEngineOn; + return NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun); } @@ -97,6 +103,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl get { return CurrentState.StrategyResponse.ShiftRequired; } } + public IHybridControlledGearbox Gearbox { protected get; set; } + public ICombustionEngine Engine { protected get; set; } + ///======================================================================================= public class HybridControllerState { @@ -107,10 +116,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public class ElectricMotorController : IElectricMotorControl { protected HybridController _controller; + protected ElectricMotorData ElectricMotorData; - public ElectricMotorController(HybridController hybridController) + public ElectricMotorController(HybridController hybridController, ElectricMotorData motorData) { _controller = hybridController; + ElectricMotorData = motorData; } public NewtonMeter MechanicalAssistPower(Second absTime, Second dt, NewtonMeter outTorque, @@ -123,12 +134,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public NewtonMeter MaxDriveTorque(PerSecond avgSpeed, Second dt) { - throw new System.NotImplementedException(); + 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) { - throw new System.NotImplementedException(); + return 0.SI<NewtonMeter>(); } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs index cf876d7395f75138befad7162f375ead5c926713..f6f58887dc55d23b03caa79fef8c55eab3254d31 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs @@ -19,7 +19,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { IVehicleContainer container, CombustionEngineData modelData, bool pt1Disabled = false) : base( container, modelData, pt1Disabled) { - IgnitionOn = true; + CombustionEngineOn = true; EngineStopStartUtilityFactor = container.RunData.DriverData.EngineStopStart.UtilityFactor; var engineRampUpEnergy = Formulas.InertiaPower(modelData.IdleSpeed, 0.RPMtoRad(), modelData.Inertia, modelData.EngineStartTime) * modelData.EngineStartTime; @@ -29,13 +29,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { EngineStartEnergy = (engineRampUpEnergy + engineDragEnergy) * EngineStopStartUtilityFactor / DeclarationData.AlternaterEfficiency / DeclarationData.AlternaterEfficiency; } - public override bool IgnitionOn { get; set; } + public override bool CombustionEngineOn { get; set; } #region Overrides of CombustionEngine public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) { - return IgnitionOn ? base.Request(absTime, dt, outTorque, outAngularVelocity, dryRun) : HandleEngineOffRequest(absTime, dt, outTorque, outAngularVelocity, dryRun); + return CombustionEngineOn ? base.Request(absTime, dt, outTorque, outAngularVelocity, dryRun) : HandleEngineOffRequest(absTime, dt, outTorque, outAngularVelocity, dryRun); } #endregion @@ -83,7 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container) { - if (IgnitionOn) { + if (CombustionEngineOn) { base.DoWriteModalResults(time, simulationInterval, container); var engineStart = !PreviousState.IgnitionOn && CurrentState.IgnitionOn; container[ModalResultField.P_ice_start] = engineStart ? EngineStartEnergy / CurrentState.dt : 0.SI<Watt>(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs index 306eaa07de6ee33ff4746fd6b7c0f45a84aa501a..49af471785e9162e6721c4f6da92218d835e57cc 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs @@ -124,7 +124,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl CurrentState.SetState(inTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity); CurrentState.OperatingPoint = operatingPoint; - CurrentState.IgnitionOn = DataBus.IgnitionOn; + CurrentState.IgnitionOn = DataBus.CombustionEngineOn; var retVal = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity); @@ -417,7 +417,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl PerSecond outAngularVelocity) { CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - CurrentState.IgnitionOn = DataBus.IgnitionOn; + CurrentState.IgnitionOn = DataBus.CombustionEngineOn; } public class TorqueConverterComponentState : SimpleComponentState diff --git a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs index 3cc67adccedf38dfdaaea1d0661959e762152d62..edd1d71e4e79367048b70fc0671370da7e4e6994 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs @@ -36,7 +36,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent } return response; } - if (DataBus.IgnitionOn) + if (DataBus.CombustionEngineOn) return base.Initialize(outTorque, outAngularVelocity); PreviousState.SetState(outTorque, outAngularVelocity, outTorque, outAngularVelocity); return NextComponent.Initialize(outTorque, outAngularVelocity); @@ -73,7 +73,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent return response; } - if (DataBus.IgnitionOn) + if (DataBus.CombustionEngineOn) { if (DataBus.DriverBehavior == DrivingBehavior.Halted && !ClutchOpen) { diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs index 7723974f97401946628f0ab30045713ea3aef0b2..b633a88af389e8b31ef5758cf989b7e0bcc74eee 100644 --- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs @@ -29,12 +29,11 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid [TestFixture] public class ParallelHybridTest { - public const string MotorFile = @"TestData\Hybrids\ElectricMotor\GenericEMotor.vem"; public const string BatFile = @"TestData\Hybrids\Battery\GenericBattery.vbat"; public const string AccelerationFile = @"TestData\Components\Truck.vacc"; - public const string MotorFile240kW = @"TestData\Hybrid\ElectricMotor\GenericEMotor240kW.vem"; + public const string MotorFile240kW = @"TestData\Hybrids\ElectricMotor\GenericEMotor240kW.vem"; public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm"; public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm"; @@ -45,21 +44,23 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); } - [TestCase(30, 0.8, 500)] + [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); - RunHybridSimulation(vmax, initialSoC, electricTorque, cycle); - } - public void RunHybridSimulation(double vmax, double initialSoC, double electricTorque, DrivingCycleData cycle) - { const bool largeMotor = true; + var electricTq = electricTorque.SI<NewtonMeter>(); var run = CreateEngineeringRun( - cycle, string.Format("SimpleParallelHybrid_acc_{0}_{2}-{1}.vmod", vmax, initialSoC, electricTorque), initialSoC, + cycle, string.Format("SimpleParallelHybrid_acc_{0}_{2}-{1}.vmod", vmax, initialSoC, electricTq.Value()), + initialSoC, new DelegateParallelHybridStrategy(), PowertrainPosition.HybridP2); var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; @@ -71,25 +72,37 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid var nextState = new StrategyState(); var currentState = new StrategyState(); + strategy.RequestFunc = (absTime, b, c, d, dryRun) => { - var shiftAllowed = absTime > currentState.lastGearShift + 2.SI<Second>(); - var triggerGearshift = shiftAllowed && ( run.GetContainer().EngineSpeed > 1600.RPMtoRad() || - run.GetContainer().EngineSpeed < 625.RPMtoRad()); + var shiftAllowed = absTime > currentState.lastGearShift + 2.SI<Second>(); + var dBus = run.GetContainer(); + var triggerGearshift = shiftAllowed && (dBus.EngineSpeed > 1600.RPMtoRad() || + dBus.EngineSpeed < 625.RPMtoRad()); //var nextGear = run.GetContainer().Gear; if (!dryRun && triggerGearshift) { nextState.lastGearShift = absTime; - nextState.nextGear = (uint)(run.GetContainer().Gear + (run.GetContainer().EngineSpeed > 1600.RPMtoRad() + nextState.nextGear = (uint)(dBus.Gear + (dBus.EngineSpeed > 1600.RPMtoRad() ? 1 - : (run.GetContainer().EngineSpeed < 625.RPMtoRad() ? -1 : 0))); + : (dBus.EngineSpeed < 625.RPMtoRad() ? -1 : 0))); } + + var assistTorque = electricTq; + if (electricTorque < 0 && dBus.VehicleSpeed > dBus.TargetSpeed - 3.KMPHtoMeterPerSecond()) { + assistTorque = 0.SI<NewtonMeter>(); + } + return new HybridStrategyResponse { + GearboxInNeutral = false, + CombustionEngineOn = true, MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() - { { PowertrainPosition.HybridP2, 0.SI<NewtonMeter>() } }, + { { PowertrainPosition.HybridP2, assistTorque } }, ShiftRequired = triggerGearshift, - NextGear = nextState.nextGear + NextGear = nextState.nextGear, }; }; strategy.InitializeFunc = (a, b) => new HybridStrategyResponse { + GearboxInNeutral = false, + CombustionEngineOn = true, MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() { { PowertrainPosition.HybridP2, 0.SI<NewtonMeter>() } } }; @@ -107,6 +120,72 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid Assert.IsTrue(modData.Rows.Count > 0); } + [TestCase(30, 0.7)] + public void P2HybridDriveOff_ElectricOnly(double vmax, double initialSoC) + { + var cycleData = string.Format( + @" 0, 0, 0, 3 + 700, {0}, 0, 0", vmax); + 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, + new DelegateParallelHybridStrategy(), pos, largeMotor: true); + + var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController; + Assert.NotNull(hybridController); + var strategy = (DelegateParallelHybridStrategy)hybridController.Strategy; + Assert.NotNull(strategy); + + var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data; + + var nextState = new StrategyState(); + var currentState = new StrategyState(); + + strategy.RequestFunc = (absTime, dt, outTorque, outSpeed, dryRun) => { + var dBus = run.GetContainer(); + var rpm = dBus.ElectricMotor(pos).ElectricMotorSpeed; + var minTorque = -hybridController.ElectricMotorControl(pos).MaxDragTorque(rpm, dt); + var maxTorque = -hybridController.ElectricMotorControl(pos).MaxDriveTorque(rpm, dt); + return new HybridStrategyResponse() { + MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() { + { PowertrainPosition.HybridP2, -outTorque.LimitTo(minTorque, maxTorque) } + }, + GearboxInNeutral = true, + CombustionEngineOn = false, + }; + }; + strategy.InitializeFunc = (outTorque, outSpeed) => { + var dBus = run.GetContainer(); + var rpm = dBus.ElectricMotor(pos).ElectricMotorSpeed; + var minTorque = -hybridController.ElectricMotorControl(pos).MaxDragTorque(rpm, 0.5.SI<Second>()); + var maxTorque = -hybridController.ElectricMotorControl(pos).MaxDriveTorque(rpm, 0.5.SI<Second>()); + return new HybridStrategyResponse { + MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() + { { PowertrainPosition.HybridP2, -outTorque.LimitTo(minTorque, maxTorque) } }, + GearboxInNeutral = true, + CombustionEngineOn = false, + }; + }; + strategy.CommitFunc = () => { + currentState = nextState; + nextState = new StrategyState() + { + lastGearShift = currentState.lastGearShift, + nextGear = currentState.nextGear, + }; + }; + + run.Run(); + Assert.IsTrue(run.FinishedWithoutErrors); + + Assert.IsTrue(modData.Rows.Count > 0); + } + + public class StrategyState { public Second lastGearShift = -double.MaxValue.SI<Second>(); @@ -116,25 +195,29 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid // ================================================= - public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, double initialSoc, IHybridControlStrategy hybridStrategy, PowertrainPosition pos, bool largeMotor = false, SummaryDataContainer sumData = null, double pAuxEl = 0) + public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, double initialSoc, + IHybridControlStrategy hybridStrategy, PowertrainPosition pos, bool largeMotor = false, + SummaryDataContainer sumData = null, double pAuxEl = 0) { var container = CreateParallelHybridPowerTrain( - cycleData, Path.GetFileNameWithoutExtension(modFileName), initialSoc, largeMotor, sumData, hybridStrategy, pAuxEl, pos); + cycleData, Path.GetFileNameWithoutExtension(modFileName), initialSoc, largeMotor, sumData, + hybridStrategy, pAuxEl, pos); return new DistanceRun(container); } - public static VehicleContainer CreateParallelHybridPowerTrain(DrivingCycleData cycleData, string modFileName, double initialBatCharge, bool largeMotor, SummaryDataContainer sumData, IHybridControlStrategy hybridStrategy, double pAuxEl, PowertrainPosition pos) + public static VehicleContainer CreateParallelHybridPowerTrain(DrivingCycleData cycleData, string modFileName, + double initialBatCharge, bool largeMotor, SummaryDataContainer sumData, + IHybridControlStrategy hybridStrategy, double pAuxEl, PowertrainPosition pos) { //var strategySettings = GetHybridStrategyParameters(largeMotor); //strategySettings.StrategyName = "SimpleParallelHybridStrategy"; var fileWriter = new FileOutputWriter(modFileName); - var modDataFilter = new IModalDataFilter[] {}; //new IModalDataFilter[] { new ActualModalDataFilter(), }; + var modDataFilter = new IModalDataFilter[] { }; //new IModalDataFilter[] { new ActualModalDataFilter(), }; var modData = new ModalDataContainer( - modFileName, new IFuelProperties[] {FuelData.Diesel}, fileWriter, - filters: modDataFilter) - { + modFileName, new IFuelProperties[] { FuelData.Diesel }, fileWriter, + filters: modDataFilter) { WriteModalResults = true, }; @@ -145,15 +228,15 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid var airdragData = CreateAirdragData(); var driverData = CreateDriverData(AccelerationFile, true); - var electricMotorData = MockSimulationDataFactory.CreateElectricMotorData(largeMotor ? MotorFile240kW : MotorFile, pos); + var electricMotorData = + MockSimulationDataFactory.CreateElectricMotorData(largeMotor ? MotorFile240kW : MotorFile, pos); var batteryData = MockSimulationDataFactory.CreateBatteryData(BatFile, initialBatCharge); var engineData = MockSimulationDataFactory.CreateEngineDataFromFile( - Truck40tPowerTrain.EngineFile, gearboxData.Gears.Count); + Truck40tPowerTrain.EngineFile, gearboxData.Gears.Count); - var runData = new VectoRunData() - { + var runData = new VectoRunData() { //PowertrainConfiguration = PowertrainConfiguration.ParallelHybrid, JobRunId = 0, DriverData = driverData, @@ -185,9 +268,11 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid var gearbox = new Gearbox(container, ctl.ShiftStrategy, runData); //var hybridStrategy = new DelegateParallelHybridStrategy(); + ctl.Gearbox = gearbox; var engine = new StopStartCombustionEngine(container, runData.EngineData); var idleController = engine.IdleController; + ctl.Engine = engine; var cycle = new DistanceBasedDrivingCycle(container, cycleData); @@ -198,17 +283,22 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid cycle .AddComponent(new Driver(container, runData.DriverData, new DefaultDriverStrategy(container))) .AddComponent(new Vehicle(container, runData.VehicleData, runData.AirdragData)) - .AddComponent(new Wheels(container, runData.VehicleData.DynamicTyreRadius, runData.VehicleData.WheelsInertia)) + .AddComponent(new Wheels(container, runData.VehicleData.DynamicTyreRadius, + runData.VehicleData.WheelsInertia)) .AddComponent(new Brakes(container)) .AddComponent(ctl) - .AddComponent(GetElectricMachine(PowertrainPosition.HybridP4, runData.ElectricMachinesData, container, es, ctl)) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP4, runData.ElectricMachinesData, container, + es, ctl)) .AddComponent(new AxleGear(container, runData.AxleGearData)) - .AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, runData.ElectricMachinesData, container, es, ctl)) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP3, runData.ElectricMachinesData, container, + es, ctl)) .AddComponent(runData.AngledriveData != null ? new Angledrive(container, runData.AngledriveData) : null) .AddComponent(gearbox, runData.Retarder, container) - .AddComponent(GetElectricMachine(PowertrainPosition.HybridP2, runData.ElectricMachinesData, container, es, ctl)) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP2, runData.ElectricMachinesData, container, + es, ctl)) .AddComponent(clutch) - .AddComponent(GetElectricMachine(PowertrainPosition.HybridP1, runData.ElectricMachinesData, container, es, ctl)) + .AddComponent(GetElectricMachine(PowertrainPosition.HybridP1, runData.ElectricMachinesData, container, + es, ctl)) .AddComponent(engine, idleController) .AddAuxiliaries(container, runData); @@ -220,13 +310,12 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid IElectricSystem es, IHybridController ctl) { var motorData = electricMachinesData.FirstOrDefault(x => x.Item1 == pos); - if (motorData == null) - { + if (motorData == null) { return null; } container.ModData.AddElectricMotor(pos); - ctl.AddElectricMotor(pos); + ctl.AddElectricMotor(pos, motorData.Item2); var motor = new ElectricMotor(container, motorData.Item2, ctl.ElectricMotorControl(pos), pos); motor.Connect(es); return motor; @@ -236,12 +325,10 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid { var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 }; - return new GearboxData - { + return new GearboxData { Gears = ratios.Select( (ratio, i) => Tuple.Create( - (uint)i, new GearData - { + (uint)i, new GearData { //MaxTorque = 2300.SI<NewtonMeter>(), LossMap = TransmissionLossMapReader.ReadFromFile( @@ -266,10 +353,8 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid private static AxleGearData CreateAxleGearData() { var ratio = 2.59; - return new AxleGearData - { - AxleGear = new GearData - { + return new AxleGearData { + AxleGear = new GearData { Ratio = ratio, LossMap = TransmissionLossMapReader.Create(0.95, ratio, "Axlegear"), } @@ -294,8 +379,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid TyreTestLoad = 30436.SI<Newton>() }, }; - return new VehicleData - { + return new VehicleData { AirDensity = DeclarationData.AirDensity, AxleConfiguration = AxleConfiguration.AxleConfig_4x2, CurbMass = 11500.SI<Kilogram>(), @@ -308,8 +392,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid private static AirdragData CreateAirdragData() { - return new AirdragData() - { + return new AirdragData() { CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup( 3.2634.SI<SquareMeter>(), @@ -320,11 +403,9 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid private static DriverData CreateDriverData(string accelerationFile, bool overspeed = false) { - return new DriverData - { + return new DriverData { AccelerationCurve = AccelerationCurveReader.ReadFromFile(accelerationFile), - LookAheadCoasting = new DriverData.LACData - { + LookAheadCoasting = new DriverData.LACData { Enabled = true, MinSpeed = 50.KMPHtoMeterPerSecond(), @@ -335,7 +416,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid OverSpeed = new DriverData.OverSpeedData() { Enabled = true, MinSpeed = 50.KMPHtoMeterPerSecond(), - OverSpeed = 5.KMPHtoMeterPerSecond() + OverSpeed = 5.KMPHtoMeterPerSecond() }, EngineStopStart = new DriverData.EngineStopStartData() { EngineOffStandStillActivationDelay = DeclarationData.Driver.EngineStopStart.ActivationDelay, diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs index e6bd409937b0feb5497546644713e1660b7a9526..72c2f2beb9ca266e7f486b2907440155f0e6878f 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs @@ -206,7 +206,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent #region Implementation of IEngineControl - public bool IgnitionOn { get; set; } + public bool CombustionEngineOn { get; set; } #endregion } diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs index fc8adfbd0e4081fde5abdd674bb5c69195907d8f..6745e0c358df7571940393d4520016383401e8c5 100644 --- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; +using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Connector.Ports; @@ -79,6 +80,10 @@ namespace TUGraz.VectoCore.Tests.Utils } public Second AbsTime { get; set; } + public IElectricMotorInfo ElectricMotor(PowertrainPosition pos) + { + return null; + } public Watt GearboxLoss() { @@ -244,7 +249,7 @@ namespace TUGraz.VectoCore.Tests.Utils #region Implementation of IEngineControl - public bool IgnitionOn { get; set; } + public bool CombustionEngineOn { get; set; } #endregion