From 3d1c74e0d3ac37445d6b2e7ad3ad27d3b6ea5a85 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Mon, 27 Jun 2016 07:57:29 +0200
Subject: [PATCH] moving mt shift strategy and amt shift strategy to separate
 files

---
 .../Impl/AMTShiftStrategy.cs                  | 239 ++++++++++++++
 .../Impl/MTShiftStrategy.cs                   |  55 ++++
 .../SimulationComponent/Impl/ShiftStrategy.cs | 295 +-----------------
 3 files changed, 295 insertions(+), 294 deletions(-)
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs
new file mode 100644
index 0000000000..76bde3d9f7
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs
@@ -0,0 +1,239 @@
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	/// <summary>
+	/// AMTShiftStrategy implements the AMT Shifting Behaviour.
+	/// </summary>
+	public class AMTShiftStrategy : ShiftStrategy
+	{
+		/// <summary>
+		/// The previous gear before the disengagement. Used for GetGear() when skipGears is false.
+		/// </summary>
+		protected uint PreviousGear;
+
+		public uint NextGear { get; set; }
+
+		public AMTShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus)
+		{
+			PreviousGear = 1;
+			Data.EarlyShiftUp = true;
+			Data.SkipGears = true;
+		}
+
+
+		private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
+		{
+			return (outAngularSpeed * Data.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
+		}
+
+		// original vecto2.2: (inAngularSpeed - IdleSpeed) / (RatedSpeed - IdleSpeed) >= 1.2
+		//                  =  inAngularSpeed - IdleSpeed >= 1.2*(RatedSpeed - IdleSpeed)
+		//                  =  inAngularSpeed >= 1.2*RatedSpeed - 0.2*IdleSpeed
+		private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed)
+		{
+			return
+				(outAngularSpeed * Data.Gears[gear].Ratio).IsGreaterOrEqual(DataBus.EngineN95hSpeed);
+		}
+
+
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
+				NextGear--;
+			}
+			while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
+				NextGear++;
+			}
+
+			return NextGear;
+		}
+
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		{
+			PreviousGear = Gearbox.Gear;
+		}
+
+		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		{
+			if (DataBus.VehicleSpeed.IsEqual(0)) {
+				for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
+					var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
+
+					var ratedSpeed = Data.Gears[gear].FullLoadCurve != null
+						? Data.Gears[gear].FullLoadCurve.RatedSpeed
+						: DataBus.EngineRatedSpeed;
+					if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) {
+						continue;
+					}
+
+					var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
+
+					var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
+					var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
+					var inTorque = response.ClutchPowerRequest / inAngularSpeed;
+
+					// if in shift curve and above idle speed and torque reserve is provided.
+					if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && inAngularSpeed > DataBus.EngineIdleSpeed &&
+						reserve >= Data.StartTorqueReserve) {
+						return gear;
+					}
+				}
+				return 1;
+			}
+			for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
+				var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
+
+				var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
+				var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
+				var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
+				var inTorque = response.ClutchPowerRequest / inAngularSpeed;
+
+				// if in shift curve and torque reserve is provided: return the current gear
+				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
+					reserve >= Data.StartTorqueReserve) {
+					if ((inAngularSpeed - DataBus.EngineIdleSpeed) / (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
+						Constants.SimulationSettings.ClutchClosingSpeedNorm && gear > 1) {
+						gear--;
+					}
+
+					return gear;
+				}
+
+				// 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) && gear < Data.Gears.Count) {
+					return gear + 1;
+				}
+			}
+
+			// fallback: return first gear
+			return 1;
+		}
+
+		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+		{
+			// no shift when vehicle stands
+			if (DataBus.VehicleStopped) {
+				return false;
+			}
+
+			// emergency shift to not stall the engine ------------------------
+			NextGear = gear;
+			while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
+				NextGear--;
+			}
+			while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
+				NextGear++;
+			}
+			if (NextGear != gear) {
+				return true;
+			}
+
+
+			// normal shift when all requirements are fullfilled ------------------
+			var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmallerOrEqual(absTime);
+			if (!minimumShiftTimePassed) {
+				return false;
+			}
+
+			NextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
+			if (NextGear != gear) {
+				return true;
+			}
+
+			NextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
+
+			if ((Data.Gears[NextGear].Ratio * outAngularVelocity - DataBus.EngineIdleSpeed) /
+				(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
+				Constants.SimulationSettings.ClutchClosingSpeedNorm && NextGear > 1) {
+				NextGear--;
+			}
+
+			return (NextGear != gear);
+		}
+
+		protected virtual uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
+		{
+			return DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
+		}
+
+		protected virtual uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
+		{
+			return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
+		}
+
+		protected virtual uint DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
+		{
+			// upshift
+			while (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				currentGear++;
+				if (!Data.SkipGears) {
+					break;
+				}
+
+				var tmpGear = Gearbox.Gear;
+				Gearbox.Gear = currentGear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				Gearbox.Gear = tmpGear;
+
+				inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
+				inTorque = response.ClutchPowerRequest / inAngularVelocity;
+			}
+
+			// early up shift to higher gear ---------------------------------------
+			if (Data.EarlyShiftUp && currentGear < Data.Gears.Count) {
+				// try if next gear would provide enough torque reserve
+				var tryNextGear = currentGear + 1;
+				var tmpGear = Gearbox.Gear;
+				Gearbox.Gear = tryNextGear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				Gearbox.Gear = tmpGear;
+				if (!(response is ResponseEngineSpeedTooLow)) {
+					inAngularVelocity = Data.Gears[tryNextGear].Ratio * outAngularVelocity;
+					inTorque = response.ClutchPowerRequest / inAngularVelocity;
+
+					// if next gear supplied enough power reserve: take it
+					// otherwise take
+					if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
+						var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
+						var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
+
+						if (reserve >= Data.TorqueReserve) {
+							currentGear = tryNextGear;
+						}
+					}
+				}
+			}
+			return currentGear;
+		}
+
+
+		protected virtual uint DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
+		{
+			// down shift
+			while (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				currentGear--;
+				if (!Data.SkipGears) {
+					break;
+				}
+				var tmpGear = Gearbox.Gear;
+				Gearbox.Gear = currentGear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				Gearbox.Gear = tmpGear;
+
+				inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
+				inTorque = response.ClutchPowerRequest / inAngularVelocity;
+			}
+			return currentGear;
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs
new file mode 100644
index 0000000000..3e869f9cd0
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs
@@ -0,0 +1,55 @@
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class MTShiftStrategy : AMTShiftStrategy
+	{
+		public MTShiftStrategy(GearboxData data, IDataBus bus) : base(data, bus)
+		{
+			Data.EarlyShiftUp = false;
+			Data.SkipGears = true;
+		}
+
+		protected override uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
+		{
+			// if the driver's intention is _not_ to accelerate or drive along then don't upshift
+			if (DataBus.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverBehavior != DrivingBehavior.Driving) {
+				return currentGear;
+			}
+			if ((absTime - Gearbox.LastDownshift).IsSmaller(10.SI<Second>())) {
+				return currentGear;
+			}
+			var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
+			if (nextGear == currentGear) {
+				return nextGear;
+			}
+
+			// estimate acceleration for selected gear
+			if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
+				// if less than 0.1 for next gear, don't shift
+				if (nextGear - currentGear == 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 > currentGear &&
+					EstimateAccelerationForGear(currentGear + 1, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
+					return currentGear;
+				}
+			}
+
+			return nextGear;
+		}
+
+		protected override uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
+		{
+			if ((absTime - Gearbox.LastUpshift).IsSmaller(10.SI<Second>())) {
+				return currentGear;
+			}
+			return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
index d53f0d2c37..8cfd9b059d 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
@@ -33,8 +33,6 @@ using System;
 using System.Drawing.Design;
 using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
@@ -85,7 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var rollResistanceLoss = DataBus.RollingResistance(avgSlope) * DataBus.VehicleSpeed;
 			var gearboxLoss = Gearbox.ModelData.Gears[gear].LossMap.GetTorqueLoss(gbxAngularVelocityOut,
 				maxEnginePower / nextEngineSpeed * Gearbox.ModelData.Gears[gear].Ratio).Value * nextEngineSpeed;
-				//DataBus.GearboxLoss();
+			//DataBus.GearboxLoss();
 			var slopeLoss = DataBus.SlopeResistance(avgSlope) * DataBus.VehicleSpeed;
 			var axleLoss = DataBus.AxlegearLoss();
 
@@ -140,295 +138,4 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return ShiftPolygon.IsRightOf(inEngineSpeed, inTorque, upSection);
 		}
 	}
-
-
-//###############################################################################
-//###############################################################################
-//###############################################################################
-
-	/// <summary>
-	/// AMTShiftStrategy implements the AMT Shifting Behaviour.
-	/// </summary>
-	public class AMTShiftStrategy : ShiftStrategy
-	{
-		/// <summary>
-		/// The previous gear before the disengagement. Used for GetGear() when skipGears is false.
-		/// </summary>
-		protected uint PreviousGear;
-
-		public uint NextGear { get; set; }
-
-		public AMTShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus)
-		{
-			PreviousGear = 1;
-			Data.EarlyShiftUp = true;
-			Data.SkipGears = true;
-		}
-
-
-		private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
-		{
-			return (outAngularSpeed * Data.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
-		}
-
-		// original vecto2.2: (inAngularSpeed - IdleSpeed) / (RatedSpeed - IdleSpeed) >= 1.2
-		//                  =  inAngularSpeed - IdleSpeed >= 1.2*(RatedSpeed - IdleSpeed)
-		//                  =  inAngularSpeed >= 1.2*RatedSpeed - 0.2*IdleSpeed
-		private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed)
-		{
-			return
-				(outAngularSpeed * Data.Gears[gear].Ratio).IsGreaterOrEqual(DataBus.EngineN95hSpeed);
-		}
-
-
-		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
-				NextGear--;
-			}
-			while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
-				NextGear++;
-			}
-
-			return NextGear;
-		}
-
-		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
-		{
-			PreviousGear = Gearbox.Gear;
-		}
-
-		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
-		{
-			if (DataBus.VehicleSpeed.IsEqual(0)) {
-				for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
-					var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
-
-					var ratedSpeed = Data.Gears[gear].FullLoadCurve != null
-						? Data.Gears[gear].FullLoadCurve.RatedSpeed
-						: DataBus.EngineRatedSpeed;
-					if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) {
-						continue;
-					}
-
-					var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
-
-					var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
-					var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
-					var inTorque = response.ClutchPowerRequest / inAngularSpeed;
-
-					// if in shift curve and above idle speed and torque reserve is provided.
-					if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && inAngularSpeed > DataBus.EngineIdleSpeed &&
-						reserve >= Data.StartTorqueReserve) {
-						return gear;
-					}
-				}
-				return 1;
-			}
-			for (var gear = (uint)Data.Gears.Count; gear > 1; gear--) {
-				var response = Gearbox.Initialize(gear, outTorque, outEngineSpeed);
-
-				var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
-				var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
-				var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
-				var inTorque = response.ClutchPowerRequest / inAngularSpeed;
-
-				// if in shift curve and torque reserve is provided: return the current gear
-				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
-					reserve >= Data.StartTorqueReserve) {
-					if ((inAngularSpeed - DataBus.EngineIdleSpeed) / (DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
-						Constants.SimulationSettings.ClutchClosingSpeedNorm && gear > 1) {
-						gear--;
-					}
-
-					return gear;
-				}
-
-				// 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) && gear < Data.Gears.Count) {
-					return gear + 1;
-				}
-			}
-
-			// fallback: return first gear
-			return 1;
-		}
-
-		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
-		{
-			// no shift when vehicle stands
-			if (DataBus.VehicleStopped) {
-				return false;
-			}
-
-			// emergency shift to not stall the engine ------------------------
-			NextGear = gear;
-			while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
-				NextGear--;
-			}
-			while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
-				NextGear++;
-			}
-			if (NextGear != gear) {
-				return true;
-			}
-
-
-			// normal shift when all requirements are fullfilled ------------------
-			var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmallerOrEqual(absTime);
-			if (!minimumShiftTimePassed) {
-				return false;
-			}
-
-			NextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
-			if (NextGear != gear) {
-				return true;
-			}
-
-			NextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear);
-
-			if ((Data.Gears[NextGear].Ratio * outAngularVelocity - DataBus.EngineIdleSpeed) /
-				(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) <
-				Constants.SimulationSettings.ClutchClosingSpeedNorm && NextGear > 1) {
-				NextGear--;
-			}
-
-			return (NextGear != gear);
-		}
-
-		protected virtual uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
-		{
-			return DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
-		}
-
-		protected virtual uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
-		{
-			return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
-		}
-
-		protected virtual uint DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
-		{
-			// upshift
-			while (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				currentGear++;
-				if (!Data.SkipGears) {
-					break;
-				}
-
-				var tmpGear = Gearbox.Gear;
-				Gearbox.Gear = currentGear;
-				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-				Gearbox.Gear = tmpGear;
-
-				inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
-				inTorque = response.ClutchPowerRequest / inAngularVelocity;
-			}
-
-			// early up shift to higher gear ---------------------------------------
-			if (Data.EarlyShiftUp && currentGear < Data.Gears.Count) {
-				// try if next gear would provide enough torque reserve
-				var tryNextGear = currentGear + 1;
-				var tmpGear = Gearbox.Gear;
-				Gearbox.Gear = tryNextGear;
-				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-				Gearbox.Gear = tmpGear;
-				if (!(response is ResponseEngineSpeedTooLow)) {
-					inAngularVelocity = Data.Gears[tryNextGear].Ratio * outAngularVelocity;
-					inTorque = response.ClutchPowerRequest / inAngularVelocity;
-
-					// if next gear supplied enough power reserve: take it
-					// otherwise take
-					if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
-						var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
-						var reserve = 1 - response.EnginePowerRequest / fullLoadPower;
-
-						if (reserve >= Data.TorqueReserve) {
-							currentGear = tryNextGear;
-						}
-					}
-				}
-			}
-			return currentGear;
-		}
-
-
-		protected virtual uint DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
-		{
-			// down shift
-			while (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				currentGear--;
-				if (!Data.SkipGears) {
-					break;
-				}
-				var tmpGear = Gearbox.Gear;
-				Gearbox.Gear = currentGear;
-				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-				Gearbox.Gear = tmpGear;
-
-				inAngularVelocity = Data.Gears[currentGear].Ratio * outAngularVelocity;
-				inTorque = response.ClutchPowerRequest / inAngularVelocity;
-			}
-			return currentGear;
-		}
-	}
-
-
-//###############################################################################
-//###############################################################################
-//###############################################################################
-
-
-	public class MTShiftStrategy : AMTShiftStrategy
-	{
-		public MTShiftStrategy(GearboxData data, IDataBus bus) : base(data, bus)
-		{
-			Data.EarlyShiftUp = false;
-			Data.SkipGears = true;
-		}
-
-		protected override uint CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
-		{
-			// if the driver's intention is _not_ to accelerate or drive along then don't upshift
-			if (DataBus.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverBehavior != DrivingBehavior.Driving) {
-				return currentGear;
-			}
-			if ((absTime - Gearbox.LastDownshift).IsSmaller(10.SI<Second>())) {
-				return currentGear;
-			}
-			var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
-			if (nextGear == currentGear) {
-				return nextGear;
-			}
-
-			// estimate acceleration for selected gear
-			if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
-				// if less than 0.1 for next gear, don't shift
-				if (nextGear - currentGear == 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 > currentGear &&
-					EstimateAccelerationForGear(currentGear + 1, outAngularVelocity).IsSmaller(0.1.SI<MeterPerSquareSecond>())) {
-					return currentGear;
-				}
-			}
-
-			return nextGear;
-		}
-
-		protected override uint CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint currentGear)
-		{
-			if ((absTime - Gearbox.LastUpshift).IsSmaller(10.SI<Second>())) {
-				return currentGear;
-			}
-			return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear);
-		}
-	}
 }
\ No newline at end of file
-- 
GitLab