From 8a307494a2efe08e905187ef90087f2247a58b8d Mon Sep 17 00:00:00 2001 From: Michael Krisper <michael.krisper@tugraz.at> Date: Thu, 10 Nov 2016 16:27:12 +0100 Subject: [PATCH] Downshift 2C -> 1C with DownshiftCurve; Refactored ShiftRequired, CheckDownshift, CheckUpshift --- .../SimulationComponent/Impl/ATGearbox.cs | 1 + .../Impl/ATShiftStrategy.cs | 204 +++++++++--------- 2 files changed, 99 insertions(+), 106 deletions(-) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs index 9f01057b2c..e3a9e76932 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs @@ -282,6 +282,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity); CurrentState.Gear = 1; + CurrentState.TorqueConverterLocked = !ModelData.Gears[Gear].HasTorqueConverter; return retval; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index 47b4abb55e..411d17352d 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -88,77 +88,48 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) { + // 0 -> 1C: drive off after stop - engage first gear if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) { - // drive off after stop - engage first gear Log.Debug("shift requried: drive off after vehicle stopped"); NextGear.SetState(absTime, false, 1, false); return true; } - if (DataBus.DriverBehavior == DrivingBehavior.Braking) { - if (DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed) && - outTorque.IsSmaller(0)) { - // disengage before halting - NextGear.SetState(absTime, true, 1, false); - return true; - } + + // _ -> 0: disengage before halting + if (DataBus.DriverBehavior == DrivingBehavior.Braking && outTorque.IsSmaller(0) && + DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed)) { + NextGear.SetState(absTime, true, 1, false); + return true; } + + // 1C -> 0: disengange when negative T_out and positive T_in if (gear == 1 && !_gearbox.TorqueConverterLocked && outTorque.IsSmaller(0) && inTorque.IsGreater(0)) { NextGear.SetState(absTime, true, 1, false); return true; } - if (inAngularVelocity != null) { - // emergency shift to not stall the engine ------------------------ - if (_gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>())) { - NextGear.SetState(absTime, false, 1, false); - return true; - } - // Emergency Shift if lower than engine idle speed - if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - Log.Debug("engine speed would fall below idle speed - shift down"); - if (_gearbox.TorqueConverterLocked) { - // downshift L -> L / C - if (Data.Gears[gear].HasTorqueConverter) { - NextGear.SetState(absTime, false, gear, false); - return true; - } - if (Data.Gears.ContainsKey(gear - 1) && Data.Gears[gear - 1].HasLockedGear) { - NextGear.SetState(absTime, false, gear - 1, true); - return true; - } - } else { - // downshift C -> C / 0 - if (Data.Gears.ContainsKey(gear - 1) && Data.Gears[gear - 1].HasTorqueConverter) { - // C -> C - NextGear.SetState(absTime, false, gear - 1, false); - return true; - } - // C -> 0 - NextGear.SetState(absTime, true, 1, false); - return true; - } - NextGear.SetState(absTime, false, gear - 1, !Data.Gears[gear - 1].HasTorqueConverter); - return true; - } + if (inAngularVelocity == null) { + return false; + } - // Emergency shift if higher than engine rated speed - if (inAngularVelocity.IsGreaterOrEqual(DataBus.EngineRatedSpeed)) { - Log.Debug("engine speed would be above rated speed - shift up"); - if (Data.Gears.ContainsKey(gear + 1) && (_gearbox.TorqueConverterLocked || Data.Gears[gear + 1].HasTorqueConverter)) { - // 1L -> 2C/L OR 1C -> 2C - NextGear.SetState(absTime, false, gear + 1, !Data.Gears[gear + 1].HasTorqueConverter); - return true; - } - if (Data.Gears[gear].HasLockedGear) { - // 1C -> 1L - NextGear.SetState(absTime, false, gear, true); - return true; - } - - // 1C -> ? -- switching directly from 1C to 2L is not allowed - throw new VectoSimulationException( - "AngularVelocity is higher than EngineRatedSpeed, Current gear has active torque converter (1C) but no locked gear (no 1L) and shifting directly to 2L is not allowed."); - } + // _ -> 1C: if n_eng == 0 + if (_gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>())) { + NextGear.SetState(absTime, false, 1, false); + return true; + } + + // Emergency Downshift: if lower than engine idle speed + if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + 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(DataBus.EngineRatedSpeed)) { + Log.Debug("engine speed would be above rated speed - shift up"); + Upshift(absTime, gear); + return true; } if ((absTime - lastShiftTime).IsSmaller(Data.ShiftTime)) { @@ -168,6 +139,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime)) { return true; } + if (CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime)) { return true; } @@ -175,39 +147,87 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return false; } + private void Upshift(Second absTime, uint gear) + { + // C -> L: switch from torque converter to locked gear + if (!_gearbox.TorqueConverterLocked && Data.Gears[gear].HasLockedGear) { + NextGear.SetState(absTime, false, gear, true); + return; + } + + // L -> L+1 + // C -> C+1 + if (Data.Gears.ContainsKey(gear + 1)) { + NextGear.SetState(absTime, false, gear + 1, _gearbox.TorqueConverterLocked); + return; + } + + // C -> L+1 -- not allowed!! + throw new VectoSimulationException( + "ShiftStrategy wanted to shift up, but current gear has active torque converter (C) but no locked gear (no L) and shifting directly to (L) is not allowed."); + } + + private void Downshift(Second absTime, uint gear) + { + // L -> C + if (_gearbox.TorqueConverterLocked && Data.Gears[gear].HasTorqueConverter) { + NextGear.SetState(absTime, false, gear, false); + return; + } + + // L -> L-1 + // C -> C-1 + if (Data.Gears.ContainsKey(gear - 1)) { + NextGear.SetState(absTime, false, gear - 1, _gearbox.TorqueConverterLocked); + return; + } + + // C -> 0 + //if (!_gearbox.TorqueConverterLocked && gear == 1) { + // NextGear.SetState(absTime, true, 1, false); + // return; + //} + + // L -> 0 -- not allowed!! + throw new VectoSimulationException( + "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."); + } + private bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) { - if (gear == Data.Gears.Keys.Max()) { - return false; - } - if ((!_gearbox.TorqueConverterLocked && Data.Gears[gear].HasLockedGear) || _gearbox.TorqueConverterLocked) { - // C -> L , or L -> L upshift - var nextGear = gear; - if (_gearbox.TorqueConverterLocked) { - nextGear = gear + 1; + if (_gearbox.TorqueConverterLocked || Data.Gears[gear].HasLockedGear) { + // L -> L+1 + // C -> L + var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear; + if (!Data.Gears.ContainsKey(nextGear)) { + return false; } + var nextEngineSpeed = outAngularVelocity * Data.Gears[nextGear].Ratio; var enginePower = inAngularVelocity * inTorque; if (nextEngineSpeed.IsEqual(0)) { return false; } + if (IsAboveUpShiftCurve(gear, enginePower / nextEngineSpeed, nextEngineSpeed, _gearbox.TorqueConverterLocked) && enginePower.IsSmallerOrEqual(DataBus.EngineStationaryFullPower(nextEngineSpeed))) { - NextGear.SetState(absTime, false, nextGear, true); + Upshift(absTime, gear); return true; } } + if (!_gearbox.TorqueConverterLocked && Data.Gears.ContainsKey(gear + 1) && Data.Gears[gear + 1].HasTorqueConverter) { - // C -> C upshift + // C -> C+1 var gearRatio = Data.Gears[gear + 1].TorqueConverterRatio / Data.Gears[gear].TorqueConverterRatio; - var minEnginseSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); + var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); var nextGbxInSpeed = outAngularVelocity * Data.Gears[gear + 1].TorqueConverterRatio; var nextGbxInTorque = outTorque / Data.Gears[gear + 1].TorqueConverterRatio; var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGbxInTorque, nextGbxInSpeed); - if (tcOperatingPoint.InAngularVelocity.IsGreater(minEnginseSpeed) && + if (tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed) && DataBus.EngineStationaryFullPower(tcOperatingPoint.InAngularVelocity) .IsGreater(0.7 * DataBus.EngineStationaryFullPower(inAngularVelocity))) { + Upshift(absTime, gear); return true; } } @@ -217,42 +237,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl private bool CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) { - if (_gearbox.TorqueConverterLocked) { - if (inAngularVelocity != null && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - // n_eng < n_eng_idle - if (Data.Gears[gear].HasTorqueConverter) { - // L -> C shift - NextGear.SetState(absTime, false, gear, false); - } else if (Data.Gears.ContainsKey(gear - 1) && Data.Gears[gear - 1].HasLockedGear) { - // L -> L shift - NextGear.SetState(absTime, false, gear - 1, true); - } else { - throw new VectoSimulationException("Downshift required, but failed to select gear!"); - } - } - } else { - // already in converter mode - - // check not possible - if (inAngularVelocity == null) - return false; - - // downshift not possible - if (!Data.Gears.ContainsKey(gear - 1)) { - return false; - } - - // emergency down shift - if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - NextGear.SetState(absTime, false, gear - 1, false); - return true; - } + // downshift not possible + if (!_gearbox.TorqueConverterLocked && gear == 1) { + return false; + } - // 2C -> 1C: shift also down if below downshiftcurve of 2L - if (IsBelowDownShiftCurve(gear - 1, inTorque, inAngularVelocity)) { - NextGear.SetState(absTime, false, gear - 1, false); - return true; - } + if (IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) { + Downshift(absTime, gear); + return true; } return false; -- GitLab