diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index 18b4b70f7b253528ecd878f0da58005ff0390dff..dd8c1d1efded28770ce7d10db68518bb99434c75 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -591,7 +591,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter ShareEngineHigh = EngineSpeedHighLookupReader.ReadFromStream( RessourceHelper.ReadStream( DeclarationData.DeclarationDataResourcePrefix + ".GearshiftParameters.ShareEngineSpeedHigh.csv") - ) + ), + //-------------------- + RatioEarlyUpshiftFC = 5, + RatioEarlyDownshiftFC = 10, }; return retVal; diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 4db546a6f7ba8e882b077a0a08ce27a95ee87001..fc9c7af5e5792be7cc075b3fcd975c31e58d3d27 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -235,12 +235,69 @@ namespace TUGraz.VectoCore.Models.Declaration public static ShiftPolygon ComputeShiftPolygon(GearboxType type, int gearIdx, EngineFullLoadCurve fullLoadCurve, IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius) { + switch (type) { + case GearboxType.MT: + return ComputeManualTransmissionShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius); + case GearboxType.AMT: + return ComputeEfficiencyShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius); + case GearboxType.ATSerial: + case GearboxType.ATPowerSplit: + return TorqueConverter.ComputeShiftPolygon(fullLoadCurve, gearIdx == 0, gearIdx >= gears.Count - 1); + case GearboxType.DrivingCycle: break; + default: throw new ArgumentOutOfRangeException(nameof(type), type, null); + } + return type.AutomaticTransmission() ? TorqueConverter.ComputeShiftPolygon(fullLoadCurve, gearIdx == 0, gearIdx >= gears.Count - 1) // That's the same for all gears, so call the same method... : ComputeManualTransmissionShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius); } + private static ShiftPolygon ComputeEfficiencyShiftPolygon(int gearIdx, EngineFullLoadCurve fullLoadCurve, IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius) + { + if (gears.Count < 2) { + throw new VectoException("ComputeShiftPolygon needs at least 2 gears. {0} gears given.", gears.Count); + } + + var p2 = new Point(engine.IdleSpeed.Value() * 1.1, 0); + var p3 = new Point(fullLoadCurve.NTq99lSpeed.Value(), 0); + var p5 = new Point(fullLoadCurve.RatedSpeed.Value(), fullLoadCurve.MaxTorque.Value() * 1.1); + + var downShift = new List<ShiftPolygon.ShiftPolygonEntry>(); + + if (gearIdx > 0) { + var downShiftPoints = fullLoadCurve + .FullLoadEntries.Where(fldEntry => fldEntry.EngineSpeed >= p2.X && fldEntry.EngineSpeed <= p3.X) + .Select( + fldEntry => + new Point(fldEntry.EngineSpeed.Value(), fldEntry.TorqueFullLoad.Value() * ShiftPolygonEngineFldMargin)) + .ToList(); + downShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDragTorque * 1.1, p2.X.SI<PerSecond>())); + if (downShiftPoints.Min(x => x.X) > p2.X) { + downShift.Add( + new ShiftPolygon.ShiftPolygonEntry( + fullLoadCurve.FullLoadStationaryTorque(p2.X.SI<PerSecond>()) * ShiftPolygonEngineFldMargin, + p2.X.SI<PerSecond>())); + } + downShift.AddRange(downShiftPoints.Select(x => new ShiftPolygon.ShiftPolygonEntry(x.Y.SI<NewtonMeter>() * 0.98, x.X.SI<PerSecond>()))); + if (downShiftPoints.Max(x => x.X) < p3.X) { + downShift.Add( + new ShiftPolygon.ShiftPolygonEntry( + fullLoadCurve.FullLoadStationaryTorque(p3.X.SI<PerSecond>()) * ShiftPolygonEngineFldMargin, + p3.X.SI<PerSecond>())); + } + + downShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxTorque * 1.1, p3.X.SI<PerSecond>())); + } + var upShift = new List<ShiftPolygon.ShiftPolygonEntry>(); + if (gearIdx >= gears.Count - 1) { + return new ShiftPolygon(downShift, upShift); + } + upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDragTorque * 1.1, p5.X.SI<PerSecond>())); + upShift.Add(new ShiftPolygon.ShiftPolygonEntry(p5.Y.SI<NewtonMeter>(), p5.X.SI<PerSecond>())); + return new ShiftPolygon(downShift, upShift); + } + public static ShiftPolygon ComputeManualTransmissionShiftPolygon(int gearIdx, EngineFullLoadCurve fullLoadCurve, IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius) diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 5ec6881029d041fd6b7681d8bf7d3a6603fde3af..2554cdd14bc9edfa20e362ea029bd77cf5210864 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -413,7 +413,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl if (string.IsNullOrWhiteSpace(runData.ShiftStrategy)) { switch (runData.GearboxData.Type) { case GearboxType.AMT: - return new AMTShiftStrategy(runData, container); + return new AMTShiftStrategyOptimized(runData, container); case GearboxType.MT: return new MTShiftStrategy(runData, container); case GearboxType.ATPowerSplit: diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs index 3519afea54911e64b4ca6b5d4e948f83c188feb0..0ab463477421f89def87245b7b12b2d2e0290e52 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs @@ -265,7 +265,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl : double.MaxValue.SI<NewtonMeter>()); var reserve = 1 - inTorque / maxTorque; - if (reserve >= ModelData.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { + if (reserve >= 0 /*ModelData.TorqueReserve */ && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { continue; } @@ -296,7 +296,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; var reserve = 1 - response.EnginePowerRequest / fullLoadPower; - if (reserve >= ModelData.TorqueReserve) { + if (reserve >= 0 /* ModelData.TorqueReserve */) { currentGear = tryNextGear; } } @@ -310,7 +310,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // down shift if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) { currentGear--; - while (SkipGears && currentGear > 1) { + while (false && SkipGears && currentGear > 1) { currentGear--; var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear);