diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index 97353753f7ebee058903b37973eaf122b879ba57..70b3b7a510536dff7d00e9dbe51c71eb07b47ae1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -52,12 +52,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { protected ATGearbox _gearbox; protected readonly NextGearState _nextGear = new NextGearState(); + private KilogramSquareMeter EngineInertia; public override IGearbox Gearbox { get { return _gearbox; } - set - { + set { _gearbox = value as ATGearbox; if (_gearbox == null) { throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType()); @@ -71,15 +71,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } public override ShiftPolygon ComputeDeclarationShiftPolygon( - GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, + GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, + IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius) { - return DeclarationData.TorqueConverter.ComputeShiftPolygon(engineDataFullLoadCurve, i == 0, i >= gearboxGears.Count - 1); + return DeclarationData.TorqueConverter.ComputeShiftPolygon( + engineDataFullLoadCurve, i == 0, i >= gearboxGears.Count - 1); } - public static string Name { get { return "AT - Classic"; } } + public static string Name + { + get { return "AT - Classic"; } + } - public ATShiftStrategy(VectoRunData data, IDataBus dataBus) : base(data.GearboxData, dataBus) {} + public ATShiftStrategy(VectoRunData data, IDataBus dataBus) : base(data.GearboxData, dataBus) + { + EngineInertia = data.EngineData?.Inertia ?? 0.SI<KilogramSquareMeter>(); + } public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity) { @@ -89,6 +97,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _gearbox.Disengaged = true; return 1; } + var torqueConverterLocked = true; for (var gear = ModelData.Gears.Keys.Max(); gear > 1; gear--) { if (_gearbox.ModelData.Gears[gear].HasTorqueConverter) { @@ -106,6 +115,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return gear; } } + // fallback: start with first gear; _gearbox.TorqueConverterLocked = false; _gearbox.Disengaged = false; @@ -120,6 +130,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _nextGear.AbsTime = null; return _nextGear.Gear; } + _nextGear.AbsTime = null; return _gearbox.Gear; } @@ -129,7 +140,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl throw new System.NotImplementedException("AT Shift Strategy does not support disengaging."); } - public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) + public override bool ShiftRequired( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) { // ENGAGE --------------------------------------------------------- // 0 -> 1C: drive off after disengaged - engage first gear @@ -170,13 +183,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } // UPSHIFT -------------------------------------------------------- - if (CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + if (CheckUpshift( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response)) { return true; } // DOWNSHIFT ------------------------------------------------------ - if (CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, + if (CheckDownshift( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response)) { return true; } @@ -184,7 +199,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return false; } - protected virtual bool CheckEmergencyShift(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, PerSecond inAngularVelocity, uint gear) + protected virtual bool CheckEmergencyShift( + Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, PerSecond inAngularVelocity, uint gear) { // Emergency Downshift: if lower than engine idle speed if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { @@ -192,6 +208,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Downshift(absTime, gear); return true; } + // Emergency Upshift: if higher than engine rated speed if (inAngularVelocity.IsGreaterOrEqual(VectoMath.Min(ModelData.Gears[gear].MaxSpeed, DataBus.EngineN95hSpeed))) { // check if upshift is possible @@ -215,11 +232,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return true; } } + return false; } [SuppressMessage("ReSharper", "UnusedParameter.Local")] - protected virtual bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) + protected virtual bool CheckUpshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) { var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime); if (!shiftTimeReached) { @@ -238,7 +258,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // UPSHIFT - Special rule for 1C -> 2C if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) && ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) { - var result = CheckUpshiftTcTc(absTime, dt, outTorque, outAngularVelocity, gear, currentGear); + var result = CheckUpshiftTcTc( + absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, currentGear, response); if (result.HasValue) { return result.Value; } @@ -255,34 +276,43 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return false; } - protected virtual bool? CheckEarlyUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) + protected virtual bool? CheckEarlyUpshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) { return null; } - protected virtual bool? CheckUpshiftTcTc(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint gear, - GearData currentGear) + protected virtual bool? CheckUpshiftTcTc( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, GearData currentGear, IResponse response) { -// C -> C+1 + // C -> C+1 var nextGear = ModelData.Gears[gear + 1]; var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; - var shiftLosses = _gearbox.ComputeShiftLosses(outTorque, outAngularVelocity, gear + 1) / ModelData.PowershiftShiftTime / nextGearboxInSpeed; + var shiftLosses = _gearbox.ComputeShiftLosses(outTorque, outAngularVelocity, gear + 1) / + ModelData.PowershiftShiftTime / nextGearboxInSpeed; nextGearboxInTorque += shiftLosses; - var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(absTime, dt, nextGearboxInTorque, nextGearboxInSpeed); + var tcOperatingPoint = + _gearbox.TorqueConverter.FindOperatingPoint(absTime, dt, nextGearboxInTorque, nextGearboxInSpeed); var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); var avgSpeed = (DataBus.EngineSpeed + tcOperatingPoint.InAngularVelocity) / 2; var engineMaxTorque = DataBus.EngineStationaryFullPower(avgSpeed) / avgSpeed; - var engineInertiaTorque = Formulas.InertiaPower(DataBus.EngineSpeed, tcOperatingPoint.InAngularVelocity, _gearbox.EngineInertia, dt) / avgSpeed; + var engineInertiaTorque = Formulas.InertiaPower( + DataBus.EngineSpeed, tcOperatingPoint.InAngularVelocity, _gearbox.EngineInertia, dt) / avgSpeed; var engineTorqueBelowMax = tcOperatingPoint.InTorque.IsSmallerOrEqual(engineMaxTorque - engineInertiaTorque); - var reachableAcceleration = EstimateAcceleration(outAngularVelocity, outTorque); // EstimateAccelerationForGear(gear + 1, outAngularVelocity); - var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration, + var reachableAcceleration = + EstimateAcceleration( + outAngularVelocity, outTorque, inAngularVelocity, inTorque, gear, response); // EstimateAccelerationForGear(gear + 1, outAngularVelocity); + var minAcceleration = VectoMath.Min( + ModelData.TorqueConverterData.CCUpshiftMinAcceleration, DataBus.DriverAcceleration); var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); @@ -290,13 +320,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Upshift(absTime, gear); return true; } + return null; } - protected virtual bool? CheckUpshiftToLocked(Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque, + protected virtual bool? CheckUpshiftToLocked( + Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear) { -// UPSHIFT - General Rule + // UPSHIFT - General Rule // L -> L+1 // C -> L var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear; @@ -319,7 +351,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var minAcceleration = _gearbox.TorqueConverterLocked ? ModelData.UpshiftMinAcceleration : ModelData.TorqueConverterData.CLUpshiftMinAcceleration; - minAcceleration = VectoMath.Min(minAcceleration, VectoMath.Max(0.SI<MeterPerSquareSecond>(), DataBus.DriverAcceleration)); + minAcceleration = VectoMath.Min( + minAcceleration, VectoMath.Max(0.SI<MeterPerSquareSecond>(), DataBus.DriverAcceleration)); minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); } @@ -327,6 +360,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Upshift(absTime, gear); return true; } + return null; } @@ -338,7 +372,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <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(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed, + protected virtual bool IsAboveUpShiftCurve( + uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed, bool torqueConverterLocked) { var shiftPolygon = torqueConverterLocked @@ -369,7 +404,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } [SuppressMessage("ReSharper", "UnusedParameter.Local")] - protected virtual bool CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) + protected virtual bool CheckDownshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) { var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime); @@ -379,18 +416,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } if (shiftTimeReached && DataBus.DrivingAction == DrivingAction.Accelerate) { - if (DataBus.VehicleSpeed < DataBus.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() && DataBus.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) { + if (DataBus.VehicleSpeed < DataBus.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() && + DataBus.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) { var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); if (_gearbox.Gear > 1 || _gearbox.Gear == 1 && _gearbox.TorqueConverterLocked) { var tmpCurr = _nextGear.Clone(); var tmpGbxState = new NextGearState(absTime, _gearbox); - + Downshift(absTime, gear); SetGear(_nextGear); var tmpResponseDs = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true); _nextGear.SetState(tmpCurr); SetGear(tmpGbxState); - if (tmpResponseDs.DeltaFullLoad < tmpResponseCurr.DeltaFullLoad) { + if (tmpResponseDs.DeltaFullLoad - Formulas.InertiaPower( + tmpResponseDs.EngineSpeed, DataBus.EngineSpeed, EngineInertia, dt) < tmpResponseCurr.DeltaFullLoad) { Downshift(absTime, gear); return true; } @@ -398,7 +437,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - if (shiftTimeReached && gear > 1 || (gear == 1 && _gearbox.TorqueConverterLocked)) { + if (shiftTimeReached && gear > 1 || (gear == 1 && _gearbox.TorqueConverterLocked)) { var earlyDownshift = CheckEarlyDownshift( absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response); if (earlyDownshift.HasValue) { @@ -409,7 +448,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return false; } - protected virtual bool? CheckEarlyDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) + protected virtual bool? CheckEarlyDownshift( + Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear, Second lastShiftTime, IResponse response) { return null; } @@ -453,6 +494,37 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl "ShiftStrategy wanted to shift down but current gear is locked (L) and has no torque converter (C) and disenganging directly from (L) is not allowed."); } + protected MeterPerSquareSecond EstimateAcceleration( + PerSecond gbxOutSpeed, NewtonMeter gbxOutTorque, PerSecond tcInSpeed, NewtonMeter tcInTorque, uint currentGear, IResponse response) + { + var vehicleSpeed = DataBus.VehicleSpeed; + var avgSlope = + ((DataBus.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude - + DataBus.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>(); + + var airDragLoss = DataBus.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleSpeed; + var rollResistanceLoss = DataBus.RollingResistance(avgSlope) * DataBus.VehicleSpeed; + + //DataBus.GearboxLoss(); + var slopeLoss = DataBus.SlopeResistance(avgSlope) * DataBus.VehicleSpeed; + var axleLoss = DataBus.AxlegearLoss(); + + var tcLossesCurrentGear = tcInSpeed * tcInTorque - gbxOutSpeed * gbxOutTorque; + + var nextTcOutSpeed = gbxOutSpeed * ModelData.Gears[currentGear + 1].TorqueConverterRatio; + + var tcNext = ModelData.TorqueConverterData.LookupOperatingPointOut( + nextTcOutSpeed, response.EngineSpeed, response.EngineTorqueDemand); + 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.VehicleSpeed / (DataBus.TotalMass + DataBus.ReducedMassWheels); + + return acceleration.Cast<MeterPerSquareSecond>(); + } + protected class NextGearState { public Second AbsTime; @@ -505,4 +577,4 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } } -} \ No newline at end of file +} diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs index d9c80470a52b2b24ad11dcbfce4c7bd23adf0d9b..4f7c21adc17da1953f159b66518f1a5b26719025 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs @@ -236,6 +236,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return null; } + if (DataBus.DriverAcceleration < 0) { + return null; + } + + var minFcGear = new GearshiftPosition(currentGear, _gearbox.TorqueConverterLocked); var minFc = double.MaxValue; var fcCurrent = double.NaN; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs index 7da17f27da639a6fbae843405cc7f564bfc5ff81..b731a524fb1c28f01889e407fe8955512239191e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs @@ -203,7 +203,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // UPSHIFT - Special rule for 1C -> 2C if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) && ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) { - var result = CheckUpshiftTcTc(absTime, dt, outTorque, outAngularVelocity, gear, currentGear); + var result = CheckUpshiftTcTc(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, currentGear, response); if (result.HasValue) { return result.Value; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs index 5b16a11e871be9edf6c83533c202ad3703800083..1cb40d344553a2930e7da2dbedd80a58525810a8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs @@ -103,26 +103,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return acceleration.Cast<MeterPerSquareSecond>(); } - protected MeterPerSquareSecond EstimateAcceleration(PerSecond gbxOutSpeed, NewtonMeter gbxOutTorque) - { - var vehicleSpeed = DataBus.VehicleSpeed; - var avgSlope = - ((DataBus.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude - - DataBus.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>(); - - var airDragLoss = DataBus.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleSpeed; - var rollResistanceLoss = DataBus.RollingResistance(avgSlope) * DataBus.VehicleSpeed; - //DataBus.GearboxLoss(); - var slopeLoss = DataBus.SlopeResistance(avgSlope) * DataBus.VehicleSpeed; - var axleLoss = DataBus.AxlegearLoss(); - - var accelerationPower = gbxOutSpeed * gbxOutTorque - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss; - - var acceleration = accelerationPower / DataBus.VehicleSpeed / (DataBus.TotalMass + DataBus.ReducedMassWheels); - - return acceleration.Cast<MeterPerSquareSecond>(); - - } + }