diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 7c95e3401ef4cce19cecc8d394d0d9aa65f44566..1aea6ae89b904b782bc16a84b2c322d466d89a3d 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -49,6 +49,7 @@ using TUGraz.VectoCore.Models.SimulationComponent; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Models.SimulationComponent.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies; using TUGraz.VectoCore.Models.SimulationComponent.Strategies; using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; @@ -1577,13 +1578,92 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl } } + public static string GetShiftStrategyName(GearboxType gearboxType, VectoSimulationJobType jobType, + bool isTestPowerTrain = false) + { + switch (gearboxType) { + case GearboxType.AMT: + switch (jobType) { + case VectoSimulationJobType.ConventionalVehicle: + case VectoSimulationJobType.ParallelHybridVehicle: + + return AMTShiftStrategyOptimized.Name; + //return new AMTShiftStrategyOptimized(container); + case VectoSimulationJobType.BatteryElectricVehicle: + case VectoSimulationJobType.SerialHybridVehicle: + return PEVAMTShiftStrategy.Name; + //return new PEVAMTShiftStrategy(container); + default: + throw new VectoException( + "no default gearshift strategy available for gearbox type {0} and job type {1}", + gearboxType, jobType); + } + case GearboxType.MT: + return MTShiftStrategy.Name; + //return new MTShiftStrategy(container); + + case GearboxType.ATPowerSplit: + case GearboxType.ATSerial: + switch (jobType) { + case VectoSimulationJobType.ParallelHybridVehicle: + case VectoSimulationJobType.ConventionalVehicle: + return ATShiftStrategyOptimized.Name; + //return new ATShiftStrategyOptimized(container); + case VectoSimulationJobType.SerialHybridVehicle: + case VectoSimulationJobType.BatteryElectricVehicle: + return APTNShiftStrategy.Name; + //return new APTNShiftStrategy(container); + default: + throw new VectoException( + "no default gearshift strategy available for gearbox type {0} and job type {1}", + gearboxType, jobType); + } + case GearboxType.APTN: + switch (jobType) { + case VectoSimulationJobType.ParallelHybridVehicle: + case VectoSimulationJobType.SerialHybridVehicle: + case VectoSimulationJobType.BatteryElectricVehicle: + case VectoSimulationJobType.IEPC_E: + case VectoSimulationJobType.IEPC_S: + return APTNShiftStrategy.Name; + //return new APTNShiftStrategy(container); + case VectoSimulationJobType.ConventionalVehicle when isTestPowerTrain: + return null; + default: + throw new ArgumentException( + "APT-N Gearbox is only applicable on hybrids and battery electric vehicles."); + } + case GearboxType.IHPC: + switch (jobType) { + case VectoSimulationJobType.IHPC: + return AMTShiftStrategyOptimized.Name; + //return new AMTShiftStrategyOptimized(container); + default: + throw new ArgumentException( + "IHPC Gearbox is only applicable on hybrid vehicle of type IHPC."); + } + default: + throw new ArgumentOutOfRangeException("GearboxType", gearboxType, + "VECTO can not automatically derive shift strategy for GearboxType."); + } + } + + public static IShiftStrategy GetShiftStrategy(IVehicleContainer container) { var runData = container.RunData; - switch (runData.GearboxData.Type) { + var gearboxType = runData.GearboxData.Type; + var jobType = runData.JobType; + var isTestPowerTrain = container.IsTestPowertrain; + + var shiftStrategyName = GetShiftStrategyName(gearboxType, jobType, isTestPowerTrain); + runData.ShiftStrategy = shiftStrategyName; + return ShiftStrategy.Create(container, runData.ShiftStrategy); + + switch (gearboxType) { case GearboxType.AMT: - switch (runData.JobType) { + switch (jobType) { case VectoSimulationJobType.ConventionalVehicle: case VectoSimulationJobType.ParallelHybridVehicle: runData.ShiftStrategy = AMTShiftStrategyOptimized.Name; @@ -1595,7 +1675,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl default: throw new VectoException( "no default gearshift strategy available for gearbox type {0} and job type {1}", - runData.GearboxData.Type, runData.JobType); + gearboxType, jobType); } case GearboxType.MT: runData.ShiftStrategy = MTShiftStrategy.Name; @@ -1603,7 +1683,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl case GearboxType.ATPowerSplit: case GearboxType.ATSerial: - switch (runData.JobType) { + switch (jobType) { case VectoSimulationJobType.ParallelHybridVehicle: case VectoSimulationJobType.ConventionalVehicle: runData.ShiftStrategy = ATShiftStrategyOptimized.Name; @@ -1615,10 +1695,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl default: throw new VectoException( "no default gearshift strategy available for gearbox type {0} and job type {1}", - runData.GearboxData.Type, runData.JobType); + gearboxType, jobType); } case GearboxType.APTN: - switch (runData.JobType) { + switch (jobType) { case VectoSimulationJobType.ParallelHybridVehicle: case VectoSimulationJobType.SerialHybridVehicle: case VectoSimulationJobType.BatteryElectricVehicle: @@ -1632,7 +1712,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl throw new ArgumentException("APT-N Gearbox is only applicable on hybrids and battery electric vehicles."); } case GearboxType.IHPC: - switch (runData.JobType) { + switch (jobType) { case VectoSimulationJobType.IHPC: runData.ShiftStrategy = AMTShiftStrategyOptimized.Name; return new AMTShiftStrategyOptimized(container); @@ -1640,10 +1720,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl throw new ArgumentException("IHPC Gearbox is only applicable on hybrid vehicle of type IHPC."); } default: - throw new ArgumentOutOfRangeException("GearboxType", runData.GearboxData.Type, "VECTO can not automatically derive shift strategy for GearboxType."); + throw new ArgumentOutOfRangeException("GearboxType", gearboxType, "VECTO can not automatically derive shift strategy for GearboxType."); } } + + private static IGearbox GetSimpleGearbox(IVehicleContainer container, VectoRunData runData) { if (runData.GearboxData.Type.AutomaticTransmission() && runData.GearboxData.Type != GearboxType.APTN && runData.GearboxData.Type != GearboxType.IHPC) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs index 0e2910e5e1eaf4937ee0ef2367616ae02e11c3a2..167bf5bf84821987d1e493cda36051d68ba85c36 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs @@ -14,6 +14,7 @@ using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies; using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs similarity index 95% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs index 827ff73e1e6fec1fdb6259385a770dce3743d104..59e58915f7c74bfc84941f8107dc9bb4767114b8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs @@ -1,394 +1,409 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2019 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -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.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// AMTShiftStrategy implements the AMT Shifting Behaviour. - /// </summary> - public class AMTShiftStrategy : ShiftStrategy - { - //protected readonly GearshiftPosition MaxStartGear; - protected GearshiftPosition _nextGear; - private GearshiftPosition DesiredGearRoadsweeping; - - public AMTShiftStrategy(IVehicleContainer dataBus) : base(dataBus) - { - var runData = dataBus.RunData; - EarlyShiftUp = true; - SkipGears = true; - if (runData.EngineData == null) { - return; - } - var transmissionRatio = runData.AxleGearData.AxleGear.Ratio * - (runData.AngledriveData?.Angledrive.Ratio ?? 1.0) / - runData.VehicleData.DynamicTyreRadius; - var minEngineSpeed = (runData.EngineData.FullLoadCurves[0].RatedSpeed - runData.EngineData.IdleSpeed) * - Constants.SimulationSettings.ClutchClosingSpeedNorm + runData.EngineData.IdleSpeed; - - DesiredGearRoadsweeping = runData.DriverData?.PTODriveRoadsweepingGear; - - MaxStartGear = GearboxModelData.GearList.First(); - foreach (var gear in GearboxModelData.GearList.Reverse()) { - var gearData = GearboxModelData.Gears[gear.Gear]; - if (GearshiftParams.StartSpeed * transmissionRatio * gearData.Ratio > minEngineSpeed) { - MaxStartGear = gear; - break; - } - } - } - - private bool SpeedTooLowForEngine(GearshiftPosition gear, PerSecond outAngularSpeed) - { - return (outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsSmaller(DataBus.EngineInfo.EngineIdleSpeed); - } - - private bool SpeedTooHighForEngine(GearshiftPosition gear, PerSecond outAngularSpeed) - { - return - (outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed, - DataBus.EngineInfo.EngineN95hSpeed - 1.RPMtoRad())); - } - - public override GearshiftPosition NextGear => _nextGear; - - public override ShiftPolygon ComputeDeclarationShiftPolygon( - GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, - CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) - { - return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon( - i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); - } - - public static string Name => "AMT - Classic"; - - public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear, outAngularVelocity)) { - _nextGear = Gears.Predecessor(_nextGear); - } - while (Gears.HasSuccessor(_nextGear) && SpeedTooHighForEngine(_nextGear, outAngularVelocity)) { - _nextGear = Gears.Successor(_nextGear); - } - - return _nextGear; - } - - public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) {} - - public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { - return InitStartGear(absTime, outTorque, outAngularVelocity); - } - - foreach (var gear in Gears.Reverse()) { - var selected = gear; - var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); - - var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio; - var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; - var inTorque = response.Clutch.PowerRequest / inAngularSpeed; - - // if in shift curve and torque reserve is provided: return the current gear - if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && - reserve >= GearshiftParams.StartTorqueReserve) { - if ((inAngularSpeed - DataBus.EngineInfo.EngineIdleSpeed) / (DataBus.EngineInfo.EngineRatedSpeed - DataBus.EngineInfo.EngineIdleSpeed) < - Constants.SimulationSettings.ClutchClosingSpeedNorm && Gears.HasPredecessor(gear)) { - selected = Gears.Predecessor(gear); - } - _nextGear = selected; - return selected; - } - - // if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve) - if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && Gears.HasSuccessor(gear)) { - selected = Gears.Successor(gear); - _nextGear = selected; - return selected; - } - } - - // fallback: return first gear - _nextGear = Gears.First(); - return _nextGear; - } - - private GearshiftPosition InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - foreach (var gear in Gears.IterateGears(MaxStartGear, Gears.First())) { - var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio; - - var ratedSpeed = DataBus.EngineInfo.EngineRatedSpeed; - if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) { - continue; - } - - var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); - - var fullLoadPower = response.Engine.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; - - if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineIdleSpeed && reserve >= GearshiftParams.StartTorqueReserve) { - _nextGear = gear; - return gear; - } - } - _nextGear = Gears.First(); - return _nextGear; - } - - protected override bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, - PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, - Second lastShiftTime, IResponse response) - { - // no shift when vehicle stands - if (DataBus.VehicleInfo.VehicleStopped) { - return false; - } - - // emergency shift to not stall the engine ------------------------ - if (Gears.First().Equals(gear) && - SpeedTooLowForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) { - return true; - } - - _nextGear = gear; - while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear, - inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) { - _nextGear = Gears.Predecessor(_nextGear); - } - - while (Gears.HasSuccessor(_nextGear) && - SpeedTooHighForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) { - _nextGear = Gears.Successor(_nextGear); - } - - if (!_nextGear.Equals(gear)) { - return true; - } - - // PTO Active while drive (roadsweeping) shift rules - if (DataBus.DrivingCycleInfo.CycleData.LeftSample.PTOActive == PTOActivity.PTOActivityRoadSweeping) { - if (gear.Equals(DesiredGearRoadsweeping)) { - return false; - } - - if (gear > DesiredGearRoadsweeping) { - if (IsAboveDownShiftCurve(DesiredGearRoadsweeping, inTorque, inAngularVelocity)) { - _nextGear = DesiredGearRoadsweeping; - return true; - } - } - - if (gear < DesiredGearRoadsweeping) { - if (!SpeedTooHighForEngine( - DesiredGearRoadsweeping, inAngularVelocity / GearboxModelData.Gears[DesiredGearRoadsweeping.Gear].Ratio)) { - _nextGear = DesiredGearRoadsweeping; - return true; - } - } - } - - // normal shift when all requirements are fullfilled ------------------ - var minimumShiftTimePassed = - (lastShiftTime + GearshiftParams.TimeBetweenGearshifts).IsSmallerOrEqual(absTime); - if (!minimumShiftTimePassed) { - return false; - } - - _nextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, - response); - if (!_nextGear.Equals(gear)) { - return true; - } - - _nextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, - response); - - return !_nextGear.Equals(gear); - } - - protected virtual GearshiftPosition CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response) - { - // if the driver's intention is _not_ to accelerate or drive along then don't upshift - if (DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Driving) { - return currentGear; - } - if ((absTime - _gearbox.LastDownshift).IsSmaller(GearshiftParams.UpshiftAfterDownshiftDelay)) { - return currentGear; - } - var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response); - if (nextGear.Equals(currentGear)) { - return nextGear; - } - - // estimate acceleration for selected gear - if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(GearshiftParams.UpshiftMinAcceleration)) { - // if less than 0.1 for next gear, don't shift - if (nextGear.Gear - currentGear.Gear == 1) { - return currentGear; - } - // if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift! - if (nextGear.Gear > currentGear.Gear && - EstimateAccelerationForGear(Gears.Successor(currentGear), outAngularVelocity) - .IsSmaller(GearshiftParams.UpshiftMinAcceleration)) { - return currentGear; - } - nextGear = Gears.Successor(currentGear); - } - - return nextGear; - } - - protected virtual GearshiftPosition CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response) - { - if ((absTime - _gearbox.LastUpshift).IsSmaller(GearshiftParams.DownshiftAfterUpshiftDelay)) { - return currentGear; - } - return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response); - } - - protected virtual GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1) - { - // upshift - if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { - currentGear = Gears.Successor(currentGear); - - while (SkipGears && Gears.HasSuccessor(currentGear)) { - currentGear = Gears.Successor(currentGear); - var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear); - - inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity; - inTorque = response.Clutch.PowerRequest / inAngularVelocity; - - var maxTorque = VectoMath.Min( - response.Engine.DynamicFullLoadPower / - ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2), - currentGear.Equals(Gears.First()) - ? double.MaxValue.SI<NewtonMeter>() - : GearboxModelData.Gears[currentGear.Gear].ShiftPolygon - .InterpolateDownshift(response.Engine.EngineSpeed)); - var reserve = 1 - inTorque.Value() / maxTorque.Value(); - - if (reserve >= 0 /*ModelData.TorqueReserve */ && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { - continue; - } - - currentGear = Gears.Predecessor(currentGear); - break; - } - } - - // early up shift to higher gear --------------------------------------- - if (EarlyShiftUp && Gears.HasSuccessor(currentGear)) { - currentGear = CheckEarlyUpshift(absTime, dt, outTorque, outAngularVelocity, currentGear, response1); - } - return currentGear; - } - - protected virtual GearshiftPosition CheckEarlyUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition currentGear, IResponse response1) - { - // try if next gear would provide enough torque reserve - var tryNextGear = Gears.Successor(currentGear); - var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear); - - var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity; - var inTorque = response.Clutch.PowerRequest / inAngularVelocity; - - // if next gear supplied enough power reserve: take it - // otherwise take - if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) { - var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; - - if (reserve >= GearshiftParams.TorqueReserve) { - currentGear = tryNextGear; - } - } - return currentGear; - } - - - protected virtual GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response) - { - // down shift - if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { - currentGear = Gears.Predecessor(currentGear); - //while (SkipGears && currentGear > 1) { - // currentGear--; - // var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear); - - // inAngularVelocity = ModelData.Gears[currentGear].Ratio * outAngularVelocity; - // inTorque = response.ClutchPowerRequest / inAngularVelocity; - // var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2), - // currentGear > 1 - // ? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed) - // : double.MaxValue.SI<NewtonMeter>()); - // var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value(); - // if (reserve >= ModelData.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { - // continue; - // } - // currentGear++; - // break; - //} - } - return currentGear; - } - - protected virtual ResponseDryRun RequestDryRunWithGear( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition tryNextGear) - { - var tmpGear = Gearbox.Gear; - _gearbox.Gear = tryNextGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - return response; - } - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2019 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +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.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class AMTShiftStrategyPolygonCalculator : IShiftPolygonCalculator + { + public ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, + CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + { + return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon( + i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); + } + } + + /// <summary> + /// AMTShiftStrategy implements the AMT Shifting Behaviour. + /// </summary> + public class AMTShiftStrategy : ShiftStrategy + { + //protected readonly GearshiftPosition MaxStartGear; + protected GearshiftPosition _nextGear; + private GearshiftPosition DesiredGearRoadsweeping; + private readonly IShiftPolygonCalculator _shiftPolygonCalculator; + + public AMTShiftStrategy(IVehicleContainer dataBus) : base(dataBus) + { + var runData = dataBus.RunData; + EarlyShiftUp = true; + SkipGears = true; + if (runData.EngineData == null) { + return; + } + + _shiftPolygonCalculator = ShiftPolygonCalculator.Create(Name, null); + var transmissionRatio = runData.AxleGearData.AxleGear.Ratio * + (runData.AngledriveData?.Angledrive.Ratio ?? 1.0) / + runData.VehicleData.DynamicTyreRadius; + var minEngineSpeed = (runData.EngineData.FullLoadCurves[0].RatedSpeed - runData.EngineData.IdleSpeed) * + Constants.SimulationSettings.ClutchClosingSpeedNorm + runData.EngineData.IdleSpeed; + + DesiredGearRoadsweeping = runData.DriverData?.PTODriveRoadsweepingGear; + + MaxStartGear = GearboxModelData.GearList.First(); + foreach (var gear in GearboxModelData.GearList.Reverse()) { + var gearData = GearboxModelData.Gears[gear.Gear]; + if (GearshiftParams.StartSpeed * transmissionRatio * gearData.Ratio > minEngineSpeed) { + MaxStartGear = gear; + break; + } + } + } + + private bool SpeedTooLowForEngine(GearshiftPosition gear, PerSecond outAngularSpeed) + { + return (outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsSmaller(DataBus.EngineInfo.EngineIdleSpeed); + } + + private bool SpeedTooHighForEngine(GearshiftPosition gear, PerSecond outAngularSpeed) + { + return + (outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed, + DataBus.EngineInfo.EngineN95hSpeed - 1.RPMtoRad())); + } + + public override GearshiftPosition NextGear => _nextGear; + + public override ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, + CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + { + return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType, + i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius, electricMotorData); + } + + public static string Name => "AMT - Classic"; + + public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear, outAngularVelocity)) { + _nextGear = Gears.Predecessor(_nextGear); + } + while (Gears.HasSuccessor(_nextGear) && SpeedTooHighForEngine(_nextGear, outAngularVelocity)) { + _nextGear = Gears.Successor(_nextGear); + } + + return _nextGear; + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) {} + + public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { + return InitStartGear(absTime, outTorque, outAngularVelocity); + } + + foreach (var gear in Gears.Reverse()) { + var selected = gear; + var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); + + var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio; + var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; + var inTorque = response.Clutch.PowerRequest / inAngularSpeed; + + // if in shift curve and torque reserve is provided: return the current gear + if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && + reserve >= GearshiftParams.StartTorqueReserve) { + if ((inAngularSpeed - DataBus.EngineInfo.EngineIdleSpeed) / (DataBus.EngineInfo.EngineRatedSpeed - DataBus.EngineInfo.EngineIdleSpeed) < + Constants.SimulationSettings.ClutchClosingSpeedNorm && Gears.HasPredecessor(gear)) { + selected = Gears.Predecessor(gear); + } + _nextGear = selected; + return selected; + } + + // if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve) + if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && Gears.HasSuccessor(gear)) { + selected = Gears.Successor(gear); + _nextGear = selected; + return selected; + } + } + + // fallback: return first gear + _nextGear = Gears.First(); + return _nextGear; + } + + private GearshiftPosition InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + foreach (var gear in Gears.IterateGears(MaxStartGear, Gears.First())) { + var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio; + + var ratedSpeed = DataBus.EngineInfo.EngineRatedSpeed; + if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) { + continue; + } + + var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity); + + var fullLoadPower = response.Engine.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; + + if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineIdleSpeed && reserve >= GearshiftParams.StartTorqueReserve) { + _nextGear = gear; + return gear; + } + } + _nextGear = Gears.First(); + return _nextGear; + } + + protected override bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, + Second lastShiftTime, IResponse response) + { + // no shift when vehicle stands + if (DataBus.VehicleInfo.VehicleStopped) { + return false; + } + + // emergency shift to not stall the engine ------------------------ + if (Gears.First().Equals(gear) && + SpeedTooLowForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) { + return true; + } + + _nextGear = gear; + while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear, + inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) { + _nextGear = Gears.Predecessor(_nextGear); + } + + while (Gears.HasSuccessor(_nextGear) && + SpeedTooHighForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) { + _nextGear = Gears.Successor(_nextGear); + } + + if (!_nextGear.Equals(gear)) { + return true; + } + + // PTO Active while drive (roadsweeping) shift rules + if (DataBus.DrivingCycleInfo.CycleData.LeftSample.PTOActive == PTOActivity.PTOActivityRoadSweeping) { + if (gear.Equals(DesiredGearRoadsweeping)) { + return false; + } + + if (gear > DesiredGearRoadsweeping) { + if (IsAboveDownShiftCurve(DesiredGearRoadsweeping, inTorque, inAngularVelocity)) { + _nextGear = DesiredGearRoadsweeping; + return true; + } + } + + if (gear < DesiredGearRoadsweeping) { + if (!SpeedTooHighForEngine( + DesiredGearRoadsweeping, inAngularVelocity / GearboxModelData.Gears[DesiredGearRoadsweeping.Gear].Ratio)) { + _nextGear = DesiredGearRoadsweeping; + return true; + } + } + } + + // normal shift when all requirements are fullfilled ------------------ + var minimumShiftTimePassed = + (lastShiftTime + GearshiftParams.TimeBetweenGearshifts).IsSmallerOrEqual(absTime); + if (!minimumShiftTimePassed) { + return false; + } + + _nextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + response); + if (!_nextGear.Equals(gear)) { + return true; + } + + _nextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + response); + + return !_nextGear.Equals(gear); + } + + protected virtual GearshiftPosition CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response) + { + // if the driver's intention is _not_ to accelerate or drive along then don't upshift + if (DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Driving) { + return currentGear; + } + if ((absTime - _gearbox.LastDownshift).IsSmaller(GearshiftParams.UpshiftAfterDownshiftDelay)) { + return currentGear; + } + var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response); + if (nextGear.Equals(currentGear)) { + return nextGear; + } + + // estimate acceleration for selected gear + if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(GearshiftParams.UpshiftMinAcceleration)) { + // if less than 0.1 for next gear, don't shift + if (nextGear.Gear - currentGear.Gear == 1) { + return currentGear; + } + // if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift! + if (nextGear.Gear > currentGear.Gear && + EstimateAccelerationForGear(Gears.Successor(currentGear), outAngularVelocity) + .IsSmaller(GearshiftParams.UpshiftMinAcceleration)) { + return currentGear; + } + nextGear = Gears.Successor(currentGear); + } + + return nextGear; + } + + protected virtual GearshiftPosition CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response) + { + if ((absTime - _gearbox.LastUpshift).IsSmaller(GearshiftParams.DownshiftAfterUpshiftDelay)) { + return currentGear; + } + return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response); + } + + protected virtual GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1) + { + // upshift + if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { + currentGear = Gears.Successor(currentGear); + + while (SkipGears && Gears.HasSuccessor(currentGear)) { + currentGear = Gears.Successor(currentGear); + var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear); + + inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity; + inTorque = response.Clutch.PowerRequest / inAngularVelocity; + + var maxTorque = VectoMath.Min( + response.Engine.DynamicFullLoadPower / + ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2), + currentGear.Equals(Gears.First()) + ? double.MaxValue.SI<NewtonMeter>() + : GearboxModelData.Gears[currentGear.Gear].ShiftPolygon + .InterpolateDownshift(response.Engine.EngineSpeed)); + var reserve = 1 - inTorque.Value() / maxTorque.Value(); + + if (reserve >= 0 /*ModelData.TorqueReserve */ && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + continue; + } + + currentGear = Gears.Predecessor(currentGear); + break; + } + } + + // early up shift to higher gear --------------------------------------- + if (EarlyShiftUp && Gears.HasSuccessor(currentGear)) { + currentGear = CheckEarlyUpshift(absTime, dt, outTorque, outAngularVelocity, currentGear, response1); + } + return currentGear; + } + + protected virtual GearshiftPosition CheckEarlyUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition currentGear, IResponse response1) + { + // try if next gear would provide enough torque reserve + var tryNextGear = Gears.Successor(currentGear); + var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear); + + var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity; + var inTorque = response.Clutch.PowerRequest / inAngularVelocity; + + // if next gear supplied enough power reserve: take it + // otherwise take + if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) { + var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; + + if (reserve >= GearshiftParams.TorqueReserve) { + currentGear = tryNextGear; + } + } + return currentGear; + } + + + protected virtual GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response) + { + // down shift + if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + currentGear = Gears.Predecessor(currentGear); + //while (SkipGears && currentGear > 1) { + // currentGear--; + // var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear); + + // inAngularVelocity = ModelData.Gears[currentGear].Ratio * outAngularVelocity; + // inTorque = response.ClutchPowerRequest / inAngularVelocity; + // var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2), + // currentGear > 1 + // ? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed) + // : double.MaxValue.SI<NewtonMeter>()); + // var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value(); + // if (reserve >= ModelData.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { + // continue; + // } + // currentGear++; + // break; + //} + } + return currentGear; + } + + protected virtual ResponseDryRun RequestDryRunWithGear( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition tryNextGear) + { + var tmpGear = Gearbox.Gear; + _gearbox.Gear = tryNextGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + return response; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs similarity index 86% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs index d63082eec148f69c0e9137a1cbfc32ed6a05a388..dc0ccc21193d1a3741de367230b19c1578d8d4fd 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs @@ -13,15 +13,28 @@ using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies; using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { + public class AMTShiftStrategyOptimizedPolygonCalculator : IShiftPolygonCalculator + { + public ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, + CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + { + return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon( + i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); + } + } public class AMTShiftStrategyOptimized : AMTShiftStrategy { + + private List<CombustionEngineFuelData> fcMap; private Dictionary<uint, EngineFullLoadCurve> fld; - private ShiftStrategyParameters shiftStrategyParameters; + private ShiftStrategyParameters _shiftStrategyParameters; private SimplePowertrainContainer TestContainer; private Gearbox TestContainerGbx; @@ -29,9 +42,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl //private AccelerationCurveData accCurve; private Kilogram vehicleMass; - + private readonly IShiftPolygonCalculator _shiftPolygonCalculator; - public AMTShiftStrategyOptimized(IVehicleContainer dataBus) : base(dataBus) { @@ -42,18 +54,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl fcMap = runData.EngineData.Fuels; fld = runData.EngineData.FullLoadCurves; - shiftStrategyParameters = runData.GearshiftParameters; + _shiftStrategyParameters = runData.GearshiftParameters; + _shiftPolygonCalculator = ShiftPolygonCalculator.Create(Name, _shiftStrategyParameters); //accCurve = runData.DriverData.AccelerationCurve; vehicleMass = runData.VehicleData.TotalVehicleMass; - if (shiftStrategyParameters == null) { + if (_shiftStrategyParameters == null) { throw new VectoException("Parameters for shift strategy missing!"); } SetupVelocityDropPreprocessor(dataBus); - if (shiftStrategyParameters.AllowedGearRangeFC > 2 || shiftStrategyParameters.AllowedGearRangeFC < 1) { + 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); + _shiftStrategyParameters.AllowedGearRangeFC = _shiftStrategyParameters.AllowedGearRangeFC.LimitTo(1, 2); } } @@ -101,17 +114,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift; - var vehicleSpeedPostShift = DataBus.VehicleInfo.VehicleSpeed - vDrop * shiftStrategyParameters.VelocityDropFactor; + var vehicleSpeedPostShift = DataBus.VehicleInfo.VehicleSpeed - vDrop * _shiftStrategyParameters.VelocityDropFactor; var totalTransmissionRatio = DataBus.EngineInfo.EngineSpeed / DataBus.VehicleInfo.VehicleSpeed; //for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) { foreach (var tryNextGear in Gears.IterateGears(Gears.Successor(currentGear), - Gears.Successor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) { + Gears.Successor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) { //var tryNextGear = (uint)(currentGear.Gear + i); if (tryNextGear == null || - !(GearboxModelData.Gears[tryNextGear.Gear].Ratio < shiftStrategyParameters.RatioEarlyUpshiftFC)) { + !(GearboxModelData.Gears[tryNextGear.Gear].Ratio < _shiftStrategyParameters.RatioEarlyUpshiftFC)) { continue; } @@ -132,7 +145,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var estimatedEngineSpeed = vehicleSpeedPostShift * (totalTransmissionRatio / GearboxModelData.Gears[currentGear.Gear].Ratio * GearboxModelData.Gears[tryNextGear.Gear].Ratio); - if (estimatedEngineSpeed.IsSmaller(shiftStrategyParameters.MinEngineSpeedPostUpshift)) { + if (estimatedEngineSpeed.IsSmaller(_shiftStrategyParameters.MinEngineSpeedPostUpshift)) { continue; } @@ -153,7 +166,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var accelerationFactor = outAngularVelocity * GearboxModelData.Gears[currentGear.Gear].Ratio < fld[0].NTq98hSpeed ? 1.0 : VectoMath.Interpolate( - fld[0].NTq98hSpeed, fld[0].NP98hSpeed, 1.0, shiftStrategyParameters.AccelerationFactor, + fld[0].NTq98hSpeed, fld[0].NP98hSpeed, 1.0, _shiftStrategyParameters.AccelerationFactor, outAngularVelocity * GearboxModelData.Gears[currentGear.Gear].Ratio); if (accelerationFactor.IsEqual(1, 1e-9)) { continue; @@ -188,7 +201,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fcNext = GetFCRating(response.Engine.EngineSpeed, tqNext); if (reserve < GearshiftParams.TorqueReserve || - !fcNext.IsSmaller(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear) || !fcNext.IsSmaller(minFc)) { + !fcNext.IsSmaller(fcCurrent * _shiftStrategyParameters.RatingFactorCurrentGear) || !fcNext.IsSmaller(minFc)) { continue; } @@ -253,10 +266,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl //for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) { foreach (var tryNextGear in Gears.IterateGears(Gears.Predecessor(currentGear), - Gears.Predecessor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) { + Gears.Predecessor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) { //var tryNextGear = (uint)(currentGear.Gear - i); - if (tryNextGear == null || !(GearboxModelData.Gears[tryNextGear.Gear].Ratio <= shiftStrategyParameters.RatioEarlyDownshiftFC)) { + if (tryNextGear == null || !(GearboxModelData.Gears[tryNextGear.Gear].Ratio <= _shiftStrategyParameters.RatioEarlyDownshiftFC)) { continue; } @@ -283,7 +296,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl fld[tryNextGear.Gear].DragLoadStationaryTorque(response.Engine.EngineSpeed), fld[tryNextGear.Gear].FullLoadStationaryTorque(response.Engine.EngineSpeed))); - if (!fcNext.IsSmaller(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear) || + if (!fcNext.IsSmaller(fcCurrent * _shiftStrategyParameters.RatingFactorCurrentGear) || !fcNext.IsSmaller(minFc)) { continue; } @@ -338,8 +351,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) { - return DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon( - i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); + return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType, i, engineDataFullLoadCurve, + gearboxGears, + engineData, axlegearRatio, dynamicTyreRadius, electricMotorData); } #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/APTNShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/APTNShiftStrategy.cs similarity index 96% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/APTNShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/APTNShiftStrategy.cs index ed2c50526f16e5319ecf01a5efbd3bcc161196fe..b449fe794b3f01f412412075a59b100c0f66bc64 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/APTNShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/APTNShiftStrategy.cs @@ -2,7 +2,7 @@ using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Simulation; -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies { public class APTNShiftStrategy : PEVAMTShiftStrategy { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategy.cs similarity index 96% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategy.cs index d1af4f8622f3d4e9e00518318b62880475a2627f..b69ee812549a5e691783d451ddc4d3dac81b8929 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategy.cs @@ -1,549 +1,562 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2019 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class ATShiftStrategy : BaseShiftStrategy - { - protected ATGearbox _gearbox; - protected readonly NextGearState _nextGear = new NextGearState(); - private KilogramSquareMeter EngineInertia; - - public override IGearbox Gearbox - { - get => _gearbox; - set { - _gearbox = value as ATGearbox; - if (_gearbox == null) { - throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType()); - } - } - } - - public override GearshiftPosition NextGear => _nextGear.Gear; - - public override ShiftPolygon ComputeDeclarationShiftPolygon( - GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, - IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, - Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) - { - return DeclarationData.TorqueConverter.ComputeShiftPolygon( - engineDataFullLoadCurve, i == 0, i >= gearboxGears.Count - 1); - } - - public static string Name => "AT - Classic"; - - public ATShiftStrategy(IVehicleContainer dataBus) : base(dataBus) - { - EngineInertia = dataBus.RunData.EngineData?.Inertia ?? 0.SI<KilogramSquareMeter>(); - - if (Gears.Any(x => !x.TorqueConverterLocked.HasValue)) { - throw new VectoException("Gear list must have TC info for all gears! {0}", Gears.Join()); - } - - MaxStartGear = Gears.Any() ? Gears.First() : new GearshiftPosition(0); - } - - public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) - { - if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { - // AT always starts in first gear and TC active! - _gearbox.Disengaged = true; - return Gears.First(); - } - - foreach (var gear in Gears.Reverse()) { - var response = _gearbox.Initialize(gear, torque, outAngularVelocity); - - if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineRatedSpeed || response.Engine.EngineSpeed < DataBus.EngineInfo.EngineIdleSpeed) { - continue; - } - - if (!IsBelowDownShiftCurve(gear, response.Engine.PowerRequest / response.Engine.EngineSpeed, response.Engine.EngineSpeed)) { - _gearbox.Disengaged = false; - return gear; - } - } - - // fallback: start with first gear; - _gearbox.Disengaged = false; - return Gears.First(); - } - - public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) { - //_gearbox.Gear = _nextGear.Gear; - _gearbox.Disengaged = _nextGear.Disengaged; - _nextGear.AbsTime = null; - return _nextGear.Gear; - } - - _nextGear.AbsTime = null; - return _gearbox.Gear; - } - - public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - throw new System.NotImplementedException("AT Shift Strategy does not support disengaging."); - } - - protected override bool DoCheckShiftRequired( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) - { - // ENGAGE --------------------------------------------------------- - // 0 -> 1C: drive off after disengaged - engage first gear - if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) { - Log.Debug("shift required: drive off after vehicle stopped"); - _nextGear.SetState(absTime, disengaged: false, gear: Gears.First()); - return true; - } - - // DISENGAGE ------------------------------------------------------ - // 1) _ -> 0: disengage before halting - var braking = DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking; - var torqueNegative = outTorque.IsSmaller(0); - var slowerThanDisengageSpeed = - DataBus.VehicleInfo.VehicleSpeed.IsSmaller(GearboxModelData.DisengageWhenHaltingSpeed); - var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed; - - // 2) L -> 0: disengage if inAngularVelocity == 0 - var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>()); - - // 3) 1C -> 0: disengange when negative T_out and positive T_in - var gear1C = Gears.First().Equals(gear); - var disengageTOutNegativeAndTInPositive = DataBus.DriverInfo.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) && - inTorque.IsGreater(0); - - var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C && - inAngularVelocity.IsSmallerOrEqual(DataBus.EngineInfo.EngineIdleSpeed); - - if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero || - disengageTOutNegativeAndTInPositive) { - _nextGear.SetState(absTime, disengaged: true, gear: Gears.First()); - return true; - } - - // EMERGENCY SHIFTS --------------------------------------- - if (CheckEmergencyShift(absTime, outTorque, outAngularVelocity, inAngularVelocity, gear)) { - return true; - } - - // UPSHIFT -------------------------------------------------------- - if (CheckUpshift( - absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, - lastShiftTime, response)) { - return true; - } - - // DOWNSHIFT ------------------------------------------------------ - if (CheckDownshift( - absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, - lastShiftTime, response)) { - return true; - } - - return false; - } - - protected virtual bool CheckEmergencyShift( - Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, PerSecond inAngularVelocity, GearshiftPosition gear) - { - // Emergency Downshift: if lower than engine idle speed - if (inAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed) && Gears.HasPredecessor(gear)) { - Log.Debug("engine speed would fall below idle speed - shift down"); - Downshift(absTime, gear); - return true; - } - - // Emergency Upshift: if higher than engine rated speed - if (inAngularVelocity.IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed, DataBus.EngineInfo.EngineN95hSpeed))) { - // check if upshift is possible - if (!Gears.HasSuccessor(gear)) { - return false; - } - - PerSecond nextInAngularSpeed; - NewtonMeter nextInTorque; - if (GearboxModelData.Gears[gear.Gear].HasLockedGear) { - nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio; - nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear].Ratio; - } else { - nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear + 1].Ratio; - nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear + 1].Ratio; - } - - var nextGear = Gears.Successor(gear); - var acc = EstimateAccelerationForGear(nextGear, outAngularVelocity); - if ((acc > 0 || _gearbox.TCLocked) && !IsBelowDownShiftCurve(nextGear, nextInTorque, nextInAngularSpeed)) { - Log.Debug("engine speed would be above max speed / rated speed - shift up"); - Upshift(absTime, gear); - return true; - } - } - - return false; - } - - [SuppressMessage("ReSharper", "UnusedParameter.Local")] - protected virtual bool CheckUpshift( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) - { - var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts); - if (!shiftTimeReached) { - return false; - } - - var currentGear = GearboxModelData.Gears[gear.Gear]; - - if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) { - var result = CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear); - if (result.HasValue) { - return result.Value; - } - } - - // UPSHIFT - Special rule for 1C -> 2C - var nextGear = Gears.Successor(gear); - if (!gear.TorqueConverterLocked.Value && nextGear != null && !nextGear.TorqueConverterLocked.Value && outAngularVelocity.IsGreater(0)) { - var result = CheckUpshiftTcTc( - absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, currentGear, response); - if (result.HasValue) { - return result.Value; - } - } - - if (Gears.HasSuccessor(gear)) { - var earlyUpshift = CheckEarlyUpshift( - absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); - if (earlyUpshift.HasValue) { - return earlyUpshift.Value; - } - } - - return false; - } - - protected virtual bool? CheckEarlyUpshift( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) - { - return null; - } - - protected virtual bool? CheckUpshiftTcTc( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear, GearData currentGear, IResponse response) - { - // C -> C+1 - var nextGearPos = Gears.Successor(gear); // GearboxModelData.Gears[gear + 1]; - var nextGear = GearboxModelData.Gears[nextGearPos.Gear]; - var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; - var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineInfo.EngineN80hSpeed - 150.RPMtoRad())); - - var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; - var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; - var shiftLosses = _gearbox.ComputeShiftLosses(outTorque, outAngularVelocity, nextGearPos) / - GearboxModelData.PowershiftShiftTime / nextGearboxInSpeed; - nextGearboxInTorque += shiftLosses; - var tcOperatingPoint = - _gearbox.TorqueConverter.FindOperatingPoint(absTime, dt, nextGearboxInTorque, nextGearboxInSpeed); - - var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); - var avgSpeed = (DataBus.EngineInfo.EngineSpeed + tcOperatingPoint.InAngularVelocity) / 2; - var engineMaxTorque = DataBus.EngineInfo.EngineStationaryFullPower(avgSpeed) / avgSpeed; - var engineInertiaTorque = Formulas.InertiaPower( - DataBus.EngineInfo.EngineSpeed, tcOperatingPoint.InAngularVelocity, _gearbox.EngineInertia, dt) / avgSpeed; - var engineTorqueBelowMax = - tcOperatingPoint.InTorque.IsSmallerOrEqual(engineMaxTorque - engineInertiaTorque); - - var reachableAcceleration = - EstimateAcceleration( - outAngularVelocity, outTorque, inAngularVelocity, inTorque, gear.Gear, response); // EstimateAccelerationForGear(gear + 1, outAngularVelocity); - var minAcceleration = VectoMath.Min( - GearboxModelData.TorqueConverterData.CCUpshiftMinAcceleration, - DataBus.DriverInfo.DriverAcceleration); - var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); - - if (engineSpeedOverMin && engineTorqueBelowMax && minAccelerationReachable) { - Upshift(absTime, gear); - return true; - } - - return null; - } - - protected virtual bool? CheckUpshiftToLocked( - Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear) - { - // UPSHIFT - General Rule - // L -> L+1 - // C -> L - var nextGear = Gears.Successor(gear); // _gearbox.TorqueConverterLocked ? gear + 1 : gear; - if (nextGear == null || !GearboxModelData.Gears.ContainsKey(nextGear.Gear)) { - return false; - } - - var nextEngineSpeed = outAngularVelocity * GearboxModelData.Gears[nextGear.Gear].Ratio; - if (nextEngineSpeed.IsEqual(0)) { - return false; - } - - var currentEnginePower = inTorque * inAngularVelocity; - var nextEngineTorque = currentEnginePower / nextEngineSpeed; - var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked); - - var minAccelerationReachable = true; - if (DataBus.DriverInfo.DriverAcceleration.IsSmaller(0)) { - return null; - } - if (!DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { - var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity); - var minAcceleration = _gearbox.TorqueConverterLocked - ? GearshiftParams.UpshiftMinAcceleration - : GearboxModelData.TorqueConverterData.CLUpshiftMinAcceleration; - minAcceleration = VectoMath.Min( - minAcceleration, VectoMath.Max(0.SI<MeterPerSquareSecond>(), DataBus.DriverInfo.DriverAcceleration)); - minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); - } - - if (isAboveUpShift && minAccelerationReachable) { - Upshift(absTime, gear); - return true; - } - - return null; - } - - /// <summary> - /// Tests if the operating point is above (right of) the up-shift curve. - /// </summary> - /// <param name="gear">The gear.</param> - /// <param name="inTorque">The in torque.</param> - /// <param name="inEngineSpeed">The in engine speed.</param> - /// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param> - /// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns> - protected virtual bool IsAboveUpShiftCurve( - GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed, - bool torqueConverterLocked) - { - var shiftPolygon = torqueConverterLocked - ? GearboxModelData.Gears[gear.Gear].ShiftPolygon - : GearboxModelData.Gears[gear.Gear].TorqueConverterShiftPolygon; - - return Gears.HasSuccessor(gear) && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed); - } - - protected virtual void Upshift(Second absTime, GearshiftPosition gear) - { - if (!Gears.HasSuccessor(gear)) { - throw new VectoSimulationException( - "ShiftStrategy wanted to shift up but no higher gear available."); - } - - _nextGear.SetState(absTime, false, Gears.Successor(gear)); - - } - - [SuppressMessage("ReSharper", "UnusedParameter.Local")] - protected virtual bool CheckDownshift( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) - { - var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts); - - if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) { - Downshift(absTime, gear); - return true; - } - - if (shiftTimeReached && DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate) { - if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() && - DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) { - var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - if (_gearbox.Gear > Gears.First()) { - // clone current state of _nextgear, set gearbox state to lower gear, issue request, restore old gearbox state - var tmp = _nextGear.Clone(); - var gbxState = new NextGearState(absTime, _gearbox); - tmp.Gear = Gears.Predecessor(_gearbox.Gear); - SetGear(tmp); - var tmpResponseDs = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - SetGear(gbxState); - // done - if (tmpResponseDs.DeltaFullLoad - Formulas.InertiaPower( - tmpResponseDs.Engine.EngineSpeed, DataBus.EngineInfo.EngineSpeed, EngineInertia, dt) < tmpResponseCurr.DeltaFullLoad) { - Downshift(absTime, gear); - return true; - } - } - } - } - - if (shiftTimeReached && gear > Gears.First()) { - var earlyDownshift = CheckEarlyDownshift( - absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); - if (earlyDownshift.HasValue) { - return earlyDownshift.Value; - } - } - - return false; - } - - protected virtual bool? CheckEarlyDownshift( - Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, - PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) - { - return null; - } - - protected virtual void SetGear(NextGearState gbxState) - { - _gearbox.Gear = gbxState.Gear; - //_gearbox.TorqueConverterLocked = gbxState.TorqueConverterLocked; - _gearbox.Disengaged = gbxState.Disengaged; - } - - /// <summary> - /// Tests if the operating point is below (left of) the down-shift curve. - /// </summary> - /// <param name="gear">The gear.</param> - /// <param name="inTorque">The in torque.</param> - /// <param name="inEngineSpeed">The in engine speed.</param> - /// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns> - protected virtual bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) - { - return !Gears.First().Equals(gear) && GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed); - } - - protected virtual void Downshift(Second absTime, GearshiftPosition gear) - { - if (!Gears.HasPredecessor(gear)) { - throw new VectoSimulationException( - "ShiftStrategy wanted to shift down but no lower gear available."); - } - _nextGear.SetState(absTime, false, Gears.Predecessor(gear)); - } - - protected MeterPerSquareSecond EstimateAcceleration( - PerSecond gbxOutSpeed, NewtonMeter gbxOutTorque, PerSecond tcInSpeed, NewtonMeter tcInTorque, uint currentGear, IResponse response) - { - var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed; - var avgSlope = - ((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude - - DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>(); - - var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed; - var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; - - var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; - var axleLoss = DataBus.AxlegearInfo.AxlegearLoss(); - - var tcLossesCurrentGear = tcInSpeed * tcInTorque - gbxOutSpeed * gbxOutTorque; - - var nextTcOutSpeed = gbxOutSpeed * GearboxModelData.Gears[currentGear + 1].TorqueConverterRatio; - - var tcNext = GearboxModelData.TorqueConverterData.LookupOperatingPointOut( - nextTcOutSpeed, response.Engine.EngineSpeed, response.Engine.TorqueOutDemand); - var tcLossesNextGear = tcNext.InAngularVelocity * tcNext.InTorque - tcNext.OutAngularVelocity * tcNext.OutTorque; - var deltaTcLosses = tcLossesNextGear - tcLossesCurrentGear; - - var accelerationPower = gbxOutSpeed * gbxOutTorque - deltaTcLosses - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss; - - var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels); - - return acceleration.Cast<MeterPerSquareSecond>(); - } - - protected class NextGearState - { - public Second AbsTime { get; internal set; } - public bool Disengaged { get; private set; } - public GearshiftPosition Gear { get; internal set; } - - public NextGearState() - { - Gear = new GearshiftPosition(0); - } - - private NextGearState(NextGearState nextGearState) - { - AbsTime = nextGearState.AbsTime; - Disengaged = nextGearState.Disengaged; - Gear = nextGearState.Gear; - } - - public NextGearState(Second absTime, ATGearbox gearbox) - { - SetState(absTime, gearbox); - } - - public void SetState(Second absTime, bool disengaged, GearshiftPosition gear) - { - AbsTime = absTime; - Disengaged = disengaged; - Gear = gear; - } - - public void SetState(Second absTime, ATGearbox gearbox) - { - AbsTime = absTime; - Disengaged = gearbox.Disengaged; - Gear = gearbox.Gear; - } - - public NextGearState Clone() - { - return new NextGearState(this); - } - } - } -} +/* +* This file is part of VECTO. +* +* Copyright © 2012-2019 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies +{ + public class ATShiftStrategyPolygonCalculator : IShiftPolygonCalculator + { + public ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, + Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + { + return DeclarationData.TorqueConverter.ComputeShiftPolygon( + engineDataFullLoadCurve, i == 0, i >= gearboxGears.Count - 1); + } + } + + public class ATShiftStrategy : BaseShiftStrategy + { + protected ATGearbox _gearbox; + protected readonly NextGearState _nextGear = new NextGearState(); + private KilogramSquareMeter EngineInertia; + private IShiftPolygonCalculator _shiftPolygonCalculator; + + public override IGearbox Gearbox + { + get => _gearbox; + set { + _gearbox = value as ATGearbox; + if (_gearbox == null) { + throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType()); + } + } + } + + public override GearshiftPosition NextGear => _nextGear.Gear; + + public override ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, + Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + { + return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType, i, engineDataFullLoadCurve, + gearboxGears, engineData, axlegearRatio, dynamicTyreRadius, electricMotorData); + } + + public static string Name => "AT - Classic"; + + public ATShiftStrategy(IVehicleContainer dataBus) : base(dataBus) + { + EngineInertia = dataBus.RunData.EngineData?.Inertia ?? 0.SI<KilogramSquareMeter>(); + ShiftPolygonCalculator.Create(Name, null); + if (Gears.Any(x => !x.TorqueConverterLocked.HasValue)) { + throw new VectoException("Gear list must have TC info for all gears! {0}", Gears.Join()); + } + + MaxStartGear = Gears.Any() ? Gears.First() : new GearshiftPosition(0); + } + + public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) + { + if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { + // AT always starts in first gear and TC active! + _gearbox.Disengaged = true; + return Gears.First(); + } + + foreach (var gear in Gears.Reverse()) { + var response = _gearbox.Initialize(gear, torque, outAngularVelocity); + + if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineRatedSpeed || response.Engine.EngineSpeed < DataBus.EngineInfo.EngineIdleSpeed) { + continue; + } + + if (!IsBelowDownShiftCurve(gear, response.Engine.PowerRequest / response.Engine.EngineSpeed, response.Engine.EngineSpeed)) { + _gearbox.Disengaged = false; + return gear; + } + } + + // fallback: start with first gear; + _gearbox.Disengaged = false; + return Gears.First(); + } + + public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) { + //_gearbox.Gear = _nextGear.Gear; + _gearbox.Disengaged = _nextGear.Disengaged; + _nextGear.AbsTime = null; + return _nextGear.Gear; + } + + _nextGear.AbsTime = null; + return _gearbox.Gear; + } + + public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + throw new System.NotImplementedException("AT Shift Strategy does not support disengaging."); + } + + protected override bool DoCheckShiftRequired( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) + { + // ENGAGE --------------------------------------------------------- + // 0 -> 1C: drive off after disengaged - engage first gear + if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) { + Log.Debug("shift required: drive off after vehicle stopped"); + _nextGear.SetState(absTime, disengaged: false, gear: Gears.First()); + return true; + } + + // DISENGAGE ------------------------------------------------------ + // 1) _ -> 0: disengage before halting + var braking = DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking; + var torqueNegative = outTorque.IsSmaller(0); + var slowerThanDisengageSpeed = + DataBus.VehicleInfo.VehicleSpeed.IsSmaller(GearboxModelData.DisengageWhenHaltingSpeed); + var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed; + + // 2) L -> 0: disengage if inAngularVelocity == 0 + var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>()); + + // 3) 1C -> 0: disengange when negative T_out and positive T_in + var gear1C = Gears.First().Equals(gear); + var disengageTOutNegativeAndTInPositive = DataBus.DriverInfo.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) && + inTorque.IsGreater(0); + + var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C && + inAngularVelocity.IsSmallerOrEqual(DataBus.EngineInfo.EngineIdleSpeed); + + if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero || + disengageTOutNegativeAndTInPositive) { + _nextGear.SetState(absTime, disengaged: true, gear: Gears.First()); + return true; + } + + // EMERGENCY SHIFTS --------------------------------------- + if (CheckEmergencyShift(absTime, outTorque, outAngularVelocity, inAngularVelocity, gear)) { + return true; + } + + // UPSHIFT -------------------------------------------------------- + if (CheckUpshift( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + lastShiftTime, response)) { + return true; + } + + // DOWNSHIFT ------------------------------------------------------ + if (CheckDownshift( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + lastShiftTime, response)) { + return true; + } + + return false; + } + + protected virtual bool CheckEmergencyShift( + Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, PerSecond inAngularVelocity, GearshiftPosition gear) + { + // Emergency Downshift: if lower than engine idle speed + if (inAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed) && Gears.HasPredecessor(gear)) { + Log.Debug("engine speed would fall below idle speed - shift down"); + Downshift(absTime, gear); + return true; + } + + // Emergency Upshift: if higher than engine rated speed + if (inAngularVelocity.IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed, DataBus.EngineInfo.EngineN95hSpeed))) { + // check if upshift is possible + if (!Gears.HasSuccessor(gear)) { + return false; + } + + PerSecond nextInAngularSpeed; + NewtonMeter nextInTorque; + if (GearboxModelData.Gears[gear.Gear].HasLockedGear) { + nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio; + nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear].Ratio; + } else { + nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear + 1].Ratio; + nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear + 1].Ratio; + } + + var nextGear = Gears.Successor(gear); + var acc = EstimateAccelerationForGear(nextGear, outAngularVelocity); + if ((acc > 0 || _gearbox.TCLocked) && !IsBelowDownShiftCurve(nextGear, nextInTorque, nextInAngularSpeed)) { + Log.Debug("engine speed would be above max speed / rated speed - shift up"); + Upshift(absTime, gear); + return true; + } + } + + return false; + } + + [SuppressMessage("ReSharper", "UnusedParameter.Local")] + protected virtual bool CheckUpshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) + { + var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts); + if (!shiftTimeReached) { + return false; + } + + var currentGear = GearboxModelData.Gears[gear.Gear]; + + if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) { + var result = CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear); + if (result.HasValue) { + return result.Value; + } + } + + // UPSHIFT - Special rule for 1C -> 2C + var nextGear = Gears.Successor(gear); + if (!gear.TorqueConverterLocked.Value && nextGear != null && !nextGear.TorqueConverterLocked.Value && outAngularVelocity.IsGreater(0)) { + var result = CheckUpshiftTcTc( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, currentGear, response); + if (result.HasValue) { + return result.Value; + } + } + + if (Gears.HasSuccessor(gear)) { + var earlyUpshift = CheckEarlyUpshift( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); + if (earlyUpshift.HasValue) { + return earlyUpshift.Value; + } + } + + return false; + } + + protected virtual bool? CheckEarlyUpshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) + { + return null; + } + + protected virtual bool? CheckUpshiftTcTc( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear, GearData currentGear, IResponse response) + { + // C -> C+1 + var nextGearPos = Gears.Successor(gear); // GearboxModelData.Gears[gear + 1]; + var nextGear = GearboxModelData.Gears[nextGearPos.Gear]; + var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; + var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineInfo.EngineN80hSpeed - 150.RPMtoRad())); + + var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; + var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; + var shiftLosses = _gearbox.ComputeShiftLosses(outTorque, outAngularVelocity, nextGearPos) / + GearboxModelData.PowershiftShiftTime / nextGearboxInSpeed; + nextGearboxInTorque += shiftLosses; + var tcOperatingPoint = + _gearbox.TorqueConverter.FindOperatingPoint(absTime, dt, nextGearboxInTorque, nextGearboxInSpeed); + + var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); + var avgSpeed = (DataBus.EngineInfo.EngineSpeed + tcOperatingPoint.InAngularVelocity) / 2; + var engineMaxTorque = DataBus.EngineInfo.EngineStationaryFullPower(avgSpeed) / avgSpeed; + var engineInertiaTorque = Formulas.InertiaPower( + DataBus.EngineInfo.EngineSpeed, tcOperatingPoint.InAngularVelocity, _gearbox.EngineInertia, dt) / avgSpeed; + var engineTorqueBelowMax = + tcOperatingPoint.InTorque.IsSmallerOrEqual(engineMaxTorque - engineInertiaTorque); + + var reachableAcceleration = + EstimateAcceleration( + outAngularVelocity, outTorque, inAngularVelocity, inTorque, gear.Gear, response); // EstimateAccelerationForGear(gear + 1, outAngularVelocity); + var minAcceleration = VectoMath.Min( + GearboxModelData.TorqueConverterData.CCUpshiftMinAcceleration, + DataBus.DriverInfo.DriverAcceleration); + var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); + + if (engineSpeedOverMin && engineTorqueBelowMax && minAccelerationReachable) { + Upshift(absTime, gear); + return true; + } + + return null; + } + + protected virtual bool? CheckUpshiftToLocked( + Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear) + { + // UPSHIFT - General Rule + // L -> L+1 + // C -> L + var nextGear = Gears.Successor(gear); // _gearbox.TorqueConverterLocked ? gear + 1 : gear; + if (nextGear == null || !GearboxModelData.Gears.ContainsKey(nextGear.Gear)) { + return false; + } + + var nextEngineSpeed = outAngularVelocity * GearboxModelData.Gears[nextGear.Gear].Ratio; + if (nextEngineSpeed.IsEqual(0)) { + return false; + } + + var currentEnginePower = inTorque * inAngularVelocity; + var nextEngineTorque = currentEnginePower / nextEngineSpeed; + var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked); + + var minAccelerationReachable = true; + if (DataBus.DriverInfo.DriverAcceleration.IsSmaller(0)) { + return null; + } + if (!DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) { + var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity); + var minAcceleration = _gearbox.TorqueConverterLocked + ? GearshiftParams.UpshiftMinAcceleration + : GearboxModelData.TorqueConverterData.CLUpshiftMinAcceleration; + minAcceleration = VectoMath.Min( + minAcceleration, VectoMath.Max(0.SI<MeterPerSquareSecond>(), DataBus.DriverInfo.DriverAcceleration)); + minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); + } + + if (isAboveUpShift && minAccelerationReachable) { + Upshift(absTime, gear); + return true; + } + + return null; + } + + /// <summary> + /// Tests if the operating point is above (right of) the up-shift curve. + /// </summary> + /// <param name="gear">The gear.</param> + /// <param name="inTorque">The in torque.</param> + /// <param name="inEngineSpeed">The in engine speed.</param> + /// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param> + /// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns> + protected virtual bool IsAboveUpShiftCurve( + GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed, + bool torqueConverterLocked) + { + var shiftPolygon = torqueConverterLocked + ? GearboxModelData.Gears[gear.Gear].ShiftPolygon + : GearboxModelData.Gears[gear.Gear].TorqueConverterShiftPolygon; + + return Gears.HasSuccessor(gear) && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed); + } + + protected virtual void Upshift(Second absTime, GearshiftPosition gear) + { + if (!Gears.HasSuccessor(gear)) { + throw new VectoSimulationException( + "ShiftStrategy wanted to shift up but no higher gear available."); + } + + _nextGear.SetState(absTime, false, Gears.Successor(gear)); + + } + + [SuppressMessage("ReSharper", "UnusedParameter.Local")] + protected virtual bool CheckDownshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) + { + var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts); + + if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) { + Downshift(absTime, gear); + return true; + } + + if (shiftTimeReached && DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate) { + if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() && + DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) { + var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + if (_gearbox.Gear > Gears.First()) { + // clone current state of _nextgear, set gearbox state to lower gear, issue request, restore old gearbox state + var tmp = _nextGear.Clone(); + var gbxState = new NextGearState(absTime, _gearbox); + tmp.Gear = Gears.Predecessor(_gearbox.Gear); + SetGear(tmp); + var tmpResponseDs = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + SetGear(gbxState); + // done + if (tmpResponseDs.DeltaFullLoad - Formulas.InertiaPower( + tmpResponseDs.Engine.EngineSpeed, DataBus.EngineInfo.EngineSpeed, EngineInertia, dt) < tmpResponseCurr.DeltaFullLoad) { + Downshift(absTime, gear); + return true; + } + } + } + } + + if (shiftTimeReached && gear > Gears.First()) { + var earlyDownshift = CheckEarlyDownshift( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); + if (earlyDownshift.HasValue) { + return earlyDownshift.Value; + } + } + + return false; + } + + protected virtual bool? CheckEarlyDownshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response) + { + return null; + } + + protected virtual void SetGear(NextGearState gbxState) + { + _gearbox.Gear = gbxState.Gear; + //_gearbox.TorqueConverterLocked = gbxState.TorqueConverterLocked; + _gearbox.Disengaged = gbxState.Disengaged; + } + + /// <summary> + /// Tests if the operating point is below (left of) the down-shift curve. + /// </summary> + /// <param name="gear">The gear.</param> + /// <param name="inTorque">The in torque.</param> + /// <param name="inEngineSpeed">The in engine speed.</param> + /// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns> + protected virtual bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) + { + return !Gears.First().Equals(gear) && GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed); + } + + protected virtual void Downshift(Second absTime, GearshiftPosition gear) + { + if (!Gears.HasPredecessor(gear)) { + throw new VectoSimulationException( + "ShiftStrategy wanted to shift down but no lower gear available."); + } + _nextGear.SetState(absTime, false, Gears.Predecessor(gear)); + } + + protected MeterPerSquareSecond EstimateAcceleration( + PerSecond gbxOutSpeed, NewtonMeter gbxOutTorque, PerSecond tcInSpeed, NewtonMeter tcInTorque, uint currentGear, IResponse response) + { + var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed; + var avgSlope = + ((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude - + DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>(); + + var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed; + var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; + + var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; + var axleLoss = DataBus.AxlegearInfo.AxlegearLoss(); + + var tcLossesCurrentGear = tcInSpeed * tcInTorque - gbxOutSpeed * gbxOutTorque; + + var nextTcOutSpeed = gbxOutSpeed * GearboxModelData.Gears[currentGear + 1].TorqueConverterRatio; + + var tcNext = GearboxModelData.TorqueConverterData.LookupOperatingPointOut( + nextTcOutSpeed, response.Engine.EngineSpeed, response.Engine.TorqueOutDemand); + var tcLossesNextGear = tcNext.InAngularVelocity * tcNext.InTorque - tcNext.OutAngularVelocity * tcNext.OutTorque; + var deltaTcLosses = tcLossesNextGear - tcLossesCurrentGear; + + var accelerationPower = gbxOutSpeed * gbxOutTorque - deltaTcLosses - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss; + + var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels); + + return acceleration.Cast<MeterPerSquareSecond>(); + } + + protected class NextGearState + { + public Second AbsTime { get; internal set; } + public bool Disengaged { get; private set; } + public GearshiftPosition Gear { get; internal set; } + + public NextGearState() + { + Gear = new GearshiftPosition(0); + } + + private NextGearState(NextGearState nextGearState) + { + AbsTime = nextGearState.AbsTime; + Disengaged = nextGearState.Disengaged; + Gear = nextGearState.Gear; + } + + public NextGearState(Second absTime, ATGearbox gearbox) + { + SetState(absTime, gearbox); + } + + public void SetState(Second absTime, bool disengaged, GearshiftPosition gear) + { + AbsTime = absTime; + Disengaged = disengaged; + Gear = gear; + } + + public void SetState(Second absTime, ATGearbox gearbox) + { + AbsTime = absTime; + Disengaged = gearbox.Disengaged; + Gear = gearbox.Gear; + } + + public NextGearState Clone() + { + return new NextGearState(this); + } + } + } +} diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs similarity index 95% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs index dbda13c068acc15ad117c4da3d36f8d50610c388..a1c4f828c0726d37590eb17cf9721f3a3bcceed7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs @@ -10,16 +10,42 @@ 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.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies { + public class ATShiftStrategyOptimizedPolygonCalculator : IShiftPolygonCalculator + { + public ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, + Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + { + var shiftLine = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon( + Math.Max(i, 2), engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); + + var upshift = new List<ShiftPolygon.ShiftPolygonEntry>(); + + if (i < gearboxGears.Count - 1) + { + var maxDragTorque = engineDataFullLoadCurve.MaxDragTorque * 1.1; + var maxTorque = engineDataFullLoadCurve.MaxTorque * 1.1; + + var speed = engineData.FullLoadCurves[0].NP98hSpeed / gearboxGears[i].Ratio * gearboxGears[i + 1].Ratio; + + upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, speed)); + upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxTorque, speed)); + } + + return new ShiftPolygon(shiftLine.Downshift.ToList(), upshift); + } + + } + public class ATShiftStrategyOptimized : ATShiftStrategy { private List<CombustionEngineFuelData> fcMap; @@ -34,12 +60,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private List<SchmittTrigger> LoadStageSteps = new List<SchmittTrigger>(); private ShiftLineSet UpshiftLineTCLocked = new ShiftLineSet(); + private IShiftPolygonCalculator _shiftPolygonCalculator; public new static string Name => "AT - EffShift"; public ATShiftStrategyOptimized(IVehicleContainer dataBus) : base(dataBus) { var runData = dataBus.RunData; + if (runData.EngineData == null) { return; } @@ -48,6 +76,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl fld = runData.EngineData.FullLoadCurves; vehicleMass = runData.VehicleData.TotalVehicleMass; shiftStrategyParameters = runData.GearshiftParameters; + _shiftPolygonCalculator = ShiftPolygonCalculator.Create(Name, shiftStrategyParameters); MinMass = runData.VehicleData.MinimumVehicleMass; MaxMass = runData.VehicleData.MaximumVehicleMass; @@ -461,27 +490,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region Overrides of ATShiftStrategy - public override ShiftPolygon ComputeDeclarationShiftPolygon( - GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, - IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, - Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null) + public override ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, + ElectricMotorData electricMotorData = null) { - var shiftLine = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon( - Math.Max(i, 2), engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius); - - var upshift = new List<ShiftPolygon.ShiftPolygonEntry>(); - - if (i < gearboxGears.Count - 1) { - var maxDragTorque = engineDataFullLoadCurve.MaxDragTorque * 1.1; - var maxTorque = engineDataFullLoadCurve.MaxTorque * 1.1; - - var speed = engineData.FullLoadCurves[0].NP98hSpeed / gearboxGears[i].Ratio * gearboxGears[i + 1].Ratio; - - upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, speed)); - upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxTorque, speed)); - } - - return new ShiftPolygon(shiftLine.Downshift.ToList(), upshift); + return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType, + i, + engineDataFullLoadCurve, + gearboxGears, + engineData, + axlegearRatio, + dynamicTyreRadius, electricMotorData); } #endregion diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyVoith.cs similarity index 99% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyVoith.cs index 60ed6796eb8f73ae222d680fd9af480dc32b2ddd..af718f0e896e0259f73a5ecee785ca5ec381f0eb 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyVoith.cs @@ -9,12 +9,11 @@ using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies { public class ATShiftStrategyVoith : ATShiftStrategy { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/BaseShiftStrategy.cs similarity index 97% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/BaseShiftStrategy.cs index c04dab62a027b87da1e39be6efabd994be84034e..5808569c0281c31b56366684bcff9ea2b9a17b46 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/BaseShiftStrategy.cs @@ -1,132 +1,132 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2019 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using System.Collections.Generic; -using System.Linq; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.OutputData; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public abstract class BaseShiftStrategy : LoggingObject, IShiftStrategy - { - protected readonly IDataBus DataBus; - protected readonly GearboxData GearboxModelData; - protected readonly ShiftStrategyParameters GearshiftParams; - - protected readonly GearList Gears; - - protected BaseShiftStrategy(IVehicleContainer dataBus) - { - GearboxModelData = dataBus.RunData.GearboxData; - GearshiftParams = dataBus.RunData.GearshiftParameters; - DataBus = dataBus; - - Gears = GearboxModelData.GearList; - } - - public virtual bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, - PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, - Second lastShiftTime, IResponse response) - { - CheckGearshiftRequired = true; - var retVal = DoCheckShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); - CheckGearshiftRequired = false; - return retVal; - } - - protected abstract bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, - PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, - Second lastShiftTime, IResponse response); - - public abstract GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity); - public abstract GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity); - public abstract void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity); - public abstract IGearbox Gearbox { get; set; } - public abstract GearshiftPosition NextGear { get; } - - public bool CheckGearshiftRequired { get; protected set; } - public GearshiftPosition MaxStartGear { get; protected set; } - - public virtual void Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) - { } - - public virtual void WriteModalResults(IModalDataContainer container) - { - - } - - public abstract ShiftPolygon ComputeDeclarationShiftPolygon( - GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, - CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null); - - protected MeterPerSquareSecond EstimateAccelerationForGear(GearshiftPosition gear, PerSecond gbxAngularVelocityOut) - { - if (!Gears.Contains(gear)) { - throw new VectoSimulationException("EstimateAccelerationForGear: invalid gear: {0}", gear); - } - - var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed; - - var nextEngineSpeed = gbxAngularVelocityOut * GearboxModelData.Gears[gear.Gear].Ratio; - var maxEnginePower = DataBus.EngineInfo.EngineStationaryFullPower(nextEngineSpeed); - - var avgSlope = - ((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude - - DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>(); - - var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed; - var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; - var gearboxLoss = GearboxModelData.Gears[gear.Gear].LossMap.GetTorqueLoss(gbxAngularVelocityOut, - maxEnginePower / nextEngineSpeed * GearboxModelData.Gears[gear.Gear].Ratio).Value * nextEngineSpeed; - //DataBus.GearboxLoss(); - var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; - var axleLoss = DataBus.AxlegearInfo.AxlegearLoss(); - - var accelerationPower = maxEnginePower - gearboxLoss - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss; - - var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels); - - return acceleration.Cast<MeterPerSquareSecond>(); - } - - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2019 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public abstract class BaseShiftStrategy : LoggingObject, IShiftStrategy + { + protected readonly IDataBus DataBus; + protected readonly GearboxData GearboxModelData; + protected readonly ShiftStrategyParameters GearshiftParams; + + protected readonly GearList Gears; + + protected BaseShiftStrategy(IVehicleContainer dataBus) + { + GearboxModelData = dataBus.RunData.GearboxData; + GearshiftParams = dataBus.RunData.GearshiftParameters; + DataBus = dataBus; + + Gears = GearboxModelData.GearList; + } + + public virtual bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, + Second lastShiftTime, IResponse response) + { + CheckGearshiftRequired = true; + var retVal = DoCheckShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); + CheckGearshiftRequired = false; + return retVal; + } + + protected abstract bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear, + Second lastShiftTime, IResponse response); + + public abstract GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity); + public abstract GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity); + public abstract void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity); + public abstract IGearbox Gearbox { get; set; } + public abstract GearshiftPosition NextGear { get; } + + public bool CheckGearshiftRequired { get; protected set; } + public GearshiftPosition MaxStartGear { get; protected set; } + + public virtual void Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) + { } + + public virtual void WriteModalResults(IModalDataContainer container) + { + + } + + public abstract ShiftPolygon ComputeDeclarationShiftPolygon( + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, + CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null); + + protected MeterPerSquareSecond EstimateAccelerationForGear(GearshiftPosition gear, PerSecond gbxAngularVelocityOut) + { + if (!Gears.Contains(gear)) { + throw new VectoSimulationException("EstimateAccelerationForGear: invalid gear: {0}", gear); + } + + var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed; + + var nextEngineSpeed = gbxAngularVelocityOut * GearboxModelData.Gears[gear.Gear].Ratio; + var maxEnginePower = DataBus.EngineInfo.EngineStationaryFullPower(nextEngineSpeed); + + var avgSlope = + ((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude - + DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>(); + + var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed; + var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; + var gearboxLoss = GearboxModelData.Gears[gear.Gear].LossMap.GetTorqueLoss(gbxAngularVelocityOut, + maxEnginePower / nextEngineSpeed * GearboxModelData.Gears[gear.Gear].Ratio).Value * nextEngineSpeed; + //DataBus.GearboxLoss(); + var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed; + var axleLoss = DataBus.AxlegearInfo.AxlegearLoss(); + + var accelerationPower = maxEnginePower - gearboxLoss - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss; + + var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels); + + return acceleration.Cast<MeterPerSquareSecond>(); + } + + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs similarity index 95% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs index a390b6d8ab318b5caaf021e84ac9d27b70293490..eb5215e876e4df9c408b66599fb9d88ba0a8b4c3 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs @@ -1,139 +1,137 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2019 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class MTShiftStrategy : AMTShiftStrategy - { - public MTShiftStrategy(IVehicleContainer bus) : base(bus) - { - EarlyShiftUp = false; - SkipGears = true; - } - - public new static string Name => "MT Shift Strategy"; - - protected override GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, - NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1) - { - // upshift - if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { - currentGear = Gears.Successor(currentGear); - - while (SkipGears && currentGear.Gear < GearboxModelData.Gears.Count) { - currentGear = Gears.Successor(currentGear); - var tmpGear = Gearbox.Gear; - _gearbox.Gear = currentGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - - inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity; - inTorque = response.Clutch.PowerRequest / inAngularVelocity; - - var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2), - currentGear.Gear > 1 - ? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed) - : double.MaxValue.SI<NewtonMeter>()); - var reserve = 1 - inTorque / maxTorque; - - if (reserve >= GearshiftParams.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { - continue; - } - - currentGear = Gears.Predecessor(currentGear); - break; - } - } - - // early up shift to higher gear --------------------------------------- - if (EarlyShiftUp && currentGear.Gear < GearboxModelData.Gears.Count) { - // try if next gear would provide enough torque reserve - var tryNextGear = Gears.Successor(currentGear); - var tmpGear = Gearbox.Gear; - _gearbox.Gear = tryNextGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - - inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity; - inTorque = response.Clutch.PowerRequest / inAngularVelocity; - - // if next gear supplied enough power reserve: take it - // otherwise take - if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) { - var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; - var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; - - if (reserve >= GearshiftParams.TorqueReserve) { - currentGear = tryNextGear; - } - } - } - return currentGear; - } - - protected override GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, - PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1) - { - // down shift - if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { - currentGear = Gears.Predecessor(currentGear); - while (SkipGears && currentGear.Gear > 1) { - currentGear = Gears.Predecessor(currentGear); - var tmpGear = Gearbox.Gear; - _gearbox.Gear = currentGear; - var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); - _gearbox.Gear = tmpGear; - - inAngularVelocity = GearboxModelData.Gears[currentGear.Gear].Ratio * outAngularVelocity; - inTorque = response.Clutch.PowerRequest / inAngularVelocity; - var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2), - currentGear.Gear > 1 - ? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed) - : double.MaxValue.SI<NewtonMeter>()); - var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value(); - if (reserve >= GearshiftParams.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { - continue; - } - currentGear = Gears.Successor(currentGear); - break; - } - } - return currentGear; - } - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2019 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies +{ + public class MTShiftStrategy : AMTShiftStrategy + { + public MTShiftStrategy(IVehicleContainer bus) : base(bus) + { + EarlyShiftUp = false; + SkipGears = true; + } + + public new static string Name => "MT Shift Strategy"; + + protected override GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1) + { + // upshift + if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { + currentGear = Gears.Successor(currentGear); + + while (SkipGears && currentGear.Gear < GearboxModelData.Gears.Count) { + currentGear = Gears.Successor(currentGear); + var tmpGear = Gearbox.Gear; + _gearbox.Gear = currentGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + + inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity; + inTorque = response.Clutch.PowerRequest / inAngularVelocity; + + var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2), + currentGear.Gear > 1 + ? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed) + : double.MaxValue.SI<NewtonMeter>()); + var reserve = 1 - inTorque / maxTorque; + + if (reserve >= GearshiftParams.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + continue; + } + + currentGear = Gears.Predecessor(currentGear); + break; + } + } + + // early up shift to higher gear --------------------------------------- + if (EarlyShiftUp && currentGear.Gear < GearboxModelData.Gears.Count) { + // try if next gear would provide enough torque reserve + var tryNextGear = Gears.Successor(currentGear); + var tmpGear = Gearbox.Gear; + _gearbox.Gear = tryNextGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + + inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity; + inTorque = response.Clutch.PowerRequest / inAngularVelocity; + + // if next gear supplied enough power reserve: take it + // otherwise take + if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) { + var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad; + var reserve = 1 - response.Engine.PowerRequest / fullLoadPower; + + if (reserve >= GearshiftParams.TorqueReserve) { + currentGear = tryNextGear; + } + } + } + return currentGear; + } + + protected override GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1) + { + // down shift + if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + currentGear = Gears.Predecessor(currentGear); + while (SkipGears && currentGear.Gear > 1) { + currentGear = Gears.Predecessor(currentGear); + var tmpGear = Gearbox.Gear; + _gearbox.Gear = currentGear; + var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); + _gearbox.Gear = tmpGear; + + inAngularVelocity = GearboxModelData.Gears[currentGear.Gear].Ratio * outAngularVelocity; + inTorque = response.Clutch.PowerRequest / inAngularVelocity; + var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2), + currentGear.Gear > 1 + ? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed) + : double.MaxValue.SI<NewtonMeter>()); + var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value(); + if (reserve >= GearshiftParams.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) { + continue; + } + currentGear = Gears.Successor(currentGear); + break; + } + } + return currentGear; + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs similarity index 89% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs index c441b6e66c7928b1ab0d838551784293e8e1a6e6..4cc028a223913212b17db2eea5070b3563422d87 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs @@ -5,7 +5,6 @@ using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Declaration; @@ -17,13 +16,46 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoCore.Models.SimulationComponent.Strategies; using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies { + public class PEVAMTShiftStrategyPolygonCreator : IShiftPolygonCalculator + { + private ShiftStrategyParameters _shiftStrategyParameters; + + public PEVAMTShiftStrategyPolygonCreator(ShiftStrategyParameters shiftStrategyparamets) + { + _shiftStrategyParameters = shiftStrategyparamets; + } + + public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, + ElectricMotorData electricMotorData = null) + { + if (electricMotorData == null) + { + throw new VectoException("ElectricMotorData is required to calculate Shift Polygon!"); + } + var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve; + return ComputeDeclarationShiftPolygon(i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData, + _shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed); + } + + + public ShiftPolygon ComputeDeclarationShiftPolygon(int i, + IList<ITransmissionInputData> gearboxGears, double axlegearRatio, + Meter dynamicTyreRadius, + ElectricMotorData electricMotorData, PerSecond downshiftMaxSpeed, PerSecond downshiftMinSpeed) + { + return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, + electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC, + gearboxGears, axlegearRatio, dynamicTyreRadius, downshiftMaxSpeed, downshiftMinSpeed); + } + } + public class PEVAMTShiftStrategy : LoggingObject, IShiftStrategy { protected IDataBus DataBus; @@ -32,7 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected Gearbox _gearbox; protected GearshiftPosition _nextGear; - private ShiftStrategyParameters shiftStrategyParameters; + private readonly ShiftStrategyParameters _shiftStrategyParameters; protected readonly VelocityRollingLookup VelocityDropData = new VelocityRollingLookup(); private SimplePowertrainContainer TestContainer; private Gearbox TestContainerGbx; @@ -50,6 +82,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private double EMRatio; protected PowertrainPosition EMPos; + private PEVAMTShiftStrategyPolygonCreator _shiftPolygonImplementation; public static string Name => "AMT - EffShift (BEV)"; @@ -62,6 +95,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return; } + + EMPos = dataBus.RunData.ElectricMachinesData.FirstOrDefault(x => x.Item1 == PowertrainPosition.BatteryElectricE2 || x.Item1 == PowertrainPosition.IEPC)?.Item1 ?? PowertrainPosition.HybridPositionNotSet; SetupVelocityDropPreprocessor(dataBus); @@ -71,7 +106,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { DataBus = dataBus; var runData = dataBus.RunData; - shiftStrategyParameters = runData.GearshiftParameters; + _shiftStrategyParameters = runData.GearshiftParameters; + _shiftPolygonImplementation = + ShiftPolygonCalculator.Create(Name, _shiftStrategyParameters) as PEVAMTShiftStrategyPolygonCreator; if (runData.VehicleData == null) { return; } @@ -90,7 +127,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl (runData.AngledriveData?.Angledrive.Ratio ?? 1.0) / runData.VehicleData.DynamicTyreRadius; - if (shiftStrategyParameters == null) { + if (_shiftStrategyParameters == null) { throw new VectoException("Parameters for shift strategy missing!"); } @@ -129,32 +166,34 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl new VelocitySpeedGearshiftPreprocessorE2(VelocityDropData, runData.GearboxData.TractionInterruption, TestContainer, -grad, grad, 2)); } - #region Implementation of IShiftPolygonCalculator - public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, - IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, - ElectricMotorData electricMotorData = null) - { - if (electricMotorData == null) { - throw new VectoException("ElectricMotorData is required to calculate Shift Polygon!"); - } - var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve; - return ComputeDeclarationShiftPolygon(i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData, - shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed); - } + //#region Implementation of IShiftPolygonCalculator - public ShiftPolygon ComputeDeclarationShiftPolygon(int i, - IList<ITransmissionInputData> gearboxGears, double axlegearRatio, - Meter dynamicTyreRadius, - ElectricMotorData electricMotorData, PerSecond downshiftMaxSpeed, PerSecond downshiftMinSpeed) - { - return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, - electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC, - gearboxGears, axlegearRatio, dynamicTyreRadius, downshiftMaxSpeed, downshiftMinSpeed); - } + //public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + // IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, + // ElectricMotorData electricMotorData = null) + //{ + // if (electricMotorData == null) { + // throw new VectoException("ElectricMotorData is required to calculate Shift Polygon!"); + // } + // var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve; + // return ComputeDeclarationShiftPolygon(i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData, + // _shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed); + //} - #endregion + + //private ShiftPolygon ComputeDeclarationShiftPolygon(int i, + // IList<ITransmissionInputData> gearboxGears, double axlegearRatio, + // Meter dynamicTyreRadius, + // ElectricMotorData electricMotorData, PerSecond downshiftMaxSpeed, PerSecond downshiftMinSpeed) + //{ + // return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, + // electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC, + // gearboxGears, axlegearRatio, dynamicTyreRadius, downshiftMaxSpeed, downshiftMinSpeed); + //} + + //#endregion protected internal Dictionary<uint, ShiftPolygon> CalculateDeratedShiftLines(ElectricMotorData em, IList<ITransmissionInputData> gearData, Meter rDyn, double axleGearRatio, GearboxType gearboxType) @@ -185,10 +224,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } }; - var shiftPolygon = ComputeDeclarationShiftPolygon((int)i, + var shiftPolygon = _shiftPolygonImplementation.ComputeDeclarationShiftPolygon((int)i, gearData, axleGearRatio, - rDyn, limitedEm, shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor * emFld.RatedSpeed, - shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed); + rDyn, limitedEm, _shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor * emFld.RatedSpeed, + _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed); retVal[i + 1] = shiftPolygon; } @@ -334,7 +373,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift; var vehicleSpeedPostShift = - DataBus.VehicleInfo.VehicleSpeed - vDrop * shiftStrategyParameters.VelocityDropFactor; + DataBus.VehicleInfo.VehicleSpeed - vDrop * _shiftStrategyParameters.VelocityDropFactor; var totalTransmissionRatio = DataBus.ElectricMotorInfo(EMPos).ElectricMotorSpeed / @@ -342,7 +381,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var results = new List<Tuple<GearshiftPosition, double>>(); foreach (var tryNextGear in GearList.IterateGears(GearList.Successor(currentGear), - GearList.Successor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) { + GearList.Successor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) { var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear); var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity; @@ -354,7 +393,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var estimatedEngineSpeed = vehicleSpeedPostShift * (totalTransmissionRatio / GearboxModelData.Gears[currentGear.Gear].Ratio * GearboxModelData.Gears[tryNextGear.Gear].Ratio); - if (estimatedEngineSpeed.IsSmaller(shiftStrategyParameters.MinEngineSpeedPostUpshift)) { + if (estimatedEngineSpeed.IsSmaller(_shiftStrategyParameters.MinEngineSpeedPostUpshift)) { continue; } @@ -379,8 +418,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var minFc = results.MaxBy(x => x.Item2); var ratingFactor = outTorque < 0 - ? 1 / shiftStrategyParameters.RatingFactorCurrentGear - : shiftStrategyParameters.RatingFactorCurrentGear; + ? 1 / _shiftStrategyParameters.RatingFactorCurrentGear + : _shiftStrategyParameters.RatingFactorCurrentGear; if (minFc.Item2.IsGreater(fcCurrent * ratingFactor)) { return minFc.Item1; @@ -483,7 +522,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var ratedSpeed = VoltageLevels.VoltageLevels.First().FullLoadCurve.RatedSpeed; var maxSpeedNorm = VoltageLevels.MaxSpeed / ratedSpeed; - var targetMotor = (shiftStrategyParameters.PEV_TargetSpeedBrakeNorm * (maxSpeedNorm - 1) + 1) * ratedSpeed; + var targetMotor = (_shiftStrategyParameters.PEV_TargetSpeedBrakeNorm * (maxSpeedNorm - 1) + 1) * ratedSpeed; if (candidates.Any(x => x.Value > targetMotor && x.Value < VoltageLevels.MaxSpeed)) { var best = candidates.Where(x => x.Value > targetMotor && x.Value < VoltageLevels.MaxSpeed) @@ -510,7 +549,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var results = new List<Tuple<GearshiftPosition, double>>(); foreach (var tryNextGear in GearList.IterateGears(GearList.Predecessor(currentGear), - GearList.Predecessor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) { + GearList.Predecessor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) { var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear); var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity; @@ -532,8 +571,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fcCurrent = GetFCRating(responseCurrent); var minFc = results.MinBy(x => x.Item2); var ratingFactor = outTorque < 0 - ? 1 / shiftStrategyParameters.RatingFactorCurrentGear - : shiftStrategyParameters.RatingFactorCurrentGear; + ? 1 / _shiftStrategyParameters.RatingFactorCurrentGear + : _shiftStrategyParameters.RatingFactorCurrentGear; if (minFc.Item2.IsGreater(fcCurrent * ratingFactor)) { return minFc.Item1; @@ -860,5 +899,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #endregion } + + #region Implementation of IShiftPolygonCalculator + + public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, + ElectricMotorData electricMotorData = null) + { + return _shiftPolygonImplementation.ComputeDeclarationShiftPolygon(gearboxType, i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius, electricMotorData); + } + + #endregion } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCreator.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCreator.cs new file mode 100644 index 0000000000000000000000000000000000000000..5aa59950a5e62b47a0bc85965122292b2338008f --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCreator.cs @@ -0,0 +1,48 @@ +using System; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Models.Simulation.Data; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies +{ + public abstract class ShiftPolygonCalculator + { + public static IShiftPolygonCalculator Create(string name, ShiftStrategyParameters shiftStrategyParameters) + { + if (name == AMTShiftStrategyOptimized.Name) { + return new AMTShiftStrategyOptimizedPolygonCalculator(); + } + + if (name == PEVAMTShiftStrategy.Name) { + if (shiftStrategyParameters == null) { + throw new ArgumentException($"{nameof(shiftStrategyParameters)} required for {name}"); + } + return new PEVAMTShiftStrategyPolygonCreator(shiftStrategyParameters); + } + + if (name == MTShiftStrategy.Name) { + return new AMTShiftStrategyPolygonCalculator(); + } + + if (name == ATShiftStrategyOptimized.Name) { + return new ATShiftStrategyOptimizedPolygonCalculator(); + } + + if (name == APTNShiftStrategy.Name) { + if (shiftStrategyParameters == null) + { + throw new ArgumentException($"{nameof(shiftStrategyParameters)} required for {name}"); + } + return new PEVAMTShiftStrategyPolygonCreator(shiftStrategyParameters); + } + + + + + throw new ArgumentException($"Could not create ShiftPolygonCalculator for {name}"); + + + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftStrategy.cs similarity index 83% rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftStrategy.cs index e7cb660c2c3d5c48c3fba2ecb7fe4986761df1d6..6aaf26834191e3a991169e3cfee8aab98e6ddb57 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftStrategy.cs @@ -1,109 +1,136 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2019 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Simulation; -using TUGraz.VectoCore.Models.Simulation.DataBus; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - /// <summary> - /// Class ShiftStrategy is a base class for shift strategies. Implements some helper methods for checking the shift curves. - /// </summary> - public abstract class ShiftStrategy : BaseShiftStrategy - { - protected bool SkipGears; - protected bool EarlyShiftUp; - protected Gearbox _gearbox; - - protected ShiftStrategy(IVehicleContainer dataBus) : base(dataBus) {} - - public override IGearbox Gearbox - { - get => _gearbox; - set { - var myGearbox = value as Gearbox; - if (myGearbox == null) { - throw new VectoException("This shift strategy can't handle gearbox of type {0}", value.GetType()); - } - _gearbox = myGearbox; - } - } - - /// <summary> - /// Tests if the operating point is below the down-shift curve (=outside of shift curve). - /// </summary> - /// <param name="gear">The gear.</param> - /// <param name="inTorque">The in torque.</param> - /// <param name="inEngineSpeed">The in engine speed.</param> - /// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns> - protected bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) - { - if (!Gears.HasPredecessor(gear)) { - return false; - } - return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed); - } - - protected bool IsAboveDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) - { - if (!Gears.HasPredecessor(gear)) { - return true; - } - return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveDownshiftCurve(inTorque, inEngineSpeed); - } - - - /// <summary> - /// Tests if the operating point is above the up-shift curve (=outside of shift curve). - /// </summary> - /// <param name="gear">The gear.</param> - /// <param name="inTorque">The in torque.</param> - /// <param name="inEngineSpeed">The in engine speed.</param> - /// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns> - protected bool IsAboveUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) - { - if (!Gears.HasSuccessor(gear)) { - return false; - } - return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed); - } - - protected bool IsBelowUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) - { - if (!Gears.HasSuccessor(gear)) { - return true; - } - return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowUpshiftCurve(inTorque, inEngineSpeed); - } - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2019 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System; +using Newtonsoft.Json; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Simulation; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies +{ + /// <summary> + /// Class ShiftStrategy is a base class for shift strategies. Implements some helper methods for checking the shift curves. + /// </summary> + public abstract class ShiftStrategy : BaseShiftStrategy + { + protected bool SkipGears; + protected bool EarlyShiftUp; + protected Gearbox _gearbox; + + public static IShiftStrategy Create(IVehicleContainer container, string name) + { + + if (name == AMTShiftStrategyOptimized.Name) { + return new AMTShiftStrategyOptimized(container); + } + + if (name == PEVAMTShiftStrategy.Name) { + return new PEVAMTShiftStrategy(container); + } + + if (name == MTShiftStrategy.Name) { + return new MTShiftStrategy(container); + } + + if (name == ATShiftStrategyOptimized.Name) { + return new ATShiftStrategyOptimized(container); + } + + if (name == APTNShiftStrategy.Name) { + return new APTNShiftStrategy(container); + } + + throw new ArgumentOutOfRangeException(nameof(name), $@"Could not create shift strategy {name}"); + } + + protected ShiftStrategy(IVehicleContainer dataBus) : base(dataBus) {} + + public override IGearbox Gearbox + { + get => _gearbox; + set { + var myGearbox = value as Gearbox; + if (myGearbox == null) { + throw new VectoException("This shift strategy can't handle gearbox of type {0}", value.GetType()); + } + _gearbox = myGearbox; + } + } + + /// <summary> + /// Tests if the operating point is below the down-shift curve (=outside of shift curve). + /// </summary> + /// <param name="gear">The gear.</param> + /// <param name="inTorque">The in torque.</param> + /// <param name="inEngineSpeed">The in engine speed.</param> + /// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns> + protected bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) + { + if (!Gears.HasPredecessor(gear)) { + return false; + } + return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed); + } + + protected bool IsAboveDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) + { + if (!Gears.HasPredecessor(gear)) { + return true; + } + return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveDownshiftCurve(inTorque, inEngineSpeed); + } + + + /// <summary> + /// Tests if the operating point is above the up-shift curve (=outside of shift curve). + /// </summary> + /// <param name="gear">The gear.</param> + /// <param name="inTorque">The in torque.</param> + /// <param name="inEngineSpeed">The in engine speed.</param> + /// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns> + protected bool IsAboveUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) + { + if (!Gears.HasSuccessor(gear)) { + return false; + } + return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed); + } + + protected bool IsBelowUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed) + { + if (!Gears.HasSuccessor(gear)) { + return true; + } + return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowUpshiftCurve(inTorque, inEngineSpeed); + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/Shiftstrategies.cd b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/Shiftstrategies.cd new file mode 100644 index 0000000000000000000000000000000000000000..40c35fc94bdb941c6cb718241aaa171b0ff71ab3 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/Shiftstrategies.cd @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="utf-8"?> +<ClassDiagram MajorVersion="1" MinorVersion="1"> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ShiftStrategy"> + <Position X="1.5" Y="2.25" Width="1.5" /> + <TypeIdentifier> + <HashCode>EEAEAAAIACABAAAAAAAAAAAAAAAAAEAgAAAAAAAAAAE=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ShiftStrategy.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.BaseShiftStrategy" Collapsed="true"> + <Position X="3.75" Y="0.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAEAAAAAAIAECAIABgAYAmAAAAAgAAEAIAAAACAAAg=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\BaseShiftStrategy.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.AMTShiftStrategy"> + <Position X="1" Y="6.25" Width="2.5" /> + <TypeIdentifier> + <HashCode>KAAAAgAAAAIAAAAAALCgYA0AAAGAAAAAIIAAAAAABAA=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\AMTShiftStrategy.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController" Collapsed="true"> + <Position X="10.75" Y="0.75" Width="1.5" /> + <Compartments> + <Compartment Name="Nested Types" Collapsed="false" /> + </Compartments> + <NestedTypes> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridCtlShiftStrategy" Collapsed="true"> + <TypeIdentifier> + <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridControllerState" Collapsed="true"> + <TypeIdentifier> + <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.ElectricMotorController" Collapsed="true"> + <TypeIdentifier> + <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridCtlATShiftStrategy" Collapsed="true"> + <TypeIdentifier> + <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridCtlIHPCShiftStrategy" Collapsed="true"> + <TypeIdentifier> + <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName> + </TypeIdentifier> + </Class> + </NestedTypes> + <TypeIdentifier> + <HashCode>BAAEAAAQAAIAAwgAAIA0ABDAAQCMhAAUBAAAABCAMAA=</HashCode> + <FileName>Models\SimulationComponent\Impl\HybridController.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ATShiftStrategyOptimized"> + <Position X="5" Y="3.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>CAAAAgACDAABAAEAJLgAgAQACAAAABAQAYAAAAAAhQA=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ATShiftStrategyOptimized.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.AMTShiftStrategyOptimized" Collapsed="true"> + <Position X="0.5" Y="12.25" Width="1.5" /> + <TypeIdentifier> + <HashCode>CAAAAgAKAAAAAAEAJJAAAAQACAAACAAAIAAAAAAABQA=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\AMTShiftStrategyOptimized.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.APTNShiftStrategy" Collapsed="true"> + <Position X="9.5" Y="6.25" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAgACAAAAAAAAAAAgAAQAAAAAAAAAAAAAAAAAAAA=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\APTNShiftStrategy.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ATShiftStrategy" Collapsed="true"> + <Position X="6" Y="2.25" Width="1.5" /> + <TypeIdentifier> + <HashCode>OAAESgACACIAAAAAABAAcA0ABAAAAIAAAoAABAAAAAE=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ATShiftStrategy.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ATShiftStrategyVoith" Collapsed="true"> + <Position X="7.25" Y="3.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>IAAAAAgADQCAEAAYABgEBAUBAAAAgBAMQIAAAAAAgAA=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ATShiftStrategyVoith.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.MTShiftStrategy" Collapsed="true"> + <Position X="2.75" Y="12.25" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAgAAQAAAAAAAAAIAAAAAAAAAA=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\MTShiftStrategy.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.PEVAMTShiftStrategy" Collapsed="true"> + <Position X="9.5" Y="3.75" Width="1.5" /> + <NestedTypes> + <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.PEVAMTShiftStrategy.PEVInitControl" Collapsed="true"> + <TypeIdentifier> + <NewMemberFileName>Models\SimulationComponent\Impl\Shiftstrategies\PEVAMTShiftStrategy.cs</NewMemberFileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + </NestedTypes> + <TypeIdentifier> + <HashCode>OJCEIgAKACIAECAMJLCgbA2ADABAiEA0AIAAEBBAAAk=</HashCode> + <FileName>Models\SimulationComponent\Impl\Shiftstrategies\PEVAMTShiftStrategy.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Interface Name="TUGraz.VectoCore.Models.SimulationComponent.IShiftStrategy"> + <Position X="12.5" Y="5.25" Width="1.5" /> + <InheritanceLine Type="TUGraz.VectoCore.Models.SimulationComponent.IShiftPolygonCalculator" FixedToPoint="true"> + <Path> + <Point X="13.25" Y="3.603" /> + <Point X="13.25" Y="4.875" /> + <Point X="13.5" Y="4.875" /> + <Point X="13.5" Y="5.25" /> + </Path> + </InheritanceLine> + <TypeIdentifier> + <HashCode>AAAEAAAAAAIAECAAAAAAQAgAAAAAgAAEAIAAAAAAAAg=</HashCode> + <FileName>Models\SimulationComponent\IShiftStrategy.cs</FileName> + </TypeIdentifier> + </Interface> + <Interface Name="TUGraz.VectoCore.Models.SimulationComponent.IShiftPolygonCalculator"> + <Position X="12.5" Y="2.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode> + <FileName>Models\SimulationComponent\IShiftStrategy.cs</FileName> + </TypeIdentifier> + </Interface> + <Font Name="Segoe UI" Size="9" /> +</ClassDiagram> \ No newline at end of file