From e1653303df3366b6dfb2138b0cd9e5633a3c844d Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 11 Mar 2025 14:53:24 +0100
Subject: [PATCH 01/22] Remamed AMTShiftStrategyTests.cs

---
 .../{AMTShistStrategyTests.cs => AMTShiftStrategyTests.cs}      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/{AMTShistStrategyTests.cs => AMTShiftStrategyTests.cs} (99%)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShistStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs
similarity index 99%
rename from Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShistStrategyTests.cs
rename to Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs
index 2210187284..f522c312af 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShistStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
@@ -22,7 +22,7 @@ using Assert = NUnit.Framework.Assert;
 
 namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
 
-public class AMTShistStrategyTests
+public class AMTShiftStrategyTests
 {
     [TestCase(8, 7, 1800, 750, true),
 TestCase(7, 6, 1800, 750, true),
-- 
GitLab


From a5028da618c02a8c207f77cf059f2bb079f7f093 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 11 Mar 2025 15:13:31 +0100
Subject: [PATCH 02/22] Added Tests to AMTShiftStrategyTests.cs

---
 .../AMTShiftStrategyTests.cs                  | 200 ++++++++++++++++++
 1 file changed, 200 insertions(+)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs
index f522c312af..13d05f4e4a 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
@@ -14,6 +14,7 @@ using TUGraz.VectoCore.Models.SimulationComponent;
 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.Data.Gearbox;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
@@ -108,6 +109,205 @@ TestCase(8, 4, 15000, 200, true),]
         var absTime = 0.SI<Second>();
         var dt = 2.SI<Second>();
 
+        var expectedN = n.RPMtoRad();
+        var angularVelocity = expectedN / ratios[gear];
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+        absTime += dt;
+
+        var expectedT = tq.SI<NewtonMeter>();
+		var torque = expectedT * ratios[gear];
+
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+	[TestCase(2, 3, 800, 1400, 20_000, true, Description = "A gear would be skipped, but due to the uphill driving conditions, the next gear should be used")]
+	[TestCase(3, 3, 1000, 1400, 30_000, false, Description = "No upshifting because acceleration would be to low")]
+    public void Gearbox_ShiftUpUphill(int gear, int newGear, double tq, double n, double slopeResistance, bool shiftExpected)
+	{
+		// the first element 0.0 is just a placeholder for axlegear, not used in this test
+		var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+		var runData = GetRunData(ratios);
+
+		var container = GetMockVehicleContainer(runData);
+
+		var accEstimationLookAhead = Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation;
+
+		container.Setup(c => c.VehicleInfo.SlopeResistance(It.IsAny<Radian>())).Returns(slopeResistance.SI<Newton>());
+
+		
+		//container.Setup(c => c.DrivingCycleInfo.CycleLookAhead(accEstimationLookAhead))
+		//	.Returns(new DrivingCycleData.DrivingCycleEntry() {
+		//		Altitude = 100.SI<Meter>()
+		//	});
+		//container.Setup(c => c.DrivingCycleInfo.Altitude).Returns(0.SI<Meter>());
+
+
+
+
+
+
+        var testPt = GetMockTestPowertrain(runData);
+
+		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+			.Returns(testPt.Object);
+		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+
+		var gbx = GetMockGearbox(container);
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineSpeed).Returns(() => n.RPMtoRad());
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineN95hSpeed).Returns(2000.RPMtoRad());
+
+		var shiftStrategy = new AMTShiftStrategy(container.Object);
+		shiftStrategy.Gearbox = gbx.Object;
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+		var expectedN = n.RPMtoRad();
+		var angularVelocity = expectedN / ratios[gear];
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+		absTime += dt;
+
+		var expectedT = tq.SI<NewtonMeter>();
+		var torque = expectedT * ratios[gear];
+
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+		Assert.AreEqual(shiftExpected, shiftRequired);
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+
+    [TestCase(7, 1, 1000, 1400, true)]
+	[TestCase(7, 2, 400, 200, true)]
+    public void InitStartGear(int gear, int newGear, double tq, double n, bool shiftExpected)
+	{
+		// the first element 0.0 is just a placeholder for axlegear, not used in this test
+		var ratios = new[] { 0.0, 6.38, 5.2, 4.3, 3.2, 2.5, 1.8, 1, 0.76 };
+		var runData = GetRunData(ratios);
+
+		var container = GetMockVehicleContainer(runData);
+		container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(0.KMPHtoMeterPerSecond());
+		var testPt = GetMockTestPowertrain(runData);
+
+		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+			.Returns(testPt.Object);
+		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+
+		var gbx = GetMockGearbox(container);
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineSpeed).Returns(() => n.RPMtoRad());
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineN95hSpeed).Returns(2000.RPMtoRad());
+
+		var shiftStrategy = new AMTShiftStrategy(container.Object);
+		shiftStrategy.Gearbox = gbx.Object;
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+		var expectedN = n.RPMtoRad();
+		var angularVelocity = expectedN / ratios[gear];
+
+
+		testPt.Setup(t => t.Gearbox.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true)).Returns(new ResponseDryRun(null)
+		{
+			Engine = {
+				TotalTorqueDemand = 2.SI<NewtonMeter>(),
+				DynamicFullLoadTorque = 4.SI<NewtonMeter>(),
+				EngineSpeed = 600.RPMtoRad(),
+			}
+		});
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+		absTime += dt;
+
+		var expectedT = tq.SI<NewtonMeter>();
+		var torque = expectedT * ratios[gear];
+
+
+		//var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+		//	new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+		//Assert.AreEqual(shiftExpected, shiftRequired);
+		Assert.GreaterOrEqual(shiftStrategy.MaxStartGear.Gear, newGear);
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+		[TestCase(2, 1, 2, 1000, 300)]
+		[TestCase(3, 2, 2, 1000, 1400)]
+		[TestCase(8, 7, 2, 1800, 750)]
+		[TestCase(7, 6, 2, 1800, 750)]
+		[TestCase(6, 5, 2, 1800, 750)]
+		[TestCase(5, 4, 2, 1800, 750)]
+		[TestCase(4, 3, 2, 1800, 750)]
+		[TestCase(3, 2, 2, 1800, 750)]
+		[TestCase(2, 2, 2, 1900, 750)]
+		[TestCase(1, 2, 2, 1200, 700)]
+		[TestCase(8, 4, 2, 15000, 200)]
+		[TestCase(2, 2, 2, 300, 1000)]
+    public void Gearbox_PTO(int gear, int newGear, int ptoGear, double tq, double n)
+	{
+		var shiftExpected = gear != newGear;
+        // the first element 0.0 is just a placeholder for axlegear, not used in this test
+        var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+        var runData = GetRunData(ratios);
+
+		runData.DriverData = new DriverData() {
+			PTODriveRoadsweepingGear = new GearshiftPosition((uint)ptoGear)
+		};
+
+        var container = GetMockVehicleContainer(runData);
+
+		container.Setup(c => c.DrivingCycleInfo.CycleData).Returns(
+			new CycleData() {
+				LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+					PTOActive = PTOActivity.PTOActivityRoadSweeping,
+					RoadGradient = 0.SI<Radian>(),
+				}
+			}
+		);
+
+
+        var testPt = GetMockTestPowertrain(runData);
+
+        var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+			.Returns(testPt.Object);
+        container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+
+		var gbx = GetMockGearbox(container);
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineSpeed).Returns(() => n.RPMtoRad());
+        Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineN95hSpeed).Returns(2000.RPMtoRad());
+
+        var shiftStrategy = new AMTShiftStrategy(container.Object);
+		shiftStrategy.Gearbox = gbx.Object;
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
         var expectedN = n.RPMtoRad();
         var angularVelocity = expectedN / ratios[gear];
 
-- 
GitLab


From 1be37e9d68bd550a19090cb2ad804c7b1841b5ca Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 10:49:43 +0100
Subject: [PATCH 03/22] Simple Powertrain Builder use overloads instead of
 default parameters (they dont go well with mocking)

---
 .../Models/Simulation/ISimplePowertrainBuilder.cs         | 5 ++---
 .../Models/Simulation/Impl/SimplePowertrainBuilder.cs     | 8 +++++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/VectoCore/VectoCore/Models/Simulation/ISimplePowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/ISimplePowertrainBuilder.cs
index b46bbb0b01..a2146fe114 100644
--- a/VectoCore/VectoCore/Models/Simulation/ISimplePowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/ISimplePowertrainBuilder.cs
@@ -9,9 +9,8 @@ namespace TUGraz.VectoCore.Models.Simulation
     public interface ISimplePowertrainBuilder
 	{
 		//ITestPowertrain CreateTestPowertrain(ISimpleVehicleContainer testContainer, IDataBus realContainer, bool createDriver);
-
-		ITestPowertrain CreateTestPowertrain(IVehicleContainer realContainer, bool createDriver, VectoSimulationJobType? overrideJobType = null);
-
+		ITestPowertrain CreateTestPowertrain(IVehicleContainer realContainer, bool createDriver, VectoSimulationJobType overrideJobType);
+		ITestPowertrain CreateTestPowertrain(IVehicleContainer realContainer, bool createDriver);
         ITestGenset CreateTestGenset(IVehicleContainer realContainer);
 
         /// <summary>
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimplePowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimplePowertrainBuilder.cs
index 9068c164fe..2ce2331314 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/SimplePowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimplePowertrainBuilder.cs
@@ -32,12 +32,18 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
         }
 
 
-		public ITestPowertrain CreateTestPowertrain(IVehicleContainer realContainer, bool createDriver, VectoSimulationJobType? overrideJobType)
+		public ITestPowertrain CreateTestPowertrain(IVehicleContainer realContainer, bool createDriver, VectoSimulationJobType overrideJobType)
 		{
 			var testContainer = BuildSimplePowertrain(realContainer.RunData, overrideJobType);
 			return new TestPowertrain(testContainer, realContainer, createDriver);
 		}
 
+		public ITestPowertrain CreateTestPowertrain(IVehicleContainer realContainer, bool createDriver)
+		{
+			var testContainer = BuildSimplePowertrain(realContainer.RunData, null);
+			return new TestPowertrain(testContainer, realContainer, createDriver);
+		}
+
         public ITestGenset CreateTestGenset(IVehicleContainer realContainer)
 		{
 			var testContainer = BuildSimpleGenSet(realContainer.RunData);
-- 
GitLab


From 2e8150be4ae482ec9eeeb7ce2658d927cd4d72ef Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 10:50:29 +0100
Subject: [PATCH 04/22] Added AMTShiftStrategyOptimizedTests.cs (with mocked
 gearboxes)

---
 .../AMTShiftStrategyOptimizedTests.cs         | 1105 +++++++++++++++++
 1 file changed, 1105 insertions(+)
 create mode 100644 Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs
new file mode 100644
index 0000000000..5e72e31099
--- /dev/null
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs	
@@ -0,0 +1,1105 @@
+using System.ComponentModel.Design.Serialization;
+using Moq;
+using NUnit.Framework;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.Models.Connector.Ports;
+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;
+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;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
+using TUGraz.VectoCore.Tests.Utils;
+using Assert = NUnit.Framework.Assert;
+using Range = System.Range;
+
+namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
+
+[TestFixture]
+public class AMTShiftStrategyOptimizedTests
+{
+    [TestCase(8, 7, 1800, 750, true),
+TestCase(7, 6, 1800, 750, true),
+TestCase(6, 5, 1800, 750, true),
+TestCase(5, 4, 1800, 750, true),
+TestCase(4, 3, 1800, 750, true),
+TestCase(3, 2, 1800, 750, true),
+TestCase(2, 1, 1900, 750, true),
+TestCase(1, 1, 1200, 700, false),
+TestCase(8, 4, 15000, 200, true),]
+    public void Gearbox_ShiftDown_ACEA_Shiftlines(int gear, int newGear, double t, double n, bool shiftExpected)
+    {
+		// the first element 0.0 is just a placeholder for axlegear, not used in this test
+		var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		//Get Containers and MockData
+		var vehicleContainer = GetMocks(ratios, out var runData, out var testPowertrain);
+
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		vehicleContainer.Setup(c => c.EngineInfo.EngineSpeed).Returns(() => n.RPMtoRad());
+		vehicleContainer.Setup(c => c.EngineInfo.EngineN95hSpeed).Returns(() => 2000.RPMtoRad());
+
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        var expectedN = n.RPMtoRad();
+        var angularVelocity = expectedN / ratios[gear];
+
+		
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+        var expectedT = t.SI<NewtonMeter>();
+		var torque = expectedT * ratios[gear];
+
+		var response = new ResponseSuccess(this);
+		response.Engine.TorqueOutDemand = expectedT;
+		response.Engine.EngineSpeed = expectedN;
+		
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), response);
+        Assert.AreEqual(shiftExpected, shiftRequired);
+        Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+	[TestCase(7, 8, 1000, 1400, true),
+	TestCase(6, 8, 800, 1400, true),
+	TestCase(5, 6, 1000, 1400, true),
+	TestCase(4, 5, 1000, 1400, true),
+	TestCase(3, 4, 1000, 1400, true),
+	TestCase(2, 4, 800, 1400, true),
+	TestCase(1, 2, 1000, 1400, true),
+	TestCase(8, 8, 1000, 1400, false),
+	TestCase(1, 6, 200, 9000, true),]
+    public void Gearbox_ShiftUp(int gear, int newGear, double tq, double n, bool shiftExpected)
+    {
+		// the first element 0.0 is just a placeholder for axlegear, not used in this test
+		var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+
+		var container = GetMocks(ratios, out var runData, out _);
+		var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gbx);
+
+		container.Setup(c => c.EngineInfo.EngineSpeed).Returns(() => n.RPMtoRad());
+		container.Setup(c => c.EngineInfo.EngineN95hSpeed).Returns(2000.RPMtoRad());
+
+
+		var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        var expectedN = n.RPMtoRad();
+        var angularVelocity = expectedN / ratios[gear];
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+        absTime += dt;
+
+        var expectedT = tq.SI<NewtonMeter>();
+		var torque = expectedT * ratios[gear];
+
+		var response = new ResponseSuccess(this);
+		//Setup Response
+		response.Engine.TorqueOutDemand = expectedT;
+		response.Engine.EngineSpeed = expectedN;
+
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), response);
+
+
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+	// [TestCase(2, 3, 800, 1400, 20_000, true, Description = "A gear would be skipped, but due to the uphill driving conditions, the next gear should be used")]
+	// [TestCase(3, 3, 1000, 1400, 30_000, false, Description = "No upshifting because acceleration would be to low")]
+ //    public void Gearbox_ShiftUpUphill(int gear, int newGear, double tq, double n, double slopeResistance, bool shiftExpected)
+	// {
+	// 	// the first element 0.0 is just a placeholder for axlegear, not used in this test
+	// 	var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+	// 	var container = GetMocks(ratios, out var runData, out _);
+ //
+	// 	var accEstimationLookAhead = Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation;
+ //
+	// 	container.Setup(c => c.VehicleInfo.SlopeResistance(It.IsAny<Radian>())).Returns(slopeResistance.SI<Newton>());
+	// 	container.Setup(c => c.DrivingCycleInfo.CycleLookAhead(accEstimationLookAhead))
+	// 		.Returns(new DrivingCycleData.DrivingCycleEntry() {
+	// 			Altitude = 100.SI<Meter>()
+	// 		});
+	// 	container.Setup(c => c.DrivingCycleInfo.Altitude).Returns(0.SI<Meter>());
+ //
+ //
+	// 	
+ //
+ //
+ //
+ //  //       var testPt = GetMockTestPowertrain(runData, out var simplePt);
+ //  //
+	// 	// var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+	// 	// ptBuilder.Setup(p => p.CreateTestPowertrain<Gearbox>(It.IsAny<ISimpleVehicleContainer>(), It.IsAny<IDataBus>()))
+	// 	// 	.Returns(testPt.Object);
+ //  //
+	// 	// ptBuilder.Setup(p => p.BuildSimplePowertrain(It.IsAny<VectoRunData>())).Returns(simplePt.Object);
+	// 	// container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+ //  //
+	// 	// var gbx = GetMockGearbox(container);
+	// 	// Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineSpeed).Returns(() => n.RPMtoRad());
+	// 	// Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineN95hSpeed).Returns(2000.RPMtoRad());
+ //
+	// 	var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gbx);
+	// 	// var shiftStrategy = new AMTShiftStrategyOptimized(container.Object);
+	// 	// shiftStrategy.Gearbox = gbx.Object;
+ //
+	// 	var absTime = 0.SI<Second>();
+	// 	var dt = 2.SI<Second>();
+ //
+	// 	var expectedN = n.RPMtoRad();
+	// 	var angularVelocity = expectedN / ratios[gear];
+ //
+	// 	var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+	// 		angularVelocity);
+ //
+	// 	absTime += dt;
+ //
+	// 	var expectedT = tq.SI<NewtonMeter>();
+	// 	var torque = expectedT * ratios[gear];
+ //
+ //
+	// 	var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+	// 		new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+ //
+	// 	Assert.AreEqual(shiftExpected, shiftRequired);
+	// 	Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+ //    }
+ //
+ //
+	[TestCase]
+	public void GetMocksTest()
+	{
+		// the first element 0.0 is just a placeholder for axlegear, not used in this test
+		var ratios = new[] { 0.0, 6.38, 4.63, 3.84, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		var mockContainer = GetMocks(ratios,
+			out var runData,
+			out var testPowertrain);
+
+		var container = mockContainer.Object;
+		var createdTestPowertrain = container.SimplePowertrainBuilder.CreateTestPowertrain(container, false);
+		
+		Assert.NotNull(createdTestPowertrain.Container.GearboxOutPort);
+		Assert.NotNull(createdTestPowertrain);
+	}
+
+
+	[TestCase(1, 2, 100, 900, true)]
+	[TestCase(4, 5, 100, 900, true)]
+	[TestCase(5, 6, 100, 900, true)]
+
+    public void Gearbox_EarlyUpShift(int gear, int newGear, double tq, double n, bool shiftExpected)
+    {
+        // the first element 0.0 is just a placeholder for axlegear, not used in this test
+        var ratios = new[] { 0.0, 6.38, 4.63, 3.84, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		var container = GetMocks(ratios,
+			out var runData,
+			out var testPowertrain);
+
+
+		
+		
+		runData.GearshiftParameters.RatioEarlyUpshiftFC = 10;
+		runData.GearshiftParameters.MinEngineSpeedPostUpshift = 1.RPMtoRad();
+		runData.GearshiftParameters.TorqueReserve = 0.1;
+		runData.GearshiftParameters.RatingFactorCurrentGear = 0.97;
+		var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gbx);
+		
+		
+		container.Setup(c => c.EngineInfo.EngineSpeed).Returns(() => n.RPMtoRad());
+		container.Setup(c => c.EngineInfo.EngineN95hSpeed).Returns(() => 2000.RPMtoRad());
+		
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        var expectedN = n.RPMtoRad();
+        var angularVelocity = expectedN / ratios[gear];
+
+        var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+            angularVelocity);
+		
+		
+		
+        absTime += dt;
+
+        var expectedT = tq.SI<NewtonMeter>();
+        var torque = expectedT * ratios[gear];
+
+		var response = new ResponseSuccess(this);
+		response.Engine.TorqueOutDemand = expectedT;
+		response.Engine.EngineSpeed = expectedN;
+
+
+
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+            new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), response);
+
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+
+	
+
+    [TestCase(7, 1, 1000, 1400, true)]
+	[TestCase(7, 2, 400, 200, true)]
+    public void InitStartGear(int gear, int newGear, double tq, double n, bool shiftExpected)
+	{
+		// the first element 0.0 is just a placeholder for axlegear, not used in this test
+		var ratios = new[] { 0.0, 6.38, 5.2, 4.3, 3.2, 2.5, 1.8, 1, 0.76 };
+		var container = GetMocks(ratios, out var runData, out var testPt);
+		
+		container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(0.KMPHtoMeterPerSecond());
+
+		var gbx = GetMockGearbox();
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineSpeed).Returns(() => n.RPMtoRad());
+		Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineN95hSpeed).Returns(2000.RPMtoRad());
+
+		var shiftStrategy = new AMTShiftStrategyOptimized(container.Object);
+		shiftStrategy.Gearbox = gbx.Object;
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+		var expectedN = n.RPMtoRad();
+		var angularVelocity = expectedN / ratios[gear];
+
+
+		testPt.Setup(t => t.Gearbox.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true)).Returns(new ResponseDryRun(null)
+		{
+			Engine = {
+				TotalTorqueDemand = 2.SI<NewtonMeter>(),
+				DynamicFullLoadTorque = 4.SI<NewtonMeter>(),
+				EngineSpeed = 600.RPMtoRad(),
+			}
+		});
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+		absTime += dt;
+
+		var expectedT = tq.SI<NewtonMeter>();
+		var torque = expectedT * ratios[gear];
+
+
+		//var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+		//	new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+		//Assert.AreEqual(shiftExpected, shiftRequired);
+		Assert.GreaterOrEqual(shiftStrategy.MaxStartGear.Gear, newGear);
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+		[TestCase(2, 1, 2, 1000, 300)]
+		[TestCase(3, 2, 2, 1000, 1400)]
+		[TestCase(8, 7, 2, 1800, 750)]
+		[TestCase(7, 6, 2, 1800, 750)]
+		[TestCase(6, 5, 2, 1800, 750)]
+		[TestCase(5, 4, 2, 1800, 750)]
+		[TestCase(4, 3, 2, 1800, 750)]
+		[TestCase(3, 2, 2, 1800, 750)]
+		[TestCase(2, 2, 2, 1900, 750)]
+		[TestCase(1, 2, 2, 1200, 700)]
+		[TestCase(8, 4, 2, 15000, 200)]
+		[TestCase(2, 2, 2, 300, 1000)]
+    public void Gearbox_PTO(int gear, int newGear, int ptoGear, double tq, double n)
+	{
+		var shiftExpected = gear != newGear;
+        // the first element 0.0 is just a placeholder for axlegear, not used in this test
+        var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		var container = GetMocks(ratios, out VectoRunData runData, out _);
+
+		runData.DriverData = new DriverData() {
+			PTODriveRoadsweepingGear = new GearshiftPosition((uint)ptoGear)
+		};
+
+		container.Setup(c => c.DrivingCycleInfo.CycleData).Returns(
+			new CycleData() {
+				LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+					PTOActive = PTOActivity.PTOActivityRoadSweeping,
+					RoadGradient = 0.SI<Radian>(),
+				}
+			}
+		);
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gbx);
+
+
+
+        ////Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineSpeed).Returns(() => n.RPMtoRad());
+        ////Mock.Get(container.Object.EngineInfo).Setup(e => e.EngineN95hSpeed).Returns(2000.RPMtoRad());
+
+
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        var expectedN = n.RPMtoRad();
+        var angularVelocity = expectedN / ratios[gear];
+
+        var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+            angularVelocity);
+
+        absTime += dt;
+
+        var expectedT = tq.SI<NewtonMeter>();
+        var torque = expectedT * ratios[gear];
+
+		var response = new ResponseSuccess(this) {
+
+		};
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+            new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), response);
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+        Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+    }
+
+
+	private Mock<IVehicleContainer> GetMocks(double[] ratios,
+		out VectoRunData runData,
+		out Mock<ITestPowertrain> testPowertrain)
+	{
+		runData = GetRunData(ratios);
+
+		var container = GetMockVehicleContainer(runData);
+
+		
+		//Use simple powertrain to create testpowertrain
+		testPowertrain = GetMockTestPowertrain(runData, out var simpleContainer);
+		
+		
+		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+
+		//TestPowertrain
+		ptBuilder.Setup(p => p.CreateTestPowertrain(
+				It.IsAny<IVehicleContainer>(),
+				It.IsAny<bool>()))
+			.Returns(testPowertrain.Object);
+
+		ptBuilder.Setup(p => p.CreateTestPowertrain(
+			It.IsAny<IVehicleContainer>(),
+			It.IsAny<bool>(), It.IsAny<VectoSimulationJobType>())).Throws(new NotImplementedException());
+		
+		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+		
+
+
+		return container;
+	}
+
+
+
+
+    private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData, out Mock<ISimpleVehicleContainer> simpleContainer)
+    {
+        var testPt = new Mock<ITestPowertrain>();
+		
+		simpleContainer = GetSimplePowertrain(runData, out var testGearbox);
+		testPt.Setup(t => t.Container).Returns(simpleContainer.Object);
+
+		testPt.Setup(t => t.Gearbox).Returns(testGearbox.Object);
+  //       tGbx.Setup(g => g.Initialize(It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>()))
+  //           .Returns((NewtonMeter t, PerSecond n) => new ResponseSuccess(this) {
+  //               Engine = { PowerRequest = n * t, 
+		// 			EngineSpeed = n },
+  //               Clutch = { PowerRequest = n * t }
+  //           });
+  //       tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+  //               It.IsAny<bool>()))
+  //           .Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => new ResponseSuccess(this) {
+  //               Engine = { PowerRequest = n * t, EngineSpeed = n },
+  //               Clutch = { PowerRequest = n * t }
+  //           });
+		// tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+		// 		It.IsAny<bool>()))
+		// 	.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => dryRun ? 
+		// 	new ResponseDryRun(this) {
+		// 		Engine = { 
+		// 			PowerRequest = n * t, 
+		// 			EngineSpeed = n,
+		// 			TotalTorqueDemand = t,
+		// 		},
+		// 		Clutch = { PowerRequest = n * t },
+		// 		DeltaFullLoad = n*t / 2 *(-1)
+		// 	}: new ResponseSuccess(this) {
+		// 		Engine = { PowerRequest = n * t, EngineSpeed = n },
+		// 		Clutch = { PowerRequest = n * t }
+		// 	});
+        var tEng = new Mock<ITestpowertrainCombustionEngine>();
+        testPt.Setup(t => t.CombustionEngine).Returns(tEng.Object);
+        tEng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
+            .Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+        return testPt;
+    }
+
+	private static Mock<IPowertainInfo> GetPowertrainInfo()
+	{
+		var tPi = new Mock<IPowertainInfo>();
+		tPi.Setup(p => p.HasCombustionEngine).Returns(true);
+		return tPi;
+	}
+
+	private static Mock<IVehicleContainer> GetMockVehicleContainer(VectoRunData runData)
+    {
+        var container = new Mock<IVehicleContainer>();
+        container.Setup(c => c.RunData).Returns(runData);
+        var veh = new Mock<IVehicleInfo>();
+        veh.Setup(v => v.VehicleSpeed).Returns(10.SI<MeterPerSecond>());
+        container.Setup(c => c.VehicleInfo).Returns(veh.Object);
+        var eng = new Mock<IEngineInfo>();
+        container.Setup(c => c.EngineInfo).Returns(eng.Object);
+        eng.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
+        eng.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
+        eng.Setup(e => e.EngineN95hSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
+		eng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
+			.Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+        var ci = new Mock<IDrivingCycleInfo>();
+        container.Setup(c => c.DrivingCycleInfo).Returns(ci.Object);
+        var di = new Mock<IDriverInfo>();
+		di.Setup(d => d.DriverBehavior).Returns(DrivingBehavior.Accelerating);
+		di.Setup(d => d.DrivingAction).Returns(DrivingAction.Accelerate);
+        container.Setup(c => c.DriverInfo).Returns(di.Object);
+        ci.Setup(c => c.CycleData).Returns(new CycleData() { LeftSample = new DrivingCycleData.DrivingCycleEntry() { PTOActive = PTOActivity.Inactive } });
+		ci.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry() {
+			Altitude = 0.SI<Meter>()
+		});
+		ci.Setup(c => c.Altitude).Returns(0.SI<Meter>());
+		var pi = new Mock<IPowertainInfo>();
+        pi.Setup(p => p.HasCombustionEngine).Returns(true);
+        container.Setup(c => c.PowertrainInfo).Returns(pi.Object);
+        var vi = new Mock<IVehicleInfo>();
+		vi.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
+			.Returns(0.SI<Newton>());
+		vi.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vi.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vi.Setup(v => v.VehicleSpeed).Returns(30.KMPHtoMeterPerSecond());
+		vi.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+		container.Setup(c => c.VehicleInfo).Returns(vi.Object);
+		var wi = new Mock<IWheelsInfo>();
+		container.Setup(c => c.WheelsInfo).Returns(wi.Object);
+		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
+		var axli = new Mock<IAxlegearInfo>();
+		container.Setup(c => c.AxlegearInfo).Returns(axli.Object);
+		axli.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
+        return container;
+    }
+
+	
+	private AMTShiftStrategyOptimized GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer, out Mock<IGearbox> gbx)
+	{
+		var shiftStrategy = new AMTShiftStrategyOptimized(vehicleContainer.Object);
+
+
+		gbx = GetMockGearbox();
+		var mockPort = new Mock<ITnOutPort>();
+		shiftStrategy.Gearbox = gbx.Object;
+
+
+		// NewtonMeter tqRequest = null;
+		// PerSecond rpmRequest = null;
+		// mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+		// 	tqRequest = tq;
+		// 	rpmRequest = rpm;
+		// 	return new ResponseSuccess(this)
+		// 	{
+		// 		Engine = {
+		// 			EngineSpeed = rpm,
+		// 			PowerRequest = tq * rpm,
+		// 		},
+		// 	};
+		// });
+		// mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
+		//
+		// gbx.Connect(mockPort.Object);
+
+		SetVelocityDropLookupData(shiftStrategy);
+        return shiftStrategy;
+	}
+
+	
+	
+
+    private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData, out Mock<ITestPowertrainTransmission> testGearbox)
+	{
+		var simplePt = new Mock<ISimpleVehicleContainer>();
+		simplePt.Setup(s => s.RunData).Returns(runData);
+		simplePt.Setup(s => s.AddComponent(It.IsAny<VectoSimulationComponent>()));
+		simplePt.Setup(s => s.PowertrainInfo).Returns(GetPowertrainInfo().Object);
+		simplePt.Setup(s => s.IsTestPowertrain).Returns(true);
+
+		var gbx = GetMockTestGearbox(runData.GearboxData.Gears);
+		simplePt.Setup(s => s.GearboxInfo).Returns(gbx.Object);
+		simplePt.Setup(s => s.GearboxCtl).Returns(gbx.Object);
+		simplePt.Setup(s => s.GearboxOutPort).Returns(gbx.Object);
+		//Vehicle Info
+		var vehicleInfo = new Mock<IVehicleInfo>();
+		simplePt.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
+		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
+
+		//VehiclePort
+		var vehiclePort = new Mock<IDriverDemandOutPort>();
+		vehiclePort.Setup(port => port.Initialize(
+			It.IsAny<MeterPerSecond>(), It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
+
+		// simplePt.Setup(c => c).Returns(vehiclePort.Object);
+
+
+		//GearboxOutPort
+
+
+  //       var mockPort = new Mock<ITnOutPort>();
+		// mockPort.Name = "MockPort1";
+		// mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+		// 	return new ResponseSuccess(this)
+		// 	{
+		// 		Engine = {
+		// 			EngineSpeed = rpm,
+		// 			PowerRequest = tq * rpm,
+		// 		},
+		// 	};
+		// });
+		// mockPort.Setup(p => p.Request(
+		// 		It.IsAny<Second>(),
+		// 		It.IsAny<Second>(),
+		// 		It.IsAny<NewtonMeter>(),
+		// 		It.IsAny<PerSecond>(),
+		// 		true)).Returns((
+		// 		Second absTime,
+		// 		Second dt,
+		// 		NewtonMeter t,
+		// 		PerSecond n,
+		// 		bool dryRun) => {
+  //
+		// 	var ratio = 
+		// 		gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+		// 	return dryRun
+  //
+		// 		? new ResponseDryRun(this)
+		// 		{
+		// 			Engine = {
+		// 				PowerRequest = n * t, EngineSpeed = n * ratio,
+		// 				DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+		// 				TotalTorqueDemand = t,
+		// 			},
+		// 			Clutch = { PowerRequest = n * t },
+		// 			DeltaFullLoad = n*t / 2 * (-1)
+		// 		}
+		// 		: new ResponseSuccess(this)
+		// 		{
+		// 			Engine = { 
+		// 				PowerRequest = n * t, 
+		// 				EngineSpeed = n * ratio
+  //
+		// 			},
+		// 			Clutch = { PowerRequest = n * t }
+		// 		};
+  //               });
+
+		// simplePt.Setup(c => c.GearboxOutPort).Returns(mockPort.Object);
+
+		testGearbox = gbx;
+		return simplePt;
+	}
+	
+	private Mock<IGearbox> GetMockGearbox()
+	{
+		var amtGearbox = new Mock<IAMTGearbox>(MockBehavior.Strict);
+		amtGearbox.Name = "AMT_Gearbox";
+		var gbx = amtGearbox.As<IGearbox>();
+
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+		return gbx;
+	} 
+	
+	
+    private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
+	{
+		
+		Mock<IAMTGearbox> amtGearbox = new Mock<IAMTGearbox>();
+		amtGearbox.Name = "AMT_TestGearbox";
+		Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
+
+		
+		
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+		GearshiftPosition gear = null;
+		gbx.SetupGet(g => g.Gear).Returns(() => {
+			
+			return gear;
+		});
+		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => {
+				gear = p;
+			});
+
+
+		GearshiftPosition nextGear = null;
+		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => nextGear = p);
+			
+		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			return new ResponseSuccess(this)
+			{
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		gbx.Setup(p => p.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true)).Returns((
+			Second absTime,
+			Second dt,
+			NewtonMeter t,
+			PerSecond n,
+			bool dryRun) => {
+
+			var ratio =
+				gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+			return dryRun
+				? new ResponseDryRun(this) {
+					Engine = {
+						PowerRequest = n * t, EngineSpeed = n * ratio,
+						DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						TotalTorqueDemand = t,
+					},
+					Clutch = { PowerRequest = n * t },
+					DeltaFullLoad = n * t / 2 * (-1)
+				}
+				: new ResponseSuccess(this) {
+					Engine = {
+						PowerRequest = n * t,
+						EngineSpeed = n * ratio
+
+					},
+					Clutch = { PowerRequest = n * t }
+				};
+		});
+		return gbx;
+	}
+	
+
+    private void SetVelocityDropLookupData(AMTShiftStrategyOptimized shiftStrategy)
+    {
+        //"StartVelocity [km/h], Gradient [-], EndVelocity [km/h]"
+        var data = new[] {
+            new[] { 5.0, -0.0997, 9.061522965237558 },
+            new[] { 5.0, -0.0798, 7.76698080079411 },
+            new[] { 5.0, -0.0599, 6.46583777913701 },
+            new[] { 5.0, -0.0400, 5.1596021788785045 },
+            new[] { 5.0, -0.0200, 3.8498121019126907 },
+            new[] { 5.0, 0.0000, 2.5380265159468918 },
+            new[] { 5.0, 0.0200, 1.2258160477557427 },
+            new[] { 5.0, 0.0400, 0.0 },
+            new[] { 5.0, 0.0599, 0.0 },
+            new[] { 5.0, 0.0798, 0.0 },
+            new[] { 5.0, 0.0997, 0.0 },
+            new[] { 10.0, -0.0997, 14.807789640888302 },
+            new[] { 10.0, -0.0798, 13.474253785811362 },
+            new[] { 10.0, -0.0599, 12.133880027250777 },
+            new[] { 10.0, -0.0400, 10.788221550084467 },
+            new[] { 10.0, -0.0200, 9.438862432338068 },
+            new[] { 10.0, 0.0000, 8.087408432114643 },
+            new[] { 10.0, 0.0200, 6.735477499784416 },
+            new[] { 10.0, 0.0400, 5.384690105076845 },
+            new[] { 10.0, 0.0599, 4.036659549786269 },
+            new[] { 10.0, 0.0798, 2.6929823705748137 },
+            new[] { 10.0, 0.0997, 1.3552289800549435 },
+            new[] { 20.0, -0.0997, 25.061542153872097 },
+            new[] { 20.0, -0.0798, 23.72002987685605 },
+            new[] { 20.0, -0.0599, 22.371630788642932 },
+            new[] { 20.0, -0.0400, 21.017907257116025 },
+            new[] { 20.0, -0.0200, 19.660452757813403 },
+            new[] { 20.0, 0.0000, 18.30088261992287 },
+            new[] { 20.0, 0.0200, 16.94082447048767 },
+            new[] { 20.0, 0.0400, 15.581908518759507 },
+            new[] { 20.0, 0.0599, 14.225757795590708 },
+            new[] { 20.0, 0.0798, 12.873978508374211 },
+            new[] { 20.0, 0.0997, 11.528150617530041 },
+            new[] { 30.000000000000004, -0.0997, 35.091774208140095 },
+            new[] { 30.000000000000004, -0.0798, 33.750904327320896 },
+            new[] { 30.000000000000004, -0.0599, 32.40315158162777 },
+            new[] { 30.000000000000004, -0.0400, 31.050077596965064 },
+            new[] { 30.000000000000004, -0.0200, 29.69327509188113 },
+            new[] { 30.000000000000004, 0.0000, 28.33435862498606 },
+            new[] { 30.000000000000004, 0.0200, 26.974955046566407 },
+            new[] { 30.000000000000004, 0.0400, 25.616693776603913 },
+            new[] { 30.000000000000004, 0.0599, 24.261197065863925 },
+            new[] { 30.000000000000004, 0.0798, 22.91007034016412 },
+            new[] { 30.000000000000004, 0.0997, 21.56489279686667 },
+            new[] { 40.0, -0.0997, 45.024018797189854 },
+            new[] { 40.0, -0.0798, 43.68636622428101 },
+            new[] { 40.0, -0.0599, 42.34185052441486 },
+            new[] { 40.0, -0.0400, 40.99202962224952 },
+            new[] { 40.0, -0.0200, 39.63849244500093 },
+            new[] { 40.0, 0.0000, 38.282849690992855 },
+            new[] { 40.0, 0.0200, 36.926724305651554 },
+            new[] { 40.0, 0.0400, 35.57174178507285 },
+            new[] { 40.0, 0.0599, 34.21952045137207 },
+            new[] { 40.0, 0.0798, 32.87166183129923 },
+            new[] { 40.0, 0.0997, 31.5297412694979 },
+            new[] { 50.0, -0.0997, 54.652157586769704 },
+            new[] { 50.0, -0.0798, 53.319266704395716 },
+            new[] { 50.0, -0.0599, 51.97954186606304 },
+            new[] { 50.0, -0.0400, 50.634535516787736 },
+            new[] { 50.0, -0.0200, 49.28583097196263 },
+            new[] { 50.0, 0.0000, 47.93503321632867 },
+            new[] { 50.0, 0.0200, 46.583759417454765 },
+            new[] { 50.0, 0.0400, 45.23362925944123 },
+            new[] { 50.0, 0.0599, 43.88625525588574 },
+            new[] { 50.0, 0.0798, 42.54323315977748 },
+            new[] { 50.0, 0.0997, 41.20613261641401 },
+            new[] { 60.00000000000001, -0.0997, 64.2503607025971 },
+            new[] { 60.00000000000001, -0.0798, 62.91932863058169 },
+            new[] { 60.00000000000001, -0.0599, 61.58156853535776 },
+            new[] { 60.00000000000001, -0.0400, 60.23862904729555 },
+            new[] { 60.00000000000001, -0.0200, 58.89369896300112 },
+            new[] { 60.00000000000001, 0.0000, 57.547040626925885 },
+            new[] { 60.00000000000001, 0.0200, 56.199911833784675 },
+            new[] { 60.00000000000001, 0.0400, 54.85392730356455 },
+            new[] { 60.00000000000001, 0.0599, 53.510694584916905 },
+            new[] { 60.00000000000001, 0.0798, 52.17180450267632 },
+            new[] { 60.00000000000001, 0.0997, 50.83882182989668 },
+            new[] { 70.0, -0.0997, 73.78388063954164 },
+            new[] { 70.0, -0.0798, 72.45700102808648 },
+            new[] { 70.0, -0.0599, 71.12341092304165 },
+            new[] { 70.0, -0.0400, 69.78459543842656 },
+            new[] { 70.0, -0.0200, 68.44188526693415 },
+            new[] { 70.0, 0.0000, 67.09719334997524 },
+            new[] { 70.0, 0.0200, 65.75212749798493 },
+            new[] { 70.0, 0.0400, 64.40829754257321 },
+            new[] { 70.0, 0.0599, 63.06730571969745 },
+            new[] { 70.0, 0.0798, 61.73073716025881 },
+            new[] { 70.0, 0.0997, 60.40015062055851 },
+            new[] { 80.0, -0.0997, 83.25457689135129 },
+            new[] { 80.0, -0.0798, 81.93182852399568 },
+            new[] { 80.0, -0.0599, 80.60238880559001 },
+            new[] { 80.0, -0.0400, 79.2676325992058 },
+            new[] { 80.0, -0.0200, 77.92916666616652 },
+            new[] { 80.0, 0.0000, 76.58872134590663 },
+            new[] { 80.0, 0.0200, 75.24790011046437 },
+            new[] { 80.0, 0.0400, 73.90830846424944 },
+            new[] { 80.0, 0.0599, 72.57154434889891 },
+            new[] { 80.0, 0.0798, 71.23918865436896 },
+            new[] { 80.0, 0.0997, 69.91277394305271 },
+        };
+        var entries = new List<VelocitySpeedGearshiftPreprocessor.Entry>();
+        foreach (var d in data)
+        {
+            entries.Add(new VelocitySpeedGearshiftPreprocessor.Entry()
+            {
+                StartVelocity = d[0].KMPHtoMeterPerSecond(),
+                Gradient = d[1].SI<Radian>(),
+                EndVelocity = d[2].KMPHtoMeterPerSecond(),
+            });
+        }
+
+        shiftStrategy.VelocityDropData.Data = entries.ToArray();
+
+    }
+
+    private static VectoRunData GetRunData(double[] ratios)
+    {
+        var gearboxData = new GearboxData {
+            Gears = new Dictionary<uint, GearData>()
+        };
+        for (uint i = 1; i < ratios.Length; i++) {
+            gearboxData.Gears[i] = new GearData {
+                Ratio = ratios[i],
+                LossMap = TransmissionLossMapReader.Create(0.96, ratios[i], $"Gear {i}")
+            };
+        }
+
+		IEnumerable<(uint key, EngineFullLoadCurve fld)> fldCurves =
+			ratios.Select(
+				(_, i) => ((uint)i,
+						FullLoadCurveReader.Create(InputDataHelper.InputDataAsTableData(EngineFldHdr, EngineFldData))
+					));
+
+
+		List<CombustionEngineFuelData> fuels = new List<CombustionEngineFuelData>() {
+			new CombustionEngineFuelData() {
+				ColdHotCorrectionFactor = 1,
+				ConsumptionMap = FuelConsumptionMapReader.Create(InputDataHelper.InputDataAsTableData(
+					EngineFcMapHdr, 
+					EngineFcMapData)),
+				FuelData = FuelData.Diesel,
+			}
+		};
+		var engineData = new CombustionEngineData() {
+            IdleSpeed = 560.RPMtoRad(),
+            FullLoadCurves = fldCurves.ToDictionary((x) => x.key, (x) => x.fld),
+			Fuels = fuels,
+        };
+
+        var axlRatio = 3.240355;
+        var gearsInput = gearboxData.Gears.Select(x => {
+            var r = new Mock<ITransmissionInputData>();
+            r.Setup(g => g.Ratio).Returns(x.Value.Ratio);
+            return r.Object;
+        }).ToList();
+        foreach (var entry in gearboxData.Gears) {
+            entry.Value.ShiftPolygon = DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon(
+                (int)(entry.Key - 1), engineData.FullLoadCurves.First().Value,
+                gearsInput, engineData, axlRatio, 0.5.SI<Meter>());
+        }
+
+
+		var mockCycle = new Mock<IDrivingCycleData>();
+		mockCycle.Setup(cd => cd.Entries).Returns(
+			new List<DrivingCycleData.DrivingCycleEntry>() {
+				new DrivingCycleData.DrivingCycleEntry() {
+					RoadGradient = 0.SI<Radian>()
+				}
+			});
+
+
+
+
+
+
+
+
+
+        var runData = new VectoRunData() {
+            GearboxData = gearboxData,
+            GearshiftParameters = new ShiftStrategyParameters() {
+                StartSpeed = 2.SI<MeterPerSecond>(),
+                TimeBetweenGearshifts = 6.SI<Second>(),
+                DownshiftAfterUpshiftDelay = 2.SI<Second>(),
+                UpshiftAfterDownshiftDelay = 2.SI<Second>(),
+                UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>(),
+				StartTorqueReserve = 0.2,
+            },
+            EngineData = engineData,
+            AxleGearData = new AxleGearData() {
+                AxleGear = new TransmissionData() {
+                    Ratio = 3.240355
+                }
+            },
+            VehicleData = new VehicleData() {
+                DynamicTyreRadius = 0.492.SI<Meter>(),
+            },
+			Cycle = mockCycle.Object,
+		};
+        return runData;
+    }
+
+    const string EngineFldHdr = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
+    
+    static readonly string[] EngineFldData = new[] {
+		"560,1180,-149,0.6		   ",
+		"600,1282,-148,0.6		   ",
+		"799.9999999,1791,-149,0.6 ",
+		"1000,2300,-160,0.6		   ",
+		"1200,2300,-179,0.6		   ",
+		"1400,2300,-203,0.6		   ",
+		"1599.999999,2079,-235,0.49",
+		"1800,1857,-264,0.25	   ",
+		"2000.000001,1352,-301,0.25",
+		"2100,1100,-320,0.25	   ",
+	};
+
+
+	const string EngineFcMapHdr = "engine speed [rpm], torque [Nm], fuel consumption [g/h]";
+	static readonly string[] EngineFcMapData = new[] {
+		"500,-235.5,0",
+"500,-135.5,0",
+"500,0,1355",
+"500,213.4,3412.291",
+"500,426.8,5830.1",
+"500,640.2,8316.426",
+"500,853.6,10439.87",
+"500,1067,12823.69",
+"500,1188,14228.79",
+"500,1401.4,16628.66",
+"600,-238,0",
+"600,-138,0",
+"600,0,1355",
+"600,213.4,3412.291",
+"600,426.8,5830.1",
+"600,640.2,8316.426",
+"600,853.6,10439.87",
+"600,1067,12823.69",
+"600,1188,14228.79",
+"600,1401.4,16628.66",
+"751,-241.775,0",
+"751,-141.775,0",
+"750.9,0,1649.255",
+"750.9,213.4,4157.795",
+"750.9,426.8,7149.494",
+"750.9,640.2,10037.08",
+"750.9,853.6,12957.07",
+"750.9,1067,16055.22",
+"750.9,1280.4,19231.36",
+"750.9,1493.8,22400.17",
+"750.9,1544.879,23213.92",
+"751,1758.279,26392.93",
+"902,-247.59,0",
+"902,-147.59,0",
+"901.8,0,2210.735",
+"901.8,213.4,5204.867",
+"901.8,426.8,8515.462",
+"901.8,640.2,11804.75",
+"901.8,853.6,15410.55",
+"901.8,1067,19081.7",
+"901.8,1280.4,22742.96",
+"901.8,1493.8,26543.87",
+"901.8,1707.2,30534.68",
+"901.8,1901.757,34352.75",
+"902,2115.157,38403.27",
+"1053,-255.445,0",
+"1053,-155.445,0",
+"1052.7,0,2768.035",
+"1052.7,213.4,6228.407",
+"1052.7,426.8,9836.041",
+"1052.7,640.2,13624.5",
+"1052.7,853.6,17854.95",
+"1052.7,1067,22072.71",
+"1052.7,1280.4,26161.13",
+"1052.7,1493.8,30525.55",
+"1052.7,1707.2,35019.18",
+"1052.7,1920.6,39913.3",
+"1052.7,2134,45438.16",
+"1053,2347.4,50542.53",
+"1204,-265.44,0",
+"1203.6,0,3086.704",
+"1203.6,213.4,6943.027",
+"1203.6,426.8,11040.37",
+"1203.6,640.2,15504.65",
+"1203.6,853.6,20335.89",
+"1203.6,1067,25176.6",
+"1203.6,1280.4,29782.22",
+"1203.6,1493.8,34642.24",
+"1203.6,1707.2,39786.14",
+"1203.6,1920.6,45254.8",
+"1203.6,2134,51129.03",
+"1204,2347.4,56732.88",
+"1367,-283.37,0",
+"1367,-183.37,0",
+"1367.1,0,3845.344",
+"1367.1,213.4,7981.742",
+"1367.1,426.8,12796.69",
+"1367.1,640.2,17789.2",
+"1367.1,853.6,22854.21",
+"1367.1,1067,28302.84",
+"1367.1,1280.4,33739.91",
+"1367.1,1493.8,39393.87",
+"1367.1,1707.2,45836.33",
+"1367.1,1920.6,52078.71",
+"1367.1,2134,58296.41",
+"1367,2347.4,64530.56",
+"1490,-300.5,0",
+"1490,-200.5,0",
+"1489.6,0,4373.424",
+"1489.6,213.4,8861.484",
+"1489.6,426.8,14090.86",
+"1489.6,640.2,19518.29",
+"1489.6,853.6,25092.8",
+"1489.6,1067,30873.69",
+"1489.6,1280.4,36865.42",
+"1489.6,1493.8,43095.57",
+"1489.6,1707.2,50249.81",
+"1489.6,1920.6,57035.25",
+"1489.6,2041.712,60609.5",
+"1490,2255.112,67311.83",
+"1612,-318.62,0",
+"1612,-218.62,0",
+"1612.2,0,4904.015",
+"1612.2,213.4,9810.482",
+"1612.2,426.8,15403.9",
+"1612.2,640.2,21301.35",
+"1612.2,853.6,27492.32",
+"1612.2,1067,33580.96",
+"1612.2,1280.4,40114.61",
+"1612.2,1493.8,46914.77",
+"1612.2,1707.2,54666.14",
+"1612.2,1915.434,61862.91",
+"1612,2128.834,69491.99",
+"1735,-335.225,0",
+"1735,-235.225,0",
+"1734.7,0,5586.953",
+"1734.7,213.4,11041.15",
+"1734.7,426.8,16949.24",
+"1734.7,640.2,23500.23",
+"1734.7,853.6,30159.59",
+"1734.7,1067,36741.18",
+"1734.7,1280.4,43923.85",
+"1734.7,1493.8,51295.21",
+"1734.7,1707.2,59469.31",
+"1734.7,1789.259,62731.31",
+"1735,2002.659,70935.23",
+"1857,-353.69,0",
+"1857,-253.69,0",
+"1857.3,0,6673.839",
+"1857.3,213.4,12518.56",
+"1857.3,426.8,18687.88",
+"1857.3,640.2,25652.39",
+"1857.3,853.6,33003.08",
+"1857.3,1067,40438.09",
+"1857.3,1280.4,48117.52",
+"1857.3,1493.8,55848.59",
+"1857.3,1587.631,59434.17",
+"1857,1801.031,67215.39",
+"1957,-370.69,0",
+"1957,-270.69,0",
+"1957.3,0,6673.839",
+"1957.3,213.4,12518.56",
+"1957.3,426.8,18687.88",
+"1957.3,640.2,25652.39",
+"1957.3,853.6,33003.08",
+"1957.3,1067,40438.09",
+"1957.3,1280.4,48117.52",
+"1957.3,1493.8,55848.59",
+"1957.3,1587.631,59434.17",
+"1957,1801.031,67215.39",
+	};
+		
+		
+}
\ No newline at end of file
-- 
GitLab


From 8d12c22d4134adc52cccc9dd24ae009f66e1854c Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 10:53:06 +0100
Subject: [PATCH 05/22] updated ptBuilder mock

---
 .../GearShiftStrategy/AMTShiftStrategyTests.cs      | 13 ++++++++-----
 .../GearShiftStrategy/ATShiftStrategyTests.cs       |  2 +-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs
index 13d05f4e4a..19c047ba8c 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
@@ -45,7 +45,7 @@ TestCase(8, 4, 15000, 200, true),]
 		var testPt = GetMockTestPowertrain(runData);
 
 		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>()))
 			.Returns(testPt.Object);
 		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
 
@@ -95,7 +95,8 @@ TestCase(8, 4, 15000, 200, true),]
 		var testPt = GetMockTestPowertrain(runData);
 
 		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), 
+				It.IsAny<bool>()))
 			.Returns(testPt.Object);
 		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
 
@@ -158,7 +159,9 @@ TestCase(8, 4, 15000, 200, true),]
         var testPt = GetMockTestPowertrain(runData);
 
 		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+		ptBuilder.Setup(p => p.CreateTestPowertrain(
+				It.IsAny<IVehicleContainer>(), 
+				It.IsAny<bool>()))
 			.Returns(testPt.Object);
 		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
 
@@ -206,7 +209,7 @@ TestCase(8, 4, 15000, 200, true),]
 		var testPt = GetMockTestPowertrain(runData);
 
 		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>()))
 			.Returns(testPt.Object);
 		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
 
@@ -294,7 +297,7 @@ TestCase(8, 4, 15000, 200, true),]
         var testPt = GetMockTestPowertrain(runData);
 
         var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>()))
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>()))
 			.Returns(testPt.Object);
         container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
 
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs
index fa6040c0cc..0e1b66fe18 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs	
@@ -148,7 +148,7 @@ public class ATShiftStrategyTests
 		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(600.RPMtoRad());
 		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(2000.RPMtoRad());
 
-		ptBuilder.Setup(b => b.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType?>())).Returns(testPt.Object);
+		ptBuilder.Setup(b => b.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>())).Returns(testPt.Object);
 
 		testPt.Setup(t => t.Gearbox).Returns(testGbx.Object);
 		testPt.Setup(t => t.Container).Returns(testContainer.Object);
-- 
GitLab


From d42d5a573329f1a16960b6ed48dcf623668ddd14 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 13:40:21 +0100
Subject: [PATCH 06/22] renamed ATShiftStrategyTests.cs to
 ATShiftStrategyOptimizedTests.cs

---
 ...ATShiftStrategyTests.cs => ATShiftStrategyOptimizedTests.cs} | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/{ATShiftStrategyTests.cs => ATShiftStrategyOptimizedTests.cs} (99%)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs
similarity index 99%
rename from Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs
rename to Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs
index 0e1b66fe18..01ef757c55 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
@@ -24,7 +24,7 @@ using Assert = NUnit.Framework.Assert;
 
 namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
 
-public class ATShiftStrategyTests
+public class ATShiftStrategyOptimizedTests
 {
 	[Test,
 	TestCase(0, 100, 1),
-- 
GitLab


From 835fc504eb117ebaf8d007b317a47b9604e18b80 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 14:07:25 +0100
Subject: [PATCH 07/22] Revert "renamed ATShiftStrategyTests.cs to
 ATShiftStrategyOptimizedTests.cs"

This reverts commit d42d5a573329f1a16960b6ed48dcf623668ddd14.
---
 ...ATShiftStrategyOptimizedTests.cs => ATShiftStrategyTests.cs} | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/{ATShiftStrategyOptimizedTests.cs => ATShiftStrategyTests.cs} (99%)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs
similarity index 99%
rename from Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs
rename to Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs
index 01ef757c55..0e1b66fe18 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs	
@@ -24,7 +24,7 @@ using Assert = NUnit.Framework.Assert;
 
 namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
 
-public class ATShiftStrategyOptimizedTests
+public class ATShiftStrategyTests
 {
 	[Test,
 	TestCase(0, 100, 1),
-- 
GitLab


From 01e070a98dff5ca808fdde2b38e511a487e2f90f Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 14:36:33 +0100
Subject: [PATCH 08/22] add params keyword to input helper

---
 Testing/UnitTests/Vecto UnitTests/Utils/InputDataHelper.cs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Testing/UnitTests/Vecto UnitTests/Utils/InputDataHelper.cs b/Testing/UnitTests/Vecto UnitTests/Utils/InputDataHelper.cs
index 7021f9b29c..424a7e7ea0 100644
--- a/Testing/UnitTests/Vecto UnitTests/Utils/InputDataHelper.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/Utils/InputDataHelper.cs	
@@ -50,11 +50,10 @@ namespace TUGraz.VectoCore.Tests.Utils
 			return cycleData;
 		}
 
-		public static TableData InputDataAsTableData(string header, string[] entries)
+		public static TableData InputDataAsTableData(string header, params string[] entries)
 		{
 			return VectoCSVFile.ReadStream(InputDataAsStream(header, entries));
 		}
-
 		public static string GetRandomFilename(string jobFile)
 		{
 			var path = Path.GetDirectoryName(Path.GetFullPath(jobFile));
-- 
GitLab


From 285f9c397bba34d11c86b60ca7d9ee245be66f6e Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Thu, 13 Mar 2025 15:47:19 +0100
Subject: [PATCH 09/22] add Initialize Method to IAPTGearbox Interface

---
 VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs   | 5 +++++
 .../Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs    | 3 +--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
index 138d035dff..e8516d48e2 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
@@ -29,6 +29,9 @@
 *   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.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
@@ -54,6 +57,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 		ATGearboxState GetPreviousState { get; }
 		bool ShiftToLocked { get; }
 		IIdleController IdleController { set; }
+		ResponseDryRun Initialize(GearshiftPosition gear, NewtonMeter outTorque,
+			PerSecond outAngularVelocity);
 	}
 
 	public interface IAPTNGearbox : IGearboxType { }
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
index ef23b916fa..c5e91915bb 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
@@ -195,8 +195,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox
         }
 
 
-
-        internal ResponseDryRun Initialize(GearshiftPosition gear, NewtonMeter outTorque,
+        public ResponseDryRun Initialize(GearshiftPosition gear, NewtonMeter outTorque,
             PerSecond outAngularVelocity)
         {
             var effectiveRatio = gear.TorqueConverterLocked.Value
-- 
GitLab


From 36fea454c692b8d502b46baa03daa6f3e48e5d14 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Sun, 16 Mar 2025 14:38:51 +0100
Subject: [PATCH 10/22] let IGearboxType implement IGearbox

---
 VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
index e8516d48e2..b422e53999 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
@@ -43,7 +43,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 	/// </summary>
 	public interface IGearbox : IPowerTrainComponent, IGearboxInfo, IGearboxControl, IUpdateable { }
 
-	public interface IGearboxType {}
+	public interface IGearboxType : IGearbox {}
 
 	public interface IMTGearbox : IGearboxType {}
 
-- 
GitLab


From 202ed33b200a787cfbe656dae0edcefeb8bb5adc Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Sun, 16 Mar 2025 14:40:44 +0100
Subject: [PATCH 11/22] MTShiftStrategy: Use testpowertrain for dry run
 requessts

added MTShiftStrategyTests
---
 .../GearShiftStrategy/MTShiftStrategyTests.cs | 689 ++++++++++++++++++
 .../Impl/Shiftstrategies/MTShiftStrategy.cs   |  37 +-
 2 files changed, 714 insertions(+), 12 deletions(-)
 create mode 100644 Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs
new file mode 100644
index 0000000000..098055db3f
--- /dev/null
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs	
@@ -0,0 +1,689 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Moq;
+using NUnit.Framework;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+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;
+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;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
+using TUGraz.VectoCore.Tests.Utils;
+
+namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
+
+public class MTShiftStrategyTests
+{
+	[TestCase(1, 2, 1000, 1500)]
+	[TestCase(1, 6, 200, 8000)]
+	[TestCase(2, 4, 800, 1400)]
+    [TestCase(7, 8, 1000, 1400)]
+	[TestCase(6, 8, 800, 1400)]
+	[TestCase(5, 6, 1000, 1300)]
+	[TestCase(4, 5, 1000, 1400)]
+	[TestCase(3, 4, 1000, 1400)]
+	[TestCase(8, 8, 1000, 1400)]
+    public void Gearbox_ShiftUp(int gear, int newGear, double tq_Nm, double n_RPM)
+	{
+		var shiftExpected = gear != newGear;
+
+		var gearRatios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+
+		var container = GetMocks(n_RPM, gearRatios,
+			out var runData,
+			out var info,
+			out var testPt,
+			out var ptBuilder);
+
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(container, out _);
+
+
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+
+		var expectedN = n_RPM.RPMtoRad();
+		var angularVelocity = expectedN / gearRatios[gear];
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+		var expectedT = tq_Nm.SI<NewtonMeter>();
+		var torque = expectedT * gearRatios[gear];
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+        Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+		Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+
+
+	[TestCase(2, 1, 1000, 300)]
+	[TestCase(3, 4, 1000, 1400)]
+	[TestCase(8, 7, 1800, 750)]
+	[TestCase(7, 6, 1800, 750)]
+	[TestCase(6, 5, 1800, 750)]
+	[TestCase(5, 4, 1800, 750)]
+	[TestCase(4, 3, 1800, 750)]
+	[TestCase(3, 2, 1800, 750)]
+	[TestCase(2, 1, 1900, 750)]
+	[TestCase(1, 1, 1200, 700)]
+	[TestCase(8, 4, 15000, 200)]
+    public void Gearbox_ShiftDown(int gear, int newGear, double tq_Nm, double n_RPM)
+	{
+		var shiftExpected = gear != newGear;
+
+		var gearRatios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		var container = GetMocks(n_RPM, gearRatios,
+			out var runData,
+			out var info,
+			out var testPt,
+			out var ptBuilder);
+
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(container, out _);
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+
+		var expectedN = n_RPM.RPMtoRad();
+		var angularVelocity = expectedN / gearRatios[gear];
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+		var expectedT = tq_Nm.SI<NewtonMeter>();
+		var torque = expectedT * gearRatios[gear];
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+		Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+
+	[TestCase(2, 1,2, 1000, 300)]
+	[TestCase(3, 2,2, 1000, 1400)]
+	[TestCase(8, 7,2, 1800, 750)]
+	[TestCase(7, 6,2, 1800, 750)]
+	[TestCase(6, 5,2, 1800, 750)]
+	[TestCase(5, 4,2, 1800, 750)]
+	[TestCase(4, 3,2, 1800, 750)]
+	[TestCase(3, 2,2, 1800, 750)]
+	[TestCase(2, 2,2, 1900, 750)]
+	[TestCase(1, 2,2, 1200, 700)]
+	[TestCase(8, 4,2, 15000, 200)]
+	[TestCase(2, 2, 2, 300, 1000)]
+    public void Gearbox_PTO(int gear, int newGear, int ptoGear, double tq_Nm, double n_RPM)
+	{
+		var shiftExpected = gear != newGear;
+
+        var gearRatios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+		var container = GetMocks(
+			n_RPM: n_RPM,
+			gearRatios: gearRatios,
+			runData: out var runData,
+			info: out _,
+			testPt: out _,
+			ptBuilder: out _);
+
+		//Cycle Info
+		var cycleInfo = new Mock<IDrivingCycleInfo>();
+		container.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
+		cycleInfo.Setup(c => c.CycleData).Returns(
+			GetPTOCycleData());
+
+		runData.DriverData = new DriverData() {
+			PTODriveRoadsweepingGear = new GearshiftPosition((uint)ptoGear)
+		};
+		//Recreate Shiftstrategy with updated rundata
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(container, out _);
+
+		
+        var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+
+		var expectedN = n_RPM.RPMtoRad();
+		var angularVelocity = expectedN / gearRatios[gear];
+
+		
+
+
+		var gearShiftPosition = shiftStrategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+			angularVelocity);
+
+
+
+		var expectedT = tq_Nm.SI<NewtonMeter>();
+		var torque = expectedT * gearRatios[gear];
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+		Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+
+
+	private MTShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container,
+		out Mock<IGearbox> gearbox)
+	{
+		gearbox = GetMockGearbox();
+		
+		var shiftStrategy = new MTShiftStrategy(container.Object) {
+			Gearbox = gearbox.Object
+		};
+		
+		SetVelocityDropLookupData(shiftStrategy);
+		return shiftStrategy;
+	}
+	
+	
+
+	private Mock<IVehicleContainer> GetMocks(
+		double n_RPM, 
+		double[] gearRatios, 
+		out VectoRunData runData, 
+		out Mock<IVehicleInfo> info, 
+		out Mock<ITestPowertrain> testPt, 
+		out Mock<ISimplePowertrainBuilder> ptBuilder)
+	{
+		runData = GetRunData(gearRatios);
+		var container = GetMockVehicleContainer(runData, n_RPM.RPMtoRad(), out info);
+
+		testPt = GetMockTestPowertrain(runData);
+		
+		ptBuilder = new Mock<ISimplePowertrainBuilder>(MockBehavior.Strict);
+		
+		ptBuilder.Setup(p => p.CreateTestPowertrain(It.IsAny<IVehicleContainer>(),It.IsAny<bool>()))
+			.Returns(testPt.Object);
+		
+
+		container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+
+		// gbx = GetMockGearbox(container.Object);
+		//
+		// var shiftStrategy = new MTShiftStrategy(container.Object)
+		// {
+		// 	Gearbox = gbx.Object
+		// };
+		// SetVelocityDropLookupData(shiftStrategy);
+		return container;
+	}
+
+
+
+
+    private VectoRunData GetRunData(double[] gearRatios)
+	{
+		var gearboxData = new GearboxData() {
+			Gears = new Dictionary<uint, GearData>()
+		};
+
+		for (uint i = 1; i < gearRatios.Length; i++) {
+			var gearRatio = gearRatios[i];
+			gearboxData.Gears[i] = new GearData() {
+				Ratio = gearRatio,
+				LossMap = TransmissionLossMapReader.Create(0.96, gearRatio, $"Gear {i}")
+			};
+		}
+
+		var gearShiftParameters = new ShiftStrategyParameters() {
+			StartSpeed = 2.SI<MeterPerSecond>(),
+			TimeBetweenGearshifts = 6.SI<Second>(),
+			DownshiftAfterUpshiftDelay = 2.SI<Second>(),
+			UpshiftAfterDownshiftDelay = 2.SI<Second>(),
+			UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>()
+		};
+
+
+		string engineFldHdr = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
+
+		string[] engineFldData = new[] {
+			"560,1180,-149,0.6		   ",
+			"600,1282,-148,0.6		   ",
+			"799.9999999,1791,-149,0.6 ",
+			"1000,2300,-160,0.6		   ",
+			"1200,2300,-179,0.6		   ",
+			"1400,2300,-203,0.6		   ",
+			"1599.999999,2079,-235,0.49",
+			"1800,1857,-264,0.25	   ",
+			"2000.000001,1352,-301,0.25",
+			"2100,1100,-320,0.25	   ",
+		};
+
+
+		var fullLoadCurve =
+			FullLoadCurveReader.Create(InputDataHelper.InputDataAsTableData(engineFldHdr, engineFldData));
+		var engineData = new CombustionEngineData() {
+			IdleSpeed = 560.RPMtoRad(),
+			FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() {
+				{
+					0u, fullLoadCurve
+				}
+			}
+		};
+
+
+		var axlRatio = 3.240355;
+		var gearsInput = gearboxData.Gears.Select(x => {
+			var r = new Mock<ITransmissionInputData>();
+			r.Setup(g => g.Ratio).Returns(x.Value.Ratio);
+			return r.Object;
+		}).ToList();
+		foreach (var entry in gearboxData.Gears) {
+			var gearIdx = (int)entry.Key - 1;
+			var dynamicTyreRadius = 0.5.SI<Meter>();
+
+			entry.Value.ShiftPolygon = 
+				DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon(
+				gearIdx, engineData.FullLoadCurves.First().Value,
+				gearsInput, engineData, axlRatio, 0.5.SI<Meter>());
+
+			entry.Value.ExtendedShiftPolygon = DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygonExtended(
+				gearIdx, engineData.FullLoadCurves.First().Value, gearsInput, engineData, axlRatio, dynamicTyreRadius);
+		}
+
+
+		var axleGearData = new AxleGearData() {
+			AxleGear = new TransmissionData() {
+				Ratio = 3.240355,
+			}
+		};
+
+
+		var vehicleData = new VehicleData() {
+			DynamicTyreRadius = 0.492.SI<Meter>(),
+		};
+
+
+		var mockCycle = new Mock<IDrivingCycleData>();
+		mockCycle.Setup(cd => cd.Entries).Returns(
+			new List<DrivingCycleData.DrivingCycleEntry>() {
+				new DrivingCycleData.DrivingCycleEntry() {
+					RoadGradient = 0.SI<Radian>()
+				}
+			});
+
+
+
+		return new VectoRunData() {
+			GearboxData = gearboxData,
+			GearshiftParameters = gearShiftParameters,
+			EngineData = engineData,
+			AxleGearData = axleGearData,
+			VehicleData = vehicleData,
+			Cycle = mockCycle.Object,
+		};
+	}
+
+
+	private Mock<IGearbox> GetMockGearbox()
+	{
+		var mtGbx = new Mock<IMTGearbox>();
+		var gbx = mtGbx.As<IGearbox>();
+		
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+		
+		return gbx;
+		// var gbx = new Mock<DeclarationData.Gearbox>(container, null);
+		// var ratios = container.RunData.GearboxData.Gears;
+
+		//
+
+		// gbx.SetupProperty(g => g.Gear);
+		// gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+		// 		It.IsAny<bool>()))
+		// 	.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
+		// 		var ratio = gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+		// 		return dryRun
+		// 			? new ResponseDryRun(this) {
+		// 				Engine = {
+		// 					PowerRequest = n * t, EngineSpeed = n * ratio,
+		// 					DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+		// 				},
+		// 				Clutch = { PowerRequest = n * t }
+		// 			}
+		// 			: new ResponseSuccess(this) {
+		// 				Engine = { PowerRequest = n * t, EngineSpeed = n * ratio },
+		// 				Clutch = { PowerRequest = n * t }
+		// 			};
+		// 	});
+		// return gbx;
+	}
+
+
+	private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
+	{
+		var gbx = new Mock<ITestPowertrainTransmission>();
+		
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+		GearshiftPosition gear = null;
+		gbx.SetupGet(g => g.Gear).Returns(() => {
+			
+			return gear;
+		});
+		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => {
+				gear = p;
+			});
+
+
+		GearshiftPosition nextGear = null;
+		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => nextGear = p);
+			
+		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			return new ResponseSuccess(this)
+			{
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		
+		
+		gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+				It.IsAny<bool>()))
+			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
+				var ratio = gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+				return dryRun
+					? new ResponseDryRun(this) {
+						Engine = {
+							PowerRequest = n * t, EngineSpeed = n * ratio,
+							DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						},
+						Clutch = { PowerRequest = n * t }
+					}
+					: new ResponseSuccess(this) {
+						Engine = { PowerRequest = n * t, EngineSpeed = n * ratio },
+						Clutch = { PowerRequest = n * t }
+					};
+			});
+		return gbx;
+	}
+	private Mock<IPowertainInfo> GetPowertrainInfo()
+	{
+		var powerTrainInfo = new Mock<IPowertainInfo>();
+		powerTrainInfo.Setup(p => p.HasCombustionEngine).Returns(true);
+		return powerTrainInfo;
+	}
+
+	private CycleData GetCycleData()
+	{
+		return new CycleData() {
+			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+				PTOActive = PTOActivity.Inactive
+			}
+		};
+	}
+
+	private CycleData GetPTOCycleData()
+	{
+		return new CycleData() {
+			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+				PTOActive = PTOActivity.PTOActivityRoadSweeping
+			}
+		};
+	}
+
+	private Mock<IVehicleContainer> GetMockVehicleContainer(VectoRunData runData, PerSecond engineSpeed, out Mock<IVehicleInfo> vehicleInfo)
+	{
+		var vehicleContainer = new Mock<IVehicleContainer>();
+
+		var preProcessingRuns = new List<ISimulationPreprocessor>();
+
+		vehicleContainer.Setup(c => c.RunData).Returns(runData);
+		vehicleContainer.Setup(c => c.AddComponent(It.IsAny<VectoSimulationComponent>()));
+
+		vehicleContainer.Setup(c => c.AddPreprocessor(It.IsAny<ISimulationPreprocessor>()))
+			.Callback((ISimulationPreprocessor pre) => preProcessingRuns.Add(pre));
+
+		//Vehicle Info
+		vehicleInfo = new Mock<IVehicleInfo>();
+		vehicleContainer.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
+		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
+
+		vehicleInfo.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
+			.Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(30.KMPHtoMeterPerSecond());
+		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+
+        //WheelsInfo
+		vehicleContainer.Setup(c => c.WheelsInfo.ReducedMassWheels).Returns(0.SI<Kilogram>());
+
+        //AxlegearInfo
+        var axleGearInfo = new Mock<IAxlegearInfo>();
+		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
+		axleGearInfo.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
+
+        //Powertrain Info
+        vehicleContainer.Setup(c => c.PowertrainInfo).Returns(GetPowertrainInfo().Object);
+
+		//Engine Info
+		var engineInfo = new Mock<IEngineInfo>();
+		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
+		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
+		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
+		engineInfo.Setup(e => e.EngineSpeed).Returns(engineSpeed);
+		engineInfo.Setup(e => e.EngineN95hSpeed).Returns
+			(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
+		engineInfo.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>())).Returns((PerSecond n) =>
+			runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+
+		//Cycle Info
+		var cycleInfo = new Mock<IDrivingCycleInfo>();
+		vehicleContainer.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
+		cycleInfo.Setup(c => c.CycleData).Returns(
+			GetCycleData());
+
+		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry() {
+			Altitude = 0.SI<Meter>()
+		});
+		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
+
+		var pi = new Mock<IPowertainInfo>();
+
+
+
+        //Driver Info
+        var driverInfo = new Mock<IDriverInfo>();
+		vehicleContainer.Setup(c => c.DriverInfo).Returns(driverInfo.Object);
+
+		driverInfo.Setup(d => d.DriverBehavior).Returns(DrivingBehavior.Accelerating);
+		driverInfo.Setup(d => d.DrivingAction).Returns(DrivingAction.Accelerate);
+
+		return vehicleContainer;
+	}
+
+	private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData)
+	{
+		var testPt = new Mock<ITestPowertrain>(MockBehavior.Strict);
+		var simplePt = GetSimplePowertrain(runData, out var gbx);
+
+		testPt.Setup(c => c.Container).Returns(simplePt.Object);
+		testPt.Setup(c => c.Gearbox).Returns(gbx.Object);
+		testPt.Setup(c => c.UpdateComponents());
+		
+		
+		// var simplePt = GetSimplePowertrain(gearRatios);
+		//
+		//
+		// testContainer.Setup(c => c.RunData).Returns(runData);
+		// testContainer.Setup(c => c.PowertrainInfo).Returns(GetPowertrainInfo().Object);
+		//
+		// testPowertrain.Setup(t => t.Gearbox).Returns(GetMockGearbox(testContainer.Object).Object);
+		
+		var tEng = new Mock<ITestpowertrainCombustionEngine>();
+		testPt.Setup(t => t.CombustionEngine).Returns(tEng.Object);
+		tEng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
+			.Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+
+		return testPt;
+	}
+
+	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData, out Mock<ITestPowertrainTransmission> testGearbox)
+	{
+		var simplePt = new Mock<ISimpleVehicleContainer>();
+		
+		simplePt.Setup(s => s.RunData).Returns(runData);
+		simplePt.Setup(s => s.AddComponent(It.IsAny<VectoSimulationComponent>()));
+		simplePt.Setup(s => s.PowertrainInfo).Returns(GetPowertrainInfo().Object);
+
+		testGearbox = GetMockTestGearbox(runData.GearboxData.Gears);
+		simplePt.Setup(s => s.GearboxCtl).Returns(testGearbox.Object);
+
+
+		//Vehicle Info
+		var vehicleInfo = new Mock<IVehicleInfo>();
+		simplePt.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
+		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
+
+
+
+
+		//simplePt.Setup(s => s.AddPreprocessor(It.IsAny<ISimulationPreprocessor>()))
+		//	.Callback((ISimulationPreprocessor p) => p.RunPreprocessing());
+		return simplePt;
+	}
+
+	private void SetVelocityDropLookupData(MTShiftStrategy shiftStrategy)
+	{
+		//"StartVelocity [km/h], Gradient [-], EndVelocity [km/h]"
+		var data = new[] {
+			new[] { 5.0, -0.0997, 9.061522965237558 },
+			new[] { 5.0, -0.0798, 7.76698080079411 },
+			new[] { 5.0, -0.0599, 6.46583777913701 },
+			new[] { 5.0, -0.0400, 5.1596021788785045 },
+			new[] { 5.0, -0.0200, 3.8498121019126907 },
+			new[] { 5.0, 0.0000, 2.5380265159468918 },
+			new[] { 5.0, 0.0200, 1.2258160477557427 },
+			new[] { 5.0, 0.0400, 0.0 },
+			new[] { 5.0, 0.0599, 0.0 },
+			new[] { 5.0, 0.0798, 0.0 },
+			new[] { 5.0, 0.0997, 0.0 },
+			new[] { 10.0, -0.0997, 14.807789640888302 },
+			new[] { 10.0, -0.0798, 13.474253785811362 },
+			new[] { 10.0, -0.0599, 12.133880027250777 },
+			new[] { 10.0, -0.0400, 10.788221550084467 },
+			new[] { 10.0, -0.0200, 9.438862432338068 },
+			new[] { 10.0, 0.0000, 8.087408432114643 },
+			new[] { 10.0, 0.0200, 6.735477499784416 },
+			new[] { 10.0, 0.0400, 5.384690105076845 },
+			new[] { 10.0, 0.0599, 4.036659549786269 },
+			new[] { 10.0, 0.0798, 2.6929823705748137 },
+			new[] { 10.0, 0.0997, 1.3552289800549435 },
+			new[] { 20.0, -0.0997, 25.061542153872097 },
+			new[] { 20.0, -0.0798, 23.72002987685605 },
+			new[] { 20.0, -0.0599, 22.371630788642932 },
+			new[] { 20.0, -0.0400, 21.017907257116025 },
+			new[] { 20.0, -0.0200, 19.660452757813403 },
+			new[] { 20.0, 0.0000, 18.30088261992287 },
+			new[] { 20.0, 0.0200, 16.94082447048767 },
+			new[] { 20.0, 0.0400, 15.581908518759507 },
+			new[] { 20.0, 0.0599, 14.225757795590708 },
+			new[] { 20.0, 0.0798, 12.873978508374211 },
+			new[] { 20.0, 0.0997, 11.528150617530041 },
+			new[] { 30.000000000000004, -0.0997, 35.091774208140095 },
+			new[] { 30.000000000000004, -0.0798, 33.750904327320896 },
+			new[] { 30.000000000000004, -0.0599, 32.40315158162777 },
+			new[] { 30.000000000000004, -0.0400, 31.050077596965064 },
+			new[] { 30.000000000000004, -0.0200, 29.69327509188113 },
+			new[] { 30.000000000000004, 0.0000, 28.33435862498606 },
+			new[] { 30.000000000000004, 0.0200, 26.974955046566407 },
+			new[] { 30.000000000000004, 0.0400, 25.616693776603913 },
+			new[] { 30.000000000000004, 0.0599, 24.261197065863925 },
+			new[] { 30.000000000000004, 0.0798, 22.91007034016412 },
+			new[] { 30.000000000000004, 0.0997, 21.56489279686667 },
+			new[] { 40.0, -0.0997, 45.024018797189854 },
+			new[] { 40.0, -0.0798, 43.68636622428101 },
+			new[] { 40.0, -0.0599, 42.34185052441486 },
+			new[] { 40.0, -0.0400, 40.99202962224952 },
+			new[] { 40.0, -0.0200, 39.63849244500093 },
+			new[] { 40.0, 0.0000, 38.282849690992855 },
+			new[] { 40.0, 0.0200, 36.926724305651554 },
+			new[] { 40.0, 0.0400, 35.57174178507285 },
+			new[] { 40.0, 0.0599, 34.21952045137207 },
+			new[] { 40.0, 0.0798, 32.87166183129923 },
+			new[] { 40.0, 0.0997, 31.5297412694979 },
+			new[] { 50.0, -0.0997, 54.652157586769704 },
+			new[] { 50.0, -0.0798, 53.319266704395716 },
+			new[] { 50.0, -0.0599, 51.97954186606304 },
+			new[] { 50.0, -0.0400, 50.634535516787736 },
+			new[] { 50.0, -0.0200, 49.28583097196263 },
+			new[] { 50.0, 0.0000, 47.93503321632867 },
+			new[] { 50.0, 0.0200, 46.583759417454765 },
+			new[] { 50.0, 0.0400, 45.23362925944123 },
+			new[] { 50.0, 0.0599, 43.88625525588574 },
+			new[] { 50.0, 0.0798, 42.54323315977748 },
+			new[] { 50.0, 0.0997, 41.20613261641401 },
+			new[] { 60.00000000000001, -0.0997, 64.2503607025971 },
+			new[] { 60.00000000000001, -0.0798, 62.91932863058169 },
+			new[] { 60.00000000000001, -0.0599, 61.58156853535776 },
+			new[] { 60.00000000000001, -0.0400, 60.23862904729555 },
+			new[] { 60.00000000000001, -0.0200, 58.89369896300112 },
+			new[] { 60.00000000000001, 0.0000, 57.547040626925885 },
+			new[] { 60.00000000000001, 0.0200, 56.199911833784675 },
+			new[] { 60.00000000000001, 0.0400, 54.85392730356455 },
+			new[] { 60.00000000000001, 0.0599, 53.510694584916905 },
+			new[] { 60.00000000000001, 0.0798, 52.17180450267632 },
+			new[] { 60.00000000000001, 0.0997, 50.83882182989668 },
+			new[] { 70.0, -0.0997, 73.78388063954164 },
+			new[] { 70.0, -0.0798, 72.45700102808648 },
+			new[] { 70.0, -0.0599, 71.12341092304165 },
+			new[] { 70.0, -0.0400, 69.78459543842656 },
+			new[] { 70.0, -0.0200, 68.44188526693415 },
+			new[] { 70.0, 0.0000, 67.09719334997524 },
+			new[] { 70.0, 0.0200, 65.75212749798493 },
+			new[] { 70.0, 0.0400, 64.40829754257321 },
+			new[] { 70.0, 0.0599, 63.06730571969745 },
+			new[] { 70.0, 0.0798, 61.73073716025881 },
+			new[] { 70.0, 0.0997, 60.40015062055851 },
+			new[] { 80.0, -0.0997, 83.25457689135129 },
+			new[] { 80.0, -0.0798, 81.93182852399568 },
+			new[] { 80.0, -0.0599, 80.60238880559001 },
+			new[] { 80.0, -0.0400, 79.2676325992058 },
+			new[] { 80.0, -0.0200, 77.92916666616652 },
+			new[] { 80.0, 0.0000, 76.58872134590663 },
+			new[] { 80.0, 0.0200, 75.24790011046437 },
+			new[] { 80.0, 0.0400, 73.90830846424944 },
+			new[] { 80.0, 0.0599, 72.57154434889891 },
+			new[] { 80.0, 0.0798, 71.23918865436896 },
+			new[] { 80.0, 0.0997, 69.91277394305271 },
+		};
+		var entries = new List<VelocitySpeedGearshiftPreprocessor.Entry>();
+		foreach (var d in data) {
+			entries.Add(new VelocitySpeedGearshiftPreprocessor.Entry() {
+				StartVelocity = d[0].KMPHtoMeterPerSecond(),
+				Gradient = d[1].SI<Radian>(),
+				EndVelocity = d[2].KMPHtoMeterPerSecond(),
+			});
+		}
+
+		shiftStrategy.VelocityDropData.Data = entries.ToArray();
+
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
index c013c4943c..78aafdcb9c 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
@@ -53,10 +53,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 
 		protected GearshiftPosition DesiredGearRoadsweeping;
 
-		protected MTGearbox _gearbox;
+		protected IMTGearbox _gearbox;
 
         public MTShiftStrategy(IVehicleContainer container) : base(container)
 		{
+			// create testcontainer
+			TestPowertrain = PowertrainBuilder.CreateTestPowertrain(Container, false);
 			PreprocessorSpeed = ConfigureSpeedPreprocessor(container);
 			container.AddPreprocessor(PreprocessorSpeed);
 
@@ -81,8 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				}
 			}
 
-			// create testcontainer
-			TestPowertrain = PowertrainBuilder.CreateTestPowertrain(Container, false);
+
 
             DesiredGearRoadsweeping = RunData.DriverData?.PTODriveRoadsweepingGear;
         }
@@ -90,7 +91,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		public override IGearbox Gearbox {
 			get => _gearbox;
 			set {
-				if (value is MTGearbox gbx) {
+				if (value is IMTGearbox gbx) {
 					_gearbox = gbx;
 					return;
 				}
@@ -200,10 +201,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 
 				while (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;
+					var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear);
 
 					inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity;
 					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
@@ -226,6 +224,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			return currentGear;
 		}
 
+		private ResponseDryRun RequestDryRunWithGear(Second absTime, Second dt, NewtonMeter outTorque,
+			PerSecond outAngularVelocity, GearshiftPosition currentGear)
+		{
+			TestPowertrain.UpdateComponents();
+			var testGearbox = TestPowertrain.Gearbox;
+			var tmpGear = testGearbox.Gear;
+			// _gearbox.Gear = currentGear;
+			testGearbox.SetGear = currentGear;
+			// _gearbox.Gear = tmpGear;
+			testGearbox.SetGear = tmpGear;
+			var response = (ResponseDryRun)testGearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+			return response;
+		}
+
 		protected virtual GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque,
 			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
 		{
@@ -243,10 +255,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				currentGear = Gears.Predecessor(currentGear);
 				while (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;
+					var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, 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;
-- 
GitLab


From 11b352dcf1a0f82a800975acba8ff67b20532c20 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Sun, 16 Mar 2025 14:41:30 +0100
Subject: [PATCH 12/22] Added ATShiftStrategyOptimizedTests.cs

---
 .../AMTShiftStrategyOptimizedTests.cs         |   22 -
 .../ATShiftStrategyOptimizedTests.cs          | 1565 +++++++++++++++++
 2 files changed, 1565 insertions(+), 22 deletions(-)
 create mode 100644 Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs
index 5e72e31099..886a5e6340 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs	
@@ -523,31 +523,9 @@ TestCase(8, 4, 15000, 200, true),]
 	{
 		var shiftStrategy = new AMTShiftStrategyOptimized(vehicleContainer.Object);
 
-
 		gbx = GetMockGearbox();
-		var mockPort = new Mock<ITnOutPort>();
 		shiftStrategy.Gearbox = gbx.Object;
 
-
-		// NewtonMeter tqRequest = null;
-		// PerSecond rpmRequest = null;
-		// mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-		// 	It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-		// 	tqRequest = tq;
-		// 	rpmRequest = rpm;
-		// 	return new ResponseSuccess(this)
-		// 	{
-		// 		Engine = {
-		// 			EngineSpeed = rpm,
-		// 			PowerRequest = tq * rpm,
-		// 		},
-		// 	};
-		// });
-		// mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
-		// 	It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
-		//
-		// gbx.Connect(mockPort.Object);
-
 		SetVelocityDropLookupData(shiftStrategy);
         return shiftStrategy;
 	}
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs
new file mode 100644
index 0000000000..8e2fa264ae
--- /dev/null
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
@@ -0,0 +1,1565 @@
+using System.ComponentModel;
+using System.Globalization;
+using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
+using System.Security.Cryptography;
+using Moq;
+using NUnit.Framework;
+using NUnit.Framework.Internal;
+using TUGraz.Vecto.UnitTests.Utils.MockComponents;
+using TUGraz.VectoCommon.BusAuxiliaries;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
+using TUGraz.VectoCore.Models.Connector.Ports;
+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;
+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;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ShiftPolygonCalc;
+using TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.ManufacturerReport_0_9.ManufacturerReportGroupWriter;
+using TUGraz.VectoCore.Tests.Utils;
+using Assert = NUnit.Framework.Assert;
+
+namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
+
+[TestFixture]
+public class ATShiftStrategyOptimizedTests
+{
+	[TestCase(0, 100, 1)]
+	[TestCase(0, 200, 1)]
+	[TestCase(5, 100, 1)]
+	[TestCase(5, 300, 1)]
+	[TestCase(5, 600, 1)]
+	[TestCase(15, 100, 3)]
+	[TestCase(15, 300, 3)]
+	[TestCase(15, 600, 3)]
+	[TestCase(40, 100, 6)]
+	[TestCase(40, 300, 6)]
+	[TestCase(40, 600, 6)]
+	[TestCase(70, 100, 6)]
+	[TestCase(70, 300, 6)]
+	[TestCase(70, 600, 6)]
+	public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear)
+	{
+		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+		var vehicleContainer = GetMockVehicleContainer(
+			speedKmh: vehicleSpeed,
+			DrivingBehavior.Accelerating,
+			gearRatios,
+			out _,
+			out var runData,
+			out _,
+			out _);
+		
+		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer.Object);
+		var angularVelocity = GetAngularVelocityBySpeed(vehicleSpeed, runData);
+		var response = shiftStrategy.InitGear(
+			0.SI<Second>(),
+			1.SI<Second>(),
+			torque.SI<NewtonMeter>(), 
+			angularVelocity);
+		
+		Assert.AreEqual(expectedGear, response.Gear);
+	}
+	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
+		double[] gearRatios,
+		out Mock<IVehicleDeclarationInputData> inputData, out VectoRunData runData, out GearboxData gearboxData,
+		out Mock<ISimpleVehicleContainer> simplePt)
+	{
+		var vehicleContainer = new Mock<IVehicleContainer>();
+		
+		inputData = GetMockInputData(gearRatios);
+		runData = GetDummyVectoRunData(inputData.Object);
+
+		
+		
+		vehicleContainer.Setup(c => c.RunData).Returns(runData);
+		
+		//Testpowertrain
+		var testPowertrain = GetMockTestPowertrain(
+			runData, 
+			out simplePt);
+			
+		vehicleContainer.Setup(c => c.SimplePowertrainBuilder.CreateTestPowertrain(It.IsAny<IVehicleContainer>(),
+			It.IsAny<bool>())).Returns(testPowertrain.Object);
+		
+		//VehicleInfo
+		vehicleContainer.Setup(v => v.VehicleInfo)
+			.Returns(GetVehicleInfo(speedKmh.KMPHtoMeterPerSecond()).Object);
+
+		//AxleGearInfo
+		var axleGearInfo = new Mock<IAxlegearInfo>();
+		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
+		axleGearInfo.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
+
+		//WheelsInfo
+		var wi = new Mock<IWheelsInfo>();
+		vehicleContainer.Setup(c => c.WheelsInfo).Returns(wi.Object);
+		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
+
+		//Cycle Info
+		var cycleInfo = new Mock<IDrivingCycleInfo>();
+		vehicleContainer.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
+		cycleInfo.Setup(c => c.CycleData).Returns(
+			GetCycleData());
+		cycleInfo.Setup(c => c.RoadGradient).Returns(0.SI<Radian>());
+
+
+		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry()
+		{
+			Altitude = 0.SI<Meter>()
+		});
+		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
+
+		//DriverINfo
+		vehicleContainer.Setup(v => v.DriverInfo.DriverBehavior).Returns(driverBehavior);
+		var acc = 0.SI<MeterPerSquareSecond>();
+		switch (driverBehavior)
+		{
+			case DrivingBehavior.Accelerating:
+				acc = 1.SI<MeterPerSquareSecond>();
+				break;
+			case DrivingBehavior.Braking:
+				acc = -1.SI<MeterPerSquareSecond>();
+				break;
+			case DrivingBehavior.Halted:
+				acc = 0.SI<MeterPerSquareSecond>();
+				break;
+			default:
+				throw new ArgumentOutOfRangeException();
+		}
+
+		
+
+
+
+		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(acc);
+		gearboxData = new GearboxData();
+		return vehicleContainer;
+	}
+	private CycleData GetCycleData()
+	{
+		return new CycleData()
+		{
+			LeftSample = new DrivingCycleData.DrivingCycleEntry()
+			{
+				PTOActive = PTOActivity.Inactive,
+				VehicleTargetSpeed = 10.KMPHtoMeterPerSecond()
+			}
+		};
+	}
+	private Mock<IVehicleInfo> GetVehicleInfo(MeterPerSecond speed)
+	{
+		var vehicleInfo = new Mock<IVehicleInfo>();
+		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(speed);
+		vehicleInfo.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
+			.Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+		return vehicleInfo;
+	}
+	private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData,
+		out Mock<ISimpleVehicleContainer> simpleContainer)
+	{
+		var testPt = new Mock<ITestPowertrain>();
+		simpleContainer = GetSimplePowertrain(runData, 
+			out var testGearbox);
+		
+		
+		
+		testPt.Setup(t => t.Container).Returns(simpleContainer.Object);
+		testPt.Setup(t => t.Gearbox).Returns(testGearbox.Object);
+
+		
+		//Vehicle
+		var vehicle = new Mock<ITestPowertrainVehicle>();
+		vehicle.Setup(v => v.Initialize(
+			It.IsAny<MeterPerSecond>(),
+			It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
+		testPt.Setup(t => t.Vehicle).Returns(vehicle.Object);
+		
+
+		return testPt;
+	}
+	private Mock<IVehicleDeclarationInputData> GetMockInputData(double[]? gearRatios)
+	{
+		var input = new Mock<IVehicleDeclarationInputData>();
+		var components = new Mock<IVehicleComponentsDeclaration>();
+		input.Setup(i => i.Components).Returns(components.Object);
+		var gbx = new Mock<IGearboxDeclarationInputData>();
+		var tc = new Mock<ITorqueConverterDeclarationInputData>();
+
+		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
+		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
+		gearRatios = gearRatios ?? new double[] {
+
+		};
+		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
+		var efficiency = 0.98;
+		var data = new List<string>();
+		
+		foreach (var speed in new[] {0, 10000}) {
+			foreach (var tq in new[] {1e5, -1e5, 0}) {
+				data.Add(FormattableString.Invariant($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}"));
+			}
+		}
+		var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
+		//lossmap.Columns
+		var gears = gearRatios.Select((x, idx) => {
+			var gear = new Mock<ITransmissionInputData>();
+			gear.Setup(g => g.Ratio).Returns(x);
+			gear.Setup(g => g.Gear).Returns(idx + 1);
+			//gear.Setup(g => g.Efficiency).Returns(0.98);
+			gear.Setup(g => g.LossMap).Returns(lossmap);
+			gear.Setup(g => g.MaxInputSpeed).Returns(2000.RPMtoRad());
+			return gear.Object;
+		}).ToList();
+		gbx.Setup(g => g.Type).Returns(GearboxType.ATSerial);
+		gbx.Setup(g => g.Gears).Returns(gears);
+
+		var tcData = InputDataHelper.InputDataAsTableData(TcHeader, TcData);
+		tc.Setup(t => t.TCData).Returns(tcData);
+		return input;
+	}
+	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
+	{
+		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
+		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
+		var fld = FullLoadCurveReader.Create(fldData);
+		
+		// create gearbox data
+		var tcDataAdapter = new TorqueConverterDataAdapter();
+
+		// fuel data
+        var fuelData = new CombustionEngineFuelData() {
+			ConsumptionMap = FuelConsumptionMapReader.Create(
+				InputDataHelper.InputDataAsTableData(
+					"engine speed [rpm] ,torque [Nm] ,fuel consumption [g/h] ,whr power electrical [W]",
+					"500,-131,0,0",
+						"500,95.6,1814.959,0",
+						"500,573.6,9771.095,0",
+						"2453,-209.12,0,0",
+						"2453,764.8,39097.94,0"
+                    )),
+			FuelData = DeclarationData.FuelData.Lookup(FuelType.DieselCI),
+		};
+
+		var runData = new VectoRunData() {
+			VehicleData = new VehicleData() {
+				DynamicTyreRadius = 0.465.SI<Meter>(),
+				GrossVehicleMass = 12_000.SI<Kilogram>(),
+				CurbMass = 10_000.SI<Kilogram>(),
+			},
+			EngineData = new CombustionEngineData() {
+				Inertia = 0.SI<KilogramSquareMeter>(),
+				FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(),
+				IdleSpeed = 600.RPMtoRad(),
+				RatedSpeedDeclared = 2000.RPMtoRad(),
+				Fuels = new List<CombustionEngineFuelData>() {
+					fuelData,
+				}
+			},
+			Cycle = new DrivingCycleData() {
+				CycleType = CycleType.DistanceBased
+			}
+		};
+		for (uint i = 0; i <= nrOfGears; i++) {
+			runData.EngineData.FullLoadCurves[i] = fld;
+		}
+
+		var gbxDataAdapter = new GearboxDataAdapter(tcDataAdapter);
+		var gbxTypes = new[] {
+			GearboxType.ATSerial, GearboxType.ATPowerSplit
+		};
+
+		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData, new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
+			GearboxType.ATSerial,
+			GearboxType.ATPowerSplit
+		});
+
+		var gearShiftParams =
+			gbxDataAdapter.CreateGearshiftData(1.0, runData.EngineData.IdleSpeed, GearboxType.ATSerial, nrOfGears);
+
+		runData.GearboxData = gearboxData;
+		runData.GearshiftParameters = gearShiftParams;
+        return runData;
+	}
+	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData, out Mock<ITestPowertrainTransmission> testGearbox)
+	{
+		var simplePt = new Mock<ISimpleVehicleContainer>();
+
+		testGearbox = GetMockTestGearbox(runData.GearboxData.Gears);
+		
+		
+		simplePt.Setup(s => s.GearboxInfo).Returns(testGearbox.Object);
+		
+		
+		
+		
+		
+		//VehiclePort
+		return simplePt;
+	}
+	private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
+	{
+		Mock<IAPTGearbox> amtGearbox = new Mock<IAPTGearbox>();
+		amtGearbox.Name = "APT_TestGearbox";
+		Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
+
+		
+		
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+		GearshiftPosition gear = null;
+		gbx.SetupGet(g => g.Gear).Returns(() => {
+			
+			return gear;
+		});
+		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => {
+				gear = p;
+			});
+
+
+		GearshiftPosition nextGear = null;
+		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => nextGear = p);
+			
+		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			return new ResponseSuccess(this)
+			{
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		gbx.Setup(p => p.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true)).Returns((
+			Second absTime,
+			Second dt,
+			NewtonMeter t,
+			PerSecond n,
+			bool dryRun) => {
+
+			var ratio =
+				gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+			return dryRun
+				? new ResponseDryRun(this) {
+					Engine = {
+						PowerRequest = n * t, EngineSpeed = n * ratio,
+						DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						TotalTorqueDemand = t,
+					},
+					Clutch = { PowerRequest = n * t },
+					DeltaFullLoad = n * t / 2 * (-1)
+				}
+				: new ResponseSuccess(this) {
+					Engine = {
+						PowerRequest = n * t,
+						EngineSpeed = n * ratio
+
+					},
+					Clutch = { PowerRequest = n * t }
+				};
+		});
+		return gbx;
+	}
+
+	private Mock<IAPTGearbox> GetGearbox(Dictionary<uint, GearData> ratios)
+	{
+				
+		Mock<IAPTGearbox> amtGearbox = new Mock<IAPTGearbox>();
+		amtGearbox.Name = "APT_Gearbox";
+		
+		var gbx = amtGearbox.As<IAPTGearbox>();
+		// Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
+
+		
+		
+		
+		// gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		// gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+		//
+		// GearshiftPosition gear = null;
+		// gbx.SetupGet(g => g.Gear).Returns(() => {
+		// 	
+		// 	return gear;
+		// });
+		// gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+		// 	.Callback<GearshiftPosition>(p => {
+		// 		gear = p;
+		// 	});
+
+
+		// GearshiftPosition nextGear = null;
+		// gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		// gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+		// 	.Callback<GearshiftPosition>(p => nextGear = p);
+		// 	
+		// gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+		// 	return new ResponseSuccess(this)
+		// 	{
+		// 		Engine = {
+		// 			EngineSpeed = rpm,
+		// 			PowerRequest = tq * rpm,
+		// 		},
+		// 	};
+		// });
+		// gbx.Setup(p => p.Request(
+		// 	It.IsAny<Second>(),
+		// 	It.IsAny<Second>(),
+		// 	It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>(),
+		// 	true)).Returns((
+		// 	Second absTime,
+		// 	Second dt,
+		// 	NewtonMeter t,
+		// 	PerSecond n,
+		// 	bool dryRun) => {
+		//
+		// 	var ratio =
+		// 		gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+		// 	return dryRun
+		// 		? new ResponseDryRun(this) {
+		// 			Engine = {
+		// 				PowerRequest = n * t, EngineSpeed = n * ratio,
+		// 				DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+		// 				TotalTorqueDemand = t,
+		// 			},
+		// 			Clutch = { PowerRequest = n * t },
+		// 			DeltaFullLoad = n * t / 2 * (-1)
+		// 		}
+		// 		: new ResponseSuccess(this) {
+		// 			Engine = {
+		// 				PowerRequest = n * t,
+		// 				EngineSpeed = n * ratio
+		//
+		// 			},
+		// 			Clutch = { PowerRequest = n * t }
+		// 		};
+		// });
+		
+		return gbx;
+	}
+	private static PerSecond GetAngularVelocityBySpeed(double speedKmh, VectoRunData runData)
+	{
+		// r_dyn = 0.465m, i_axle = 6.2
+		var angularVelocity =
+			speedKmh.KMPHtoMeterPerSecond()
+			/ runData.VehicleData.DynamicTyreRadius * 6.2;
+		return angularVelocity;
+	}
+
+	
+	
+	
+	
+	
+	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
+
+	public static readonly string[] TcData = new[] {
+		"0.0,1.80,377.80",
+		"0.1,1.71,365.21",
+		"0.2,1.61,352.62",
+		"0.3,1.52,340.02",
+		"0.4,1.42,327.43",
+		"0.5,1.33,314.84",
+		"0.6,1.23,302.24",
+		"0.7,1.14,264.46",
+		"0.8,1.04,226.68",
+		"0.9,1.02,188.90",
+		"1.0,1.0,0.00",
+		"1.100,0.999,-40.34",
+		"1.222,0.998,-80.34",
+		"1.375,0.997,-136.11",
+		"1.571,0.996,-216.52",
+		"1.833,0.995,-335.19",
+		"2.200,0.994,-528.77",
+		"2.750,0.993,-883.40",
+		"4.400,0.992,-2462.17",
+		"11.000,0.991,-16540.98",
+	};
+
+	public const string EngineFldHeader = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
+
+	public static readonly string[] EngineFldData = new[] {
+		"560,1180,-149,0.6",
+		"600,1282,-148,0.6",
+		"799.9999999,1791,-149,0.6",
+		"1000,2300,-160,0.6",
+		"1200,2300,-179,0.6",
+		"1400,2300,-203,0.6",
+		"1599.999999,2079,-235,0.49",
+		"1800,1857,-264,0.25",
+		"2000.000001,1352,-301,0.25",
+		"2100,1100,-320,0.25",
+	};
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+}
+
+// 	public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear)
+// 	{
+// 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+//
+//         var gbxTypes = new[] {
+// 			GearboxType.ATSerial
+// 		};
+//
+// 		var vehicleContainer = GetMockVehicleContainer(
+// 			vehicleSpeed,
+// 			DrivingBehavior.Accelerating,
+// 			gearRatios,
+// 			out var inputData, 
+// 			out var runData, 
+// 			out var gearboxData, out _);
+//
+// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+//
+//         var angularVelocity = GetAngularVelocityBySpeed(vehicleSpeed, runData);
+// 		var response = gbx.Initialize(torque.SI<NewtonMeter>(), angularVelocity);
+//
+// 		Assert.IsInstanceOf(typeof(ResponseSuccess), response);
+// 		Assert.AreEqual(expectedGear, gbx.Gear.Gear);
+// 		Assert.AreEqual(vehicleSpeed.IsEqual(0), gbx.Disengaged);
+// 	}
+//
+//
+// 	[TestCase(1, 1, 1000, 1500, 0, Description = "Engage 0-> 1C")]
+// 	public void Gearbox_Engage(int gear, int newGear, double tqNm, double nRPM, double speedKmh)
+// 	{
+// 		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+//
+// 		var vehicleContainer = GetMockVehicleContainer(speedKmh, DrivingBehavior.Accelerating, gearRatios, 
+// 			inputData: out _,
+// 			runData: out var runData,
+// 			gearboxData: out _, simplePt: out _);
+//
+// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData: runData);
+//
+// 		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+//
+//
+// 		var absTime = 0.SI<Second>();
+// 		var dt = 2.SI<Second>();
+//
+//
+// 		var expectedN = nRPM.RPMtoRad();
+// 		angularVelocity = expectedN / gearRatios[gear];
+//
+//
+// 		gbx.CurrentState = new ATGearbox.ATGearboxState()
+// 		{
+// 			Gear = gbx.Gear,
+// 		};
+//
+// 		var expectedT = tqNm.SI<NewtonMeter>();
+// 		var torque = expectedT * gearRatios[gear];
+//
+// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+// 			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+//
+// 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+//
+// 		var shiftExpected = gear != newGear; //Different Gear
+// 		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+// 		Assert.AreEqual(shiftExpected, shiftRequired);
+// 	}
+//
+// 	[TestCase(2, 1, -1000, 1500, 4, DrivingBehavior.Braking, Description = "_ -> 0: disengage before halting")]
+// 	public void Gearbox_Disengange(int gear, int newGear, double tqNm, double nRPM, double speedKmh,
+// 		DrivingBehavior driverBehavior)
+// 	{
+// 		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+//
+// 		var vehicleContainer = GetMockVehicleContainer(speedKmh,
+// 			driverBehavior,
+// 			gearRatios,
+// 			out var inputData,
+// 			out var runData,
+// 			out var gearboxData, out _);
+//
+// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+// 		gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+//
+// 		var absTime = 0.SI<Second>();
+// 		var dt = 2.SI<Second>();
+//
+//
+// 		var expectedN = nRPM.RPMtoRad();
+// 		angularVelocity = expectedN / gearRatios[gear];
+//
+// 		//Called in gbx initialize
+// 		//var gearShiftPosition = shiftStrategy.InitGear(absTime, Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+// 		//    angularVelocity);
+// 		var engagedPosition = shiftStrategy.Engage(absTime, dt, null, null);
+//
+//
+// 		Assert.IsTrue(engagedPosition.Engaged);
+//
+// 		gbx.CurrentState = new ATGearbox.ATGearboxState()
+// 		{
+// 			Disengaged = gbx.Disengaged,
+// 			Gear = gbx.Gear,
+// 		};
+//
+// 		var expectedT = tqNm.SI<NewtonMeter>();
+// 		var torque = expectedT * gearRatios[gear];
+//
+//
+// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+// 			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+//
+// 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+//
+// 		var shiftExpected = gear != newGear; //Different Gear
+// 		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+// 		Assert.AreEqual(shiftExpected, shiftRequired);
+// 	}
+//
+//
+// 	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked", TestName="Upshift-TCLocked")]
+// 	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC", TestName = "Upshift-TC")]
+//
+//
+//     [TestCase(2, true, 3, true, 100, 800, 13, Description = "Upshift-TCLocked", TestName = "EarlyUpshift")]
+//
+//     [TestCase(1, false, 1, true, 100, 500, 1, Description = "EarlyUpshift-TC", TestName="EarlyUpshift-TC")]
+//     public void Gearbox_Upshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+// 	{
+//         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+//
+//         var vehicleContainer = GetMockVehicleContainer(
+// 			speedKmh, 
+// 			DrivingBehavior.Accelerating, 
+// 			gearRatios, 
+// 			out var inputData, out var runData, out var gearboxData, out var simplePt);
+//
+//
+// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+// 		var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+// 		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+// 		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+//
+//
+//         var absTime = 0.SI<Second>();
+//         var dt = 2.SI<Second>();
+//
+//         gbx.CurrentState = new ATGearbox.ATGearboxState()
+//         {
+//             Disengaged = gbx.Disengaged,
+//             Gear = gbx.Gear,
+//         };
+//
+//
+// 		var inAngularVelocity = nRPM.RPMtoRad();
+// 		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+//
+//         var inTorque = tqNm.SI<NewtonMeter>();
+//         var outTortque = inTorque * gearRatios[gear];
+//
+// 		var response = new ResponseSuccess(this);
+// 		response.Engine.DynamicFullLoadTorque = 50.SI<NewtonMeter>();
+// 		response.Engine.EngineSpeed = inAngularVelocity;
+// 		response.Engine.TorqueOutDemand = inTorque;
+//
+//
+// 		runData.GearshiftParameters.RatingFactorCurrentGear = 1.1;
+//
+//
+//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+//
+//
+// 		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+// 		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+//
+//         var shiftExpected = gear != newGear; //Different Gear
+//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+//         Assert.AreEqual(shiftExpected, shiftRequired);
+//     }
+//
+//
+// 	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked")]
+// 	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC")]
+// 	public void Gearbox_EarlyUpshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+// 	{
+// 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+//
+// 		var vehicleContainer = GetMockVehicleContainer(
+// 			speedKmh,
+// 			DrivingBehavior.Accelerating,
+// 			gearRatios,
+// 			out var inputData, out var runData, out var gearboxData, out _);
+//
+//
+// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+// 		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+// 		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+// 		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+//
+//
+// 		var absTime = 0.SI<Second>();
+// 		var dt = 2.SI<Second>();
+//
+// 		gbx.CurrentState = new ATGearbox.ATGearboxState()
+// 		{
+// 			Disengaged = gbx.Disengaged,
+// 			Gear = gbx.Gear,
+// 		};
+//
+//
+// 		var inAngularVelocity = nRPM.RPMtoRad();
+// 		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+//
+// 		var inTorque = tqNm.SI<NewtonMeter>();
+// 		var outTortque = inTorque * gearRatios[gear];
+//
+// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+//
+//
+// 		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+// 		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+//
+// 		var shiftExpected = gear != newGear; //Different Gear
+// 		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+// 		Assert.AreEqual(shiftExpected, shiftRequired);
+// 	}
+//
+//
+//     [TestCase(1, false, 2, false, 100, 1000, 1, Description = "Upshift-TC")]
+//     public void Gearbox_Upshift_TC_TC(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+//     {
+//         var gearRatios = new[] { 3.4, 1.3, 1.1, 1.0, 0.7, 0.62 };
+//
+//         var vehicleContainer = GetMockVehicleContainer(
+//             speedKmh,
+//             DrivingBehavior.Accelerating,
+//             gearRatios,
+//             out var inputData, out var runData, out var gearboxData, out _);
+//
+//
+//         var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+//         var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+//         var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+//
+//
+//         var absTime = 0.SI<Second>();
+//         var dt = 2.SI<Second>();
+//
+//         gbx.CurrentState = new ATGearbox.ATGearboxState()
+//         {
+//             Disengaged = gbx.Disengaged,
+//             Gear = gbx.Gear,
+//         };
+//
+// 		Assert.That(gbx.ModelData.GearList.First(p => p.Gear == 2).TorqueConverterLocked, Is.False, "Expected 2nd gear with TC");
+//         var inAngularVelocity = nRPM.RPMtoRad();
+//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+//
+//         var inTorque = tqNm.SI<NewtonMeter>();
+//         var outTortque = inTorque * gearRatios[gear];
+//
+// 		var response = new ResponseSuccess(this);
+// 		response.Engine.EngineSpeed = inAngularVelocity;
+// 		response.Engine.TorqueOutDemand = inTorque;
+//
+//
+//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+//
+//
+//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+//
+//         var shiftExpected = gear != newGear; //Different Gear
+//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+//         Assert.AreEqual(shiftExpected, shiftRequired);
+//     }
+//
+//
+//
+//
+//     [TestCase(3, true, 2, true, 900, 600, 15, Description = "Downshift", TestName="Gearbox_DownShift_1")]
+//     public void Gearbox_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+//     {
+//         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+//
+//         var vehicleContainer = GetMockVehicleContainer(
+//             speedKmh,
+//             DrivingBehavior.Accelerating,
+//             gearRatios,
+//             out var inputData, out var runData, out var gearboxData, out var simplePt);
+//
+// 		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+//
+//         var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+//         var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+//         var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+//
+//
+//         var absTime = 0.SI<Second>();
+//         var dt = 2.SI<Second>();
+//
+//         gbx.CurrentState = new ATGearbox.ATGearboxState()
+//         {
+//             Disengaged = gbx.Disengaged,
+//             Gear = gbx.Gear,
+//         };
+//
+//
+//         var inAngularVelocity = nRPM.RPMtoRad();
+//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+//
+//         var inTorque = tqNm.SI<NewtonMeter>();
+//         var outTortque = inTorque * gearRatios[gear];
+//
+// 		var response = new ResponseSuccess(this);
+// 		response.Engine.EngineSpeed = inAngularVelocity;
+// 		response.Engine.TorqueOutDemand = inTorque;
+//
+//
+// 		var mockPort = new Mock<ITnOutPort>();
+// 		
+// 		simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
+// 		mockPort.Setup(p => p.Request(
+// 			It.IsAny<Second>(),
+// 			It.IsAny<Second>(),
+// 			It.IsAny<NewtonMeter>(),
+// 			It.IsAny<PerSecond>(),
+// 			true
+// 		)).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
+// 			var response = new ResponseDryRun(this);
+// 			response.Engine.PowerRequest = outTorque * outAngularVelocity;
+// 			return response;
+// 		});
+//
+//
+//
+//
+// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+//
+//
+//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+//
+//         var shiftExpected = gear != newGear; //Different Gear
+//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+//         Assert.AreEqual(shiftExpected, shiftRequired);
+//     }
+//
+// 	[TestCase(3, true, 2, true, 200, 700, 15, Description = "Downshift_3", TestName = "Gearbox_DownShift_3")]
+// 	public void Gearbox_Downshift_2(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM,
+// 		double speedKmh)
+// 	{
+// 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+//
+// 		var vehicleContainer = GetMockVehicleContainer(
+// 			speedKmh,
+// 			DrivingBehavior.Accelerating,
+// 			gearRatios,
+// 			out var inputData, out var runData, out var gearboxData, out _);
+//
+// 		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+//
+// 		// Condition from ATShiftStrategy
+// 		//if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() &&
+// 		//	DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>())
+// 		vehicleContainer.Setup(v => v.DrivingCycleInfo.CycleData).Returns(new CycleData() {
+// 			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+// 				VehicleTargetSpeed = 30.KMPHtoMeterPerSecond()
+// 			}
+// 		});
+//
+// 		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(-0.1.SI<MeterPerSquareSecond>());
+//
+//
+// 		runData.EngineData.Inertia = 1.SI<KilogramSquareMeter>();
+// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx, out var gbxNextComponent);
+//
+//
+// 		var dryRunResponse = new ResponseDryRun(this);
+// 		dryRunResponse.Engine.EngineSpeed =
+// 			vehicleContainer.Object.EngineInfo.EngineN95hSpeed - 1.SI<PerSecond>();
+// 		dryRunResponse.DeltaFullLoad = 40_000.SI<Watt>();
+//
+//
+// 		gbxNextComponent.Setup(c => c.Request(
+// 			It.IsAny<Second>(),
+// 			It.IsAny<Second>(),
+// 			It.IsAny<NewtonMeter>(),
+// 			It.IsAny<PerSecond>(), true)).Returns(
+// 			dryRunResponse);
+//
+// 	var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+//         var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+//
+//
+//         var absTime = 0.SI<Second>();
+//         var dt = 2.SI<Second>();
+//
+//         gbx.CurrentState = new ATGearbox.ATGearboxState()
+//         {
+//             Disengaged = gbx.Disengaged,
+//             Gear = gbx.Gear,
+//         };
+//
+//
+//         var inAngularVelocity = nRPM.RPMtoRad();
+//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+//
+//         var inTorque = tqNm.SI<NewtonMeter>();
+//         var outTortque = inTorque * gearRatios[gear];
+//
+//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+//
+//
+//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+//
+//         var shiftExpected = gear != newGear; //Different Gear
+//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+//         Assert.AreEqual(shiftExpected, shiftRequired);
+//     }
+//
+//     [TestCase(3, true, 2, true, 1700, 700, 15, Description = "Downshift", TestName = "Gearbox_Early_DownShift_1")]
+//     public void Gearbox_Early_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+//     {
+//         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+//
+//         var vehicleContainer = GetMockVehicleContainer(
+//             speedKmh,
+//             DrivingBehavior.Accelerating,
+//             gearRatios,
+//             out var inputData, out var runData, out var gearboxData, out var simplePt);
+//
+//         vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+//
+//         var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+//         var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+//
+//         var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+//
+//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+//
+//
+//         var absTime = 0.SI<Second>();
+//         var dt = 2.SI<Second>();
+//
+//         gbx.CurrentState = new ATGearbox.ATGearboxState()
+//         {
+//             Disengaged = gbx.Disengaged,
+//             Gear = gbx.Gear,
+//         };
+//
+//
+//         var inAngularVelocity = nRPM.RPMtoRad();
+//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+//
+//         var inTorque = tqNm.SI<NewtonMeter>();
+//         var outTortque = inTorque * gearRatios[gear];
+//
+//         var response = new ResponseSuccess(this);
+//         response.Engine.EngineSpeed = inAngularVelocity;
+//         response.Engine.TorqueOutDemand = inTorque;
+//
+//
+//         var mockPort = new Mock<ITnOutPort>();
+//
+//         simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
+//         mockPort.Setup(p => p.Request(
+//             It.IsAny<Second>(),
+//             It.IsAny<Second>(),
+//             It.IsAny<NewtonMeter>(),
+//             It.IsAny<PerSecond>(),
+//             true
+//         )).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
+//             var response = new ResponseDryRun(this);
+//             response.Engine.PowerRequest = outTorque * outAngularVelocity;
+//             return response;
+//         });
+//
+//
+//
+//
+//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+//
+//
+//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+//
+//         var shiftExpected = gear != newGear; //Different Gear
+//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+//         Assert.AreEqual(shiftExpected, shiftRequired);
+//     }
+//
+//     private ATShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer, out ATGearbox gbx)
+// 	{
+// 		return GetShiftStrategyAndGearbox(vehicleContainer, out gbx, out _);
+// 	}
+//
+// 	private ATShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer, out ATGearbox gbx,
+// 		out Mock<ITnOutPort> gbxNextComponent)
+// 	{
+// 		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer.Object);
+//
+// 		gbx = new ATGearbox(vehicleContainer.Object, shiftStrategy);
+// 		var mockPort = new Mock<ITnOutPort>();
+// 		NewtonMeter tqRequest = null;
+// 		PerSecond rpmRequest = null;
+// 		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+// 			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+// 			tqRequest = tq;
+// 			rpmRequest = rpm;
+// 			return new ResponseSuccess(this)
+// 			{
+// 				Engine = {
+// 					EngineSpeed = rpm,
+// 					PowerRequest = tq * rpm,
+// 				},
+// 			};
+// 		});
+// 		mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
+// 			It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
+//
+// 		var idleController = new Mock<IIdleController>();
+//
+//
+// 		gbx.IdleController = idleController.Object;
+// 		gbx.Connect(mockPort.Object);
+//
+// 		gbxNextComponent = mockPort;
+// 		return shiftStrategy;
+// 	}
+//
+// 	/// <summary>
+// 	/// Calculated the angular velocity based on the vehicle speed
+// 	/// </summary>
+// 	/// <param name="speedKmh"></param>
+// 	/// <param name="runData"></param>
+// 	/// <returns></returns>
+// 	private static PerSecond GetAngularVelocityBySpeed(double speedKmh, VectoRunData runData)
+// 	{
+// 		// r_dyn = 0.465m, i_axle = 6.2
+//         var angularVelocity =
+// 			speedKmh.KMPHtoMeterPerSecond()
+// 			/ runData.VehicleData.DynamicTyreRadius * 6.2;
+// 		return angularVelocity;
+// 	}
+//
+// 	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
+// 		double[] gearRatios,
+// 		out IVehicleDeclarationInputData inputData, out VectoRunData runData, out GearboxData gearboxData,
+// 		out Mock<ISimpleVehicleContainer> simplePt)
+// 	{
+// 		inputData = GetMockInputData(gearRatios);
+// 		var gbxTypes = new[] {
+// 			GearboxType.ATSerial
+// 		};
+// 		var runDataLocal = GetDummyVectoRunData(inputData);
+// 		var shiftPolygonCalc = GetShiftPolygonCalculator(true);
+// 		
+//
+//         //Setup VehicleContainer
+//         var vehicleContainer = new Mock<IVehicleContainer>();
+// 		var vehicleInfo = new Mock<IVehicleInfo>();
+//
+// 		vehicleContainer.Setup(c => c.RunData).Returns(runDataLocal);
+// 		vehicleContainer.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
+// 		
+//
+//         //EngineInfo
+//         var engineInfo = new Mock<IEngineInfo>();
+// 		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
+// 		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(runDataLocal.EngineData.IdleSpeed);
+// 		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(runDataLocal.EngineData.FullLoadCurves.First().Value.RatedSpeed);
+//
+// 		engineInfo.Setup(e => e.EngineSpeed).Returns(1400.RPMtoRad());
+// 		engineInfo.Setup(e => e.EngineN95hSpeed).Returns
+// 			(runDataLocal.EngineData.FullLoadCurves.First().Value.N95hSpeed);
+// 		engineInfo.Setup(e => e.EngineN80hSpeed).Returns(
+// 			runDataLocal.EngineData.FullLoadCurves.First().Value.N80hSpeed);
+// 		engineInfo.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>())).Returns((PerSecond n) =>
+// 			runDataLocal.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+//
+//         //VehicleInfo
+//         vehicleInfo.Setup(v => v.VehicleSpeed).Returns(speedKmh.KMPHtoMeterPerSecond());
+// 		vehicleInfo.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
+// 			.Returns(0.SI<Newton>());
+// 		vehicleInfo.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+// 		vehicleInfo.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+// 		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+//
+// 		//AxleGearInfo
+// 		var axleGearInfo = new Mock<IAxlegearInfo>();
+// 		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
+// 		axleGearInfo.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
+//
+// 		//WheelsInfo
+// 		var wi = new Mock<IWheelsInfo>();
+// 		vehicleContainer.Setup(c => c.WheelsInfo).Returns(wi.Object);
+// 		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
+//
+// 		//Cycle Info
+// 		var cycleInfo = new Mock<IDrivingCycleInfo>();
+// 		vehicleContainer.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
+// 		cycleInfo.Setup(c => c.CycleData).Returns(
+// 			GetCycleData());
+// 		cycleInfo.Setup(c => c.RoadGradient).Returns(0.SI<Radian>());
+//
+//
+// 		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry()
+// 		{
+// 			Altitude = 0.SI<Meter>()
+// 		});
+// 		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
+//
+// 		//DriverINfo
+// 		vehicleContainer.Setup(v => v.DriverInfo.DriverBehavior).Returns(driverBehavior);
+// 		var acc = 0.SI<MeterPerSquareSecond>();
+// 		switch (driverBehavior)
+// 		{
+// 			case DrivingBehavior.Accelerating:
+// 				acc = 1.SI<MeterPerSquareSecond>();
+// 				break;
+// 			case DrivingBehavior.Braking:
+// 				acc = -1.SI<MeterPerSquareSecond>();
+// 				break;
+// 			case DrivingBehavior.Halted:
+// 				acc = 0.SI<MeterPerSquareSecond>();
+// 				break;
+// 			default:
+// 				throw new ArgumentOutOfRangeException();
+// 		}
+//
+//
+//
+//
+// 		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(acc);
+// 		runData = runDataLocal;
+// 		gearboxData = runData.GearboxData;
+//
+//
+//         //TestPowertrain
+// 		//TestPowertrainBuilder
+// 		var testPt = GetMockTestPowertrain(runData);
+//
+// 		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+// 		ptBuilder.Setup(p => p.CreateTestPowertrain<Gearbox>(It.IsAny<ISimpleVehicleContainer>(), It.IsAny<IDataBus>()))
+// 			.Returns(testPt.Object);
+// 		simplePt = GetSimplePowertrain(inputData);
+// 		ptBuilder.Setup(ptBuilder => ptBuilder.BuildSimplePowertrain(It.IsAny<VectoRunData>()))
+// 			.Returns(simplePt.Object);
+//
+//
+//         vehicleContainer.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+//
+//         return vehicleContainer;
+// 	}
+//
+// 	private Mock<IPowertainInfo> GetPowertrainInfo()
+// 	{
+// 		var powerTrainInfo = new Mock<IPowertainInfo>();
+// 		powerTrainInfo.Setup(p => p.HasCombustionEngine).Returns(true);
+// 		return powerTrainInfo;
+// 	}
+//
+//     private Mock<ITestPowertrain<Gearbox>> GetMockTestPowertrain(VectoRunData runData)
+// 	{
+// 		var testPt = new Mock<ITestPowertrain<Gearbox>>();
+// 		var tCnt = new Mock<ISimpleVehicleContainer>();
+// 		tCnt.Setup(c => c.RunData).Returns(runData);
+//
+// 		tCnt.Setup(c => c.PowertrainInfo).Returns(GetPowertrainInfo().Object);
+//
+//
+// 		var tGbx = new Mock<Gearbox>(tCnt.Object, null);
+// 		testPt.Setup(t => t.Gearbox).Returns(tGbx.Object);
+// 		tGbx.Setup(g => g.Initialize(It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>()))
+// 			.Returns((NewtonMeter t, PerSecond n) => new ResponseSuccess(this)
+// 			{
+// 				Engine = { PowerRequest = n * t, EngineSpeed = n },
+// 				Clutch = { PowerRequest = n * t }
+// 			});
+// 		tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+// 				It.IsAny<bool>()))
+// 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => new ResponseSuccess(this)
+// 			{
+// 				Engine = { PowerRequest = n * t, EngineSpeed = n },
+// 				Clutch = { PowerRequest = n * t }
+// 			});
+// 		tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+// 				It.IsAny<bool>()))
+// 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => dryRun ?
+// 				new ResponseDryRun(this)
+// 				{
+// 					Engine = { PowerRequest = n * t, EngineSpeed = n },
+// 					Clutch = { PowerRequest = n * t }
+// 				} : new ResponseSuccess(this)
+// 				{
+// 					Engine = { PowerRequest = n * t, EngineSpeed = n },
+// 					Clutch = { PowerRequest = n * t }
+// 				});
+// 		var tEng = new Mock<ICombustionEngine>();
+// 		testPt.Setup(t => t.CombustionEngine).Returns(tEng.Object);
+// 		tEng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
+// 			.Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+// 		return testPt;
+//     }
+//
+// 	private CycleData GetCycleData()
+// 	{
+// 		return new CycleData()
+// 		{
+// 			LeftSample = new DrivingCycleData.DrivingCycleEntry()
+// 			{
+// 				PTOActive = PTOActivity.Inactive,
+// 				VehicleTargetSpeed = 10.KMPHtoMeterPerSecond()
+// 			}
+// 		};
+// 	}
+//
+//
+//
+//     [TestCase(2, 3, 400, 2300, 5, DrivingBehavior.Accelerating, Description = "Upshift")]
+//     public void Gearbox_EmergencyShift(int gear, int newGear, double tqNm, double nRPM, double speedKmh,
+// 		DrivingBehavior driverBehavior)
+// 	{
+//
+// 	}
+//
+//
+// 	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
+// 	{
+// 		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
+// 		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
+// 		var fld = FullLoadCurveReader.Create(fldData);
+//
+//
+// 		// create gearbox data
+// 		var tcDataAdapter = new TorqueConverterDataAdapter();
+//
+//
+//
+// 		// fuel data
+//         var fuelData = new CombustionEngineFuelData() {
+// 			ConsumptionMap = FuelConsumptionMapReader.Create(
+// 				InputDataHelper.InputDataAsTableData(
+// 					"engine speed [rpm] ,torque [Nm] ,fuel consumption [g/h] ,whr power electrical [W]",
+// 					"500,-131,0,0",
+// 						"500,95.6,1814.959,0",
+// 						"500,573.6,9771.095,0",
+// 						"2453,-209.12,0,0",
+// 						"2453,764.8,39097.94,0"
+//                     )),
+// 			FuelData = DeclarationData.FuelData.Lookup(FuelType.DieselCI),
+//
+//
+// 		};
+//
+// 		var runData = new VectoRunData() {
+// 			VehicleData = new VehicleData() {
+// 				DynamicTyreRadius = 0.465.SI<Meter>(),
+// 				GrossVehicleMass = 12_000.SI<Kilogram>(),
+// 				CurbMass = 10_000.SI<Kilogram>(),
+// 			},
+// 			EngineData = new CombustionEngineData() {
+// 				Inertia = 0.SI<KilogramSquareMeter>(),
+// 				FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(),
+// 				IdleSpeed = 600.RPMtoRad(),
+// 				RatedSpeedDeclared = 2000.RPMtoRad(),
+// 				Fuels = new List<CombustionEngineFuelData>() {
+// 					fuelData,
+// 				}
+// 			},
+// 			Cycle = new DrivingCycleData() {
+// 				CycleType = CycleType.DistanceBased
+// 			}
+// 		};
+// 		for (uint i = 0; i <= nrOfGears; i++) {
+// 			runData.EngineData.FullLoadCurves[i] = fld;
+// 		}
+//
+// 		var gbxDataAdapter = new GearboxDataAdapter(tcDataAdapter);
+// 		var gbxTypes = new[] {
+// 			GearboxType.ATSerial, GearboxType.ATPowerSplit
+// 		};
+//
+// 		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData, new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
+// 			GearboxType.ATSerial,
+// 			GearboxType.ATPowerSplit
+// 		});
+//
+// 		var gearShiftParams =
+// 			gbxDataAdapter.CreateGearshiftData(1.0, runData.EngineData.IdleSpeed, GearboxType.ATSerial, nrOfGears);
+//
+// 		runData.GearboxData = gearboxData;
+// 		runData.GearshiftParameters = gearShiftParams;
+//         return runData;
+// 	}
+//
+// 	private static IShiftPolygonCalculator GetShiftPolygonCalculator(bool optimized)
+// 	{
+//
+// 		IShiftPolygonCalculator shiftPolygonCalc = optimized ? new ATShiftStrategyOptimizedPolygonCalculator() :  new ATShiftStrategyPolygonCalculator();
+//
+// 		return shiftPolygonCalc;
+// 	}
+//
+// 	// private static IShiftPolygonCalculator GetMockShiftPolygonCalc()
+// 	// {
+// 	// 	var shiftPolygonCalc = new Mock<IShiftPolygonCalculator>();
+// 	// 	var downshift = new List<ShiftPolygon.ShiftPolygonEntry>() { };
+// 	// 	var upshift = new List<ShiftPolygon.ShiftPolygonEntry>() { };
+// 	// 	var shiftpolygon = new ShiftPolygon(downshift, upshift);
+// 	// 	shiftPolygonCalc.Setup(s => s.ComputeDeclarationShiftPolygon(It.IsIn(GearboxType.ATSerial), It.IsAny<int>(),
+// 	// 			It.IsAny<EngineFullLoadCurve>(), It.IsAny<IList<ITransmissionInputData>>(),
+// 	// 			It.IsAny<CombustionEngineData>(), It.IsAny<double>(), It.IsAny<Meter>(), It.IsAny<ElectricMotorData>()))
+// 	// 		.Returns(shiftpolygon);
+// 	// 	return shiftPolygonCalc.Object;
+// 	// }
+//
+// 	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(IVehicleDeclarationInputData inputData)
+// 	{
+// 		var simplePt = new Mock<ISimpleVehicleContainer>();
+// 		simplePt.Setup(s => s.RunData).Returns(GetDummyVectoRunData(inputData));
+// 		simplePt.Setup(s => s.AddComponent(It.IsAny<VectoSimulationComponent>()));
+// 		simplePt.Setup(s => s.PowertrainInfo).Returns(GetPowertrainInfo().Object);
+// 		simplePt.Setup(s => s.GearboxCtl).Returns(GetMockGearbox(simplePt.Object).Object);
+//
+// 		//Vehicle Info
+// 		var vehicleInfo = new Mock<IVehicleInfo>();
+// 		simplePt.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
+// 		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
+//
+//
+// 		//VehiclePort
+// 		var vehiclePort = new Mock<IDriverDemandOutPort>();
+// 		vehiclePort.Setup(port => port.Initialize(
+// 			It.IsAny<MeterPerSecond>(), It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
+//
+// 		simplePt.Setup(c => c.VehiclePort).Returns(vehiclePort.Object);
+//
+// 		var mockPort = new Mock<ITnOutPort>();
+//
+// 		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+// 			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+// 			return new ResponseSuccess(this)
+// 			{
+// 				Engine = {
+// 					EngineSpeed = rpm,
+// 					PowerRequest = tq * rpm,
+// 				},
+// 			};
+// 		});
+// 		mockPort.Setup(p => p.Request(
+// 			It.IsAny<Second>(),
+// 			It.IsAny<Second>(),
+// 			It.IsAny<NewtonMeter>(),
+// 			It.IsAny<PerSecond>(),
+// 			true)).Returns((
+// 			Second absTime,
+// 			Second dt,
+// 			NewtonMeter tq,
+// 			PerSecond ang,
+// 			bool dryRun) => {
+// 			return new ResponseDryRun(this) {
+// 				Engine = {
+// 					EngineSpeed = ang,
+// 					PowerRequest = tq * ang,
+// 					TorqueOutDemand = tq
+// 				},
+// 				DeltaFullLoad = 10_000.SI<Watt>(),
+// 			};
+// 		});
+//
+// 		simplePt.Setup(c => c.GearboxOutPort).Returns(mockPort.Object);
+//         return simplePt;
+// 	}
+// 	private Mock<ATGearbox> GetMockGearbox(IVehicleContainer container)
+// 	{
+// 		var gbx = new Mock<ATGearbox>(container, null);
+// 		var ratios = container.RunData.GearboxData.Gears;
+//
+//
+// 		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+// 		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+// 		gbx.SetupProperty(g => g.Gear);
+// 		gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+// 				It.IsAny<bool>()))
+// 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
+// 				var ratio = gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+// 				return dryRun
+// 					? new ResponseDryRun(this)
+// 					{
+// 						Engine = {
+// 							PowerRequest = n * t, EngineSpeed = n * ratio,
+// 							DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+// 						},
+// 						Clutch = { PowerRequest = n * t },
+// 						DeltaFullLoad = 10.SI<Watt>()
+// 					}
+// 					: new ResponseSuccess(this)
+// 					{
+// 						Engine = { PowerRequest = n * t, EngineSpeed = n * ratio },
+// 						Clutch = { PowerRequest = n * t }
+// 					};
+// 			});
+// 		return gbx;
+// 	}
+//
+//
+//     private IVehicleDeclarationInputData GetMockInputData(double[]? gearRatios)
+// 	{
+// 		var input = new Mock<IVehicleDeclarationInputData>();
+// 		var components = new Mock<IVehicleComponentsDeclaration>();
+// 		input.Setup(i => i.Components).Returns(components.Object);
+// 		var gbx = new Mock<IGearboxDeclarationInputData>();
+// 		var tc = new Mock<ITorqueConverterDeclarationInputData>();
+//
+// 		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
+// 		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
+// 		gearRatios = gearRatios ?? new double[] {
+//
+// 		};
+// 		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
+// 		var efficiency = 0.98;
+// 		var data = new List<string>();
+// 		
+// 		foreach (var speed in new[] {0, 10000}) {
+// 			foreach (var tq in new[] {1e5, -1e5, 0}) {
+// 				data.Add(FormattableString.Invariant($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}"));
+// 			}
+// 		}
+//         var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
+// 		//lossmap.Columns
+// 		var gears = gearRatios.Select((x, idx) => {
+// 			var gear = new Mock<ITransmissionInputData>();
+// 			gear.Setup(g => g.Ratio).Returns(x);
+// 			gear.Setup(g => g.Gear).Returns(idx + 1);
+// 			//gear.Setup(g => g.Efficiency).Returns(0.98);
+// 			gear.Setup(g => g.LossMap).Returns(lossmap);
+// 			gear.Setup(g => g.MaxInputSpeed).Returns(2000.RPMtoRad());
+// 			return gear.Object;
+// 		}).ToList();
+// 		gbx.Setup(g => g.Type).Returns(GearboxType.ATSerial);
+// 		gbx.Setup(g => g.Gears).Returns(gears);
+//
+// 		var tcData = InputDataHelper.InputDataAsTableData(TcHeader, TcData);
+// 		tc.Setup(t => t.TCData).Returns(tcData);
+// 		return input.Object;
+// 	}
+//
+// 	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
+//
+// 	public static readonly string[] TcData = new[] {
+// 		"0.0,1.80,377.80",
+// 		"0.1,1.71,365.21",
+// 		"0.2,1.61,352.62",
+// 		"0.3,1.52,340.02",
+// 		"0.4,1.42,327.43",
+// 		"0.5,1.33,314.84",
+// 		"0.6,1.23,302.24",
+// 		"0.7,1.14,264.46",
+// 		"0.8,1.04,226.68",
+// 		"0.9,1.02,188.90",
+// 		"1.0,1.0,0.00",
+// 		"1.100,0.999,-40.34",
+// 		"1.222,0.998,-80.34",
+// 		"1.375,0.997,-136.11",
+// 		"1.571,0.996,-216.52",
+// 		"1.833,0.995,-335.19",
+// 		"2.200,0.994,-528.77",
+// 		"2.750,0.993,-883.40",
+// 		"4.400,0.992,-2462.17",
+// 		"11.000,0.991,-16540.98",
+// 	};
+//
+// 	public const string EngineFldHeader = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
+//
+// 	public static readonly string[] EngineFldData = new[] {
+// 		"560,1180,-149,0.6",
+// 		"600,1282,-148,0.6",
+// 		"799.9999999,1791,-149,0.6",
+// 		"1000,2300,-160,0.6",
+// 		"1200,2300,-179,0.6",
+// 		"1400,2300,-203,0.6",
+// 		"1599.999999,2079,-235,0.49",
+// 		"1800,1857,-264,0.25",
+// 		"2000.000001,1352,-301,0.25",
+// 		"2100,1100,-320,0.25",
+// 	};
+//
+//
+// }
\ No newline at end of file
-- 
GitLab


From 79dd57c8b5b946e448c9815c0c7c10896b092198 Mon Sep 17 00:00:00 2001
From: Harald Martini <harald.martini@student.tugraz.at>
Date: Mon, 17 Mar 2025 12:37:10 +0100
Subject: [PATCH 13/22] added PEVAMTShiftStrategyTests.cs

---
 .../PEVAMTShiftStrategyTests.cs               | 2023 +++++++++++++++++
 1 file changed, 2023 insertions(+)
 create mode 100644 Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs
new file mode 100644
index 0000000000..aad578ce85
--- /dev/null
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs	
@@ -0,0 +1,2023 @@
+using Moq;
+using NUnit.Framework;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData.Impl;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
+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;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor;
+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.Tests.Utils;
+using TUGraz.VectoCore.Utils;
+using Range = System.Range;
+
+// ReSharper disable InconsistentNaming
+
+namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
+{
+    [TestFixture]
+    public class PEVAMTShiftStrategyTests
+    {
+		[TestCase(500, 80, 1)]
+		[TestCase(5, 500, 2)]
+		public void InitGear(double torque_Nm, double speed_rpm, int expectedGear)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+
+            var container = GetMocks(ratios);
+
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var torque = torque_Nm.SI<NewtonMeter>();
+			var speed = speed_rpm.RPMtoRad();
+
+			var result = shiftStrategy.InitGear(absTime, dt, torque, speed);
+
+			var newGear = result.Gear;
+			Assert.AreEqual(expectedGear, newGear);
+
+
+
+		}
+		
+		[TestCase(5000, 80, 1)]
+		[TestCase(5, 500, 2)]
+		public void InitStartGear(double torque_Nm, double speed_rpm, int expectedGear)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+
+			var container = GetMocks(ratios);
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(0.KMPHtoMeterPerSecond());
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var torque = torque_Nm.SI<NewtonMeter>();
+			var speed = speed_rpm.RPMtoRad();
+
+			var result = shiftStrategy.InitGear(absTime, dt, torque, speed);
+
+			var newGear = result.Gear;
+			Assert.AreEqual(expectedGear, newGear);
+
+
+
+		}
+
+		[TestCase(
+			500,
+			80,
+			500,
+			10000,
+			1,
+			2, TestName = "Emergency UpShift")]
+
+		[TestCase(
+			500,
+			80,
+			1000,
+			1800,
+			1,
+			2, TestName = "UpShift")]
+		[TestCase(
+			500,
+			80,
+			1000,
+			800,
+			1,
+			1, TestName = "No Upshift")]
+		public void Upshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			CheckUpshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, false);
+		}
+		
+		[TestCase(
+			500,
+			80,
+			100,
+			1800,
+			1,
+			3, TestName = "UpShiftSkipGear")]
+		public void UpshiftSkipGear(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			CheckUpshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, false, new[] { 0.0, 3.86, 1.93, 1.92 });
+		}
+		
+		
+		public void CheckUpshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear, bool effShift, double[]? ratios = null)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			ratios = ratios ?? new[] { 0.0, 3.86, 1.93 };
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+
+			if (!effShift) {
+				DisableEffshift(container.Object.RunData);
+			}
+
+		
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			var gear = new GearshiftPosition((uint)currentGear);
+			gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+			var response = new ResponseSuccess(this);
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity.AsRPM} [rpm]\n" + 
+				$"InSpeed: {inAngularVelocity.AsRPM} [rpm]\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result);
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+			
+			
+			
+		}
+
+		[TestCase(
+			500,
+			80,
+			-10,
+			1000,
+			1,
+			2, TestName = "UpShift")]
+		public void EarlyUpshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(20.KMPHtoMeterPerSecond());
+
+		
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			var gear = new GearshiftPosition((uint)currentGear);
+			gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+			var response = new ResponseSuccess(this);
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity.AsRPM} [rpm]\n" + 
+				$"InSpeed: {inAngularVelocity.AsRPM} [rpm]\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result);
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+
+
+		}
+		
+		
+		[TestCase(
+			5,
+			200,
+			2000,
+			200,
+			2,
+			1, TestName = "Downshift")]
+		public void Downshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear, int speedKmh=1)
+		{
+			var ratios = new[] { 0.0,  3.86, 1.93 };
+			CheckDownshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, ratios, false, speedKmh);
+		}
+		
+		[TestCase(
+			5,
+			200,
+			-500,
+			200,
+			4,
+			2, 
+			40, TestName = "EarlyDownshift")]
+		public void EarlyDownshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear, int speedKmh=1)
+		{
+			var ratios = new[] { 0.0, 3.86, 3, 2.5, 1.93 };
+			CheckDownshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, ratios, true, speedKmh);
+		}
+
+		[TestCase(
+			5,
+			200,
+			2000,
+			40,
+			4,
+			2, TestName = "Downshift_SkipGear")]
+		public void DownshiftSkipGears(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			var ratios = new[] { 0.0, 3.86, 3,  2.5, 1.93 };
+			CheckDownshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, ratios, false);
+		}
+		
+		private void DisableEffshift(VectoRunData runData)
+		{
+			TestContext.WriteLine("EffShift Disabled");
+			runData.GearshiftParameters.AllowedGearRangeFC = 0;
+		}
+
+		private void DisableEffshift(Mock<IVehicleContainer> vehicleContainer)
+		{
+			DisableEffshift(vehicleContainer.Object.RunData);
+		}
+		
+				
+		[TestCase(
+			5,
+			200,
+			2000,
+			200,
+			2,
+			1, TestName = "BrakingGear")]
+		public void BrakingGear(
+			double init_outTorque_Nm,
+			double init_outSpeed_rpm,
+			double outTorque_Nm, 
+			double outSpeed_rpm, 
+			int currentGear,
+			int expectedGear, 
+			int vehicleSpeed_kmH = 1)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0,  3.86, 1.93 };
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+			
+			
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(vehicleSpeed_kmH.KMPHtoMeterPerSecond());
+			container.Setup(c => c.DriverInfo.DriverBehavior).Returns(DrivingBehavior.Braking);
+			
+
+			DisableEffshift(container.Object.RunData);
+
+			
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			var gear = new GearshiftPosition((uint)currentGear);
+			gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity}\n" + 
+				$"InSpeed: {inAngularVelocity}\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			var response = new ResponseSuccess(this) { };
+			response.ElectricMotor.AngularVelocity = inAngularVelocity;
+			response.ElectricMotor.TorqueRequestEmMap = inTorque;
+			response.ElectricMotor.DeRatingActive = false;
+			response.Gearbox.InputSpeed = inAngularVelocity;
+			// response.ElectricMotor;
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result, "Expected Shift");
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+			
+			
+			
+		}
+		
+		
+		public void CheckDownshift(
+			double init_outTorque_Nm,
+			double init_outSpeed_rpm,
+			double outTorque_Nm, 
+			double outSpeed_rpm, 
+			int currentGear,
+			int expectedGear, 
+			double[] ratios,
+			bool effShift = true,
+			int vehicleSpeed_kmH = 1)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(vehicleSpeed_kmH.KMPHtoMeterPerSecond());
+
+			
+			if (!effShift) {
+				DisableEffshift(container.Object.RunData);
+			}
+			
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			var gear = new GearshiftPosition((uint)currentGear);
+			gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity}\n" + 
+				$"InSpeed: {inAngularVelocity}\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			var response = new ResponseSuccess(this) { };
+			response.ElectricMotor.AngularVelocity = inAngularVelocity;
+			response.ElectricMotor.TorqueRequestEmMap = inTorque;
+			response.ElectricMotor.DeRatingActive = false;
+			// response.ElectricMotor;
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result, "Expected Shift");
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+			
+			
+			
+		}
+		
+		
+		
+		
+		
+		private PEVAMTShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container, out PEVGearbox gearbox)
+		{
+			var shiftStrategy = new PEVAMTShiftStrategy(container.Object);
+			gearbox = new PEVGearbox(container.Object, shiftStrategy);
+
+			SetVelocityDropLookupData(shiftStrategy);
+			
+			gearbox.Gear = new GearshiftPosition(0);
+			container.Setup(c => c.GearboxInfo).Returns(gearbox);
+			
+			
+			return shiftStrategy;
+		}
+
+		private Mock<IVehicleContainer> GetMocks(double[] ratios)
+		{
+			var container = new Mock<IVehicleContainer>();
+
+			//RunData
+			var runData = GetRunData(ratios);
+			container.Setup(r => r.RunData).Returns(runData);
+
+			//EmInfo
+			var em = GetMockElectricMotor(container.Object, runData.ElectricMachinesData.Single().Item2);
+			container.Setup(c => c.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2))
+				.Returns(em);
+			container.Setup(c => c.PowertrainInfo.ElectricMotorPositions).Returns(new[] {
+				PowertrainPosition.BatteryElectricE2
+			});
+			
+			// container.Setup(r => r.GetElectricMotors()).Returns(new List<IElectricMotorInfo>(){em});
+			
+			container.Setup(c => c.PowertrainInfo.HasCombustionEngine).Returns(false);
+
+			//BatteryInfo
+			container.Setup(c => c.BatteryInfo.InternalVoltage).Returns(700.SI<Volt>());
+			
+			//VehicleInfo
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
+			container.Setup(c => c.VehicleInfo.VehicleStopped).Returns(false);
+			
+			//DriverInfo
+			container.Setup(c => c.DriverInfo.DriverBehavior).Returns(DrivingBehavior.Accelerating);
+			container.Setup(c => c.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+			// container.Set
+			
+            //PowertrainBuilder, SimplePowertrain
+			var testPt = GetTestPowertrain(ratios, container, out _);
+			var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+			container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+
+			//DrivingCycleInfo
+			container.Setup(c => c.DrivingCycleInfo.RoadGradient).Returns(0.SI<Radian>());
+
+            return container;
+		}
+
+		private Mock<ITestPowertrain> GetTestPowertrain(double[] ratios, 
+			Mock<IVehicleContainer> container,
+			out Mock<ISimpleVehicleContainer> simplePt)
+		{
+			var testPt = new Mock<ITestPowertrain>();
+			
+			simplePt = GetSimplePowertrain(ratios, container);
+
+			return testPt;
+		}
+
+		private Mock<IElectricSystem> GetMockElectricSystem()
+		{
+			var electricSystem = new Mock<IElectricSystem>();
+			
+			
+			electricSystem
+				.Setup(es => es.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<Watt>(), true))
+				.Returns((Second t, Second dt, Watt powerDemand, bool dryrun) => {
+					
+					var response = new Mock<IElectricSystemResponse>();
+					response
+						.Setup(mr => mr.MaxPowerDrive)
+						.Returns(-100E3.SI<Watt>());
+					response
+						.Setup(mr => mr.MaxPowerDrag)
+						.Returns(100E3.SI<Watt>());
+					response
+						.Setup(mr => mr.RESSPowerDemand).Returns(powerDemand);
+						
+						
+					
+					
+					return response.Object;
+				});
+
+
+			return electricSystem;
+		}
+		
+		private ElectricMotor GetMockElectricMotor(IVehicleContainer container, ElectricMotorData emData)
+		{
+			var emControl = new SimpleElectricMotorControl();
+			
+			var electricMotor = new ElectricMotor(container: container, emData, emControl,
+				PowertrainPosition.BatteryElectricE2);
+
+			//Connect Electric System
+			var es = GetMockElectricSystem();
+			electricMotor.Connect(es.Object);
+			return electricMotor;
+		}
+		
+		private Mock<ISimpleVehicleContainer> GetSimplePowertrain(double[] ratios, Mock<IVehicleContainer> container)
+		{
+			var simplePt = new Mock<ISimpleVehicleContainer>();
+
+			var components = new List<VectoSimulationComponent>();
+			
+			var runData = container.Object.RunData;
+			var em = GetMockElectricMotor(container.Object, runData.ElectricMachinesData.Single().Item2);
+			var emDict = new Dictionary<PowertrainPosition, IElectricMotorInfo>() {
+				{ PowertrainPosition.BatteryElectricE2, em },
+			};
+			simplePt.Setup(r => r.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2))
+				.Returns(em);
+
+
+			simplePt.Setup(r => r.ElectricMotors).Returns(emDict);
+
+			simplePt.Setup(s => s.PowertrainInfo.HasCombustionEngine).Returns(false);
+			simplePt.Setup(s => s.RunData).Returns(GetRunData(ratios));
+
+			var testGbx = GetTestGearbox(simplePt.Object, em);
+			simplePt.Setup(s => s.GearboxCtl).Returns(testGbx.Object);
+			simplePt.Setup(s => s.GearboxInfo).Returns(testGbx.Object);
+			simplePt.Setup(s => s.GearboxOutPort).Returns(testGbx.Object);
+			
+			simplePt.Setup(s => s.SimulationComponents()).Returns(components);
+			simplePt.Setup(s => s.Brakes).Returns(new Mock<IBrakes>().Object);
+
+			//Take from real powertrain
+			simplePt.Setup(s => s.VehicleInfo).Returns(container.Object.VehicleInfo);
+			simplePt.Setup(s => s.DriverInfo).Returns(container.Object.DriverInfo);
+			
+			return simplePt;
+		}
+		
+		Mock<ITestPowertrainTransmission> GetTestGearbox(ISimpleVehicleContainer simpleContainer, ElectricMotor em)
+		{
+			Mock<IAMTGearbox> amtGearbox = new Mock<IAMTGearbox>();
+			amtGearbox.Name = "PEVAMT_TestGearbox";
+			Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
+
+			
+			
+			gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+			gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+			GearshiftPosition gear = null;
+			gbx.SetupGet(g => g.Gear).Returns(() => {
+				
+				return gear;
+			});
+			gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+				.Callback<GearshiftPosition>(p => {
+					gear = p;
+				});
+
+
+			GearshiftPosition nextGear = null;
+			gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+			gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+				.Callback<GearshiftPosition>(p => nextGear = p);
+				
+			gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+				It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+				return new ResponseSuccess(this)
+				{
+					Engine = {
+						EngineSpeed = rpm,
+						PowerRequest = tq * rpm,
+					},
+				};
+			});
+			gbx.Setup(p => p.Request(
+				It.IsAny<Second>(),
+				It.IsAny<Second>(),
+				It.IsAny<NewtonMeter>(),
+				It.IsAny<PerSecond>(),
+				true)).Returns((
+				Second absTime,
+				Second dt,
+				NewtonMeter t,
+				PerSecond n,
+				bool dryRun) => {
+
+				var ratio =
+					gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+				return dryRun
+					? new ResponseDryRun(this) {
+						Engine = {
+							PowerRequest = n * t, EngineSpeed = n * ratio,
+							DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+							TotalTorqueDemand = t,
+						},
+						Clutch = { PowerRequest = n * t },
+						DeltaFullLoad = n * t / 2 * (-1)
+					}
+					: new ResponseSuccess(this) {
+						Engine = {
+							PowerRequest = n * t,
+							EngineSpeed = n * ratio
+
+						},
+						Clutch = { PowerRequest = n * t }
+					};
+			});
+			return gbx;
+		}
+
+
+		private VectoRunData GetRunData(double[] ratios)
+		{
+			var runData = new VectoRunData();
+
+			//GearShiftParameters
+			var gearshiftParameters = new ShiftStrategyParameters() {
+				TorqueReserve = 0.0,
+				TimeBetweenGearshifts = 2.SI<Second>(),
+				DownshiftAfterUpshiftDelay = 2.SI<Second>(),
+				UpshiftAfterDownshiftDelay = 2.SI<Second>(),
+				UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>(),
+				StartSpeed = 0.KMPHtoMeterPerSecond(),
+				RatingFactorCurrentGear = 1,
+				AllowedGearRangeFC = 2,
+				MinEngineSpeedPostUpshift = 0.RPMtoRad(),
+			};
+			runData.GearshiftParameters = gearshiftParameters;
+
+			runData.ElectricMachinesData = GetElectricMachinesData();
+			var emData = runData.ElectricMachinesData.Single(i => i.Item1 == PowertrainPosition.BatteryElectricE2)
+				.Item2;
+			//VehicleData
+			var vehicleData = new VehicleData() {
+				DynamicTyreRadius = 0.492.SI<Meter>(),
+            };
+			runData.VehicleData = vehicleData;
+
+			//CycleData 
+			var mockCycle = new Mock<IDrivingCycleData>();
+			mockCycle.Setup(cd => cd.Entries).Returns(
+				new List<DrivingCycleData.DrivingCycleEntry>() {
+					new DrivingCycleData.DrivingCycleEntry() {
+						RoadGradient = 0.SI<Radian>()
+					}
+				});
+			runData.Cycle = mockCycle.Object;
+			
+
+            //Gearboxdata
+			var gearboxInputData = new Mock<IGearboxDeclarationInputData>();
+
+			var gearsInputData = new List<Mock<ITransmissionInputData>>();
+
+			gearboxInputData.Setup(
+				d => d.Gears)
+				.Returns(gearsInputData.Select(m => m.Object)
+				.ToList());
+
+
+			var gearboxData = new GearboxData() {
+				Gears = new Dictionary<uint, GearData>(ratios.Length),
+				InputData = gearboxInputData.Object,
+				Type = GearboxType.AMT,
+				TractionInterruption = 1.SI<Second>(),
+				Inertia = 0.SI<KilogramSquareMeter>(),
+			};
+			
+
+
+
+			
+			runData.GearboxData = gearboxData;
+			for (uint i = 1; i < ratios.Length; i++) {
+				gearboxData.Gears[i] = new GearData
+				{
+					Ratio = ratios[i],
+					LossMap = TransmissionLossMapReader.Create(0.96, ratios[i], $"Gear {i}"),
+
+				};
+			}
+			var axlRatio = 3.240355;
+			var gearsInput = gearboxData.Gears.Select(x => {
+				var r = new Mock<ITransmissionInputData>();
+				r.Setup(g => g.Ratio).Returns(x.Value.Ratio);
+				r.Setup(g => g.MaxTorque).Returns(x.Value.MaxTorque);
+				r.Setup(g => g.MaxInputSpeed).Returns(x.Value.MaxSpeed);
+				
+				return r.Object;
+			}).ToList();
+			foreach (var entry in gearboxData.Gears) {
+				var gearIdx = (int)entry.Key - 1;
+				var dynamicTyreRadius = 0.5.SI<Meter>();
+
+				var shiftPolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(
+					gearIdx,
+					emData,
+					gearsInput);
+					
+				entry.Value.ShiftPolygon = shiftPolygon;
+
+			}
+
+
+			return runData;
+		}
+
+		private IList<Tuple<PowertrainPosition, ElectricMotorData>> GetElectricMachinesData()
+		{
+			//Nr of electric machines
+			const int emCount = 2;
+			//ElectricMachines
+			// var electricMotorData = new ElectricMotorData() {
+			// 	
+			// };
+			var emDataAdapter = new ElectricMachinesDataAdapter();
+			var emInputData = new Mock<IElectricMotorDeclarationInputData>();
+
+			var powerMapMock = new Mock<IElectricMotorPowerMap>();
+			powerMapMock.Setup(pm => pm.Gear).Returns(0);
+			powerMapMock.Setup(pm => pm.PowerMap).Returns(GetEfficiencyMapData());
+			
+			var voltageLevels = new List<IElectricMotorVoltageLevel>() {
+				new ElectricMotorVoltageLevel(){
+					VoltageLevel = 100.SI<Volt>(),
+					ContinuousTorque = 450.SI<NewtonMeter>(),
+					ContinuousTorqueSpeed = 2460.RPMtoRad(),
+					OverloadTorque = 485.SI<NewtonMeter>(),
+					OverloadTestSpeed = 2460.RPMtoRad(),
+					OverloadTime = 120.SI<Second>(),
+					FullLoadCurve = GetFullLoadCurveData(),
+					PowerMap = new List<IElectricMotorPowerMap>(){powerMapMock.Object}
+				},
+				new ElectricMotorVoltageLevel(){
+					VoltageLevel = 1000.SI<Volt>(),
+					ContinuousTorque = 450.SI<NewtonMeter>(),
+					ContinuousTorqueSpeed = 2460.RPMtoRad(),
+					OverloadTorque = 485.SI<NewtonMeter>(),
+					OverloadTestSpeed = 2460.RPMtoRad(),
+					OverloadTime = 120.SI<Second>(),
+					FullLoadCurve = GetFullLoadCurveData(),
+					PowerMap = new List<IElectricMotorPowerMap>(){powerMapMock.Object}
+				}
+			};
+			
+			emInputData.Setup(em => em.CertificationMethod).Returns(CertificationMethod.Measured);
+			emInputData.Setup(em => em.Inertia).Returns(0.225.SI<KilogramSquareMeter>());
+			emInputData.Setup(em => em.R85RatedPower).Returns(250E3.SI<Watt>());
+			emInputData.Setup(em => em.ElectricMachineType).Returns(ElectricMachineType.ASM);
+			emInputData.Setup(em => em.VoltageLevels).Returns(voltageLevels);
+			emInputData.Setup(em => em.DragCurve).Returns(GetDragCurveData);
+			
+			var adcInputData = new Mock<IADCDeclarationInputData>();
+			adcInputData.Setup(adc => adc.Ratio).Returns(1.0f);
+			
+			var emsInputData = new Mock<IElectricMachinesDeclarationInputData>();
+			emsInputData.Setup(em => em.Entries).Returns(
+				new List<ElectricMachineEntry<IElectricMotorDeclarationInputData>>() {
+					new ElectricMachineEntry<IElectricMotorDeclarationInputData>() {
+						Count = emCount,
+						Position = PowertrainPosition.BatteryElectricE2,
+						ElectricMachine = emInputData.Object,
+						ADC = adcInputData.Object,
+						RatioADC = 2.0,
+						MechanicalTransmissionEfficiency = 0.97,
+					}
+				});
+			
+			var avgVoltage = 200.SI<Volt>();
+			IDictionary<PowertrainPosition, IList<Tuple<Volt, TableData>>> torqueLimits = new Dictionary<PowertrainPosition, IList<Tuple<Volt, TableData>>>();
+			
+			var electricMachinesData = emDataAdapter.CreateElectricMachines(emsInputData.Object, torqueLimits:torqueLimits, 
+				avgVoltage, null);
+
+			
+			
+			
+
+			return electricMachinesData;
+		
+		}
+
+		private TableData GetDragCurveData()
+		{
+			return InputDataHelper.InputDataAsTableData(
+				"n [rpm] , T_drag [Nm]",
+				"0       , -6.06",
+				"7363.77    , -30.31");
+		}
+
+
+		private TableData GetFullLoadCurveData()
+		{
+			return InputDataHelper.InputDataAsTableData("n [rpm] , T_drive [Nm] , T_drag [Nm]",
+				#region data
+				"0,485,-485",
+"2461.158914,485,-485",
+"2452.135493,485,-485",
+"2466.863034,483.8845,-483.8845",
+"2481.590574,481.010875,-481.010875",
+"2496.318115,478.173625,-478.173625",
+"2503.681885,476.767125,-476.767125",
+"2577.319588,463.138625,-463.138625",
+"2650.95729,450.274,-450.274",
+"2724.594993,438.1005,-438.1005",
+"2798.232695,426.58175,-426.58175",
+"2871.870398,415.645,-415.645",
+"2945.5081,405.253875,-405.253875",
+"3019.145803,395.359875,-395.359875",
+"3092.783505,385.950875,-385.950875",
+"3166.421208,376.978375,-376.978375",
+"3240.05891,368.406,-368.406",
+"3313.696613,360.221625,-360.221625",
+"3387.334315,352.388875,-352.388875",
+"3460.972018,344.895625,-344.895625",
+"3534.60972,337.7055,-337.7055",
+"3608.247423,330.8185,-330.8185",
+"3681.885125,324.19825,-324.19825",
+"3755.522828,317.84475,-317.84475",
+"3829.16053,311.73375,-311.73375",
+"3902.798233,305.853125,-305.853125",
+"3976.435935,300.178625,-300.178625",
+"4050.073638,294.722375,-294.722375",
+"4123.71134,289.460125,-289.460125",
+"4197.349043,284.37975,-284.37975",
+"4270.986745,279.48125,-279.48125",
+"4344.624448,274.740375,-274.740375",
+"4418.26215,270.16925,-270.16925",
+"4491.899853,265.7315,-265.7315",
+"4565.537555,261.451375,-261.451375",
+"4639.175258,257.304625,-257.304625",
+"4712.81296,253.279125,-253.279125",
+"4786.450663,249.387,-249.387",
+"4860.088365,245.604,-245.604",
+"4933.726068,241.94225,-241.94225",
+"5007.36377,238.3775,-238.3775",
+"5081.001473,234.921875,-234.921875",
+"5154.639175,231.575375,-231.575375",
+"5228.276878,228.31375,-228.31375",
+"5301.91458,225.137,-225.137",
+"5375.552283,222.05725,-222.05725",
+"5449.189985,219.05025,-219.05025",
+"5522.827688,216.128125,-216.128125",
+"5596.46539,213.290875,-213.290875",
+"5670.103093,210.51425,-210.51425",
+"5743.740795,207.8225,-207.8225",
+"5817.378498,205.191375,-205.191375",
+"5891.0162,202.620875,-202.620875",
+"5964.653903,200.123125,-200.123125",
+"6038.291605,197.686,-197.686",
+"6111.929308,195.297375,-195.297375",
+"6185.56701,192.969375,-192.969375",
+"6259.204713,190.702,-190.702",
+"6332.842415,188.483125,-188.483125",
+"6406.480118,186.324875,-186.324875",
+"6480.11782,184.203,-184.203",
+"6553.755523,182.129625,-182.129625",
+"6627.393225,180.10475,-180.10475",
+"6701.030928,178.128375,-178.128375",
+"6774.66863,176.2005,-176.2005",
+"6848.306333,174.296875,-174.296875",
+"6921.944035,172.44175,-172.44175",
+"6995.581738,170.635125,-170.635125",
+"7069.21944,168.85275,-168.85275",
+"7142.857143,167.10675,-167.10675",
+"7216.494845,165.40925,-165.40925",
+"7290.132548,163.736,-163.736",
+"7363.77025,162.099125,-162.099125"
+				#endregion data
+			);
+		}
+		private ElectricMotorFullLoadCurve GetFullLoadCurve(int count)
+		{
+			var inputData = GetFullLoadCurveData();
+			return ElectricFullLoadCurveReader.Create(inputData, count);
+		}
+		private TableData GetEfficiencyMapData()
+		{
+			return InputDataHelper.InputDataAsTableData(
+				"n [rpm] , T [Nm] , P_el [kW]",
+				#region entries
+				"0, -485, 0.000",
+"0, -461, 0.000",
+"0, -437, 0.000",
+"0, -412, 0.000",
+"0, -388, 0.000",
+"0, -364, 0.000",
+"0, -340, 0.000",
+"0, -315, 0.000",
+"0, -291, 0.000",
+"0, -267, 0.000",
+"0, -243, 0.000",
+"0, -218, 0.000",
+"0, -194, 0.000",
+"0, -170, 0.000",
+"0, -146, 0.000",
+"0, -121, 0.000",
+"0, -97, 0.000",
+"0, -73, 0.000",
+"0, -48, 0.000",
+"0, -24, 0.000",
+"0, -5, 0.000",
+"0, 5, 0.000",
+"0, 24, 0.000",
+"0, 48, 0.000",
+"0, 73, 0.000",
+"0, 97, 0.000",
+"0, 121, 0.000",
+"0, 146, 0.000",
+"0, 170, 0.000",
+"0, 194, 0.000",
+"0, 218, 0.000",
+"0, 243, 0.000",
+"0, 267, 0.000",
+"0, 291, 0.000",
+"0, 315, 0.000",
+"0, 340, 0.000",
+"0, 364, 0.000",
+"0, 388, 0.000",
+"0, 412, 0.000",
+"0, 437, 0.000",
+"0, 461, 0.000",
+"0, 485, 0.000",
+"49, -485, 0.000",
+"49, -461, 0.000",
+"49, -437, 0.000",
+"49, -412, 0.000",
+"49, -388, 0.000",
+"49, -364, 0.000",
+"49, -340, -0.045",
+"49, -315, -0.111",
+"49, -291, -0.166",
+"49, -267, -0.211",
+"49, -243, -0.245",
+"49, -218, -0.268",
+"49, -194, -0.280",
+"49, -170, -0.281",
+"49, -146, -0.272",
+"49, -121, -0.252",
+"49, -97, -0.221",
+"49, -73, -0.179",
+"49, -48, -0.126",
+"49, -24, -0.062",
+"49, -5, -0.004",
+"49, 5, 0.048",
+"49, 24, 0.193",
+"49, 48, 0.384",
+"49, 73, 0.587",
+"49, 97, 0.802",
+"49, 121, 1.029",
+"49, 146, 1.267",
+"49, 170, 1.518",
+"49, 194, 1.779",
+"49, 218, 2.053",
+"49, 243, 2.338",
+"49, 267, 2.636",
+"49, 291, 2.944",
+"49, 315, 3.265",
+"49, 340, 3.597",
+"49, 364, 3.941",
+"49, 388, 4.297",
+"49, 412, 4.665",
+"49, 437, 5.044",
+"49, 461, 5.435",
+"49, 485, 5.838",
+"492, -485, -20.733",
+"492, -461, -19.800",
+"492, -437, -18.856",
+"492, -412, -17.900",
+"492, -388, -16.932",
+"492, -364, -15.953",
+"492, -340, -14.962",
+"492, -315, -13.959",
+"492, -291, -12.945",
+"492, -267, -11.919",
+"492, -243, -10.881",
+"492, -218, -9.832",
+"492, -194, -8.771",
+"492, -170, -7.699",
+"492, -146, -6.614",
+"492, -121, -5.519",
+"492, -97, -4.411",
+"492, -73, -3.292",
+"492, -48, -2.161",
+"492, -24, -1.019",
+"492, -5, -0.097",
+"492, 5, 0.416",
+"492, 24, 1.498",
+"492, 48, 2.863",
+"492, 73, 4.240",
+"492, 97, 5.630",
+"492, 121, 7.033",
+"492, 146, 8.448",
+"492, 170, 9.876",
+"492, 194, 11.316",
+"492, 218, 12.769",
+"492, 243, 14.235",
+"492, 267, 15.713",
+"492, 291, 17.204",
+"492, 315, 18.708",
+"492, 340, 20.224",
+"492, 364, 21.753",
+"492, 388, 23.294",
+"492, 412, 24.848",
+"492, 437, 26.415",
+"492, 461, 27.994",
+"492, 485, 29.586",
+"984, -485, -44.101",
+"984, -461, -42.013",
+"984, -437, -39.910",
+"984, -412, -37.794",
+"984, -388, -35.664",
+"984, -364, -33.520",
+"984, -340, -31.362",
+"984, -315, -29.190",
+"984, -291, -27.004",
+"984, -267, -24.805",
+"984, -243, -22.591",
+"984, -218, -20.363",
+"984, -194, -18.122",
+"984, -170, -15.867",
+"984, -146, -13.597",
+"984, -121, -11.314",
+"984, -97, -9.017",
+"984, -73, -6.706",
+"984, -48, -4.381",
+"984, -24, -2.042",
+"984, -5, -0.161",
+"984, 5, 0.867",
+"984, 24, 2.993",
+"984, 48, 5.663",
+"984, 73, 8.349",
+"984, 97, 11.049",
+"984, 121, 13.765",
+"984, 146, 16.496",
+"984, 170, 19.242",
+"984, 194, 22.003",
+"984, 218, 24.779",
+"984, 243, 27.571",
+"984, 267, 30.377",
+"984, 291, 33.198",
+"984, 315, 36.035",
+"984, 340, 38.887",
+"984, 364, 41.754",
+"984, 388, 44.635",
+"984, 412, 47.532",
+"984, 437, 50.445",
+"984, 461, 53.372",
+"984, 485, 56.314",
+"1477, -485, -67.122",
+"1477, -461, -63.906",
+"1477, -437, -60.673",
+"1477, -412, -57.422",
+"1477, -388, -54.153",
+"1477, -364, -50.867",
+"1477, -340, -47.563",
+"1477, -315, -44.241",
+"1477, -291, -40.902",
+"1477, -267, -37.545",
+"1477, -243, -34.170",
+"1477, -218, -30.778",
+"1477, -194, -27.368",
+"1477, -170, -23.941",
+"1477, -146, -20.496",
+"1477, -121, -17.033",
+"1477, -97, -13.552",
+"1477, -73, -10.054",
+"1477, -48, -6.539",
+"1477, -24, -3.005",
+"1477, -5, -0.166",
+"1477, 5, 1.383",
+"1477, 24, 4.552",
+"1477, 48, 8.530",
+"1477, 73, 12.528",
+"1477, 97, 16.545",
+"1477, 121, 20.581",
+"1477, 146, 24.636",
+"1477, 170, 28.710",
+"1477, 194, 32.804",
+"1477, 218, 36.916",
+"1477, 243, 41.048",
+"1477, 267, 45.199",
+"1477, 291, 49.369",
+"1477, 315, 53.558",
+"1477, 340, 57.766",
+"1477, 364, 61.994",
+"1477, 388, 66.240",
+"1477, 412, 70.506",
+"1477, 437, 74.791",
+"1477, 461, 79.095",
+"1477, 485, 83.418",
+"1969, -485, -89.780",
+"1969, -461, -85.464",
+"1969, -437, -81.126",
+"1969, -412, -76.766",
+"1969, -388, -72.382",
+"1969, -364, -67.976",
+"1969, -340, -63.546",
+"1969, -315, -59.094",
+"1969, -291, -54.620",
+"1969, -267, -50.122",
+"1969, -243, -45.602",
+"1969, -218, -41.058",
+"1969, -194, -36.492",
+"1969, -170, -31.904",
+"1969, -146, -27.292",
+"1969, -121, -22.658",
+"1969, -97, -18.000",
+"1969, -73, -13.320",
+"1969, -48, -8.618",
+"1969, -24, -3.892",
+"1969, -5, -0.095",
+"1969, 5, 1.980",
+"1969, 24, 6.193",
+"1969, 48, 11.483",
+"1969, 73, 16.796",
+"1969, 97, 22.135",
+"1969, 121, 27.498",
+"1969, 146, 32.886",
+"1969, 170, 38.299",
+"1969, 194, 43.736",
+"1969, 218, 49.199",
+"1969, 243, 54.686",
+"1969, 267, 60.197",
+"1969, 291, 65.734",
+"1969, 315, 71.295",
+"1969, 340, 76.881",
+"1969, 364, 82.492",
+"1969, 388, 88.127",
+"1969, 412, 93.787",
+"1969, 437, 99.472",
+"1969, 461, 105.182",
+"1969, 485, 110.916",
+"2461, -485, -112.056",
+"2461, -461, -106.670",
+"2461, -437, -101.254",
+"2461, -412, -95.808",
+"2461, -388, -90.334",
+"2461, -364, -84.830",
+"2461, -340, -79.296",
+"2461, -315, -73.733",
+"2461, -291, -68.141",
+"2461, -267, -62.519",
+"2461, -243, -56.868",
+"2461, -218, -51.188",
+"2461, -194, -45.478",
+"2461, -170, -39.738",
+"2461, -146, -33.970",
+"2461, -121, -28.172",
+"2461, -97, -22.344",
+"2461, -73, -16.487",
+"2461, -48, -10.601",
+"2461, -24, -4.685",
+"2461, -5, 0.000",
+"2461, 5, 2.679",
+"2461, 24, 7.937",
+"2461, 48, 14.539",
+"2461, 73, 21.173",
+"2461, 97, 27.839",
+"2461, 121, 34.536",
+"2461, 146, 41.266",
+"2461, 170, 48.027",
+"2461, 194, 54.820",
+"2461, 218, 61.646",
+"2461, 243, 68.503",
+"2461, 267, 75.392",
+"2461, 291, 82.313",
+"2461, 315, 89.265",
+"2461, 340, 96.250",
+"2461, 364, 103.267",
+"2461, 388, 110.315",
+"2461, 412, 117.396",
+"2461, 437, 124.508",
+"2461, 461, 131.652",
+"2461, 485, 138.828",
+"2953, -485, -133.934",
+"2953, -461, -127.504",
+"2953, -437, -121.037",
+"2953, -412, -114.532",
+"2953, -388, -107.990",
+"2953, -364, -101.411",
+"2953, -340, -94.794",
+"2953, -315, -88.140",
+"2953, -291, -81.448",
+"2953, -267, -74.719",
+"2953, -243, -67.952",
+"2953, -218, -61.148",
+"2953, -194, -54.306",
+"2953, -170, -47.427",
+"2953, -146, -40.511",
+"2953, -121, -33.557",
+"2953, -97, -26.566",
+"2953, -73, -19.537",
+"2953, -48, -12.471",
+"2953, -24, -5.367",
+"2953, -5, 0.000",
+"2953, 5, 3.497",
+"2953, 24, 9.801",
+"2953, 48, 17.718",
+"2953, 73, 25.676",
+"2953, 97, 33.674",
+"2953, 121, 41.713",
+"2953, 146, 49.793",
+"2953, 170, 57.913",
+"2953, 194, 66.074",
+"2953, 218, 74.275",
+"2953, 243, 82.517",
+"2953, 267, 90.800",
+"2953, 291, 99.123",
+"2953, 315, 107.487",
+"2953, 340, 115.892",
+"2953, 364, 124.337",
+"2953, 388, 132.823",
+"2953, 412, 141.349",
+"2953, 437, 149.916",
+"2953, 461, 158.524",
+"2953, 485, 167.172",
+"3446, -485, -155.396",
+"3446, -461, -147.951",
+"3446, -437, -140.460",
+"3446, -412, -132.921",
+"3446, -388, -125.335",
+"3446, -364, -117.703",
+"3446, -340, -110.023",
+"3446, -315, -102.297",
+"3446, -291, -94.524",
+"3446, -267, -86.703",
+"3446, -243, -78.836",
+"3446, -218, -70.922",
+"3446, -194, -62.961",
+"3446, -170, -54.953",
+"3446, -146, -46.898",
+"3446, -121, -38.797",
+"3446, -97, -30.648",
+"3446, -73, -22.452",
+"3446, -48, -14.210",
+"3446, -24, -5.921",
+"3446, -5, 0.000",
+"3446, 5, 4.454",
+"3446, 24, 11.805",
+"3446, 48, 21.040",
+"3446, 73, 30.325",
+"3446, 97, 39.661",
+"3446, 121, 49.049",
+"3446, 146, 58.487",
+"3446, 170, 67.976",
+"3446, 194, 77.516",
+"3446, 218, 87.107",
+"3446, 243, 96.749",
+"3446, 267, 106.442",
+"3446, 291, 116.185",
+"3446, 315, 125.980",
+"3446, 340, 135.826",
+"3446, 364, 145.722",
+"3446, 388, 155.669",
+"3446, 412, 165.668",
+"3446, 437, 175.717",
+"3446, 461, 185.817",
+"3446, 485, 195.968",
+"3938, -485, -176.425",
+"3938, -461, -167.994",
+"3938, -437, -159.504",
+"3938, -412, -150.956",
+"3938, -388, -142.351",
+"3938, -364, -133.687",
+"3938, -340, -124.966",
+"3938, -315, -116.187",
+"3938, -291, -107.351",
+"3938, -267, -98.456",
+"3938, -243, -89.503",
+"3938, -218, -80.493",
+"3938, -194, -71.425",
+"3938, -170, -62.299",
+"3938, -146, -53.115",
+"3938, -121, -43.873",
+"3938, -97, -34.574",
+"3938, -73, -25.217",
+"3938, -48, -15.801",
+"3938, -24, -6.328",
+"3938, -5, 0.000",
+"3938, 5, 5.568",
+"3938, 24, 13.967",
+"3938, 48, 24.521",
+"3938, 73, 35.138",
+"3938, 97, 45.818",
+"3938, 121, 56.561",
+"3938, 146, 67.366",
+"3938, 170, 78.235",
+"3938, 194, 89.166",
+"3938, 218, 100.159",
+"3938, 243, 111.216",
+"3938, 267, 122.335",
+"3938, 291, 133.517",
+"3938, 315, 144.762",
+"3938, 340, 156.070",
+"3938, 364, 167.440",
+"3938, 388, 178.873",
+"3938, 412, 190.369",
+"3938, 437, 201.927",
+"3938, 461, 213.549",
+"3938, 485, 225.233",
+"4430, -485, -197.004",
+"4430, -461, -187.614",
+"4430, -437, -178.152",
+"4430, -412, -168.621",
+"4430, -388, -159.020",
+"4430, -364, -149.348",
+"4430, -340, -139.606",
+"4430, -315, -129.794",
+"4430, -291, -119.912",
+"4430, -267, -109.959",
+"4430, -243, -99.936",
+"4430, -218, -89.844",
+"4430, -194, -79.680",
+"4430, -170, -69.447",
+"4430, -146, -59.144",
+"4430, -121, -48.770",
+"4430, -97, -38.326",
+"4430, -73, -27.812",
+"4430, -48, -17.228",
+"4430, -24, -6.573",
+"4430, -5, 0.000",
+"4430, 5, 6.859",
+"4430, 24, 16.305",
+"4430, 48, 28.182",
+"4430, 73, 40.135",
+"4430, 97, 52.164",
+"4430, 121, 64.269",
+"4430, 146, 76.450",
+"4430, 170, 88.707",
+"4430, 194, 101.041",
+"4430, 218, 113.451",
+"4430, 243, 125.937",
+"4430, 267, 138.499",
+"4430, 291, 151.138",
+"4430, 315, 163.852",
+"4430, 340, 176.643",
+"4430, 364, 189.510",
+"4430, 388, 202.453",
+"4430, 412, 215.472",
+"4430, 437, 228.567",
+"4430, 461, 241.739",
+"4430, 485, 254.986",
+"4922, -485, -217.116",
+"4922, -461, -206.794",
+"4922, -437, -196.388",
+"4922, -412, -185.899",
+"4922, -388, -175.325",
+"4922, -364, -164.667",
+"4922, -340, -153.925",
+"4922, -315, -143.099",
+"4922, -291, -132.190",
+"4922, -267, -121.196",
+"4922, -243, -110.118",
+"4922, -218, -98.956",
+"4922, -194, -87.710",
+"4922, -170, -76.381",
+"4922, -146, -64.967",
+"4922, -121, -53.469",
+"4922, -97, -41.887",
+"4922, -73, -30.221",
+"4922, -48, -18.472",
+"4922, -24, -6.638",
+"4922, -5, 0.000",
+"4922, 5, 8.344",
+"4922, 24, 18.839",
+"4922, 48, 32.040",
+"4922, 73, 45.333",
+"4922, 97, 58.716",
+"4922, 121, 72.191",
+"4922, 146, 85.757",
+"4922, 170, 99.413",
+"4922, 194, 113.161",
+"4922, 218, 127.001",
+"4922, 243, 140.931",
+"4922, 267, 154.952",
+"4922, 291, 169.065",
+"4922, 315, 183.269",
+"4922, 340, 197.564",
+"4922, 364, 211.950",
+"4922, 388, 226.427",
+"4922, 412, 240.995",
+"4922, 437, 255.655",
+"4922, 461, 270.406",
+"4922, 485, 285.247",
+"5415, -485, -236.743",
+"5415, -461, -225.518",
+"5415, -437, -214.194",
+"5415, -412, -202.771",
+"5415, -388, -191.249",
+"5415, -364, -179.627",
+"5415, -340, -167.906",
+"5415, -315, -156.086",
+"5415, -291, -144.167",
+"5415, -267, -132.149",
+"5415, -243, -120.031",
+"5415, -218, -107.814",
+"5415, -194, -95.497",
+"5415, -170, -83.082",
+"5415, -146, -70.567",
+"5415, -121, -57.953",
+"5415, -97, -45.240",
+"5415, -73, -32.428",
+"5415, -48, -19.516",
+"5415, -24, -6.505",
+"5415, -5, 0.000",
+"5415, 5, 10.043",
+"5415, 24, 21.588",
+"5415, 48, 36.116",
+"5415, 73, 50.751",
+"5415, 97, 65.495",
+"5415, 121, 80.346",
+"5415, 146, 95.305",
+"5415, 170, 110.371",
+"5415, 194, 125.545",
+"5415, 218, 140.827",
+"5415, 243, 156.217",
+"5415, 267, 171.714",
+"5415, 291, 187.319",
+"5415, 315, 203.031",
+"5415, 340, 218.852",
+"5415, 364, 234.779",
+"5415, 388, 250.815",
+"5415, 412, 266.958",
+"5415, 437, 283.209",
+"5415, 461, 299.568",
+"5415, 485, 316.034",
+"5907, -485, -255.867",
+"5907, -461, -243.768",
+"5907, -437, -231.553",
+"5907, -412, -219.222",
+"5907, -388, -206.774",
+"5907, -364, -194.211",
+"5907, -340, -181.532",
+"5907, -315, -168.738",
+"5907, -291, -155.827",
+"5907, -267, -142.800",
+"5907, -243, -129.657",
+"5907, -218, -116.399",
+"5907, -194, -103.024",
+"5907, -170, -89.534",
+"5907, -146, -75.928",
+"5907, -121, -62.205",
+"5907, -97, -48.367",
+"5907, -73, -34.413",
+"5907, -48, -20.343",
+"5907, -24, -6.157",
+"5907, -5, 0.000",
+"5907, 5, 11.974",
+"5907, 24, 24.569",
+"5907, 48, 40.426",
+"5907, 73, 56.409",
+"5907, 97, 72.518",
+"5907, 121, 88.753",
+"5907, 146, 105.113",
+"5907, 170, 121.599",
+"5907, 194, 138.211",
+"5907, 218, 154.949",
+"5907, 243, 171.813",
+"5907, 267, 188.802",
+"5907, 291, 205.917",
+"5907, 315, 223.158",
+"5907, 340, 240.525",
+"5907, 364, 258.017",
+"5907, 388, 275.635",
+"5907, 412, 293.379",
+"5907, 437, 311.249",
+"5907, 461, 329.245",
+"5907, 485, 347.366",
+"6399, -485, -274.473",
+"6399, -461, -261.527",
+"6399, -437, -248.447",
+"6399, -412, -235.232",
+"6399, -388, -221.884",
+"6399, -364, -208.402",
+"6399, -340, -194.786",
+"6399, -315, -181.036",
+"6399, -291, -167.151",
+"6399, -267, -153.133",
+"6399, -243, -138.981",
+"6399, -218, -124.694",
+"6399, -194, -110.274",
+"6399, -170, -95.719",
+"6399, -146, -81.031",
+"6399, -121, -66.208",
+"6399, -97, -51.252",
+"6399, -73, -36.161",
+"6399, -48, -20.936",
+"6399, -24, -5.577",
+"6399, -5, 0.000",
+"6399, 5, 14.156",
+"6399, 24, 27.802",
+"6399, 48, 44.991",
+"6399, 73, 62.325",
+"6399, 97, 79.805",
+"6399, 121, 97.430",
+"6399, 146, 115.201",
+"6399, 170, 133.117",
+"6399, 194, 151.179",
+"6399, 218, 169.386",
+"6399, 243, 187.738",
+"6399, 267, 206.236",
+"6399, 291, 224.879",
+"6399, 315, 243.668",
+"6399, 340, 262.602",
+"6399, 364, 281.682",
+"6399, 388, 300.907",
+"6399, 412, 320.277",
+"6399, 437, 339.793",
+"6399, 461, 359.455",
+"6399, 485, 379.261",
+"6891, -485, -292.541",
+"6891, -461, -278.777",
+"6891, -437, -264.858",
+"6891, -412, -250.787",
+"6891, -388, -236.561",
+"6891, -364, -222.182",
+"6891, -340, -207.650",
+"6891, -315, -192.963",
+"6891, -291, -178.124",
+"6891, -267, -163.130",
+"6891, -243, -147.983",
+"6891, -218, -132.683",
+"6891, -194, -117.228",
+"6891, -170, -101.621",
+"6891, -146, -85.859",
+"6891, -121, -69.944",
+"6891, -97, -53.876",
+"6891, -73, -37.653",
+"6891, -48, -21.278",
+"6891, -24, -4.748",
+"6891, -5, 0.000",
+"6891, 5, 16.608",
+"6891, 24, 31.306",
+"6891, 48, 49.829",
+"6891, 73, 68.518",
+"6891, 97, 87.374",
+"6891, 121, 106.397",
+"6891, 146, 125.587",
+"6891, 170, 144.943",
+"6891, 194, 164.466",
+"6891, 218, 184.155",
+"6891, 243, 204.011",
+"6891, 267, 224.034",
+"6891, 291, 244.223",
+"6891, 315, 264.580",
+"6891, 340, 285.102",
+"6891, 364, 305.792",
+"6891, 388, 326.648",
+"6891, 412, 347.671",
+"6891, 437, 368.860",
+"6891, 461, 390.216",
+"6891, 485, 411.739",
+"7383, -485, -310.056",
+"7383, -461, -295.501",
+"7383, -437, -280.771",
+"7383, -412, -265.867",
+"7383, -388, -250.788",
+"7383, -364, -235.535",
+"7383, -340, -220.106",
+"7383, -315, -204.504",
+"7383, -291, -188.726",
+"7383, -267, -172.775",
+"7383, -243, -156.648",
+"7383, -218, -140.347",
+"7383, -194, -123.871",
+"7383, -170, -107.221",
+"7383, -146, -90.396",
+"7383, -121, -73.397",
+"7383, -97, -56.222",
+"7383, -73, -38.874",
+"7383, -48, -21.350",
+"7383, -24, -3.653",
+"7383, -5, 0.000",
+"7383, 5, 19.348",
+"7383, 24, 35.099",
+"7383, 48, 54.958",
+"7383, 73, 75.007",
+"7383, 97, 95.245",
+"7383, 121, 115.672",
+"7383, 146, 136.289",
+"7383, 170, 157.095",
+"7383, 194, 178.091",
+"7383, 218, 199.276",
+"7383, 243, 220.651",
+"7383, 267, 242.215",
+"7383, 291, 263.969",
+"7383, 315, 285.912",
+"7383, 340, 308.044",
+"7383, 364, 330.366",
+"7383, 388, 352.878",
+"7383, 412, 375.578",
+"7383, 437, 398.469",
+"7383, 461, 421.549",
+"7383, 485, 444.818",
+"7876, -485, -327.000",
+"7876, -461, -311.682",
+"7876, -437, -296.167",
+"7876, -412, -280.456",
+"7876, -388, -264.547",
+"7876, -364, -248.442",
+"7876, -340, -232.139",
+"7876, -315, -215.639",
+"7876, -291, -198.942",
+"7876, -267, -182.048",
+"7876, -243, -164.958",
+"7876, -218, -147.670",
+"7876, -194, -130.185",
+"7876, -170, -112.503",
+"7876, -146, -94.624",
+"7876, -121, -76.548",
+"7876, -97, -58.274",
+"7876, -73, -39.804",
+"7876, -48, -21.137",
+"7876, -24, -2.273",
+"7876, -5, 0.000",
+"7876, 5, 22.396",
+"7876, 24, 39.201",
+"7876, 48, 60.398",
+"7876, 73, 81.810",
+"7876, 97, 103.435",
+"7876, 121, 125.274",
+"7876, 146, 147.327",
+"7876, 170, 169.593",
+"7876, 194, 192.074",
+"7876, 218, 214.768",
+"7876, 243, 237.676",
+"7876, 267, 260.798",
+"7876, 291, 284.134",
+"7876, 315, 307.683",
+"7876, 340, 331.447",
+"7876, 364, 355.424",
+"7876, 388, 379.615",
+"7876, 412, 404.019",
+"7876, 437, 428.638",
+"7876, 461, 453.470",
+"7876, 485, 478.516",
+"8368, -485, -343.355",
+"8368, -461, -327.303",
+"8368, -437, -311.030",
+"8368, -412, -294.536",
+"8368, -388, -277.822",
+"8368, -364, -260.886",
+"8368, -340, -243.730",
+"8368, -315, -226.352",
+"8368, -291, -208.754",
+"8368, -267, -190.935",
+"8368, -243, -172.895",
+"8368, -218, -154.634",
+"8368, -194, -136.152",
+"8368, -170, -117.449",
+"8368, -146, -98.525",
+"8368, -121, -79.380",
+"8368, -97, -60.014",
+"8368, -73, -40.428",
+"8368, -48, -20.620",
+"8368, -24, -0.592",
+"8368, -5, 0.000",
+"8368, 5, 25.770",
+"8368, 24, 43.629",
+"8368, 48, 66.167",
+"8368, 73, 88.946",
+"8368, 97, 111.964",
+"8368, 121, 135.221",
+"8368, 146, 158.719",
+"8368, 170, 182.456",
+"8368, 194, 206.433",
+"8368, 218, 230.649",
+"8368, 243, 255.106",
+"8368, 267, 279.802",
+"8368, 291, 304.738",
+"8368, 315, 329.913",
+"8368, 340, 355.328",
+"8368, 364, 380.983",
+"8368, 388, 406.878",
+"8368, 412, 433.012",
+"8368, 437, 459.386",
+"8368, 461, 486.000",
+"8368, 485, 512.853",
+"8860, -485, -359.104",
+"8860, -461, -342.346",
+"8860, -437, -325.341",
+"8860, -412, -308.091",
+"8860, -388, -290.594",
+"8860, -364, -272.851",
+"8860, -340, -254.862",
+"8860, -315, -236.626",
+"8860, -291, -218.144",
+"8860, -267, -199.416",
+"8860, -243, -180.442",
+"8860, -218, -161.221",
+"8860, -194, -141.755",
+"8860, -170, -122.042",
+"8860, -146, -102.082",
+"8860, -121, -81.877",
+"8860, -97, -61.425",
+"8860, -73, -40.727",
+"8860, -48, -19.783",
+"8860, -24, 0.000",
+"8860, -5, 0.000",
+"8860, 5, 29.489",
+"8860, 24, 48.402",
+"8860, 48, 72.284",
+"8860, 73, 96.433",
+"8860, 97, 120.849",
+"8860, 121, 145.533",
+"8860, 146, 170.484",
+"8860, 170, 195.701",
+"8860, 194, 221.186",
+"8860, 218, 246.939",
+"8860, 243, 272.958",
+"8860, 267, 299.245",
+"8860, 291, 325.798",
+"8860, 315, 352.619",
+"8860, 340, 379.708",
+"8860, 364, 407.063",
+"8860, 388, 434.685",
+"8860, 412, 462.575",
+"8860, 437, 490.732",
+"8860, 461, 519.156",
+"8860, 485, 547.847",
+"9352, -485, -374.230",
+"9352, -461, -356.794",
+"9352, -437, -339.084",
+"9352, -412, -321.102",
+"9352, -388, -302.847",
+"9352, -364, -284.319",
+"9352, -340, -265.517",
+"9352, -315, -246.443",
+"9352, -291, -227.096",
+"9352, -267, -207.475",
+"9352, -243, -187.582",
+"9352, -218, -167.416",
+"9352, -194, -146.976",
+"9352, -170, -126.264",
+"9352, -146, -105.279",
+"9352, -121, -84.021",
+"9352, -97, -62.489",
+"9352, -73, -40.685",
+"9352, -48, -18.608",
+"9352, -24, 0.000",
+"9352, -5, 0.000",
+"9352, 5, 33.571",
+"9352, 24, 53.540",
+"9352, 48, 78.768",
+"9352, 73, 104.291",
+"9352, 97, 130.111",
+"9352, 121, 156.228",
+"9352, 146, 182.640",
+"9352, 170, 209.349",
+"9352, 194, 236.354",
+"9352, 218, 263.655",
+"9352, 243, 291.252",
+"9352, 267, 319.146",
+"9352, 291, 347.335",
+"9352, 315, 375.821",
+"9352, 340, 404.604",
+"9352, 364, 433.682",
+"9352, 388, 463.057",
+"9352, 412, 492.728",
+"9352, 437, 522.695",
+"9352, 461, 552.958",
+"9352, 485, 583.518",
+"9845, -485, -388.716",
+"9845, -461, -370.630",
+"9845, -437, -352.242",
+"9845, -412, -333.553",
+"9845, -388, -314.563",
+"9845, -364, -295.272",
+"9845, -340, -275.680",
+"9845, -315, -255.786",
+"9845, -291, -235.591",
+"9845, -267, -215.095",
+"9845, -243, -194.298",
+"9845, -218, -173.200",
+"9845, -194, -151.800",
+"9845, -170, -130.099",
+"9845, -146, -108.097",
+"9845, -121, -85.794",
+"9845, -97, -63.190",
+"9845, -73, -40.284",
+"9845, -48, -17.077",
+"9845, -24, 0.000",
+"9845, -5, 0.000",
+"9845, 5, 38.036",
+"9845, 24, 59.061",
+"9845, 48, 85.637",
+"9845, 73, 112.539",
+"9845, 97, 139.768",
+"9845, 121, 167.324",
+"9845, 146, 195.207",
+"9845, 170, 223.417",
+"9845, 194, 251.953",
+"9845, 218, 280.816",
+"9845, 243, 310.007",
+"9845, 267, 339.523",
+"9845, 291, 369.367",
+"9845, 315, 399.538",
+"9845, 340, 430.035",
+"9845, 364, 460.859",
+"9845, 388, 492.010",
+"9845, 412, 523.488",
+"9845, 437, 555.293",
+"9845, 461, 587.424",
+"9845, 485, 619.883"
+				#endregion data
+				).ApplyFactor(ElectricMotorMapReader.Fields.PowerElectrical, 1E3); //Convert from kW to W
+		}
+
+		private EfficiencyMap GetEfficiencyMap(int count)
+		{
+			return ElectricMotorMapReader.Create(GetEfficiencyMapData(), count, ExecutionMode.Declaration);
+		}
+		private void SetVelocityDropLookupData(PEVAMTShiftStrategy shiftStrategy)
+		{
+			//"StartVelocity [km/h], Gradient [-], EndVelocity [km/h]"
+			var data = new[] {
+				new[] { 5.0, -0.0997, 9.061522965237558 },
+				new[] { 5.0, -0.0798, 7.76698080079411 },
+				new[] { 5.0, -0.0599, 6.46583777913701 },
+				new[] { 5.0, -0.0400, 5.1596021788785045 },
+				new[] { 5.0, -0.0200, 3.8498121019126907 },
+				new[] { 5.0, 0.0000, 2.5380265159468918 },
+				new[] { 5.0, 0.0200, 1.2258160477557427 },
+				new[] { 5.0, 0.0400, 0.0 },
+				new[] { 5.0, 0.0599, 0.0 },
+				new[] { 5.0, 0.0798, 0.0 },
+				new[] { 5.0, 0.0997, 0.0 },
+				new[] { 10.0, -0.0997, 14.807789640888302 },
+				new[] { 10.0, -0.0798, 13.474253785811362 },
+				new[] { 10.0, -0.0599, 12.133880027250777 },
+				new[] { 10.0, -0.0400, 10.788221550084467 },
+				new[] { 10.0, -0.0200, 9.438862432338068 },
+				new[] { 10.0, 0.0000, 8.087408432114643 },
+				new[] { 10.0, 0.0200, 6.735477499784416 },
+				new[] { 10.0, 0.0400, 5.384690105076845 },
+				new[] { 10.0, 0.0599, 4.036659549786269 },
+				new[] { 10.0, 0.0798, 2.6929823705748137 },
+				new[] { 10.0, 0.0997, 1.3552289800549435 },
+				new[] { 20.0, -0.0997, 25.061542153872097 },
+				new[] { 20.0, -0.0798, 23.72002987685605 },
+				new[] { 20.0, -0.0599, 22.371630788642932 },
+				new[] { 20.0, -0.0400, 21.017907257116025 },
+				new[] { 20.0, -0.0200, 19.660452757813403 },
+				new[] { 20.0, 0.0000, 18.30088261992287 },
+				new[] { 20.0, 0.0200, 16.94082447048767 },
+				new[] { 20.0, 0.0400, 15.581908518759507 },
+				new[] { 20.0, 0.0599, 14.225757795590708 },
+				new[] { 20.0, 0.0798, 12.873978508374211 },
+				new[] { 20.0, 0.0997, 11.528150617530041 },
+				new[] { 30.000000000000004, -0.0997, 35.091774208140095 },
+				new[] { 30.000000000000004, -0.0798, 33.750904327320896 },
+				new[] { 30.000000000000004, -0.0599, 32.40315158162777 },
+				new[] { 30.000000000000004, -0.0400, 31.050077596965064 },
+				new[] { 30.000000000000004, -0.0200, 29.69327509188113 },
+				new[] { 30.000000000000004, 0.0000, 28.33435862498606 },
+				new[] { 30.000000000000004, 0.0200, 26.974955046566407 },
+				new[] { 30.000000000000004, 0.0400, 25.616693776603913 },
+				new[] { 30.000000000000004, 0.0599, 24.261197065863925 },
+				new[] { 30.000000000000004, 0.0798, 22.91007034016412 },
+				new[] { 30.000000000000004, 0.0997, 21.56489279686667 },
+				new[] { 40.0, -0.0997, 45.024018797189854 },
+				new[] { 40.0, -0.0798, 43.68636622428101 },
+				new[] { 40.0, -0.0599, 42.34185052441486 },
+				new[] { 40.0, -0.0400, 40.99202962224952 },
+				new[] { 40.0, -0.0200, 39.63849244500093 },
+				new[] { 40.0, 0.0000, 38.282849690992855 },
+				new[] { 40.0, 0.0200, 36.926724305651554 },
+				new[] { 40.0, 0.0400, 35.57174178507285 },
+				new[] { 40.0, 0.0599, 34.21952045137207 },
+				new[] { 40.0, 0.0798, 32.87166183129923 },
+				new[] { 40.0, 0.0997, 31.5297412694979 },
+				new[] { 50.0, -0.0997, 54.652157586769704 },
+				new[] { 50.0, -0.0798, 53.319266704395716 },
+				new[] { 50.0, -0.0599, 51.97954186606304 },
+				new[] { 50.0, -0.0400, 50.634535516787736 },
+				new[] { 50.0, -0.0200, 49.28583097196263 },
+				new[] { 50.0, 0.0000, 47.93503321632867 },
+				new[] { 50.0, 0.0200, 46.583759417454765 },
+				new[] { 50.0, 0.0400, 45.23362925944123 },
+				new[] { 50.0, 0.0599, 43.88625525588574 },
+				new[] { 50.0, 0.0798, 42.54323315977748 },
+				new[] { 50.0, 0.0997, 41.20613261641401 },
+				new[] { 60.00000000000001, -0.0997, 64.2503607025971 },
+				new[] { 60.00000000000001, -0.0798, 62.91932863058169 },
+				new[] { 60.00000000000001, -0.0599, 61.58156853535776 },
+				new[] { 60.00000000000001, -0.0400, 60.23862904729555 },
+				new[] { 60.00000000000001, -0.0200, 58.89369896300112 },
+				new[] { 60.00000000000001, 0.0000, 57.547040626925885 },
+				new[] { 60.00000000000001, 0.0200, 56.199911833784675 },
+				new[] { 60.00000000000001, 0.0400, 54.85392730356455 },
+				new[] { 60.00000000000001, 0.0599, 53.510694584916905 },
+				new[] { 60.00000000000001, 0.0798, 52.17180450267632 },
+				new[] { 60.00000000000001, 0.0997, 50.83882182989668 },
+				new[] { 70.0, -0.0997, 73.78388063954164 },
+				new[] { 70.0, -0.0798, 72.45700102808648 },
+				new[] { 70.0, -0.0599, 71.12341092304165 },
+				new[] { 70.0, -0.0400, 69.78459543842656 },
+				new[] { 70.0, -0.0200, 68.44188526693415 },
+				new[] { 70.0, 0.0000, 67.09719334997524 },
+				new[] { 70.0, 0.0200, 65.75212749798493 },
+				new[] { 70.0, 0.0400, 64.40829754257321 },
+				new[] { 70.0, 0.0599, 63.06730571969745 },
+				new[] { 70.0, 0.0798, 61.73073716025881 },
+				new[] { 70.0, 0.0997, 60.40015062055851 },
+				new[] { 80.0, -0.0997, 83.25457689135129 },
+				new[] { 80.0, -0.0798, 81.93182852399568 },
+				new[] { 80.0, -0.0599, 80.60238880559001 },
+				new[] { 80.0, -0.0400, 79.2676325992058 },
+				new[] { 80.0, -0.0200, 77.92916666616652 },
+				new[] { 80.0, 0.0000, 76.58872134590663 },
+				new[] { 80.0, 0.0200, 75.24790011046437 },
+				new[] { 80.0, 0.0400, 73.90830846424944 },
+				new[] { 80.0, 0.0599, 72.57154434889891 },
+				new[] { 80.0, 0.0798, 71.23918865436896 },
+				new[] { 80.0, 0.0997, 69.91277394305271 },
+			};
+			var entries = new List<VelocitySpeedGearshiftPreprocessor.Entry>();
+			foreach (var d in data) {
+				entries.Add(new VelocitySpeedGearshiftPreprocessor.Entry() {
+					StartVelocity = d[0].KMPHtoMeterPerSecond(),
+					Gradient = d[1].SI<Radian>(),
+					EndVelocity = d[2].KMPHtoMeterPerSecond(),
+				});
+			}
+
+			shiftStrategy.VelocityDropData.Data = entries.ToArray();
+
+		}
+		
+	}
+	
+}
-- 
GitLab


From d07e27988822d3a4d5d3ec6349040f7546c78a01 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Mon, 17 Mar 2025 14:17:39 +0100
Subject: [PATCH 14/22] Transfer all ATShiftStrategyOptimizedTestcases

---
 .../ATShiftStrategyOptimizedTests.cs          | 1215 ++++++++---------
 1 file changed, 546 insertions(+), 669 deletions(-)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs
index 8e2fa264ae..7e05644e5c 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
@@ -26,6 +26,7 @@ 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;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ShiftPolygonCalc;
 using TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.ManufacturerReport_0_9.ManufacturerReportGroupWriter;
@@ -62,43 +63,46 @@ public class ATShiftStrategyOptimizedTests
 			out var runData,
 			out _,
 			out _);
-		
-		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer.Object);
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx, out _);
 		var angularVelocity = GetAngularVelocityBySpeed(vehicleSpeed, runData);
 		var response = shiftStrategy.InitGear(
 			0.SI<Second>(),
 			1.SI<Second>(),
-			torque.SI<NewtonMeter>(), 
+			torque.SI<NewtonMeter>(),
 			angularVelocity);
-		
+
 		Assert.AreEqual(expectedGear, response.Gear);
 	}
+
 	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
 		double[] gearRatios,
 		out Mock<IVehicleDeclarationInputData> inputData, out VectoRunData runData, out GearboxData gearboxData,
 		out Mock<ISimpleVehicleContainer> simplePt)
 	{
 		var vehicleContainer = new Mock<IVehicleContainer>();
-		
+
 		inputData = GetMockInputData(gearRatios);
 		runData = GetDummyVectoRunData(inputData.Object);
-
-		
 		
 		vehicleContainer.Setup(c => c.RunData).Returns(runData);
+
 		
 		//Testpowertrain
 		var testPowertrain = GetMockTestPowertrain(
-			runData, 
+			runData,
 			out simplePt);
-			
+
 		vehicleContainer.Setup(c => c.SimplePowertrainBuilder.CreateTestPowertrain(It.IsAny<IVehicleContainer>(),
 			It.IsAny<bool>())).Returns(testPowertrain.Object);
-		
+
 		//VehicleInfo
-		vehicleContainer.Setup(v => v.VehicleInfo)
+		vehicleContainer.Setup(c => c.VehicleInfo)
 			.Returns(GetVehicleInfo(speedKmh.KMPHtoMeterPerSecond()).Object);
 
+		//EngineInfo
+		vehicleContainer.Setup(c => c.EngineInfo).Returns(GetEngineInfo(vehicleContainer, runData));
+		
 		//AxleGearInfo
 		var axleGearInfo = new Mock<IAxlegearInfo>();
 		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
@@ -117,8 +121,7 @@ public class ATShiftStrategyOptimizedTests
 		cycleInfo.Setup(c => c.RoadGradient).Returns(0.SI<Radian>());
 
 
-		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry()
-		{
+		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry() {
 			Altitude = 0.SI<Meter>()
 		});
 		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
@@ -126,8 +129,7 @@ public class ATShiftStrategyOptimizedTests
 		//DriverINfo
 		vehicleContainer.Setup(v => v.DriverInfo.DriverBehavior).Returns(driverBehavior);
 		var acc = 0.SI<MeterPerSquareSecond>();
-		switch (driverBehavior)
-		{
+		switch (driverBehavior) {
 			case DrivingBehavior.Accelerating:
 				acc = 1.SI<MeterPerSquareSecond>();
 				break;
@@ -141,7 +143,7 @@ public class ATShiftStrategyOptimizedTests
 				throw new ArgumentOutOfRangeException();
 		}
 
-		
+
 
 
 
@@ -149,17 +151,35 @@ public class ATShiftStrategyOptimizedTests
 		gearboxData = new GearboxData();
 		return vehicleContainer;
 	}
+
+	private IEngineInfo GetEngineInfo(Mock<IVehicleContainer> vehicleContainer, VectoRunData runData)
+	{
+		        //EngineInfo
+        var engineInfo = new Mock<IEngineInfo>();
+		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
+		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
+		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
+
+		engineInfo.Setup(e => e.EngineSpeed).Returns(1400.RPMtoRad());
+		engineInfo.Setup(e => e.EngineN95hSpeed).Returns
+			(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
+		engineInfo.Setup(e => e.EngineN80hSpeed).Returns(
+			runData.EngineData.FullLoadCurves.First().Value.N80hSpeed);
+		engineInfo.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>())).Returns((PerSecond n) =>
+			runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+		return engineInfo.Object;
+	}
+
 	private CycleData GetCycleData()
 	{
-		return new CycleData()
-		{
-			LeftSample = new DrivingCycleData.DrivingCycleEntry()
-			{
+		return new CycleData() {
+			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
 				PTOActive = PTOActivity.Inactive,
 				VehicleTargetSpeed = 10.KMPHtoMeterPerSecond()
 			}
 		};
 	}
+
 	private Mock<IVehicleInfo> GetVehicleInfo(MeterPerSecond speed)
 	{
 		var vehicleInfo = new Mock<IVehicleInfo>();
@@ -171,29 +191,30 @@ public class ATShiftStrategyOptimizedTests
 		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
 		return vehicleInfo;
 	}
+
 	private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData,
 		out Mock<ISimpleVehicleContainer> simpleContainer)
 	{
 		var testPt = new Mock<ITestPowertrain>();
-		simpleContainer = GetSimplePowertrain(runData, 
+		simpleContainer = GetSimplePowertrain(runData,
 			out var testGearbox);
-		
-		
-		
+
+
+
 		testPt.Setup(t => t.Container).Returns(simpleContainer.Object);
 		testPt.Setup(t => t.Gearbox).Returns(testGearbox.Object);
 
-		
 		//Vehicle
 		var vehicle = new Mock<ITestPowertrainVehicle>();
 		vehicle.Setup(v => v.Initialize(
 			It.IsAny<MeterPerSecond>(),
 			It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
 		testPt.Setup(t => t.Vehicle).Returns(vehicle.Object);
-		
+
 
 		return testPt;
 	}
+
 	private Mock<IVehicleDeclarationInputData> GetMockInputData(double[]? gearRatios)
 	{
 		var input = new Mock<IVehicleDeclarationInputData>();
@@ -204,18 +225,17 @@ public class ATShiftStrategyOptimizedTests
 
 		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
 		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
-		gearRatios = gearRatios ?? new double[] {
-
-		};
+		gearRatios = gearRatios ?? new double[] { };
 		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
 		var efficiency = 0.98;
 		var data = new List<string>();
-		
-		foreach (var speed in new[] {0, 10000}) {
-			foreach (var tq in new[] {1e5, -1e5, 0}) {
+
+		foreach (var speed in new[] { 0, 10000 }) {
+			foreach (var tq in new[] { 1e5, -1e5, 0 }) {
 				data.Add(FormattableString.Invariant($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}"));
 			}
 		}
+
 		var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
 		//lossmap.Columns
 		var gears = gearRatios.Select((x, idx) => {
@@ -234,26 +254,27 @@ public class ATShiftStrategyOptimizedTests
 		tc.Setup(t => t.TCData).Returns(tcData);
 		return input;
 	}
+
 	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
 	{
 		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
 		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
 		var fld = FullLoadCurveReader.Create(fldData);
-		
+
 		// create gearbox data
 		var tcDataAdapter = new TorqueConverterDataAdapter();
 
 		// fuel data
-        var fuelData = new CombustionEngineFuelData() {
+		var fuelData = new CombustionEngineFuelData() {
 			ConsumptionMap = FuelConsumptionMapReader.Create(
 				InputDataHelper.InputDataAsTableData(
 					"engine speed [rpm] ,torque [Nm] ,fuel consumption [g/h] ,whr power electrical [W]",
 					"500,-131,0,0",
-						"500,95.6,1814.959,0",
-						"500,573.6,9771.095,0",
-						"2453,-209.12,0,0",
-						"2453,764.8,39097.94,0"
-                    )),
+					"500,95.6,1814.959,0",
+					"500,573.6,9771.095,0",
+					"2453,-209.12,0,0",
+					"2453,764.8,39097.94,0"
+				)),
 			FuelData = DeclarationData.FuelData.Lookup(FuelType.DieselCI),
 		};
 
@@ -285,65 +306,63 @@ public class ATShiftStrategyOptimizedTests
 			GearboxType.ATSerial, GearboxType.ATPowerSplit
 		};
 
-		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData, new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
-			GearboxType.ATSerial,
-			GearboxType.ATPowerSplit
-		});
+		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData,
+			new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
+				GearboxType.ATSerial,
+				GearboxType.ATPowerSplit
+			});
 
 		var gearShiftParams =
 			gbxDataAdapter.CreateGearshiftData(1.0, runData.EngineData.IdleSpeed, GearboxType.ATSerial, nrOfGears);
 
 		runData.GearboxData = gearboxData;
 		runData.GearshiftParameters = gearShiftParams;
-        return runData;
+		return runData;
 	}
-	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData, out Mock<ITestPowertrainTransmission> testGearbox)
+
+	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData,
+		out Mock<ITestPowertrainTransmission> testGearbox)
 	{
 		var simplePt = new Mock<ISimpleVehicleContainer>();
 
 		testGearbox = GetMockTestGearbox(runData.GearboxData.Gears);
-		
-		
+
+
 		simplePt.Setup(s => s.GearboxInfo).Returns(testGearbox.Object);
-		
-		
-		
-		
-		
+		simplePt.Setup(s => s.GearboxOutPort).Returns(testGearbox.Object);
+
+
+
+
 		//VehiclePort
 		return simplePt;
 	}
+
 	private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
 	{
 		Mock<IAPTGearbox> amtGearbox = new Mock<IAPTGearbox>();
 		amtGearbox.Name = "APT_TestGearbox";
 		Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
 
-		
-		
+
+
 		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
 		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
 
 		GearshiftPosition gear = null;
-		gbx.SetupGet(g => g.Gear).Returns(() => {
-			
-			return gear;
-		});
+		gbx.SetupGet(g => g.Gear).Returns(() => { return gear; });
 		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
-			.Callback<GearshiftPosition>(p => {
-				gear = p;
-			});
+			.Callback<GearshiftPosition>(p => { gear = p; });
 
 
 		GearshiftPosition nextGear = null;
 		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
 		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
 			.Callback<GearshiftPosition>(p => nextGear = p);
-			
+
 		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
 			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-			return new ResponseSuccess(this)
-			{
+			return new ResponseSuccess(this) {
 				Engine = {
 					EngineSpeed = rpm,
 					PowerRequest = tq * rpm,
@@ -370,6 +389,7 @@ public class ATShiftStrategyOptimizedTests
 						PowerRequest = n * t, EngineSpeed = n * ratio,
 						DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
 						TotalTorqueDemand = t,
+						TorqueOutDemand = t,
 					},
 					Clutch = { PowerRequest = n * t },
 					DeltaFullLoad = n * t / 2 * (-1)
@@ -386,83 +406,6 @@ public class ATShiftStrategyOptimizedTests
 		return gbx;
 	}
 
-	private Mock<IAPTGearbox> GetGearbox(Dictionary<uint, GearData> ratios)
-	{
-				
-		Mock<IAPTGearbox> amtGearbox = new Mock<IAPTGearbox>();
-		amtGearbox.Name = "APT_Gearbox";
-		
-		var gbx = amtGearbox.As<IAPTGearbox>();
-		// Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
-
-		
-		
-		
-		// gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
-		// gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
-		//
-		// GearshiftPosition gear = null;
-		// gbx.SetupGet(g => g.Gear).Returns(() => {
-		// 	
-		// 	return gear;
-		// });
-		// gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
-		// 	.Callback<GearshiftPosition>(p => {
-		// 		gear = p;
-		// 	});
-
-
-		// GearshiftPosition nextGear = null;
-		// gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
-		// gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
-		// 	.Callback<GearshiftPosition>(p => nextGear = p);
-		// 	
-		// gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-		// 	It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-		// 	return new ResponseSuccess(this)
-		// 	{
-		// 		Engine = {
-		// 			EngineSpeed = rpm,
-		// 			PowerRequest = tq * rpm,
-		// 		},
-		// 	};
-		// });
-		// gbx.Setup(p => p.Request(
-		// 	It.IsAny<Second>(),
-		// 	It.IsAny<Second>(),
-		// 	It.IsAny<NewtonMeter>(),
-		// 	It.IsAny<PerSecond>(),
-		// 	true)).Returns((
-		// 	Second absTime,
-		// 	Second dt,
-		// 	NewtonMeter t,
-		// 	PerSecond n,
-		// 	bool dryRun) => {
-		//
-		// 	var ratio =
-		// 		gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
-		// 	return dryRun
-		// 		? new ResponseDryRun(this) {
-		// 			Engine = {
-		// 				PowerRequest = n * t, EngineSpeed = n * ratio,
-		// 				DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
-		// 				TotalTorqueDemand = t,
-		// 			},
-		// 			Clutch = { PowerRequest = n * t },
-		// 			DeltaFullLoad = n * t / 2 * (-1)
-		// 		}
-		// 		: new ResponseSuccess(this) {
-		// 			Engine = {
-		// 				PowerRequest = n * t,
-		// 				EngineSpeed = n * ratio
-		//
-		// 			},
-		// 			Clutch = { PowerRequest = n * t }
-		// 		};
-		// });
-		
-		return gbx;
-	}
 	private static PerSecond GetAngularVelocityBySpeed(double speedKmh, VectoRunData runData)
 	{
 		// r_dyn = 0.465m, i_axle = 6.2
@@ -472,11 +415,11 @@ public class ATShiftStrategyOptimizedTests
 		return angularVelocity;
 	}
 
-	
-	
-	
-	
-	
+
+
+
+
+
 	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
 
 	public static readonly string[] TcData = new[] {
@@ -517,400 +460,346 @@ public class ATShiftStrategyOptimizedTests
 		"2100,1100,-320,0.25",
 	};
 	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-}
+	[TestCase(1, 1, 1000, 1500, 0, Description = "Engage 0-> 1C")]
+	public void Gearbox_Engage(int gear, int newGear, double tqNm, double nRPM, double speedKmh)
+	{
+		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		var vehicleContainer = GetMockVehicleContainer(speedKmh, DrivingBehavior.Accelerating, gearRatios, 
+			inputData: out _,
+			runData: out var runData,
+			gearboxData: out _, simplePt: out _);
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData: runData);
+
+		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+
+		var expectedN = nRPM.RPMtoRad();
+		angularVelocity = expectedN / gearRatios[gear];
+
+
+		gbx.CurrentState = new ATGearboxState()
+		{
+			Gear = gbx.Gear,
+		};
+
+		var expectedT = tqNm.SI<NewtonMeter>();
+		var torque = expectedT * gearRatios[gear];
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+
+		var shiftExpected = gear != newGear; //Different Gear
+		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+		Assert.AreEqual(shiftExpected, shiftRequired);
+	}
+
+	[TestCase(2, 1, -1000, 1500, 4, DrivingBehavior.Braking, Description = "_ -> 0: disengage before halting")]
+	public void Gearbox_Disengange(int gear, int newGear, double tqNm, double nRPM, double speedKmh,
+		DrivingBehavior driverBehavior)
+	{
+		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+
+		var vehicleContainer = GetMockVehicleContainer(speedKmh,
+			driverBehavior,
+			gearRatios,
+			out var inputData,
+			out var runData,
+			out var gearboxData, out _);
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+		gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+
+		var expectedN = nRPM.RPMtoRad();
+		angularVelocity = expectedN / gearRatios[gear];
+
+		//Called in gbx initialize
+		//var gearShiftPosition = shiftStrategy.InitGear(absTime, Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
+		//    angularVelocity);
+		var engagedPosition = shiftStrategy.Engage(absTime, dt, null, null);
+
+
+		Assert.IsTrue(engagedPosition.Engaged);
+
+		gbx.CurrentState = new ATGearboxState()
+		{
+			Disengaged = gbx.Disengaged,
+			Gear = gbx.Gear,
+		};
+
+		var expectedT = tqNm.SI<NewtonMeter>();
+		var torque = expectedT * gearRatios[gear];
+
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
+			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
+
+		var shiftExpected = gear != newGear; //Different Gear
+		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+		Assert.AreEqual(shiftExpected, shiftRequired);
+	}
+
+	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked", TestName="Upshift-TCLocked")]
+	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC", TestName = "Upshift-TC")]
+    [TestCase(2, true, 3, true, 100, 800, 13, Description = "Upshift-TCLocked", TestName = "EarlyUpshift")]
+    [TestCase(1, false, 1, true, 100, 500, 1, Description = "EarlyUpshift-TC", TestName="EarlyUpshift-TC")]
+    public void Gearbox_Upshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+	{
+        var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+
+        var vehicleContainer = GetMockVehicleContainer(
+			speedKmh, 
+			DrivingBehavior.Accelerating, 
+			gearRatios, 
+			out var inputData, out var runData, out var gearboxData, out var simplePt);
+
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+		var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        gbx.CurrentState = new ATGearboxState()
+        {
+            Disengaged = gbx.Disengaged,
+            Gear = gbx.Gear,
+        };
+
+
+		var inAngularVelocity = nRPM.RPMtoRad();
+		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+
+		var response = new ResponseSuccess(this);
+		response.Engine.DynamicFullLoadTorque = 50.SI<NewtonMeter>();
+		response.Engine.EngineSpeed = inAngularVelocity;
+		response.Engine.TorqueOutDemand = inTorque;
+
+
+		runData.GearshiftParameters.RatingFactorCurrentGear = 1.1;
+
+
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+
+
+		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+
+        var shiftExpected = gear != newGear; //Different Gear
+        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+
+	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked")]
+	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC")]
+	public void Gearbox_EarlyUpshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+	{
+		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+
+		var vehicleContainer = GetMockVehicleContainer(
+			speedKmh,
+			DrivingBehavior.Accelerating,
+			gearRatios,
+			out var inputData, out var runData, out var gearboxData, out _);
+
+
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+
+		gbx.CurrentState = new ATGearboxState()
+		{
+			Disengaged = gbx.Disengaged,
+			Gear = gbx.Gear,
+		};
+
+
+		var inAngularVelocity = nRPM.RPMtoRad();
+		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+
+		var inTorque = tqNm.SI<NewtonMeter>();
+		var outTortque = inTorque * gearRatios[gear];
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+
+		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+
+		var shiftExpected = gear != newGear; //Different Gear
+		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+		Assert.AreEqual(shiftExpected, shiftRequired);
+	}
 
-// 	public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear)
-// 	{
-// 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-//
-//         var gbxTypes = new[] {
-// 			GearboxType.ATSerial
-// 		};
-//
-// 		var vehicleContainer = GetMockVehicleContainer(
-// 			vehicleSpeed,
-// 			DrivingBehavior.Accelerating,
-// 			gearRatios,
-// 			out var inputData, 
-// 			out var runData, 
-// 			out var gearboxData, out _);
 //
-// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+    [TestCase(1, false, 2, false, 100, 1000, 1, Description = "Upshift-TC")]
+    public void Gearbox_Upshift_TC_TC(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+    {
+        var gearRatios = new[] { 3.4, 1.3, 1.1, 1.0, 0.7, 0.62 };
+
+        var vehicleContainer = GetMockVehicleContainer(
+            speedKmh,
+            DrivingBehavior.Accelerating,
+            gearRatios,
+            out var inputData, out var runData, out var gearboxData, out _);
+
+
+        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+        var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+        Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+        Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        gbx.CurrentState = new ATGearboxState()
+        {
+            Disengaged = gbx.Disengaged,
+            Gear = gbx.Gear,
+        };
+
+		Assert.That(gbx.ModelData.GearList.First(p => p.Gear == 2).TorqueConverterLocked, Is.False, "Expected 2nd gear with TC");
+        var inAngularVelocity = nRPM.RPMtoRad();
+        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+
+		var response = new ResponseSuccess(this);
+		response.Engine.EngineSpeed = inAngularVelocity;
+		response.Engine.TorqueOutDemand = inTorque;
+
+
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+
+
+        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+
+        var shiftExpected = gear != newGear; //Different Gear
+        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
 //
-//         var angularVelocity = GetAngularVelocityBySpeed(vehicleSpeed, runData);
-// 		var response = gbx.Initialize(torque.SI<NewtonMeter>(), angularVelocity);
 //
-// 		Assert.IsInstanceOf(typeof(ResponseSuccess), response);
-// 		Assert.AreEqual(expectedGear, gbx.Gear.Gear);
-// 		Assert.AreEqual(vehicleSpeed.IsEqual(0), gbx.Disengaged);
-// 	}
 //
 //
-// 	[TestCase(1, 1, 1000, 1500, 0, Description = "Engage 0-> 1C")]
-// 	public void Gearbox_Engage(int gear, int newGear, double tqNm, double nRPM, double speedKmh)
-// 	{
-// 		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
-//
-// 		var vehicleContainer = GetMockVehicleContainer(speedKmh, DrivingBehavior.Accelerating, gearRatios, 
-// 			inputData: out _,
-// 			runData: out var runData,
-// 			gearboxData: out _, simplePt: out _);
-//
-// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData: runData);
-//
-// 		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-//
-//
-// 		var absTime = 0.SI<Second>();
-// 		var dt = 2.SI<Second>();
-//
-//
-// 		var expectedN = nRPM.RPMtoRad();
-// 		angularVelocity = expectedN / gearRatios[gear];
-//
-//
-// 		gbx.CurrentState = new ATGearbox.ATGearboxState()
-// 		{
-// 			Gear = gbx.Gear,
-// 		};
-//
-// 		var expectedT = tqNm.SI<NewtonMeter>();
-// 		var torque = expectedT * gearRatios[gear];
-//
-// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
-// 			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
-//
-// 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
-//
-// 		var shiftExpected = gear != newGear; //Different Gear
-// 		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-// 		Assert.AreEqual(shiftExpected, shiftRequired);
-// 	}
-//
-// 	[TestCase(2, 1, -1000, 1500, 4, DrivingBehavior.Braking, Description = "_ -> 0: disengage before halting")]
-// 	public void Gearbox_Disengange(int gear, int newGear, double tqNm, double nRPM, double speedKmh,
-// 		DrivingBehavior driverBehavior)
-// 	{
-// 		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
-//
-// 		var vehicleContainer = GetMockVehicleContainer(speedKmh,
-// 			driverBehavior,
-// 			gearRatios,
-// 			out var inputData,
-// 			out var runData,
-// 			out var gearboxData, out _);
-//
-// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-// 		gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-//
-// 		var absTime = 0.SI<Second>();
-// 		var dt = 2.SI<Second>();
-//
-//
-// 		var expectedN = nRPM.RPMtoRad();
-// 		angularVelocity = expectedN / gearRatios[gear];
-//
-// 		//Called in gbx initialize
-// 		//var gearShiftPosition = shiftStrategy.InitGear(absTime, Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
-// 		//    angularVelocity);
-// 		var engagedPosition = shiftStrategy.Engage(absTime, dt, null, null);
-//
-//
-// 		Assert.IsTrue(engagedPosition.Engaged);
-//
-// 		gbx.CurrentState = new ATGearbox.ATGearboxState()
-// 		{
-// 			Disengaged = gbx.Disengaged,
-// 			Gear = gbx.Gear,
-// 		};
-//
-// 		var expectedT = tqNm.SI<NewtonMeter>();
-// 		var torque = expectedT * gearRatios[gear];
-//
-//
-// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
-// 			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
-//
-// 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
-//
-// 		var shiftExpected = gear != newGear; //Different Gear
-// 		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-// 		Assert.AreEqual(shiftExpected, shiftRequired);
-// 	}
-//
-//
-// 	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked", TestName="Upshift-TCLocked")]
-// 	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC", TestName = "Upshift-TC")]
-//
-//
-//     [TestCase(2, true, 3, true, 100, 800, 13, Description = "Upshift-TCLocked", TestName = "EarlyUpshift")]
-//
-//     [TestCase(1, false, 1, true, 100, 500, 1, Description = "EarlyUpshift-TC", TestName="EarlyUpshift-TC")]
-//     public void Gearbox_Upshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-// 	{
-//         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-//
-//         var vehicleContainer = GetMockVehicleContainer(
-// 			speedKmh, 
-// 			DrivingBehavior.Accelerating, 
-// 			gearRatios, 
-// 			out var inputData, out var runData, out var gearboxData, out var simplePt);
-//
-//
-// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-// 		var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-// 		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-// 		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-//
-//
-//         var absTime = 0.SI<Second>();
-//         var dt = 2.SI<Second>();
-//
-//         gbx.CurrentState = new ATGearbox.ATGearboxState()
-//         {
-//             Disengaged = gbx.Disengaged,
-//             Gear = gbx.Gear,
-//         };
-//
-//
-// 		var inAngularVelocity = nRPM.RPMtoRad();
-// 		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-//
-//         var inTorque = tqNm.SI<NewtonMeter>();
-//         var outTortque = inTorque * gearRatios[gear];
-//
-// 		var response = new ResponseSuccess(this);
-// 		response.Engine.DynamicFullLoadTorque = 50.SI<NewtonMeter>();
-// 		response.Engine.EngineSpeed = inAngularVelocity;
-// 		response.Engine.TorqueOutDemand = inTorque;
-//
-//
-// 		runData.GearshiftParameters.RatingFactorCurrentGear = 1.1;
-//
-//
-//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
-//
-//
-// 		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-// 		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
-//
-//         var shiftExpected = gear != newGear; //Different Gear
-//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-//         Assert.AreEqual(shiftExpected, shiftRequired);
-//     }
-//
-//
-// 	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked")]
-// 	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC")]
-// 	public void Gearbox_EarlyUpshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-// 	{
-// 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-//
-// 		var vehicleContainer = GetMockVehicleContainer(
-// 			speedKmh,
-// 			DrivingBehavior.Accelerating,
-// 			gearRatios,
-// 			out var inputData, out var runData, out var gearboxData, out _);
-//
-//
-// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-// 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-// 		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-// 		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-// 		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-//
-//
-// 		var absTime = 0.SI<Second>();
-// 		var dt = 2.SI<Second>();
-//
-// 		gbx.CurrentState = new ATGearbox.ATGearboxState()
-// 		{
-// 			Disengaged = gbx.Disengaged,
-// 			Gear = gbx.Gear,
-// 		};
-//
-//
-// 		var inAngularVelocity = nRPM.RPMtoRad();
-// 		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-//
-// 		var inTorque = tqNm.SI<NewtonMeter>();
-// 		var outTortque = inTorque * gearRatios[gear];
-//
-// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
-//
-//
-// 		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-// 		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
-//
-// 		var shiftExpected = gear != newGear; //Different Gear
-// 		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-// 		Assert.AreEqual(shiftExpected, shiftRequired);
-// 	}
-//
-//
-//     [TestCase(1, false, 2, false, 100, 1000, 1, Description = "Upshift-TC")]
-//     public void Gearbox_Upshift_TC_TC(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-//     {
-//         var gearRatios = new[] { 3.4, 1.3, 1.1, 1.0, 0.7, 0.62 };
-//
-//         var vehicleContainer = GetMockVehicleContainer(
-//             speedKmh,
-//             DrivingBehavior.Accelerating,
-//             gearRatios,
-//             out var inputData, out var runData, out var gearboxData, out _);
-//
-//
-//         var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-//         var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-//         var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-//
-//
-//         var absTime = 0.SI<Second>();
-//         var dt = 2.SI<Second>();
-//
-//         gbx.CurrentState = new ATGearbox.ATGearboxState()
-//         {
-//             Disengaged = gbx.Disengaged,
-//             Gear = gbx.Gear,
-//         };
-//
-// 		Assert.That(gbx.ModelData.GearList.First(p => p.Gear == 2).TorqueConverterLocked, Is.False, "Expected 2nd gear with TC");
-//         var inAngularVelocity = nRPM.RPMtoRad();
-//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-//
-//         var inTorque = tqNm.SI<NewtonMeter>();
-//         var outTortque = inTorque * gearRatios[gear];
-//
-// 		var response = new ResponseSuccess(this);
-// 		response.Engine.EngineSpeed = inAngularVelocity;
-// 		response.Engine.TorqueOutDemand = inTorque;
-//
-//
-//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
-//
-//
-//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
-//
-//         var shiftExpected = gear != newGear; //Different Gear
-//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-//         Assert.AreEqual(shiftExpected, shiftRequired);
-//     }
-//
-//
-//
-//
-//     [TestCase(3, true, 2, true, 900, 600, 15, Description = "Downshift", TestName="Gearbox_DownShift_1")]
-//     public void Gearbox_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-//     {
-//         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-//
-//         var vehicleContainer = GetMockVehicleContainer(
-//             speedKmh,
-//             DrivingBehavior.Accelerating,
-//             gearRatios,
-//             out var inputData, out var runData, out var gearboxData, out var simplePt);
-//
-// 		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
-//
-//         var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-//         var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-//         var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-//
-//
-//         var absTime = 0.SI<Second>();
-//         var dt = 2.SI<Second>();
-//
-//         gbx.CurrentState = new ATGearbox.ATGearboxState()
-//         {
-//             Disengaged = gbx.Disengaged,
-//             Gear = gbx.Gear,
-//         };
-//
-//
-//         var inAngularVelocity = nRPM.RPMtoRad();
-//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-//
-//         var inTorque = tqNm.SI<NewtonMeter>();
-//         var outTortque = inTorque * gearRatios[gear];
-//
-// 		var response = new ResponseSuccess(this);
-// 		response.Engine.EngineSpeed = inAngularVelocity;
-// 		response.Engine.TorqueOutDemand = inTorque;
-//
-//
-// 		var mockPort = new Mock<ITnOutPort>();
-// 		
-// 		simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
-// 		mockPort.Setup(p => p.Request(
-// 			It.IsAny<Second>(),
-// 			It.IsAny<Second>(),
-// 			It.IsAny<NewtonMeter>(),
-// 			It.IsAny<PerSecond>(),
-// 			true
-// 		)).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
-// 			var response = new ResponseDryRun(this);
-// 			response.Engine.PowerRequest = outTorque * outAngularVelocity;
-// 			return response;
-// 		});
-//
-//
-//
-//
-// 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
-//
-//
-//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
-//
-//         var shiftExpected = gear != newGear; //Different Gear
-//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-//         Assert.AreEqual(shiftExpected, shiftRequired);
-//     }
+    [TestCase(3, true, 2, true, 900, 600, 15, Description = "Downshift", TestName="Gearbox_DownShift_1")]
+    public void Gearbox_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+    {
+        var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+
+        var vehicleContainer = GetMockVehicleContainer(
+            speedKmh,
+            DrivingBehavior.Accelerating,
+            gearRatios,
+            out var inputData, out var runData, out var gearboxData, out var simplePt);
+
+		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+
+        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+        var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+        Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+        Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        gbx.CurrentState = new ATGearboxState()
+        {
+            Disengaged = gbx.Disengaged,
+            Gear = gbx.Gear,
+        };
+
+
+        var inAngularVelocity = nRPM.RPMtoRad();
+        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+
+		var response = new ResponseSuccess(this);
+		response.Engine.EngineSpeed = inAngularVelocity;
+		response.Engine.TorqueOutDemand = inTorque;
+
+
+		var mockPort = new Mock<ITnOutPort>();
+		
+		simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
+		mockPort.Setup(p => p.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true
+		)).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
+			var response = new ResponseDryRun(this);
+			response.Engine.PowerRequest = outTorque * outAngularVelocity;
+			return response;
+		});
+
+
+
+
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+
+
+        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+
+        var shiftExpected = gear != newGear; //Different Gear
+        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
 //
 // 	[TestCase(3, true, 2, true, 200, 700, 15, Description = "Downshift_3", TestName = "Gearbox_DownShift_3")]
 // 	public void Gearbox_Downshift_2(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM,
@@ -991,133 +880,129 @@ public class ATShiftStrategyOptimizedTests
 //         Assert.AreEqual(shiftExpected, shiftRequired);
 //     }
 //
-//     [TestCase(3, true, 2, true, 1700, 700, 15, Description = "Downshift", TestName = "Gearbox_Early_DownShift_1")]
-//     public void Gearbox_Early_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-//     {
-//         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-//
-//         var vehicleContainer = GetMockVehicleContainer(
-//             speedKmh,
-//             DrivingBehavior.Accelerating,
-//             gearRatios,
-//             out var inputData, out var runData, out var gearboxData, out var simplePt);
-//
-//         vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
-//
-//         var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-//         var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-//         var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-//
-//
-//         var absTime = 0.SI<Second>();
-//         var dt = 2.SI<Second>();
-//
-//         gbx.CurrentState = new ATGearbox.ATGearboxState()
-//         {
-//             Disengaged = gbx.Disengaged,
-//             Gear = gbx.Gear,
-//         };
-//
-//
-//         var inAngularVelocity = nRPM.RPMtoRad();
-//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-//
-//         var inTorque = tqNm.SI<NewtonMeter>();
-//         var outTortque = inTorque * gearRatios[gear];
-//
-//         var response = new ResponseSuccess(this);
-//         response.Engine.EngineSpeed = inAngularVelocity;
-//         response.Engine.TorqueOutDemand = inTorque;
-//
-//
-//         var mockPort = new Mock<ITnOutPort>();
-//
-//         simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
-//         mockPort.Setup(p => p.Request(
-//             It.IsAny<Second>(),
-//             It.IsAny<Second>(),
-//             It.IsAny<NewtonMeter>(),
-//             It.IsAny<PerSecond>(),
-//             true
-//         )).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
-//             var response = new ResponseDryRun(this);
-//             response.Engine.PowerRequest = outTorque * outAngularVelocity;
-//             return response;
-//         });
-//
-//
-//
-//
-//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
-//
-//
-//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
-//
-//         var shiftExpected = gear != newGear; //Different Gear
-//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-//         Assert.AreEqual(shiftExpected, shiftRequired);
-//     }
-//
-//     private ATShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer, out ATGearbox gbx)
-// 	{
-// 		return GetShiftStrategyAndGearbox(vehicleContainer, out gbx, out _);
-// 	}
-//
-// 	private ATShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer, out ATGearbox gbx,
-// 		out Mock<ITnOutPort> gbxNextComponent)
-// 	{
-// 		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer.Object);
-//
-// 		gbx = new ATGearbox(vehicleContainer.Object, shiftStrategy);
-// 		var mockPort = new Mock<ITnOutPort>();
-// 		NewtonMeter tqRequest = null;
-// 		PerSecond rpmRequest = null;
-// 		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-// 			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-// 			tqRequest = tq;
-// 			rpmRequest = rpm;
-// 			return new ResponseSuccess(this)
-// 			{
-// 				Engine = {
-// 					EngineSpeed = rpm,
-// 					PowerRequest = tq * rpm,
-// 				},
-// 			};
-// 		});
-// 		mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
-// 			It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
-//
-// 		var idleController = new Mock<IIdleController>();
-//
-//
-// 		gbx.IdleController = idleController.Object;
-// 		gbx.Connect(mockPort.Object);
-//
-// 		gbxNextComponent = mockPort;
-// 		return shiftStrategy;
-// 	}
-//
-// 	/// <summary>
-// 	/// Calculated the angular velocity based on the vehicle speed
-// 	/// </summary>
-// 	/// <param name="speedKmh"></param>
-// 	/// <param name="runData"></param>
-// 	/// <returns></returns>
-// 	private static PerSecond GetAngularVelocityBySpeed(double speedKmh, VectoRunData runData)
-// 	{
-// 		// r_dyn = 0.465m, i_axle = 6.2
-//         var angularVelocity =
-// 			speedKmh.KMPHtoMeterPerSecond()
-// 			/ runData.VehicleData.DynamicTyreRadius * 6.2;
-// 		return angularVelocity;
-// 	}
-//
+    [TestCase(3, true, 2, true, 1700, 700, 15, Description = "Downshift", TestName = "Gearbox_Early_DownShift_1")]
+    public void Gearbox_Early_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+    {
+        var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+
+        var vehicleContainer = GetMockVehicleContainer(
+            speedKmh,
+            DrivingBehavior.Accelerating,
+            gearRatios,
+            out var inputData, out var runData, out var gearboxData, out var simplePt);
+
+        vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+
+        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+        var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+
+        Assert.AreEqual((uint)gear, gbx.Gear.Gear);
+        Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+
+
+        var absTime = 0.SI<Second>();
+        var dt = 2.SI<Second>();
+
+        gbx.CurrentState = new ATGearboxState()
+        {
+            Disengaged = gbx.Disengaged,
+            Gear = gbx.Gear,
+        };
+
+
+        var inAngularVelocity = nRPM.RPMtoRad();
+        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+
+        var response = new ResponseSuccess(this);
+        response.Engine.EngineSpeed = inAngularVelocity;
+        response.Engine.TorqueOutDemand = inTorque;
+
+
+        var mockPort = new Mock<ITnOutPort>();
+
+        simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
+        mockPort.Setup(p => p.Request(
+            It.IsAny<Second>(),
+            It.IsAny<Second>(),
+            It.IsAny<NewtonMeter>(),
+            It.IsAny<PerSecond>(),
+            true
+        )).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
+            var response = new ResponseDryRun(this);
+            response.Engine.PowerRequest = outTorque * outAngularVelocity;
+            return response;
+        });
+
+
+
+
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+
+
+        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+
+        var shiftExpected = gear != newGear; //Different Gear
+        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+	
+
+	private ATShiftStrategyOptimized GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer,
+		out APTGearbox gbx)
+	{
+		return GetShiftStrategyAndGearbox(vehicleContainer, out gbx, out _);
+	}
+
+	private ATShiftStrategyOptimized GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer,
+		out APTGearbox gbx,
+		out Mock<ITnOutPort> gbxNextComponent)
+	{
+		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer.Object);
+		
+		var gbxMock = new Mock<APTGearbox>(vehicleContainer.Object, shiftStrategy) {
+			CallBase = true
+		};
+		
+		gbx = gbxMock.Object;
+		shiftStrategy.Gearbox = gbx;
+		
+		var mockPort = new Mock<ITnOutPort>();
+		NewtonMeter tqRequest = null;
+		PerSecond rpmRequest = null;
+
+		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			tqRequest = tq;
+			rpmRequest = rpm;
+			return new ResponseSuccess(this) {
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		
+		mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
+
+		var idleController = new Mock<IIdleController>();
+
+
+		gbx.IdleController = idleController.Object;
+		gbx.Connect(mockPort.Object);
+
+		gbxNextComponent = mockPort;
+		return shiftStrategy;
+	}
+}
+
 // 	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
 // 		double[] gearRatios,
 // 		out IVehicleDeclarationInputData inputData, out VectoRunData runData, out GearboxData gearboxData,
@@ -1292,14 +1177,6 @@ public class ATShiftStrategyOptimizedTests
 //
 //
 //
-//     [TestCase(2, 3, 400, 2300, 5, DrivingBehavior.Accelerating, Description = "Upshift")]
-//     public void Gearbox_EmergencyShift(int gear, int newGear, double tqNm, double nRPM, double speedKmh,
-// 		DrivingBehavior driverBehavior)
-// 	{
-//
-// 	}
-//
-//
 // 	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
 // 	{
 // 		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
-- 
GitLab


From 19abb7dc4996ea97b5848a757cc54a07797afc1b Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Mon, 17 Mar 2025 14:21:27 +0100
Subject: [PATCH 15/22] Remove ATShiftStrategyTests (all tests covered in
 ATShiftStrategyOptimizedTests)

---
 .../GearShiftStrategy/ATShiftStrategyTests.cs | 240 ------------------
 1 file changed, 240 deletions(-)
 delete mode 100644 Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs
deleted file mode 100644
index 0e1b66fe18..0000000000
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyTests.cs	
+++ /dev/null
@@ -1,240 +0,0 @@
-using Moq;
-using NUnit.Framework;
-using NUnit.Framework.Interfaces;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.InputData.Reader.ComponentData;
-using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
-using TUGraz.VectoCore.Models.Connector.Ports;
-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;
-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;
-using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
-using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
-using TUGraz.VectoCore.Tests.Utils;
-using Assert = NUnit.Framework.Assert;
-
-namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
-
-public class ATShiftStrategyTests
-{
-	[Test,
-	TestCase(0, 100, 1),
-	TestCase(0, 200, 1),
-	TestCase(5, 100, 1),
-	TestCase(5, 300, 1),
-	TestCase(5, 600, 1),
-	TestCase(15, 100, 3),
-	TestCase(15, 300, 3),
-	TestCase(15, 600, 3),
-	TestCase(40, 100, 6),
-	TestCase(40, 300, 6),
-	TestCase(40, 600, 6),
-	TestCase(70, 100, 6),
-	TestCase(70, 300, 6),
-	TestCase(70, 600, 6),
-	]
-	public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear)
-	{
-        var inputData = GetMockInputData();
-		var gbxTypes = new[] {
-			GearboxType.ATSerial
-		};
-		var runData = GetDummyVectoRunData(inputData.Components.GearboxInputData.Gears.Count);
-		var shiftPolygonCalc = GetMockShiftPolygonCalc();
-		
-		// create gearbox data
-		var tcDataAdapter = new TorqueConverterDataAdapter();
-		var gearboxData = new GearboxDataAdapter(tcDataAdapter).CreateGearboxData(inputData, runData, shiftPolygonCalc, gbxTypes); 
-		runData.GearboxData = gearboxData;
-
-        var vehicleContainer = GetMockVehicleContainer(runData, out var vehicleInfo);
-		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(vehicleSpeed.KMPHtoMeterPerSecond());
-		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer);
-        
-		var gearbox = new APTGearbox(vehicleContainer, shiftStrategy);
-
-		var mockPort = new Mock<ITnOutPort>();
-		NewtonMeter tqRequest = null;
-		PerSecond rpmRequest = null;
-		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-				tqRequest = tq;
-				rpmRequest = rpm;
-				return new ResponseSuccess(this) {
-					Engine = {
-						EngineSpeed = rpm,
-						PowerRequest = tq * rpm,
-					}
-				};
-			});
-		gearbox.Connect(mockPort.Object);
-
-		// r_dyn = 0.465m, i_axle = 6.2
-		var angularVelocity = vehicleSpeed.KMPHtoMeterPerSecond() / runData.VehicleData.DynamicTyreRadius * 6.2;
-
-		var response = gearbox.Initialize(torque.SI<NewtonMeter>(), angularVelocity);
-
-		Assert.IsInstanceOf(typeof(ResponseSuccess), response);
-		Assert.AreEqual(expectedGear, gearbox.Gear.Gear);
-		Assert.AreEqual(vehicleSpeed.IsEqual(0), gearbox.Disengaged);
-	}
-
-	private static VectoRunData GetDummyVectoRunData(int inputData)
-	{
-		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
-		var fld = FullLoadCurveReader.Create(fldData);
-		var engineIdlingSpeed = 600.RPMtoRad();
-		var runData = new VectoRunData() {
-			Cycle = new DrivingCycleData() {
-				CycleType = CycleType.DistanceBased,
-			},
-			VehicleData = new VehicleData() {
-				DynamicTyreRadius = 0.465.SI<Meter>(),
-			},
-			EngineData = new CombustionEngineData() {
-				Inertia = 0.SI<KilogramSquareMeter>(),
-				FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>()
-			},
-			GearshiftParameters = new ShiftStrategyParameters() {
-				LoadStageThresoldsUp = DeclarationData.GearboxTCU.LoadStageThresholdsUp,
-				LoadStageThresoldsDown = DeclarationData.GearboxTCU.LoadStageThresoldsDown,
-				ShiftSpeedsTCToLocked = engineIdlingSpeed == null ? null : DeclarationData.GearboxTCU.ShiftSpeedsTCToLocked
-					.Select(x => x.Select(y => y + engineIdlingSpeed.AsRPM).ToArray()).ToArray(),
-            }
-		};
-		for(uint i = 0; i <= inputData; i++)
-			runData.EngineData.FullLoadCurves[i] = fld;
-		return runData;
-	}
-
-	private static IShiftPolygonCalculator GetMockShiftPolygonCalc()
-	{
-		var shiftPolygonCalc = new Mock<IShiftPolygonCalculator>();
-		var downshift = new List<ShiftPolygon.ShiftPolygonEntry>() { };
-		var upshift = new List<ShiftPolygon.ShiftPolygonEntry>() { };
-		var shiftpolygon = new ShiftPolygon(downshift, upshift);
-		shiftPolygonCalc.Setup(s => s.ComputeDeclarationShiftPolygon(It.IsIn(GearboxType.ATSerial), It.IsAny<int>(),
-				It.IsAny<EngineFullLoadCurve>(), It.IsAny<IList<ITransmissionInputData>>(),
-				It.IsAny<CombustionEngineData>(), It.IsAny<double>(), It.IsAny<Meter>(), It.IsAny<ElectricMotorData>()))
-			.Returns(shiftpolygon);
-		return shiftPolygonCalc.Object;
-	}
-
-	private static IVehicleContainer GetMockVehicleContainer(VectoRunData runData, out Mock<IVehicleInfo> vehicleInfo)
-	{
-		var vehicleContainer = new Mock<IVehicleContainer>();
-		vehicleInfo = new Mock<IVehicleInfo>();
-		var engineInfo = new Mock<IEngineInfo>();
-		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-		var testPt = new Mock<ITestPowertrain>();
-		var testContainer = new Mock<ISimpleVehicleContainer>();
-		var vehiclePort = new Mock<ITestPowertrainVehicle>();
-		var testGbx = new Mock<ITestPowertrainTransmission>();
-
-		vehicleContainer.Setup(c => c.RunData).Returns(runData);
-		vehicleContainer.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
-		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
-		vehicleContainer.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
-		
-		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(600.RPMtoRad());
-		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(2000.RPMtoRad());
-
-		ptBuilder.Setup(b => b.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>())).Returns(testPt.Object);
-
-		testPt.Setup(t => t.Gearbox).Returns(testGbx.Object);
-		testPt.Setup(t => t.Container).Returns(testContainer.Object);
-		testPt.Setup(t => t.Vehicle).Returns(vehiclePort.Object);
-
-        testContainer.Setup(c => c.RunData).Returns(runData);
-		testContainer.Setup(c => c.GearboxCtl).Returns(new APTGearbox(testContainer.Object, null));
-		
-		return vehicleContainer.Object;
-	}
-
-	private IVehicleDeclarationInputData GetMockInputData()
-	{
-		var input = new Mock<IVehicleDeclarationInputData>();
-		var components = new Mock<IVehicleComponentsDeclaration>();
-		input.Setup(i => i.Components).Returns(components.Object);
-		var gbx = new Mock<IGearboxDeclarationInputData>();
-		var tc = new Mock<ITorqueConverterDeclarationInputData>();
-
-		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
-		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
-		var gearRatios = new double[] {
-			3.4, 1.9, 1.42, 1.0, 0.7, 0.62
-		};
-		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
-		var efficiency = 0.98;
-		var data = new List<string>();
-		foreach (var speed in new[] {0, 10000}) {
-			foreach (var tq in new[] {1e5, -1e5, 0}) {
-				data.Add($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}");
-			}
-		}
-        var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
-		var gears = gearRatios.Select((x, idx) => {
-			var gear = new Mock<ITransmissionInputData>();
-			gear.Setup(g => g.Ratio).Returns(x);
-			gear.Setup(g => g.Gear).Returns(idx + 1);
-			//gear.Setup(g => g.Efficiency).Returns(0.98);
-			gear.Setup(g => g.LossMap).Returns(lossmap);
-			return gear.Object;
-		}).ToList();
-		gbx.Setup(g => g.Type).Returns(GearboxType.ATSerial);
-		gbx.Setup(g => g.Gears).Returns(gears);
-
-		var tcData = InputDataHelper.InputDataAsTableData(TcHeader, TcData);
-		tc.Setup(t => t.TCData).Returns(tcData);
-		return input.Object;
-	}
-
-	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
-
-	public static readonly string[] TcData = new[] {
-		"0.0,1.80,377.80",
-		"0.1,1.71,365.21",
-		"0.2,1.61,352.62",
-		"0.3,1.52,340.02",
-		"0.4,1.42,327.43",
-		"0.5,1.33,314.84",
-		"0.6,1.23,302.24",
-		"0.7,1.14,264.46",
-		"0.8,1.04,226.68",
-		"0.9,1.02,188.90",
-		"1.0,1.0,0.00",
-		"1.100,0.999,-40.34",
-		"1.222,0.998,-80.34",
-		"1.375,0.997,-136.11",
-		"1.571,0.996,-216.52",
-		"1.833,0.995,-335.19",
-		"2.200,0.994,-528.77",
-		"2.750,0.993,-883.40",
-		"4.400,0.992,-2462.17",
-		"11.000,0.991,-16540.98",
-	};
-
-	public const string EngineFldHeader = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
-
-	public static readonly string[] EngineFldData = new[] {
-		"560,1180,-149,0.6",
-		"600,1282,-148,0.6",
-		"799.9999999,1791,-149,0.6",
-		"1000,2300,-160,0.6",
-		"1200,2300,-179,0.6",
-		"1400,2300,-203,0.6",
-		"1599.999999,2079,-235,0.49",
-		"1800,1857,-264,0.25",
-		"2000.000001,1352,-301,0.25",
-		"2100,1100,-320,0.25",
-	};
-}
\ No newline at end of file
-- 
GitLab


From 4b3faa2048bc0e6b1ec82ffd68e7afc498a70609 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Mon, 17 Mar 2025 14:38:50 +0100
Subject: [PATCH 16/22] Fixed requestdryrun with gear method in MTShiftStrategy

---
 .../Impl/Shiftstrategies/MTShiftStrategy.cs               | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
index 78aafdcb9c..90c57a49da 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
@@ -230,11 +230,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			TestPowertrain.UpdateComponents();
 			var testGearbox = TestPowertrain.Gearbox;
 			var tmpGear = testGearbox.Gear;
-			// _gearbox.Gear = currentGear;
+
+			
 			testGearbox.SetGear = currentGear;
-			// _gearbox.Gear = tmpGear;
-			testGearbox.SetGear = tmpGear;
+			
 			var response = (ResponseDryRun)testGearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+			
+			testGearbox.SetGear = tmpGear;
 			return response;
 		}
 
-- 
GitLab


From 789e2c6c41894358cc319196f5f69f46b383853a Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Mon, 17 Mar 2025 14:48:37 +0100
Subject: [PATCH 17/22] Mock overloaded version of create test powertrain

---
 .../PowertrainBuilderComponentTests.cs                     | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Testing/IntegrationTests/VECTO IntegrationTests/TestCases/Declaration/PowertrainBuilderTests/PowertrainBuilderComponentTests.cs b/Testing/IntegrationTests/VECTO IntegrationTests/TestCases/Declaration/PowertrainBuilderTests/PowertrainBuilderComponentTests.cs
index 52c49f0b49..1e7118d16b 100644
--- a/Testing/IntegrationTests/VECTO IntegrationTests/TestCases/Declaration/PowertrainBuilderTests/PowertrainBuilderComponentTests.cs	
+++ b/Testing/IntegrationTests/VECTO IntegrationTests/TestCases/Declaration/PowertrainBuilderTests/PowertrainBuilderComponentTests.cs	
@@ -105,9 +105,12 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
             var retVal = new Mock<ISimplePowertrainBuilder>();
             //var ptBuilder = new SimplePowertrainBuilder(_kernel.Get<IPowertrainComponentFactory>(), _kernel.Get<IShiftStrategyFactory>());
 			retVal.Setup(b => b.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>(),
-					It.IsAny<VectoSimulationJobType?>()))
-				.Returns((IVehicleContainer container, bool createDriver, VectoSimulationJobType? jobType) =>
+					It.IsAny<VectoSimulationJobType>()))
+				.Returns((IVehicleContainer container, bool createDriver, VectoSimulationJobType jobType) =>
 					_simplePowertrainBuilder.CreateTestPowertrain(container, createDriver, jobType));
+            retVal.Setup(b => b.CreateTestPowertrain(It.IsAny<IVehicleContainer>(), It.IsAny<bool>()))
+                .Returns((IVehicleContainer container, bool createDriver) =>
+                    _simplePowertrainBuilder.CreateTestPowertrain(container, createDriver));
             return retVal.Object;
         }
 
-- 
GitLab


From 056fb0b1b3bd272a386b02e8ffe574b0e821af18 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 18 Mar 2025 11:33:46 +0100
Subject: [PATCH 18/22] Added PEVAMTShiftStrategyTests.cs

Use Gearbox instead of EM in PEVAMTShiftStrategy.cs

Updated PEV Shiftpolygon calculation
---
 .../PEVAMTShiftStrategyTests.cs               | 140 +++--
 .../GearShiftStrategy/PEV_ShiftLineTests.cs   | 587 +++++++++++++++++-
 .../GearBoxDataAdapter.cs                     |  11 +-
 .../Models/Declaration/DeclarationData.cs     | 109 +++-
 .../Simulation/DataBus/IElectricMotorInfo.cs  |   3 +-
 .../PowertrainComponentNinjectModule.cs       |   2 +-
 .../ElectricMotor/ElectricMotorData.cs        |  30 +
 .../Data/Gearbox/ShiftPolygon.cs              |   6 +-
 .../Data/Gearbox/TransmissionLossMap.cs       |  54 +-
 .../SimulationComponent/ITestPowertrain.cs    |   4 +-
 .../SimulationComponent/Impl/ElectricMotor.cs |  17 +-
 .../Shiftstrategies/PEVAMTShiftStrategy.cs    | 142 +++--
 .../PEVAMTShiftStrategyPolygonCreator.cs      |  58 +-
 .../SimulationComponent/Impl/Vehicle.cs       |   4 +-
 14 files changed, 987 insertions(+), 180 deletions(-)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs
index aad578ce85..e140fa06e3 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs	
@@ -503,7 +503,7 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			container.Setup(r => r.RunData).Returns(runData);
 
 			//EmInfo
-			var em = GetMockElectricMotor(container.Object, runData.ElectricMachinesData.Single().Item2);
+			var em = GetElectricMotor(container.Object, runData.ElectricMachinesData.Single().Item2);
 			container.Setup(c => c.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2))
 				.Returns(em);
 			container.Setup(c => c.PowertrainInfo.ElectricMotorPositions).Returns(new[] {
@@ -529,6 +529,12 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
             //PowertrainBuilder, SimplePowertrain
 			var testPt = GetTestPowertrain(ratios, container, out _);
 			var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+			ptBuilder.Setup(c => c.CreateTestPowertrain(
+					It.IsAny<IVehicleContainer>(), It.IsAny<bool>()))
+				.Returns(testPt.Object);
+			ptBuilder.Setup(c => c.CreateTestPowertrain(
+					It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType>()))
+				.Returns(testPt.Object);
 			container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
 
 			//DrivingCycleInfo
@@ -542,9 +548,23 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			out Mock<ISimpleVehicleContainer> simplePt)
 		{
 			var testPt = new Mock<ITestPowertrain>();
-			
-			simplePt = GetSimplePowertrain(ratios, container);
+			simplePt = GetSimplePowertrain(ratios, container, out var gbx);
+			var simplePtObj = simplePt.Object;
+			testPt.Setup(t => t.ElectricMotors).Returns(() => {
+				var dict = new Dictionary<PowertrainPosition, ITestpowertrainElectricMotor>();
+				foreach (var (k, v) in simplePtObj.ElectricMotors) {
+					if (v is ITestpowertrainElectricMotor testEm) {
+						dict[k] = testEm;
+					} else {
+						throw new Exception("Expected TestElectricMotor in simple powertrain");
+					}
+				}
+				return dict;
+			});
 
+			testPt.Setup(t => t.Container).Returns(simplePt.Object);
+			
+			testPt.Setup(t => t.Gearbox).Returns(gbx.Object);
 			return testPt;
 		}
 
@@ -577,7 +597,7 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			return electricSystem;
 		}
 		
-		private ElectricMotor GetMockElectricMotor(IVehicleContainer container, ElectricMotorData emData)
+		private ElectricMotor GetElectricMotor(IVehicleContainer container, ElectricMotorData emData)
 		{
 			var emControl = new SimpleElectricMotorControl();
 			
@@ -589,28 +609,51 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			electricMotor.Connect(es.Object);
 			return electricMotor;
 		}
+
+		private TestPowertrainElectricMotor GetTestPowertrainElectricMotor(ISimpleVehicleContainer container,
+			ElectricMotorData emData)
+		{
+			var emControl = new SimpleElectricMotorControl();
+			
+			var electricMotor = new TestPowertrainElectricMotor(container: container, emData, emControl,
+				PowertrainPosition.BatteryElectricE2);
+
+			//Connect Electric System
+			var es = GetMockElectricSystem();
+			electricMotor.Connect(es.Object);
+			return electricMotor;
+		}
 		
-		private Mock<ISimpleVehicleContainer> GetSimplePowertrain(double[] ratios, Mock<IVehicleContainer> container)
+		private Mock<ISimpleVehicleContainer> GetSimplePowertrain(
+			double[] ratios, 
+			Mock<IVehicleContainer> container, 
+			out Mock<ITestPowertrainTransmission> testGbx)
 		{
 			var simplePt = new Mock<ISimpleVehicleContainer>();
-
+			simplePt.Setup(s => s.IsTestPowertrain).Returns(true);
+			
+			
 			var components = new List<VectoSimulationComponent>();
 			
 			var runData = container.Object.RunData;
-			var em = GetMockElectricMotor(container.Object, runData.ElectricMachinesData.Single().Item2);
+			var em = GetTestPowertrainElectricMotor(simplePt.Object, runData.ElectricMachinesData.Single().Item2);
 			var emDict = new Dictionary<PowertrainPosition, IElectricMotorInfo>() {
 				{ PowertrainPosition.BatteryElectricE2, em },
 			};
 			simplePt.Setup(r => r.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2))
 				.Returns(em);
 
+			//BatteryInfo
+			simplePt.Setup(s => s.BatteryInfo.InternalVoltage).Returns(700.SI<Volt>());
 
-			simplePt.Setup(r => r.ElectricMotors).Returns(emDict);
+			simplePt.Setup(s => s.ElectricMotors).Returns(emDict);
 
 			simplePt.Setup(s => s.PowertrainInfo.HasCombustionEngine).Returns(false);
-			simplePt.Setup(s => s.RunData).Returns(GetRunData(ratios));
+			
+			simplePt.Setup(s => s.RunData).Returns(runData);
 
-			var testGbx = GetTestGearbox(simplePt.Object, em);
+			testGbx = GetTestGearbox(simplePt.Object, em, runData.GearboxData.Gears);
+			
 			simplePt.Setup(s => s.GearboxCtl).Returns(testGbx.Object);
 			simplePt.Setup(s => s.GearboxInfo).Returns(testGbx.Object);
 			simplePt.Setup(s => s.GearboxOutPort).Returns(testGbx.Object);
@@ -624,42 +667,45 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			
 			return simplePt;
 		}
-		
-		Mock<ITestPowertrainTransmission> GetTestGearbox(ISimpleVehicleContainer simpleContainer, ElectricMotor em)
+
+		Mock<ITestPowertrainTransmission> GetTestGearbox(
+			ISimpleVehicleContainer simpleContainer,
+			TestPowertrainElectricMotor em,
+			Dictionary<uint, GearData> ratios)
 		{
 			Mock<IAMTGearbox> amtGearbox = new Mock<IAMTGearbox>();
 			amtGearbox.Name = "PEVAMT_TestGearbox";
 			Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
-
-			
 			
 			gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
 			gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
 
 			GearshiftPosition gear = null;
-			gbx.SetupGet(g => g.Gear).Returns(() => {
-				
-				return gear;
-			});
+			gbx.SetupGet(g => g.Gear).Returns(() => gear);
 			gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
 				.Callback<GearshiftPosition>(p => {
 					gear = p;
 				});
 
-
+		
 			GearshiftPosition nextGear = null;
 			gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
 			gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
 				.Callback<GearshiftPosition>(p => nextGear = p);
 				
+			
 			gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-				It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+				It.IsAny<PerSecond>())).Returns((NewtonMeter outTorque, PerSecond outSpeed) => {
+				var ratio =
+					gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+				
+				var inSpeed = outSpeed * ratio;
+				var inTorque = outTorque / ratio;
+				
+				em.Initialize(inTorque, inSpeed);
 				return new ResponseSuccess(this)
 				{
-					Engine = {
-						EngineSpeed = rpm,
-						PowerRequest = tq * rpm,
-					},
+					
 				};
 			});
 			gbx.Setup(p => p.Request(
@@ -670,29 +716,43 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 				true)).Returns((
 				Second absTime,
 				Second dt,
-				NewtonMeter t,
-				PerSecond n,
+				NewtonMeter outTorque,
+				PerSecond outSpeed,
 				bool dryRun) => {
-
+		
 				var ratio =
 					gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+
+				var inSpeed = outSpeed * ratio;
+				var inTorque = outTorque / ratio;
+
+				var emResponse = em.Request(absTime, dt, inTorque, inSpeed, dryRun);
 				return dryRun
-					? new ResponseDryRun(this) {
-						Engine = {
-							PowerRequest = n * t, EngineSpeed = n * ratio,
-							DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
-							TotalTorqueDemand = t,
+					? new ResponseDryRun(this, emResponse) {
+						// Engine = {
+						// 	PowerRequest = n * t, EngineSpeed = n * ratio,
+						// 	DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						// 	TotalTorqueDemand = t,
+						// },
+						// ElectricMotor = emResponse.ElectricMotor,
+						Gearbox = {
+							Gear = gbx.Object.Gear,
+							InputSpeed = inSpeed,
+							InputTorque = inTorque,
+							OutputSpeed = outSpeed,
+							OutputTorque = outTorque,
+							PowerRequest = outSpeed * outTorque,
 						},
-						Clutch = { PowerRequest = n * t },
-						DeltaFullLoad = n * t / 2 * (-1)
+						Clutch = { PowerRequest = outSpeed * outTorque },
+						DeltaFullLoad = outSpeed * outTorque / 2 * (-1)
 					}
 					: new ResponseSuccess(this) {
-						Engine = {
-							PowerRequest = n * t,
-							EngineSpeed = n * ratio
-
+						Gearbox = {
+							Gear = gbx.Object.Gear,
+							InputSpeed = inSpeed,
+							InputTorque = inTorque,
 						},
-						Clutch = { PowerRequest = n * t }
+						Clutch = { PowerRequest = outSpeed * outTorque }
 					};
 			});
 			return gbx;
@@ -781,7 +841,7 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			foreach (var entry in gearboxData.Gears) {
 				var gearIdx = (int)entry.Key - 1;
 				var dynamicTyreRadius = 0.5.SI<Meter>();
-
+				
 				var shiftPolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(
 					gearIdx,
 					emData,
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/DeclarationDataTests/GenericModelParams/GearShiftStrategy/PEV_ShiftLineTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/DeclarationDataTests/GenericModelParams/GearShiftStrategy/PEV_ShiftLineTests.cs
index a742c2ba91..d5a1e87e47 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/DeclarationDataTests/GenericModelParams/GearShiftStrategy/PEV_ShiftLineTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/DeclarationDataTests/GenericModelParams/GearShiftStrategy/PEV_ShiftLineTests.cs	
@@ -3,14 +3,18 @@ using NUnit.Framework;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor;
 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.Impl.Shiftstrategies.ShiftPolygonCalc;
+using TUGraz.VectoCore.Tests.Utils;
+using TUGraz.VectoCore.Utils;
 using Assert = NUnit.Framework.Assert;
 
 namespace TUGraz.Vecto.UnitTests.TestCases.DeclarationDataTests.GenericModelParams.GearShiftStrategy;
@@ -18,6 +22,156 @@ namespace TUGraz.Vecto.UnitTests.TestCases.DeclarationDataTests.GenericModelPara
 public class PEV_ShiftLineTests
 {
     [TestCase]
+    public void ComputePEVShiftLinesADC()
+    {
+		var axlegearRatio = 2.64;
+		var r_dyn = 0.421.SI<Meter>();
+
+		var expectedDownshiftNoADC = new[] {
+			// Gear 1
+            new Point[] {
+
+			},
+            // Gear 2
+            new[] {
+				new Point(1969.345479169557, -1067),
+				new Point(1969.345479169557, -950.6),
+				new Point(253.98783622789142, -950.6),
+				new Point(253.98783622789142, 950.6),
+				new Point(2452.135493, 950.6),
+				new Point(2461.1589140000006, 950.6),
+				new Point(2466.8630340000004, 948.41362),
+				new Point(2481.590574, 942.781315),
+				new Point(2496.3181150000005, 937.220305),
+				new Point(2503.681885, 934.463565),
+				new Point(2539.878362278914, 921.3333994166501),
+				new Point(2539.878362278914, 1067),
+            },
+			// Gear 3
+			new[] {
+				new Point(1969.345479169557, -1067),
+				new Point(1969.345479169557, -950.6),
+				new Point(253.98783622789142, -950.6),
+				new Point(253.98783622789142, 950.6),
+				new Point(2452.135493, 950.6),
+				new Point(2461.1589140000006, 950.6),
+				new Point(2466.8630340000004, 948.41362),
+				new Point(2481.590574, 942.781315),
+				new Point(2496.3181150000005, 937.220305),
+				new Point(2503.681885, 934.463565),
+				new Point(2539.878362278914, 921.3333994166501),
+				new Point(2539.878362278914, 1067),
+			},
+        };
+		var expectedUpshiftNoADC = new[] {
+			// Gear 1
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+			// Gear 2
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+			// Gear 3
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+        };
+		var countEm = 2;
+		var emRatio = 2.0;
+
+		var expectedUpshift =
+			expectedUpshiftNoADC.Select(ps => ps.Select(p => new Point(p.X / emRatio, p.Y * emRatio)).ToArray()).ToArray();
+		var expectedDownshift =
+			expectedDownshiftNoADC.Select(ps => ps.Select(p => new Point(p.X / emRatio, p.Y * emRatio)).ToArray()).ToArray();
+
+
+
+        var emFld = new ElectricMotorFullLoadCurve(EM_FullLoad_125kW_485Nm.Select(x =>
+			new ElectricMotorFullLoadCurve.FullLoadEntry() {
+				// invert motor full load curve here as would be done in respective reader class
+				MotorSpeed = x[0].RPMtoRad(),
+				FullDriveTorque = -x[1].SI<NewtonMeter>() * countEm,
+				FullGenerationTorque = -x[2].SI<NewtonMeter>() * countEm,
+			}).ToList());
+		
+		var emEffMap = GetEffMap(emFld, countEm);
+
+
+		
+
+		var emData = new ElectricMotorData() {
+			EfficiencyData = new VoltageLevelData() {
+				VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
+					new ElectricMotorVoltageLevelData() {
+						FullLoadCurve = emFld,
+						EfficiencyMap = emEffMap,
+					}
+				}
+			},
+			TransmissionLossMap = TransmissionLossMapReader.CreateEmADCLossMap(1, emRatio, "ADC"),
+			RatioADC = emRatio
+		};
+		var gearboxData = new Mock<IGearboxEngineeringInputData>().Object;
+		var gear = new Mock<ITransmissionInputData>().Object;
+		Mock.Get(gearboxData).Setup(g => g.Gears).Returns(new List<ITransmissionInputData>() {
+			gear, gear, gear, gear, gear, gear, gear, gear, gear, gear, gear, gear,
+        });
+
+		var shiftPolygons = new List<ShiftPolygon>();
+
+		var shiftStrategyParams = new ShiftStrategyParameters(); // use default (declaration) shift strategy params
+		// var downshiftMaxSpeed = emFld.RatedSpeed * shiftStrategyParams.PEV_DownshiftSpeedFactor.LimitTo(0, 1);
+		// var downshiftMinSpeed = emFld.RatedSpeed * shiftStrategyParams.PEV_DownshiftMinSpeedFactor;
+
+		
+		
+        for (var i = 0; i < gearboxData.Gears.Count; i++) {
+			var shiftPolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(
+				i,
+				emData,
+				gearboxData.Gears,
+				shiftStrategyParams.PEV_DownshiftSpeedFactor.LimitTo(0,1),
+				shiftStrategyParams.PEV_DownshiftMinSpeedFactor
+			);
+			
+			// var shiftpolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, 
+			// 	emFld, emRatio, 
+			// 	gearboxData.Gears, 
+			// 	axlegearRatio,
+			// 	r_dyn, 
+			// 	downshiftMaxSpeed, 
+			// 	downshiftMinSpeed);
+            shiftPolygons.Add(shiftPolygon);
+        }
+
+
+		CommonSanityChecks(shiftPolygons, emData.EfficiencyData.MaxSpeed / emRatio);
+		
+
+		for (var i = 0; i < Math.Min(gearboxData.Gears.Count, Math.Min(expectedDownshift.Length, expectedUpshift.Length)); i++) {
+			foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+			}
+
+			foreach (var tuple in expectedUpshift[i].Zip(shiftPolygons[i].Upshift, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+			}
+		}
+
+		Assert.AreEqual(0, shiftPolygons.First().Downshift.Count);
+		Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
+
+        //var suffix = factorDownshiftSpeed.HasValue ? $"_{factorDownshiftSpeed.Value}" : "";
+
+    }
+
+	[TestCase]
     public void ComputePEVShiftLines()
     {
 		var axlegearRatio = 2.64;
@@ -78,7 +232,7 @@ public class PEV_ShiftLineTests
         };
 
 		var countEm = 2;
-		var emRatio = 2.0;
+		var emRatio = 1.0;
 
         var emFld = new ElectricMotorFullLoadCurve(EM_FullLoad_125kW_485Nm.Select(x =>
 			new ElectricMotorFullLoadCurve.FullLoadEntry() {
@@ -88,6 +242,23 @@ public class PEV_ShiftLineTests
 				FullGenerationTorque = -x[2].SI<NewtonMeter>() * countEm,
 			}).ToList());
 		
+		var emEffMap = GetEffMap(emFld, countEm);
+
+
+		
+
+		var emData = new ElectricMotorData() {
+			EfficiencyData = new VoltageLevelData() {
+				VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
+					new ElectricMotorVoltageLevelData() {
+						FullLoadCurve = emFld,
+						EfficiencyMap = emEffMap,
+					}
+				}
+			},
+			TransmissionLossMap = TransmissionLossMapReader.CreateEmADCLossMap(1, emRatio, "ADC"),
+			RatioADC = emRatio
+		};
 		var gearboxData = new Mock<IGearboxEngineeringInputData>().Object;
 		var gear = new Mock<ITransmissionInputData>().Object;
 		Mock.Get(gearboxData).Setup(g => g.Gears).Returns(new List<ITransmissionInputData>() {
@@ -97,14 +268,33 @@ public class PEV_ShiftLineTests
 		var shiftPolygons = new List<ShiftPolygon>();
 
 		var shiftStrategyParams = new ShiftStrategyParameters(); // use default (declaration) shift strategy params
-		var downshiftMaxSpeed = emFld.RatedSpeed * shiftStrategyParams.PEV_DownshiftSpeedFactor.LimitTo(0, 1);
-		var downshiftMinSpeed = emFld.RatedSpeed * shiftStrategyParams.PEV_DownshiftMinSpeedFactor;
+		// var downshiftMaxSpeed = emFld.RatedSpeed * shiftStrategyParams.PEV_DownshiftSpeedFactor.LimitTo(0, 1);
+		// var downshiftMinSpeed = emFld.RatedSpeed * shiftStrategyParams.PEV_DownshiftMinSpeedFactor;
 
+		
+		
         for (var i = 0; i < gearboxData.Gears.Count; i++) {
-			var shiftpolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, emFld, emRatio, gearboxData.Gears, axlegearRatio, r_dyn, downshiftMaxSpeed, downshiftMinSpeed);
-            shiftPolygons.Add(shiftpolygon);
+			var shiftPolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(
+				i,
+				emData,
+				gearboxData.Gears,
+				shiftStrategyParams.PEV_DownshiftSpeedFactor.LimitTo(0,1),
+				shiftStrategyParams.PEV_DownshiftMinSpeedFactor
+			);
+			
+			// var shiftpolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i, 
+			// 	emFld, emRatio, 
+			// 	gearboxData.Gears, 
+			// 	axlegearRatio,
+			// 	r_dyn, 
+			// 	downshiftMaxSpeed, 
+			// 	downshiftMinSpeed);
+            shiftPolygons.Add(shiftPolygon);
         }
 
+
+		CommonSanityChecks(shiftPolygons, emData.EfficiencyData.MaxSpeed / emRatio);
+
 		for (var i = 0; i < Math.Min(gearboxData.Gears.Count, Math.Min(expectedDownshift.Length, expectedUpshift.Length)); i++) {
 			foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
 				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
@@ -124,7 +314,339 @@ public class PEV_ShiftLineTests
 
     }
 
-    [TestCase]
+	
+	
+	[TestCase]
+    public void ComputePEVShiftLinesDeratedSanity()
+    {
+		var axlegearRatio = 2.64;
+		var r_dyn = 0.421.SI<Meter>();
+
+		var expectedDownshift = new[] {
+			// Gear 1
+            new Point[] {
+
+			},
+            // Gear 2
+            new[] {
+				new Point(1969.345479169557, -1067),
+				new Point(1969.345479169557, -950.6),
+				new Point(253.98783622789142, -950.6),
+				new Point(253.98783622789142, 950.6),
+				new Point(2452.135493, 950.6),
+				new Point(2461.1589140000006, 950.6),
+				new Point(2466.8630340000004, 948.41362),
+				new Point(2481.590574, 942.781315),
+				new Point(2496.3181150000005, 937.220305),
+				new Point(2503.681885, 934.463565),
+				new Point(2539.878362278914, 921.3333994166501),
+				new Point(2539.878362278914, 1067),
+            },
+			// Gear 3
+			new[] {
+				new Point(1969.345479169557, -1067),
+				new Point(1969.345479169557, -950.6),
+				new Point(253.98783622789142, -950.6),
+				new Point(253.98783622789142, 950.6),
+				new Point(2452.135493, 950.6),
+				new Point(2461.1589140000006, 950.6),
+				new Point(2466.8630340000004, 948.41362),
+				new Point(2481.590574, 942.781315),
+				new Point(2496.3181150000005, 937.220305),
+				new Point(2503.681885, 934.463565),
+				new Point(2539.878362278914, 921.3333994166501),
+				new Point(2539.878362278914, 1067),
+			},
+        };
+		var expectedUpshift = new[] {
+			// Gear 1
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+			// Gear 2
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+			// Gear 3
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+        };
+
+		var countEm = 2;
+		var emRatio = 1.0;
+
+        var emFld = new ElectricMotorFullLoadCurve(EM_FullLoad_125kW_485Nm.Select(x =>
+			new ElectricMotorFullLoadCurve.FullLoadEntry() {
+				// invert motor full load curve here as would be done in respective reader class
+				MotorSpeed = x[0].RPMtoRad(),
+				FullDriveTorque = -x[1].SI<NewtonMeter>() * countEm,
+				FullGenerationTorque = -x[2].SI<NewtonMeter>() * countEm,
+			}).ToList());
+		
+		var emEffMap = GetEffMap(emFld, countEm);
+
+
+
+		var continuousTorque = emFld.MaxGenerationTorque;
+		var emData = new ElectricMotorData() {
+			Overload = new OverloadData() {
+				ContinuousTorque = continuousTorque,
+			},
+			EfficiencyData = new VoltageLevelData() {
+				VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
+					new ElectricMotorVoltageLevelData() {
+						FullLoadCurve = emFld,
+						EfficiencyMap = emEffMap,
+					}
+				}
+			},
+			TransmissionLossMap = TransmissionLossMapReader.CreateEmADCLossMap(1, emRatio, "ADC"),
+			RatioADC = emRatio
+		};
+		var gearboxData = new Mock<IGearboxEngineeringInputData>().Object;
+		var gear = new Mock<ITransmissionInputData>().Object;
+		Mock.Get(gearboxData).Setup(g => g.Gears).Returns(new List<ITransmissionInputData>() {
+			gear, gear, gear, gear, gear, gear, gear, gear, gear, gear, gear, gear,
+        });
+
+		var shiftPolygons = new List<ShiftPolygon>();
+		var runData = new VectoRunData() { GearshiftParameters = new ShiftStrategyParameters() };
+		var container = new Mock<IVehicleContainer>();
+		container.Setup(c => c.RunData).Returns(runData);
+		// var shiftStrategy = new PEVAMTShiftStrategy(container.Object);
+		// var deRatedShiftLines = shiftStrategy.CalculateDeratedShiftLines(emData, gearboxData.Gears,
+		// 	r_dyn, axlegearRatio, GearboxType.AMT);
+		
+		var shiftStrategy = new PEVAMTShiftStrategyPolygonCreator(runData.GearshiftParameters);
+		//var deRatedShiftLines = shiftStrategy.CalculateDeratedShiftLines(emData, gearboxData.Gears,
+		//    r_dyn, axlegearRatio, GearboxType.AMT);
+
+		for (var i = 0; i < gearboxData.Gears.Count; i++) {
+			//var emFld = emData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
+			var contTq = emData.Overload.ContinuousTorque;
+			var limitedFld = DeclarationData.Gearbox.LimitElectricMotorFullLoadCurve(emFld, contTq);
+			var limitedEm = new ElectricMotorData() {
+				EfficiencyData = new VoltageLevelData() {
+					VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
+						new DeratedVoltageLevelData(emFld.MaxSpeed) {
+							FullLoadCurve = limitedFld
+						}
+					}
+				},
+				RatioADC = emData.RatioADC,
+			};
+
+			var deratedShiftLine = shiftStrategy.ComputeElectricMotorDeclarationShiftPolygon(GearboxType.APTN, i,
+				gearboxData.Gears, axlegearRatio, r_dyn, emData, limitedEm);
+			shiftPolygons.Add(deratedShiftLine);
+		}
+
+
+		CommonSanityChecks(shiftPolygons, emData.EfficiencyData.MaxSpeed / emRatio);
+
+		for (var i = 0; i < Math.Min(gearboxData.Gears.Count, Math.Min(expectedDownshift.Length, expectedUpshift.Length)); i++) {
+			foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+			}
+
+			foreach (var tuple in expectedUpshift[i].Zip(shiftPolygons[i].Upshift, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+			}
+		}
+
+		Assert.AreEqual(0, shiftPolygons.First().Downshift.Count);
+		Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
+
+        //var suffix = factorDownshiftSpeed.HasValue ? $"_{factorDownshiftSpeed.Value}" : "";
+
+    }
+
+	
+	
+	[TestCase]
+    public void ComputePEVShiftLinesDeratedSanityADC()
+    {
+		var axlegearRatio = 2.64;
+		var r_dyn = 0.421.SI<Meter>();
+
+		var expectedDownshiftNoADC = new[] {
+			// Gear 1
+            new Point[] {
+
+			},
+            // Gear 2
+            new[] {
+				new Point(1969.345479169557, -1067),
+				new Point(1969.345479169557, -950.6),
+				new Point(253.98783622789142, -950.6),
+				new Point(253.98783622789142, 950.6),
+				new Point(2452.135493, 950.6),
+				new Point(2461.1589140000006, 950.6),
+				new Point(2466.8630340000004, 948.41362),
+				new Point(2481.590574, 942.781315),
+				new Point(2496.3181150000005, 937.220305),
+				new Point(2503.681885, 934.463565),
+				new Point(2539.878362278914, 921.3333994166501),
+				new Point(2539.878362278914, 1067),
+            },
+			// Gear 3
+			new[] {
+				new Point(1969.345479169557, -1067),
+				new Point(1969.345479169557, -950.6),
+				new Point(253.98783622789142, -950.6),
+				new Point(253.98783622789142, 950.6),
+				new Point(2452.135493, 950.6),
+				new Point(2461.1589140000006, 950.6),
+				new Point(2466.8630340000004, 948.41362),
+				new Point(2481.590574, 942.781315),
+				new Point(2496.3181150000005, 937.220305),
+				new Point(2503.681885, 934.463565),
+				new Point(2539.878362278914, 921.3333994166501),
+				new Point(2539.878362278914, 1067),
+			},
+        };
+		var expectedUpshiftNoADC = new[] {
+			// Gear 1
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+			// Gear 2
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+			// Gear 3
+			new[] {
+				new Point(6627.393225000001, 1067),
+				new Point(6627.393225000001, -1067),
+			},
+        };
+
+		var countEm = 2;
+		var emRatio = 2.0;
+
+		var expectedUpshift =
+			expectedUpshiftNoADC.Select(ps => ps.Select(p => new Point(p.X / emRatio, p.Y * emRatio)).ToArray()).ToArray();
+		var expectedDownshift =
+			expectedDownshiftNoADC.Select(ps => ps.Select(p => new Point(p.X / emRatio, p.Y * emRatio)).ToArray()).ToArray();
+
+		
+        var emFld = new ElectricMotorFullLoadCurve(EM_FullLoad_125kW_485Nm.Select(x =>
+			new ElectricMotorFullLoadCurve.FullLoadEntry() {
+				// invert motor full load curve here as would be done in respective reader class
+				MotorSpeed = x[0].RPMtoRad(),
+				FullDriveTorque = -x[1].SI<NewtonMeter>() * countEm,
+				FullGenerationTorque = -x[2].SI<NewtonMeter>() * countEm,
+			}).ToList());
+		
+		var emEffMap = GetEffMap(emFld, countEm);
+
+
+
+		var continuousTorque = emFld.MaxGenerationTorque;
+		var emData = new ElectricMotorData() {
+			Overload = new OverloadData() {
+				ContinuousTorque = continuousTorque,
+			},
+			EfficiencyData = new VoltageLevelData() {
+				VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
+					new ElectricMotorVoltageLevelData() {
+						FullLoadCurve = emFld,
+						EfficiencyMap = emEffMap,
+					}
+				}
+			},
+			TransmissionLossMap = TransmissionLossMapReader.CreateEmADCLossMap(1, emRatio, "ADC"),
+			RatioADC = emRatio
+		};
+		var gearboxData = new Mock<IGearboxEngineeringInputData>().Object;
+		var gear = new Mock<ITransmissionInputData>().Object;
+		Mock.Get(gearboxData).Setup(g => g.Gears).Returns(new List<ITransmissionInputData>() {
+			gear, gear, gear, gear, gear, gear, gear, gear, gear, gear, gear, gear,
+        });
+
+		var shiftPolygons = new List<ShiftPolygon>();
+		var runData = new VectoRunData() { GearshiftParameters = new ShiftStrategyParameters() };
+		var container = new Mock<IVehicleContainer>();
+		container.Setup(c => c.RunData).Returns(runData);
+
+		var polygonCreator = new PEVAMTShiftStrategyPolygonCreator(runData.GearshiftParameters);
+		//var deRatedShiftLines = shiftStrategy.CalculateDeratedShiftLines(emData, gearboxData.Gears,
+		//    r_dyn, axlegearRatio, GearboxType.AMT);
+
+		for (var i = 0; i < gearboxData.Gears.Count; i++) {
+			//var emFld = emData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
+			var contTq = emData.Overload.ContinuousTorque;
+			var limitedFld = DeclarationData.Gearbox.LimitElectricMotorFullLoadCurve(emFld, contTq);
+			var limitedEm = new ElectricMotorData() {
+				EfficiencyData = new VoltageLevelData() {
+					VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
+						new DeratedVoltageLevelData(emFld.MaxSpeed) {
+							FullLoadCurve = limitedFld
+						}
+					}
+				},
+				RatioADC = emData.RatioADC,
+			};
+
+			var deratedShiftLine = polygonCreator.ComputeElectricMotorDeclarationShiftPolygon(GearboxType.APTN, i,
+				gearboxData.Gears, axlegearRatio, r_dyn, emData, limitedEm);
+			shiftPolygons.Add(deratedShiftLine);
+		}
+
+
+		CommonSanityChecks(shiftPolygons, emData.EfficiencyData.MaxSpeed / emRatio);
+		
+		for (var i = 0; i < Math.Min(gearboxData.Gears.Count, Math.Min(expectedDownshift.Length, expectedUpshift.Length)); i++) {
+			foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+			}
+
+			foreach (var tuple in expectedUpshift[i].Zip(shiftPolygons[i].Upshift, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+			}
+		}
+
+		Assert.AreEqual(0, shiftPolygons.First().Downshift.Count);
+		Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
+
+        //var suffix = factorDownshiftSpeed.HasValue ? $"_{factorDownshiftSpeed.Value}" : "";
+
+    }
+
+	
+	
+	private static EfficiencyMap GetEffMap(ElectricMotorFullLoadCurve emFld, int countEm)
+	{
+		var emEffMap = ElectricMotorMapReader.Create(
+			InputDataHelper.InputDataAsTableData(
+				"n [rpm] , T [Nm] , P_el [kW]",
+				$"0, {emFld.MaxDriveTorque.Value()}, 0",
+				$"0, {emFld.MaxGenerationTorque.Value()}, 0",
+				$"0, 0, 0",
+				$"{emFld.MaxSpeed.AsRPM / 3}, {emFld.MaxDriveTorque.Value()}, -300",
+				$"{emFld.MaxSpeed.AsRPM / 3}, {emFld.MaxGenerationTorque.Value()}, 750",
+				$"{emFld.MaxSpeed.AsRPM / 3}, 0, 100",
+				$"{emFld.MaxSpeed.AsRPM / 2}, {emFld.MaxDriveTorque.Value()}, -300",
+				$"{emFld.MaxSpeed.AsRPM / 2}, {emFld.MaxGenerationTorque.Value()}, 750",
+				$"{emFld.MaxSpeed.AsRPM / 2}, 0, 100",
+				$"{emFld.MaxSpeed.AsRPM}, {emFld.MaxDriveTorque.Value()}, -300",
+				$"{emFld.MaxSpeed.AsRPM}, {emFld.MaxGenerationTorque.Value()}, 750",
+				$"{emFld.MaxSpeed.AsRPM}, 0, 100"
+			).ApplyFactor(ElectricMotorMapReader.Fields.PowerElectrical, 1E3), countEm, ExecutionMode.Declaration);
+		return emEffMap;
+	}
+
+	[TestCase]
     public void ComputePEVShiftLinesDeRated()
     {
 
@@ -312,7 +834,7 @@ public class PEV_ShiftLineTests
         //    });
 
 		var countEm = 2;
-		var emRatio = 2.0;
+		var emRatio = 1.0;
 		var continuousTorque = 145.SI<NewtonMeter>() * countEm;
         var emFld = new ElectricMotorFullLoadCurve(EM_FullLoad_125kW_485Nm.Select(x =>
 			new ElectricMotorFullLoadCurve.FullLoadEntry() {
@@ -322,6 +844,9 @@ public class PEV_ShiftLineTests
 				FullGenerationTorque = -x[2].SI<NewtonMeter>() * countEm,
 			}).ToList());
 
+		var emEffMap = GetEffMap(emFld: emFld, countEm: countEm);
+		
+
 		var emData = new ElectricMotorData() {
 			RatioADC = emRatio,
 			Overload = new OverloadData() {
@@ -330,10 +855,12 @@ public class PEV_ShiftLineTests
 			EfficiencyData = new VoltageLevelData() {
 				VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
 					new ElectricMotorVoltageLevelData() {
-						FullLoadCurve = emFld
+						FullLoadCurve = emFld,
+						EfficiencyMap = emEffMap
 					}
 				}
-			}
+			},
+			TransmissionLossMap = TransmissionLossMapReader.CreateEmADCLossMap(1, emRatio, "ADC")
 		};
 		var gearboxData = new Mock<IGearboxEngineeringInputData>().Object;
 		var gear = new Mock<ITransmissionInputData>().Object;
@@ -358,9 +885,10 @@ public class PEV_ShiftLineTests
 		var runData = new VectoRunData() { GearshiftParameters = new ShiftStrategyParameters() };
 		var container = new Mock<IVehicleContainer>();
 		container.Setup(c => c.RunData).Returns(runData);
-        var shiftStrategy = new PEVAMTShiftStrategyPolygonCreator(runData.GearshiftParameters);
-        //var deRatedShiftLines = shiftStrategy.CalculateDeratedShiftLines(emData, gearboxData.Gears,
-        //    r_dyn, axlegearRatio, GearboxType.AMT);
+
+		var polygonCreator = new PEVAMTShiftStrategyPolygonCreator(runData.GearshiftParameters);
+		//var deRatedShiftLines = shiftStrategy.CalculateDeratedShiftLines(emData, gearboxData.Gears,
+		//    r_dyn, axlegearRatio, GearboxType.AMT);
 
 		for (var i = 0; i < gearboxData.Gears.Count; i++) {
 			//var emFld = emData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
@@ -369,7 +897,7 @@ public class PEV_ShiftLineTests
 			var limitedEm = new ElectricMotorData() {
 				EfficiencyData = new VoltageLevelData() {
 					VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
-						new ElectricMotorVoltageLevelData() {
+						new DeratedVoltageLevelData(emFld.MaxSpeed) {
 							FullLoadCurve = limitedFld
 						}
 					}
@@ -377,11 +905,14 @@ public class PEV_ShiftLineTests
 				RatioADC = emData.RatioADC,
 			};
 
-            var deratedShiftLine = shiftStrategy.ComputeElectricMotorDeclarationShiftPolygon(GearboxType.APTN, i,
+			var deratedShiftLine = polygonCreator.ComputeElectricMotorDeclarationShiftPolygon(GearboxType.APTN, i,
 				gearboxData.Gears, axlegearRatio, r_dyn, emData, limitedEm);
 			shiftPolygons.Add(deratedShiftLine);
-        }
+		}
 
+		
+		CommonSanityChecks(shiftPolygons, emData.EfficiencyData.MaxSpeed / emRatio);
+		
 		for (var i = 0; i < Math.Min(gearboxData.Gears.Count, Math.Min(expectedDownshift.Length, expectedUpshift.Length)); i++) {
 			foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
 				Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.AsRPM, 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
@@ -477,4 +1008,30 @@ public class PEV_ShiftLineTests
 		new[] { 7290.132548,163.736,-163.736 },
 		new[] { 7363.77025,162.099125,-162.099125 },
     };
+
+
+
+
+	private void CommonSanityChecks(IEnumerable<ShiftPolygon> shiftPolygons, PerSecond emMaxSpeed)
+	{
+		var polygonList = shiftPolygons.ToList();
+		foreach (var upShiftPolygon in polygonList.Select(p => p.Upshift)) {
+			foreach (var entry in upShiftPolygon) {
+				Assert.Less(entry.AngularSpeed, emMaxSpeed );
+			}
+		}
+
+		foreach (var shiftPolygon in polygonList) {
+			var upshift = shiftPolygon.Upshift;
+			var downshift = shiftPolygon.Downshift;
+			if (upshift.Count > 0 && downshift.Count > 0) {
+				Assert.True(downshift.All(d => d.AngularSpeed.IsSmallerOrEqual(upshift.First().AngularSpeed)));
+			}
+		}
+
+
+
+
+
+	}
 }
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/GearBoxDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/GearBoxDataAdapter.cs
index dd9893ae6d..8e5c554882 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/GearBoxDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/GearBoxDataAdapter.cs
@@ -462,16 +462,19 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 			var limitedEm = new ElectricMotorData() {
 				EfficiencyData = new VoltageLevelData() {
 					VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
-						new ElectricMotorVoltageLevelData() {
+						new DeratedVoltageLevelData(em.EfficiencyData.MaxSpeed) {
 							FullLoadCurve = limitedFld
 						}
 					}
 				},
 				RatioADC = em.RatioADC,
 			};
-			var deratedEmShiftPolygon = shiftPolygonCalculator.ComputeElectricMotorDeclarationShiftPolygon(gearbox.Type, (int)i,
+			var deratedEmShiftPolygon = shiftPolygonCalculator.ComputeElectricMotorDeclarationShiftPolygon(
+				gearbox.Type, (int)i,
 				gearbox.Gears, axlegearRatio,
-				dynamicTyreRadius, em, limitedEm);
+				dynamicTyreRadius, 
+				em, 
+				limitedEm);
 			return deratedEmShiftPolygon;
 			//retVal[i + 1] = shiftPolygon;
 		}
@@ -611,7 +614,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 			var limitedEm = new ElectricMotorData() {
 				EfficiencyData = new VoltageLevelData() {
 					VoltageLevels = new List<ElectricMotorVoltageLevelData>() {
-						new ElectricMotorVoltageLevelData() {
+						new DeratedVoltageLevelData(em.EfficiencyData.MaxSpeed) {
 							FullLoadCurve = limitedFld
 						}
 					}
diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
index 47f74e2345..968a959ba8 100644
--- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
@@ -58,6 +58,7 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Batter
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.OutputData;
 using Point = TUGraz.VectoCommon.Utils.Point;
+using NLog.Fluent;
 using ElectricSystem = TUGraz.VectoCore.Models.Declaration.Auxiliaries.ElectricSystem;
 
 namespace TUGraz.VectoCore.Models.Declaration
@@ -1063,40 +1064,108 @@ namespace TUGraz.VectoCore.Models.Declaration
 				}
 
 			}
-
-			public static ShiftPolygon ComputeElectricMotorShiftPolygon(int gearIdx,
-				ElectricMotorFullLoadCurve fullLoadCurveOrig, double emRatio, IList<ITransmissionInputData> gears,
-				double axlegearRatio, Meter dynamicTyreRadius, PerSecond downshiftMaxSpeed = null, PerSecond downshiftMinSpeed = null)
+			
+			
+			public static ShiftPolygon ComputeElectricMotorShiftPolygon(
+				int gearIdx, 
+				ElectricMotorData electricMotorData,
+				IList<ITransmissionInputData> gears, 
+				double? downshiftMaxSpeedFactor = null,
+				double? downShiftMinSpeedFactor = null)
 			{
-				var gbxMaxTq = gears[gearIdx].MaxTorque != null ? gears[gearIdx].MaxTorque / emRatio : null;
-				var gbxMaxSpeed = gears[gearIdx].MaxInputSpeed != null ? gears[gearIdx].MaxInputSpeed * emRatio : null;
-
+				if ((downshiftMaxSpeedFactor != null && !downshiftMaxSpeedFactor.Value.IsBetween(0.0, 1.0)) ||
+					downShiftMinSpeedFactor != null && !downShiftMinSpeedFactor.Value.IsBetween(0.0, 1.0)) {
+					throw new VectoException("Invalid downshift factors: must be between 0.0 and 1.0");
+				}
+				
+				//EM FullloadCurve
+				var fullLoadCurveOrig = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
+				
+				var emRatio = electricMotorData.RatioADC;
+				var lossMap = electricMotorData.TransmissionLossMap;
+				var emMaxSpeed = electricMotorData.EfficiencyData.MaxSpeed;
+				
+				//Transform EM Fullloadcurve to include ADC losses and ratio. Convert EM to Drivetrain
+				var fullLoadCurveTransformed = TransformFullLoadCurve(fullLoadCurveOrig, lossMap, emRatio);
+				var emMaxSpeedDt = emMaxSpeed / emRatio;
+				
+				
+				//From now on we are on the gbx_in side.
+				var gbxMaxTq = gears[gearIdx].MaxTorque != null ? gears[gearIdx].MaxTorque : null;
+				var gbxMaxSpeed = gears[gearIdx].MaxInputSpeed != null ? gears[gearIdx].MaxInputSpeed : null;
+				
+				
 				var fullLoadCurve = gbxMaxTq == null
-					? fullLoadCurveOrig
-					: LimitElectricMotorFullLoadCurve(fullLoadCurveOrig, gbxMaxTq);
+					? fullLoadCurveTransformed
+					: LimitElectricMotorFullLoadCurve(fullLoadCurveTransformed, gbxMaxTq);
+				
 				if (gears.Count < 2) {
 					throw new VectoException("ComputeShiftPolygon needs at least 2 gears. {0} gears given.", gears.Count);
 				}
-
+			
 				var downShift = new List<ShiftPolygon.ShiftPolygonEntry>();
 				var upShift = new List<ShiftPolygon.ShiftPolygonEntry>();
 				if (gearIdx > 0) {
-					var nMax = downshiftMaxSpeed ?? fullLoadCurve.NP80low;
-					var nMin = downshiftMinSpeed ?? 0.1 * fullLoadCurve.RatedSpeed;
-
-					downShift.AddRange(DownshiftLineDrive(fullLoadCurve, fullLoadCurveOrig, nMin, fullLoadCurve.NP80low));
-					downShift.AddRange(DownshiftLineDrag(fullLoadCurve, fullLoadCurveOrig, nMin, nMax));
-
+					var nMax = downshiftMaxSpeedFactor.HasValue
+						? downshiftMaxSpeedFactor.Value * fullLoadCurve.RatedSpeed
+						: fullLoadCurve.NP80low;
+					
+					var nMin = downShiftMinSpeedFactor.HasValue 
+						? downShiftMinSpeedFactor.Value * fullLoadCurve.RatedSpeed
+						: fullLoadCurve.RatedSpeed * 0.1;
+					
+					downShift.AddRange(DownshiftLineDrive(fullLoadCurve, fullLoadCurveTransformed, nMin, fullLoadCurve.NP80low));
+					downShift.AddRange(DownshiftLineDrag(fullLoadCurve, fullLoadCurveTransformed, nMin, nMax));
+			
 				}
 				if (gearIdx >= gears.Count - 1) {
-					return new ShiftPolygon(downShift, upShift);
+					return new ShiftPolygon(TransformShiftPolygonEntries(downShift, emRatio, lossMap), TransformShiftPolygonEntries(upShift, emRatio, lossMap));
 				}
+			
+				upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxGenerationTorque * 1.1, VectoMath.Min(emMaxSpeedDt * 0.9, gbxMaxSpeed)));
+				upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDriveTorque * 1.1, VectoMath.Min(emMaxSpeedDt * 0.9, gbxMaxSpeed)));
+				return new ShiftPolygon(TransformShiftPolygonEntries(downShift, emRatio, lossMap), TransformShiftPolygonEntries(upShift, emRatio, lossMap));
+			}
 
-				upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxGenerationTorque * 1.1, VectoMath.Min(fullLoadCurve.MaxSpeed * 0.9, gbxMaxSpeed)));
-				upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDriveTorque * 1.1, VectoMath.Min(fullLoadCurve.MaxSpeed * 0.9, gbxMaxSpeed)));
-				return new ShiftPolygon(downShift, upShift);
+
+			/// <summary>
+			/// Transforms the shiftpolygons from em side to drivetrain side (= gearbox in), considering the ADC ratio and losses
+			/// </summary>
+			/// <param name="entries"></param>
+			/// <param name="emRatio"></param>
+			/// <param name="lossMap"></param>
+			/// <returns></returns>
+			private static IList<ShiftPolygon.ShiftPolygonEntry> TransformShiftPolygonEntries(
+				IEnumerable<ShiftPolygon.ShiftPolygonEntry> entries, double emRatio, TransmissionLossMap lossMap)
+			{
+				return entries.ToList();
 			}
 
+			private static ElectricMotorFullLoadCurve TransformFullLoadCurve(ElectricMotorFullLoadCurve emFld,
+				TransmissionLossMap lossMap, double ratioAdc)
+			{
+				var fldCurve =
+					new ElectricMotorFullLoadCurve(
+						emFld.FullLoadEntries.Select(e => {
+								var drive = lossMap.GetOutTorqueAndSpeed(e.MotorSpeed, e.FullDriveTorque);
+								var generation = lossMap.GetOutTorqueAndSpeed(e.MotorSpeed, e.FullGenerationTorque);
+								return new ElectricMotorFullLoadCurve.FullLoadEntry() {
+									FullDriveTorque = drive.outTorque,
+									FullGenerationTorque = generation.outTorque,
+									MotorSpeed = drive.outAngularVelocity
+								};
+							}
+						).ToList());
+				
+				return fldCurve;
+			}
+			
+			/// <summary>
+			/// Limit the fullload curve to the max gearbox in torque
+			/// </summary>
+			/// <param name="emFld"></param>
+			/// <param name="maxTq"></param>
+			/// <returns></returns>
 			public static ElectricMotorFullLoadCurve LimitElectricMotorFullLoadCurve(ElectricMotorFullLoadCurve emFld, NewtonMeter maxTq)
 			{
 				var contTqFld = new ElectricMotorFullLoadCurve(new List<ElectricMotorFullLoadCurve.FullLoadEntry>() {
diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs
index 59cde098fc..6d16bced64 100644
--- a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs
+++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs
@@ -12,7 +12,8 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus
 		PerSecond ElectricMotorSpeed { get; }
 		NewtonMeter ElectricMotorTorque { get; }
 		PowertrainPosition Position { get; }
-		PerSecond MaxSpeed { get; }
+		PerSecond MaxSpeedDt { get; }
+		PerSecond RatedSpeedDt { get; }
 		Watt DragPower(Volt volt, PerSecond electricMotorSpeed, GearshiftPosition gear);
 		Watt MaxPowerDrive(Volt volt, PerSecond inAngularVelocity, GearshiftPosition gear);
 		NewtonMeter GetTorqueForElectricPower(Volt volt, Watt electricPower, PerSecond avgEmSpeed, Second dt, GearshiftPosition gear, bool allowExtrapolation);
diff --git a/VectoCore/VectoCore/Models/Simulation/PowertrainComponentNinjectModule.cs b/VectoCore/VectoCore/Models/Simulation/PowertrainComponentNinjectModule.cs
index 243fb2574b..9de7660fc8 100644
--- a/VectoCore/VectoCore/Models/Simulation/PowertrainComponentNinjectModule.cs
+++ b/VectoCore/VectoCore/Models/Simulation/PowertrainComponentNinjectModule.cs
@@ -147,7 +147,7 @@ namespace TUGraz.VectoCore.Models.Simulation
 			}
             Bind<IElectricSystem>().To<TestpowertrainElectricSystem>().Named(_testPowertrain.Prefix);
 			Bind<IElectricChargerPort>().To<TestpowertrainGensetChargerAdapter>().Named(_testPowertrain.Prefix);
-			Bind<IElectricMotor>().To<TestpowertrainElectricMotor>().Named(_testPowertrain.ElectricMotorName(false));
+			Bind<IElectricMotor>().To<TestPowertrainElectricMotor>().Named(_testPowertrain.ElectricMotorName(false));
 			Bind<IElectricMotor>().To<TestpowertrainIEPC>().Named(_testPowertrain.ElectricMotorName(true));
 
 			Bind<IElectricMotorControl>().To<SimpleElectricMotorControl>().Named(_testPowertrain.ElectricMotorControllerName(CycleType.DistanceBased));
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricComponents/ElectricMotor/ElectricMotorData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricComponents/ElectricMotor/ElectricMotorData.cs
index 3f5056383b..41192481b7 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricComponents/ElectricMotor/ElectricMotorData.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricComponents/ElectricMotor/ElectricMotorData.cs
@@ -244,6 +244,36 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 	{
 
 	}
+	
+	public class DeratedVoltageLevelData : ElectricMotorVoltageLevelData
+	{
+		public DeratedVoltageLevelData(PerSecond maxSpeed)
+		{
+			_maxSpeed = maxSpeed;
+		}
+		
+		#region Overrides of ElectricMotorVoltageLevelData
+		public override EfficiencyMap.EfficiencyResult LookupElectricPower(PerSecond avgSpeed, NewtonMeter torque, uint gear, bool allowExtrapolation)
+		{
+			throw new NotImplementedException();
+		}
+		public override NewtonMeter LookupTorque(Watt electricPower, PerSecond avgSpeed, NewtonMeter maxEmTorque, uint gear)
+		{
+			throw new NotImplementedException();
+		}
+		public override NewtonMeter FullLoadDriveTorque(PerSecond avgSpeed)
+		{
+			throw new NotImplementedException();
+		}
+		public override NewtonMeter FullGenerationTorque(PerSecond avgSpeed)
+		{
+			throw new NotImplementedException();
+		}
+
+		#endregion
+	}
+
+	
 
 	public class OverloadData
 	{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
index d9f07a5528..39e0170128 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
@@ -47,10 +47,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 		private readonly List<ShiftPolygonEntry> _upShiftPolygon;
 		private readonly List<ShiftPolygonEntry> _downShiftPolygon;
 
-		internal ShiftPolygon(List<ShiftPolygonEntry> downshift, List<ShiftPolygonEntry> upShift)
+		internal ShiftPolygon(IList<ShiftPolygonEntry> downshift, IList<ShiftPolygonEntry> upShift)
 		{
-			_upShiftPolygon = upShift;
-			_downShiftPolygon = downshift;
+			_upShiftPolygon = upShift.ToList();
+			_downShiftPolygon = downshift.ToList();
 		}
 
 		[JsonIgnore]
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs
index 197feb4516..7eee96a5a1 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs
@@ -45,8 +45,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 	{
 		[ValidateObject] internal readonly IReadOnlyList<GearLossMapEntry> _entries;
 
-		private readonly double _ratio;
-
 		/// <summary>
 		/// The Loss map. [X=Output EngineSpeed, Y=Output Torque] => Z=Torque Loss
 		/// </summary>
@@ -59,6 +57,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 
 		public string GearName { get; private set; }
 
+		public double Ratio { get; }
 
 
 		public string[] LossMapSerialized
@@ -69,7 +68,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 		public TransmissionLossMap(IReadOnlyList<GearLossMapEntry> entries, double gearRatio, string gearName, bool createInnvertedMap)
 		{
 			GearName = gearName;
-			_ratio = gearRatio;
+			Ratio = gearRatio;
 			_entries = entries;
 			_lossMap = new DelaunayMap("TransmissionLossMap " + GearName);
 			_invertedLossMap = createInnvertedMap ? new DelaunayMap("TransmissionLossMapInv. " + GearName) : null;
@@ -91,10 +90,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 		public LossMapResult GetTorqueLoss(PerSecond outAngularVelocity, NewtonMeter outTorque)
 		{
 			var result = new LossMapResult();
-			var torqueLoss = _lossMap.Interpolate(outAngularVelocity.Value() * _ratio, outTorque.Value() / _ratio);
+			var torqueLoss = _lossMap.Interpolate(outAngularVelocity.Value() * Ratio, outTorque.Value() / Ratio);
 
 			if (torqueLoss.IsNaN()) {
-				torqueLoss = _lossMap.Extrapolate(outAngularVelocity.Value() * _ratio, outTorque.Value() / _ratio);
+				torqueLoss = _lossMap.Extrapolate(outAngularVelocity.Value() * Ratio, outTorque.Value() / Ratio);
 				result.Extrapolated = true;
 			}
 
@@ -111,6 +110,47 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 			public bool Extrapolated;
 			public NewtonMeter Value;
 		}
+		/// <summary>
+		/// Computes the OUTPUT torque and speed given by the input speed and input torque
+		/// </summary>
+		/// <param name="inAngularVelocity"></param>
+		/// <param name="inTorque"></param>
+		/// <param name="allowExtrapolation"></param>
+		/// <returns></returns>
+		public (NewtonMeter outTorque, PerSecond outAngularVelocity) GetOutTorqueAndSpeed(PerSecond inAngularVelocity,
+			NewtonMeter inTorque, bool allowExtrapolation = false)
+		{
+			var outTorque = this.GetOutTorque(inAngularVelocity, inTorque, allowExtrapolation);
+			var outAngularVelocity = inAngularVelocity / Ratio;
+
+			var torqueLoss = this.GetTorqueLoss(outAngularVelocity, outTorque);
+			var inTorqueBackward = GetInTorque(outAngularVelocity, outTorque);
+
+			if(!inTorque.IsEqual(inTorqueBackward, 1E-8.SI<NewtonMeter>()))
+			{
+				Log.Debug($"{nameof(TransmissionLossMap)}: Forward Calculation and Backward Calculation of DriveTorque do not match...");
+				//Search outTorque:
+				Log.Debug("Forward Calculation and Backward Calculation do not match...");
+				outTorque = SearchAlgorithm.Search(inTorque, (inTorqueBackward - inTorque) * 1e3, outTorque / 10,
+					getYValue: r => ((r as NewtonMeter) - inTorque) * 1e3,
+					evaluateFunction: x => GetInTorque(outAngularVelocity, x),
+					criterion: r => {
+						var i = r as NewtonMeter;
+						return (i - inTorque).Value() * 1e3;
+					},
+					searcher: this);
+			}
+
+			return (outTorque, outAngularVelocity);
+		}
+
+		public NewtonMeter GetInTorque(PerSecond outAngularVelocity, NewtonMeter outTorque)
+		{
+			var torqueLoss = this.GetTorqueLoss(outAngularVelocity, outTorque);
+			var inTorque = outTorque / Ratio + torqueLoss.Value;
+			return inTorque;
+		}
+		
 
 		///  <summary>
 		/// 	Computes the OUTPUT torque given by the input engineSpeed and the input torque.
@@ -126,12 +166,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 			}
 			var torqueLoss = _invertedLossMap.Interpolate(inAngularVelocity.Value(), inTorque.Value());
 			if (!torqueLoss.IsNaN()) {
-				return (inTorque - torqueLoss.SI<NewtonMeter>()) * _ratio;
+				return (inTorque - torqueLoss.SI<NewtonMeter>()) * Ratio;
 			}
 
 			if (allowExtrapolation) {
 				torqueLoss = _invertedLossMap.Extrapolate(inAngularVelocity.Value(), inTorque.Value());
-				return (inTorque - torqueLoss.SI<NewtonMeter>()) * _ratio;
+				return (inTorque - torqueLoss.SI<NewtonMeter>()) * Ratio;
 			}
 
 			throw new VectoException("TransmissionLossMap {0}: Interpolation failed. inTorque: {1}, inAngularVelocity: {2}",
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/ITestPowertrain.cs b/VectoCore/VectoCore/Models/SimulationComponent/ITestPowertrain.cs
index e3add8c86b..f4121fd0f0 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/ITestPowertrain.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/ITestPowertrain.cs
@@ -29,8 +29,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
         IBrakes Brakes { get; }
 
 		ITestpowertrainElectricMotor ElectricMotor { get; }
-		Dictionary<PowertrainPosition, ITestpowertrainElectricMotor> ElectricMotors { get; }
-        Dictionary<PowertrainPosition, IElectricMotor> ElectricMotorsUpstreamTransmission { get; }
+		Dictionary<PowertrainPosition, ITestpowertrainElectricMotor> ElectricMotors { get; } 
+		Dictionary<PowertrainPosition, IElectricMotor> ElectricMotorsUpstreamTransmission { get; }
         IDCDCConverter DCDCConverter { get; }
         ITorqueConverter TorqueConverter { get; }
 		ITestpowertrainGensetChargerAdapter Charger { get; }
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
index 56575e123e..5af085c3be 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
@@ -16,9 +16,9 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
-    public class TestpowertrainElectricMotor : ElectricMotor, ITestpowertrainElectricMotor
+    public class TestPowertrainElectricMotor : ElectricMotor, ITestpowertrainElectricMotor
 	{
-		public TestpowertrainElectricMotor(IVehicleContainer container, ElectricMotorData data,
+		public TestPowertrainElectricMotor(IVehicleContainer container, ElectricMotorData data,
 			IElectricMotorControl control, PowertrainPosition position) : base(container, data, control, position, false)
 		{
 			if (!container.IsTestPowertrain) {
@@ -52,7 +52,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public IElectricMotorControl Control { get; }
 		protected ElectricMotorData ModelData;
 		private PerSecond _maxSpeed;
-
+		private PerSecond _ratedSpeed;
+		
 		protected internal Joule ThermalBuffer = 0.SI<Joule>();
 		
 
@@ -92,12 +93,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				Log.Error("Overload buffer for thermal de-rating is zero or negative! Please check electric motor data!");
 			}
 		}
-
 		public double[] TransmissionRatioPerGear { get; set; }
-
 		public PowertrainPosition Position { get; }
-		public PerSecond MaxSpeed => _maxSpeed ?? (_maxSpeed = ModelData.EfficiencyData.MaxSpeed / ModelData.RatioADC);
-
+		public PerSecond MaxSpeedDt => _maxSpeed ?? (_maxSpeed = ModelData.EfficiencyData.MaxSpeed / ModelData.RatioADC);
+		public PerSecond RatedSpeedDt => _ratedSpeed ?? (_ratedSpeed = ModelData.EfficiencyData.VoltageLevels.First().FullLoadCurve.RatedSpeed / ModelData.RatioADC);
 		public Watt DragPower(Volt volt, PerSecond electricMotorSpeed, GearshiftPosition gear)
 		{
 			return ModelData.DragCurveLookup(electricMotorSpeed, gear) * electricMotorSpeed;
@@ -505,10 +504,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected virtual PerSecond GetMotorSpeedLimit(Second absTime)
 		{
 			if (DataBus.GearboxInfo == null || DataBus.GearboxInfo.Gear.Gear == 0) {
-				return MaxSpeed;
+				return MaxSpeedDt;
 			}
 
-			return VectoMath.Min(DataBus.GearboxInfo.GetGearData(DataBus.GearboxInfo.Gear.Gear)?.MaxSpeed, MaxSpeed);
+			return VectoMath.Min(DataBus.GearboxInfo.GetGearData(DataBus.GearboxInfo.Gear.Gear)?.MaxSpeed, MaxSpeedDt);
 		}
 
         private NewtonMeter GetMaxRecuperationTorque(Volt volt, Second dt, PerSecond avgSpeed, GearshiftPosition gear)
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs
index 50bf9fb32d..54578edcb7 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs
@@ -208,27 +208,34 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			GearshiftPosition currentGear, IResponse r)
 		{
 			var nextGear = currentGear;
+			var derated = r.ElectricMotor.DeRatingActive;
 			// upshift
-			if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity, r.ElectricMotor.DeRatingActive)) {
+			if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity, derated)) {
+				
+				inTorque = null;
+				inAngularVelocity = null;
+				r = null;
+				
 				nextGear = GearList.Successor(currentGear);
-
 				while (GearList.HasSuccessor(nextGear)) {
 					// check skip gears
 					nextGear = GearList.Successor(nextGear);
-					var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, nextGear);
-
-					inAngularVelocity = response.ElectricMotor.AngularVelocity;
-					inTorque = response.ElectricMotor.PowerRequest / inAngularVelocity;
+					var nextResponse = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, nextGear);
 
-					var maxTorque = VectoMath.Min(-response.ElectricMotor.MaxDriveTorque,
+					var nextInAngularVelocity = nextResponse.Gearbox.InputSpeed;
+					var nextInTorque = nextResponse.Gearbox.InputTorque;
+					
+					var maxTorque = VectoMath.Min(
+						-nextResponse.ElectricMotor.MaxDriveTorque, //ADC considered
 						!nextGear.Equals(GearList.First())
-							? GearboxModelData.Gears[nextGear.Gear].ShiftPolygon
-								.InterpolateDownshift(response.Engine.EngineSpeed)
-							: double.MaxValue.SI<NewtonMeter>());
-					var reserve = 1 - inTorque / maxTorque;
+							? GearboxModelData.Gears[nextGear.Gear].ShiftPolygon.InterpolateDownshift(nextInAngularVelocity)
+							: double.MaxValue.SI<NewtonMeter>()
+						);
+					
+					var reserve = 1 - nextInTorque / maxTorque;
 
 					if (reserve >= 0 /*ModelData.TorqueReserve */ &&
-						IsAboveDownShiftCurve(nextGear, inTorque, inAngularVelocity, r.ElectricMotor.DeRatingActive)) {
+						IsAboveDownShiftCurve(nextGear, nextInTorque, nextInAngularVelocity, derated)) {
 						continue;
 					}
 
@@ -249,7 +256,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			) {
 				return currentGear;
 			}
-
+			if (_shiftStrategyParameters.AllowedGearRangeFC == 0) {
+				return currentGear;
+			}
+			
 			var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift;
 			var vehicleSpeedPostShift =
 				DataBus.VehicleInfo.VehicleSpeed - vDrop * _shiftStrategyParameters.VelocityDropFactor;
@@ -319,19 +329,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			if (!GearList.HasPredecessor(currentGear)) {
 				return currentGear;
 			}
-
-			if (response.ElectricMotor.DeRatingActive) {
-
-			}
+			var derated = response.ElectricMotor.DeRatingActive;
 			// check with shiftline
-			if (response.ElectricMotor.TorqueRequestEmMap != null && IsBelowDownShiftCurve(currentGear,
-				response.ElectricMotor.TorqueRequestEmMap,
-				response.ElectricMotor.AngularVelocity, response.ElectricMotor.DeRatingActive)) {
-
-				if (DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking) {
-					var brakingGear = SelectBrakingGear(currentGear, response);
-					return brakingGear;
-				}
+			if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity, derated)) {
+				inTorque = null;
+				inAngularVelocity = null;
+				
+				
+				 if (DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking) {
+				 	var brakingGear = SelectBrakingGear(currentGear, response);
+				 	return brakingGear;
+				 }
 
 				var nextGear = GearList.Predecessor(currentGear);
 				if (SpeedTooHighForEngine(nextGear, outAngularVelocity)) {
@@ -341,25 +349,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				while (GearList.HasPredecessor(nextGear)) {
 					// check skip gears
 					nextGear = GearList.Predecessor(nextGear);
-					var resp = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, nextGear);
+					var nextReponse = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, nextGear);
 
-					inAngularVelocity = resp.ElectricMotor.AngularVelocity;
-					inTorque = resp.ElectricMotor.PowerRequest / resp.ElectricMotor.AvgDrivetrainSpeed;
-
-					if (IsAboveUpShiftCurve(nextGear, inTorque, inAngularVelocity, resp.ElectricMotor.DeRatingActive)) {
+					var nextInAngularVelocity = nextReponse.Gearbox.InputSpeed;
+					var nextInTorque = nextReponse.Gearbox.InputTorque;
+					
+					if (IsAboveUpShiftCurve(nextGear, nextInTorque, nextInAngularVelocity, derated)) {
 						nextGear = GearList.Successor(nextGear);
 						break;
 					}
-
-					var maxTorque = VectoMath.Min(resp.ElectricMotor.MaxDriveTorque == null ? null : - resp.ElectricMotor.MaxDriveTorque,
-						!nextGear.Equals(GearList.First())
-							? GearboxModelData.Gears[nextGear.Gear].ShiftPolygon
-								.InterpolateDownshift(resp.Engine.EngineSpeed)
-							: double.MaxValue.SI<NewtonMeter>());
-					var reserve = 1 - inTorque / maxTorque;
+					
+					var maxDriveTorque = nextReponse.ElectricMotor.MaxDriveTorque; //Already on drivetrain side
+					
+					var isFirstGear = nextGear.Equals(GearList.First());
+					
+					var maxTorque = VectoMath.Min(
+					(maxDriveTorque == null
+								? null
+								: -maxDriveTorque
+					),
+					(!isFirstGear 
+								? GearboxModelData.Gears[nextGear.Gear].ShiftPolygon.InterpolateDownshift(nextInAngularVelocity)
+								: double.MaxValue.SI<NewtonMeter>()
+					));
+					var reserve = 1 - nextInTorque / maxTorque;
 
 					if (reserve >= 0 /*ModelData.TorqueReserve */ &&
-						IsBelowDownShiftCurve(nextGear, inTorque, inAngularVelocity, resp.ElectricMotor.DeRatingActive)) {
+						IsBelowDownShiftCurve(nextGear, nextInTorque, nextInAngularVelocity, derated)) {
 						continue;
 					}
 
@@ -370,7 +386,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 
 				return nextGear;
 			}
-
+			//Should not matter if calculated on gbx or em side.
 			if (response.ElectricMotor.TorqueRequestEmMap != null 
 				&& response.ElectricMotor.MaxRecuperationTorqueEM != null 
 				&& response.ElectricMotor.TorqueRequestEmMap.IsEqual(
@@ -385,14 +401,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		}
 
 		private GearshiftPosition SelectBrakingGear(GearshiftPosition currentGear, IResponse response)
-		{
+		{   
 			var tmpGear = new GearshiftPosition(currentGear.Gear, currentGear.TorqueConverterLocked);
 			var candidates = new Dictionary<GearshiftPosition, PerSecond>();
-			var gbxOutSpeed = response.Engine.EngineSpeed /
+			
+			var gbxOutSpeed = response.Gearbox.InputSpeed /
 							GearboxModelData.Gears[tmpGear.Gear].Ratio;
+			
+			
 			var firstGear = GearList.Predecessor(currentGear, 1);
 			var lastGear = GearList.Predecessor(currentGear, (uint)GearshiftParams.AllowedGearRangeFC);
-			var maxEmSpeed = DataBus.GetElectricMotors().First(x => x.Position != PowertrainPosition.GEN).MaxSpeed;
+
+			var electricMotor = DataBus.GetElectricMotors().First(x => x.Position != PowertrainPosition.GEN);
+			var maxEmSpeedDt = electricMotor.MaxSpeedDt; //Drivetrain
+			
 			foreach (var gear in GearList.IterateGears(firstGear, lastGear)) {
 				var ratio = gear.IsLockedGear()
 					? GearboxModelData.Gears[gear.Gear].Ratio
@@ -402,7 +424,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 					continue;
 				}
 
-				if (gbxInSpeed.IsGreater(maxEmSpeed)) {
+				if (gbxInSpeed.IsGreater(maxEmSpeedDt)) {
 					continue;
 				}
                 candidates[gear] = gbxInSpeed;
@@ -412,18 +434,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				return tmpGear;
 			}
 
-			var ratedSpeed = VoltageLevels.VoltageLevels.First().FullLoadCurve.RatedSpeed;
-			var maxSpeedNorm = VoltageLevels.MaxSpeed / ratedSpeed;
+
+
+			var ratedSpeed = electricMotor.RatedSpeedDt;
+			var maxSpeedNorm = maxEmSpeedDt / ratedSpeed;
 			var targetMotor = (_shiftStrategyParameters.PEV_TargetSpeedBrakeNorm * (maxSpeedNorm - 1) + 1) * ratedSpeed;
 
-			if (candidates.Any(x => x.Value > targetMotor / EMRatio && x.Value < VoltageLevels.MaxSpeed / EMRatio)) {
-				var best = candidates.Where(x => x.Value > targetMotor / EMRatio && x.Value < VoltageLevels.MaxSpeed / EMRatio)
+			if (candidates.Any(x => x.Value > targetMotor && x.Value < maxEmSpeedDt)) {
+				var best = candidates.Where(x => x.Value > targetMotor && x.Value < maxEmSpeedDt)
 					.OrderBy(x => x.Value).First();
 				return best.Key;
 			}
 
-			if (candidates.Any(x => x.Value < VoltageLevels.MaxSpeed / EMRatio))
-				return candidates.Where(x => x.Value < VoltageLevels.MaxSpeed / EMRatio).MaxBy(x => x.Value).Key;
+			if (candidates.Any(x => x.Value < maxEmSpeedDt))
+				return candidates.Where(x => x.Value < maxEmSpeedDt).MaxBy(x => x.Value).Key;
 			else {
 				return candidates.MaxBy(x => x.Value).Key;
 			}
@@ -439,14 +463,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				return currentGear;
 			}
 
+			if (_shiftStrategyParameters.AllowedGearRangeFC == 0) {
+				return currentGear;
+			}
+
 			var results = new List<Tuple<GearshiftPosition, double>>();
 			foreach (var tryNextGear in GearList.IterateGears(GearList.Predecessor(currentGear),
 				GearList.Predecessor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) {
 
 				var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear);
-				var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
-				var inTorque = response.ElectricMotor.PowerRequest / inAngularVelocity;
+				// var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
+				// var inTorque = response.ElectricMotor.PowerRequest / inAngularVelocity;
 
+				var inAngularVelocity = response.Gearbox.InputSpeed;
+				var inTorque = response.Gearbox.InputTorque;
+				
 				if (IsAboveUpShiftCurve(tryNextGear, inTorque, inAngularVelocity, response.ElectricMotor.DeRatingActive)) {
 					continue;
 				}
@@ -541,9 +572,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
                     Constants.SimulationSettings.MeasuredSpeedTargetTimeInterval, outTorque, outAngularVelocity,
                     true);
 
-                var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
-				var inTorque = response.ElectricMotor.PowerRequest / inAngularSpeed;
+    //             var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
+				// var inTorque = response.Gearbox.PowerRequest / inAngularSpeed;
 
+				var inAngularSpeed = response.Gearbox.InputSpeed;
+				var inTorque = response.Gearbox.InputTorque;
+				
 				// if in shift curve and torque reserve is provided: return the current gear
 				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed, false) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed, false)) {
 					_nextGear = gear;
@@ -700,7 +734,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		{
 			return
 				(outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed,
-					DataBus.ElectricMotorInfo(EMPos).MaxSpeed));
+					DataBus.ElectricMotorInfo(EMPos).MaxSpeedDt));
 		}
 
 		public void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) { }
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCalc/PEVAMTShiftStrategyPolygonCreator.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCalc/PEVAMTShiftStrategyPolygonCreator.cs
index e71334c296..f5827b0549 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCalc/PEVAMTShiftStrategyPolygonCreator.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCalc/PEVAMTShiftStrategyPolygonCreator.cs
@@ -35,21 +35,26 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.Shift
             throw new NotImplementedException("Not applicable to PEVAMT Gearbox.");
         }
 
-        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;
+		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), _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor);
+		}
+		
+		public ShiftPolygon ComputeDeclarationShiftPolygon(int i,
+			IList<ITransmissionInputData> gearboxGears, double axlegearRatio,
+			Meter dynamicTyreRadius,
+			ElectricMotorData electricMotorData, double? downshiftMaxSpeed, double? downshiftMinSpeed)
+		{
 			return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i,
-				electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve,
-				electricMotorData.RatioADC, gearboxGears, axlegearRatio, dynamicTyreRadius,
-				_shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed,
-				_shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
-			//return ComputeElectricMotorDeclarationShiftPolygon(gearboxType, i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData,
-			//             _shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
+				electricMotorData,  gearboxGears, downshiftMaxSpeed, downshiftMinSpeed);
 		}
 
 
@@ -57,13 +62,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.Shift
 			IList<ITransmissionInputData> gearboxGears, double axlegearRatio,
 			Meter dynamicTyreRadius,
 			ElectricMotorData electricMotorData, ElectricMotorData emDataLimited)
-        {
-			var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
-            return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i,
-				emDataLimited.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC,
-                gearboxGears, axlegearRatio, dynamicTyreRadius,
-				_shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor * emFld.RatedSpeed,
-				_shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
-        }
+		{
+			if (!electricMotorData.EfficiencyData.MaxSpeed.IsEqual(emDataLimited.EfficiencyData.MaxSpeed)) {
+				throw new VectoException("Limited em data should have the same max speed as the original data");
+			}
+			return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(
+				i,
+				emDataLimited,
+				gearboxGears,
+				_shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor.LimitTo(0, 1),
+				_shiftStrategyParameters.PEV_DownshiftMinSpeedFactor);
+
+			//         return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i,
+			// emDataLimited.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC,
+			//             gearboxGears, axlegearRatio, dynamicTyreRadius,
+			// _shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor,
+			// _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor);
+		}
     }
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
index 70ef9e9025..c98e1fc2f8 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
@@ -129,7 +129,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 				var pos = positions.First();
 				if (pos.IsBatteryElectric()) {
-					var maxEMSpeed = DataBus.ElectricMotorInfo(pos).MaxSpeed;
+					var maxEMSpeed = DataBus.ElectricMotorInfo(pos).MaxSpeedDt;
 
 					var ratio = 1.0;
 					if (pos == PowertrainPosition.BatteryElectricE3) {
@@ -142,7 +142,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 								(DataBus.AngledriveInfo?.Ratio ?? 1.0);
 
 						maxEMSpeed = VectoMath.Min(
-							DataBus.ElectricMotorInfo(pos).MaxSpeed,
+							DataBus.ElectricMotorInfo(pos).MaxSpeedDt,
 							DataBus.GearboxInfo.GetGearData(DataBus.GearboxInfo.NumGears).MaxSpeed);
 					}
 					MaxVehicleSpeed = maxEMSpeed / ratio * DataBus.WheelsInfo.DynamicTyreRadius * 0.995;
-- 
GitLab


From 10fa9c00cddeb1b5e533c52210b17419e2ed3db8 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 18 Mar 2025 11:55:18 +0100
Subject: [PATCH 19/22] Renamed IGearboxType to ITypedGearbox

---
 .../Models/SimulationComponent/IGearbox.cs         | 14 +++++++-------
 .../SimulationComponent/Impl/CycleGearbox.cs       |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
index b422e53999..2e41ad204d 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
@@ -43,16 +43,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 	/// </summary>
 	public interface IGearbox : IPowerTrainComponent, IGearboxInfo, IGearboxControl, IUpdateable { }
 
-	public interface IGearboxType : IGearbox {}
+	public interface ITypedGearbox : IGearbox {}
 
-	public interface IMTGearbox : IGearboxType {}
+	public interface IMTGearbox : ITypedGearbox {}
 
-	public interface IAMTGearbox : IGearboxType
+	public interface IAMTGearbox : ITypedGearbox
 	{
 		GearboxState GetPreviousState { get; }
 	}
 
-	public interface IAPTGearbox : IGearboxType
+	public interface IAPTGearbox : ITypedGearbox
 	{
 		ATGearboxState GetPreviousState { get; }
 		bool ShiftToLocked { get; }
@@ -61,11 +61,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 			PerSecond outAngularVelocity);
 	}
 
-	public interface IAPTNGearbox : IGearboxType { }
+	public interface IAPTNGearbox : ITypedGearbox { }
 
-	public interface IPEVGearbox : IGearboxType { }
+	public interface IPEVGearbox : ITypedGearbox { }
 
-	public interface IIEPCGearbox : IGearboxType { }
+	public interface IIEPCGearbox : ITypedGearbox { }
 
 	public interface ITorqueConverter : ITorqueConverterInfo, ITorqueConverterControl, IUpdateable { }
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
index 226212530a..81bd7362a1 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
@@ -51,7 +51,7 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
-	public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState>, IGearboxType
+	public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState>, ITypedGearbox
 	{
 		/// <summary>
 		/// True if gearbox is disengaged (no gear is set).
-- 
GitLab


From 083e77248038756c4b0b10be5411d97c4efeb00d Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 18 Mar 2025 13:32:12 +0100
Subject: [PATCH 20/22] Use IAPTGearbox in ATShiftStrategyOptimized.cs

---
 .../Models/SimulationComponent/IGearbox.cs    | 10 +++
 .../Impl/AbstractGearbox.cs                   |  2 +-
 .../Impl/Gearbox/APTGearbox.cs                | 24 ++++++-
 .../ATShiftStrategyOptimized.cs               | 64 +++++++++++--------
 4 files changed, 68 insertions(+), 32 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
index 2e41ad204d..81aa795e99 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
@@ -57,8 +57,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 		ATGearboxState GetPreviousState { get; }
 		bool ShiftToLocked { get; }
 		IIdleController IdleController { set; }
+		bool TorqueConverterLocked { get; }
+
+		
+		
 		ResponseDryRun Initialize(GearshiftPosition gear, NewtonMeter outTorque,
 			PerSecond outAngularVelocity);
+
+		new bool Disengaged { get; set; }
+		KilogramSquareMeter EngineInertia { get; }
+		TorqueConverter TorqueConverter { get; }
+
+		WattSecond ComputeShiftLosses(NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGearPos);
 	}
 
 	public interface IAPTNGearbox : ITypedGearbox { }
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
index fa9c458ef3..962f08e873 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
@@ -152,7 +152,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return nextGear.TorqueConverterLocked.HasValue && nextGear.TorqueConverterLocked.Value;
 		}
 
-		protected internal WattSecond ComputeShiftLosses(NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition gear)
+		public WattSecond ComputeShiftLosses(NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition gear)
 		{
 			var ratio = ModelData.Gears[gear.Gear].Ratio;
 			if (double.IsNaN(ratio)) {
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
index c5e91915bb..47c608f540 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
@@ -51,17 +51,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox
 	public class APTGearbox : AbstractGearbox<ATGearboxState>, IHybridControlledGearbox, IAPTGearbox
     {
         protected internal readonly IShiftStrategy _strategy;
-        protected internal readonly TorqueConverter TorqueConverter;
+
         private IIdleController _idleController;
 
         internal WattSecond _powershiftLossEnergy;
-        protected internal KilogramSquareMeter EngineInertia;
 
         public bool TorqueConverterLocked => CurrentState.Gear.TorqueConverterLocked.Value;
 
         //set { CurrentState.TorqueConverterLocked = value; }
         public override bool TCLocked => Gear.TorqueConverterLocked.Value;
 
+        public TorqueConverter TorqueConverter
+        {
+            get;
+            private set;
+        }
+
+        // public WattSecond ComputeShiftLosses(NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGearPos)
+        // {
+        //     return base.ComputeShiftLosses(outTorque, outAngularVelocity, nextGearPos);
+        // }
+
+        public KilogramSquareMeter EngineInertia
+        {
+            get;
+            private set;
+        }
+        
         public APTGearbox(IVehicleContainer container, IShiftStrategy strategy)
             : this(container, strategy, false)
         {
@@ -607,7 +623,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox
 
 		public ATGearboxState GetPreviousState => PreviousState.Clone();
 
-		#endregion
+
+
+        #endregion
 	}
 
 	public class ATGearboxState : GearboxState
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
index 1c28784d5c..59737053e1 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
@@ -648,15 +648,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
             if (shiftTimeReached && Container.DriverInfo.DrivingAction == DrivingAction.Accelerate) {
                 if (Container.VehicleInfo.VehicleSpeed < Container.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() &&
                     Container.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) {
-                    var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+					var currentGear = gear;
+					var tmpResponseCurr = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, gear);
+					
+                    // var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
                     if (_gearbox.Gear > Gears.First()) {
+						// var tmpGear = 
+						
                         // 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);
+                        // 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);
+						var tmpGear = Gears.Predecessor(currentGear);
+						var tmpResponseDs = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tmpGear);
+						
                         // done
                         if (tmpResponseDs.Engine.EngineSpeed.IsSmaller(Container.EngineInfo.EngineN95hSpeed) && tmpResponseDs.DeltaFullLoad - Formulas.InertiaPower(
                                 tmpResponseDs.Engine.EngineSpeed, Container.EngineInfo.EngineSpeed, EngineInertia, dt) < tmpResponseCurr.DeltaFullLoad) {
@@ -773,12 +781,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			_nextGear.SetState(absTime, false, Gears.Predecessor(gear));
 		}
 
-		protected virtual void SetGear(NextGearState gbxState)
-		{
-			_gearbox.Gear = gbxState.Gear;
-			//_gearbox.TorqueConverterLocked = gbxState.TorqueConverterLocked;
-			_gearbox.Disengaged = gbxState.Disengaged;
-		}
+		// protected virtual void SetGear(NextGearState gbxState)
+		// {
+		// 	_gearbox.Gear = gbxState.Gear;
+		// 	//_gearbox.TorqueConverterLocked = gbxState.TorqueConverterLocked;
+		// 	_gearbox.Disengaged = gbxState.Disengaged;
+		// }
 
         private double GetFCRating(PerSecond engineSpeed, NewtonMeter tqCurrent)
 		{
@@ -899,10 +907,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				Gear = nextGearState.Gear;
 			}
 
-			public NextGearState(Second absTime, APTGearbox gearbox)
-			{
-				SetState(absTime, gearbox);
-			}
+			// public NextGearState(Second absTime, IAPTGearbox gearbox)
+			// {
+			// 	SetState(absTime, gearbox);
+			// }
 
 			public void SetState(Second absTime, bool disengaged, GearshiftPosition gear)
 			{
@@ -911,17 +919,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 				Gear = gear;
 			}
 
-			public void SetState(Second absTime, APTGearbox gearbox)
-			{
-				AbsTime = absTime;
-				Disengaged = gearbox.Disengaged;
-				Gear = gearbox.Gear;
-			}
-
-			public NextGearState Clone()
-			{
-				return new NextGearState(this);
-			}
+			// public void SetState(Second absTime, IAPTGearbox gearbox)
+			// {
+			// 	AbsTime = absTime;
+			// 	Disengaged = gearbox.Disengaged;
+			// 	Gear = gearbox.Gear;
+			// }
+			//
+			// public NextGearState Clone()
+			// {
+			// 	return new NextGearState(this);
+			// }
 		}
     }
 }
-- 
GitLab


From d946af37b59c6ee236f3325693ea2e11155e6dc8 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 18 Mar 2025 14:13:22 +0100
Subject: [PATCH 21/22] Added APTN ShiftStrategyTests

---
 .../APTNShiftStrategyTests.cs                 | 2004 +++++++++++++++++
 1 file changed, 2004 insertions(+)
 create mode 100644 Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs
new file mode 100644
index 0000000000..69476d7097
--- /dev/null
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs	
@@ -0,0 +1,2004 @@
+using Moq;
+using NUnit.Framework;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData.Impl;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
+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;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
+using TUGraz.VectoCore.Models.SimulationComponent.Strategies;
+using TUGraz.VectoCore.Tests.Utils;
+using TUGraz.VectoCore.Utils;
+using Range = System.Range;
+
+namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
+{
+	[TestFixture]
+	public class APTNShiftStrategyTests
+	{
+		[TestCase(500, 80, 1)]
+		[TestCase(5, 500, 2)]
+		public void InitGear(double torque_Nm, double speed_rpm, int expectedGear)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+
+            var container = GetMocks(ratios);
+
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var torque = torque_Nm.SI<NewtonMeter>();
+			var speed = speed_rpm.RPMtoRad();
+
+			var result = shiftStrategy.InitGear(absTime, dt, torque, speed);
+
+			var newGear = result.Gear;
+			Assert.AreEqual(expectedGear, newGear);
+
+
+
+		}
+		
+		[TestCase(5000, 80, 1)]
+		[TestCase(5, 500, 2)]
+		public void InitStartGear(double torque_Nm, double speed_rpm, int expectedGear)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+
+			var container = GetMocks(ratios);
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(0.KMPHtoMeterPerSecond());
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var torque = torque_Nm.SI<NewtonMeter>();
+			var speed = speed_rpm.RPMtoRad();
+
+			var result = shiftStrategy.InitGear(absTime, dt, torque, speed);
+
+			var newGear = result.Gear;
+			Assert.AreEqual(expectedGear, newGear);
+
+
+
+		}
+
+		[TestCase(
+			500,
+			80,
+			500,
+			10000,
+			1,
+			2, TestName = "Emergency UpShift")]
+
+		[TestCase(
+			500,
+			80,
+			1000,
+			1800,
+			1,
+			2, TestName = "UpShift")]
+		[TestCase(
+			500,
+			80,
+			1000,
+			800,
+			1,
+			1, TestName = "No Upshift")]
+		public void Upshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			CheckUpshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, false);
+		}
+		
+		
+		public void CheckUpshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear, bool effShift)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+
+			if (!effShift) {
+				DisableEffshift(container.Object.RunData);
+			}
+
+		
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			// var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+			var response = new ResponseSuccess(this);
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity.AsRPM} [rpm]\n" + 
+				$"InSpeed: {inAngularVelocity.AsRPM} [rpm]\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result);
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+			
+			
+			
+		}
+
+		[TestCase(
+			500,
+			80,
+			-10,
+			1000,
+			1,
+			2, TestName = "UpShift")]
+		public void EarlyUpshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratios = new[] { 0.0, 3.86, 1.93 };
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(20.KMPHtoMeterPerSecond());
+
+		
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+			var response = new ResponseSuccess(this);
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity.AsRPM} [rpm]\n" + 
+				$"InSpeed: {inAngularVelocity.AsRPM} [rpm]\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result);
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+
+
+		}
+		
+		[TestCase(
+			5,
+			200,
+			2000,
+			200,
+			2,
+			1, TestName = "Downshift")]
+		public void Downshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear, int speedKmh=1)
+		{
+			var ratios = new[] { 0.0,  3.86, 1.93 };
+			CheckDownshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, ratios, false, speedKmh);
+		}
+		
+		[TestCase(
+			5,
+			200,
+			-500,
+			200,
+			4,
+			2, 
+			40, TestName = "EarlyDownshift")]
+		public void EarlyDownshift(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear, int speedKmh=1)
+		{
+			var ratios = new[] { 0.0, 3.86, 3, 2.5, 1.93 };
+			CheckDownshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, ratios, true, speedKmh);
+		}
+
+		[TestCase(
+			5,
+			200,
+			2000,
+			40,
+			4,
+			2, TestName = "Downshift_SkipGear")]
+		public void DownshiftSkipGears(double init_outTorque_Nm, double init_outSpeed_rpm, double outTorque_Nm,
+			double outSpeed_rpm, int currentGear, int expectedGear)
+		{
+			var ratios = new[] { 0.0, 3.86, 3,  2.5, 1.93 };
+			CheckDownshift(init_outTorque_Nm, init_outSpeed_rpm, outTorque_Nm, outSpeed_rpm, currentGear, expectedGear, ratios, false);
+		}
+
+		private void DisableEffshift(VectoRunData runData)
+		{
+			TestContext.WriteLine("EffShift Disabled");
+			runData.GearshiftParameters.AllowedGearRangeFC = 0;
+		}
+
+		private void DisableEffshift(Mock<IVehicleContainer> vehicleContainer)
+		{
+			DisableEffshift(vehicleContainer.Object.RunData);
+		}
+		
+		public void CheckDownshift(
+			double init_outTorque_Nm,
+			double init_outSpeed_rpm,
+			double outTorque_Nm, 
+			double outSpeed_rpm, 
+			int currentGear,
+			int expectedGear, 
+			double[] ratios,
+			bool effShift = true,
+			int vehicleSpeed_kmH = 1)
+		{
+			// the first element 0.0 is just a placeholder for axlegear, not used in this test
+			var ratio = ratios[currentGear];
+			var container = GetMocks(ratios);
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(vehicleSpeed_kmH.KMPHtoMeterPerSecond());
+
+			
+			if (!effShift) {
+				DisableEffshift(container.Object.RunData);
+			}
+			
+			var shiftRequired = currentGear != expectedGear;
+			
+			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
+			var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
+			
+			var absTime = 0.SI<Second>();
+			var dt = 0.5.SI<Second>();
+
+			var init_outTorque = init_outTorque_Nm.SI<NewtonMeter>();
+			var init_outAngularVelocity = init_outSpeed_rpm.RPMtoRad();
+			
+			var outTorque = outTorque_Nm.SI<NewtonMeter>();
+			var outAngularVelocity = outSpeed_rpm.RPMtoRad();
+			
+			var inTorque = outTorque / ratio;
+			var inAngularVelocity = outAngularVelocity * ratio;
+			
+			var lastShiftTime = float.MinValue.SI<Second>();
+
+
+			
+			Console.WriteLine(
+				$"OutTorque: {outTorque}\n" +
+				$"InTorque: {inTorque} \n" +
+				$"OutSpeed: {outAngularVelocity}\n" + 
+				$"InSpeed: {inAngularVelocity}\n");
+			
+			
+			//Init gear
+			var initResult = shiftStrategy.InitGear(absTime, dt, init_outTorque, init_outAngularVelocity);
+			Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(currentGear));
+			
+			var response = new ResponseSuccess(this) { };
+			response.ElectricMotor.AngularVelocity = inAngularVelocity;
+			response.ElectricMotor.TorqueRequestEmMap = inTorque;
+			response.ElectricMotor.DeRatingActive = false;
+			// response.ElectricMotor;
+			
+			//Check shift required
+			var result = shiftStrategy.ShiftRequired(absTime, dt,
+				outTorque: outTorque,
+				outAngularVelocity: outAngularVelocity,
+				inTorque: inTorque,
+				inAngularVelocity: inAngularVelocity,
+				gear: shiftStrategy.NextGear,
+				lastShiftTime: lastShiftTime,
+				response: response);
+
+			Assert.AreEqual(shiftRequired, result, "Expected Shift");
+			Assert.AreEqual(expectedGear, shiftStrategy.NextGear.Gear);
+			
+			
+			
+		}
+		
+		
+		
+		
+		
+		private PEVAMTShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container, out IEPCGearbox gearbox)
+		{
+			var shiftStrategy = new APTNShiftStrategy(container.Object);
+
+			var gbxFactory = new Mock<IIEPCGearboxFactory>();
+			gbxFactory.Setup(g => g.CreateIEPCGearbox(
+				false,
+				It.IsAny<IVehicleContainer>(),
+				It.IsAny<IShiftStrategy>())).Returns(
+				(bool singleSpeed, IVehicleContainer container, IShiftStrategy shiftStrategy) => {
+					return new IEPCGearboxMultipleGears(container, shiftStrategy);
+				});
+			
+			gearbox = new IEPCGearbox(container.Object, 
+				shiftStrategy, gbxFactory.Object);
+
+			SetVelocityDropLookupData(shiftStrategy);
+			
+			container.Setup(c => c.GearboxInfo).Returns(gearbox);
+			
+			
+			return shiftStrategy;
+		}
+
+		private Mock<IVehicleContainer> GetMocks(double[] ratios)
+		{
+			var container = new Mock<IVehicleContainer>();
+
+			//RunData
+			var runData = GetRunData(ratios);
+			container.Setup(r => r.RunData).Returns(runData);
+
+			//EmInfo
+			var em = GetElectricMotor(container.Object, runData.ElectricMachinesData.Single().Item2);
+			container.Setup(c => c.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2))
+				.Returns(em);
+			container.Setup(c => c.PowertrainInfo.ElectricMotorPositions).Returns(new[] {
+				PowertrainPosition.BatteryElectricE2
+			});
+			
+			// container.Setup(r => r.GetElectricMotors()).Returns(new List<IElectricMotorInfo>(){em});
+			
+			container.Setup(c => c.PowertrainInfo.HasCombustionEngine).Returns(false);
+
+			//BatteryInfo
+			container.Setup(c => c.BatteryInfo.InternalVoltage).Returns(700.SI<Volt>());
+			
+			//VehicleInfo
+			container.Setup(c => c.VehicleInfo.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
+			container.Setup(c => c.VehicleInfo.VehicleStopped).Returns(false);
+			
+			//DriverInfo
+			container.Setup(c => c.DriverInfo.DriverBehavior).Returns(DrivingBehavior.Accelerating);
+			container.Setup(c => c.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+			// container.Set
+			
+			//PowertrainBuilder, SimplePowertrain
+			var testPt = GetTestPowertrain(ratios, container, out _);
+			var ptBuilder = new Mock<ISimplePowertrainBuilder>();
+			ptBuilder.Setup(c => c.CreateTestPowertrain(
+					It.IsAny<IVehicleContainer>(), It.IsAny<bool>()))
+				.Returns(testPt.Object);
+			ptBuilder.Setup(c => c.CreateTestPowertrain(
+					It.IsAny<IVehicleContainer>(), It.IsAny<bool>(), It.IsAny<VectoSimulationJobType>()))
+				.Returns(testPt.Object);
+			container.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
+
+			//DrivingCycleInfo
+			container.Setup(c => c.DrivingCycleInfo.RoadGradient).Returns(0.SI<Radian>());
+
+			return container;
+		}
+		
+		private ElectricMotor GetElectricMotor(IVehicleContainer container, ElectricMotorData emData)
+		{
+			var emControl = new SimpleElectricMotorControl();
+			
+			var electricMotor = new ElectricMotor(container: container, emData, emControl,
+				PowertrainPosition.BatteryElectricE2);
+
+			//Connect Electric System
+			var es = GetMockElectricSystem();
+			electricMotor.Connect(es.Object);
+			return electricMotor;
+		}
+		
+		private TestPowertrainElectricMotor GetTestPowertrainElectricMotor(ISimpleVehicleContainer container,
+			ElectricMotorData emData)
+		{
+			var emControl = new SimpleElectricMotorControl();
+			
+			var electricMotor = new TestPowertrainElectricMotor(container: container, emData, emControl,
+				PowertrainPosition.BatteryElectricE2);
+
+			//Connect Electric System
+			var es = GetMockElectricSystem();
+			electricMotor.Connect(es.Object);
+			return electricMotor;
+		}
+
+		private Mock<ITestPowertrain> GetTestPowertrain(double[] ratios, 
+			Mock<IVehicleContainer> container,
+			out Mock<ISimpleVehicleContainer> simplePt)
+		{
+			var testPt = new Mock<ITestPowertrain>();
+			simplePt = GetSimplePowertrain(ratios, container, out var gbx);
+			var simplePtObj = simplePt.Object;
+			testPt.Setup(t => t.ElectricMotors).Returns(() => {
+				var dict = new Dictionary<PowertrainPosition, ITestpowertrainElectricMotor>();
+				foreach (var (k, v) in simplePtObj.ElectricMotors) {
+					if (v is ITestpowertrainElectricMotor testEm) {
+						dict[k] = testEm;
+					} else {
+						throw new Exception("Expected TestElectricMotor in simple powertrain");
+					}
+				}
+				return dict;
+			});
+
+			testPt.Setup(t => t.Container).Returns(simplePt.Object);
+			
+			testPt.Setup(t => t.Gearbox).Returns(gbx.Object);
+			return testPt;
+		}
+		
+		private Mock<IElectricSystem> GetMockElectricSystem()
+		{
+			var electricSystem = new Mock<IElectricSystem>();
+			
+			
+			electricSystem
+				.Setup(es => es.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<Watt>(), true))
+				.Returns((Second t, Second dt, Watt powerDemand, bool dryrun) => {
+					
+					var response = new Mock<IElectricSystemResponse>();
+					response
+						.Setup(mr => mr.MaxPowerDrive)
+						.Returns(-100E3.SI<Watt>());
+					response
+						.Setup(mr => mr.MaxPowerDrag)
+						.Returns(100E3.SI<Watt>());
+					response
+						.Setup(mr => mr.RESSPowerDemand).Returns(powerDemand);
+						
+						
+					
+					
+					return response.Object;
+				});
+
+
+			return electricSystem;
+		}
+		
+		private ElectricMotor GetMockElectricMotor(IVehicleContainer container, ElectricMotorData emData)
+		{
+			var emControl = new SimpleElectricMotorControl();
+			
+			var electricMotor = new ElectricMotor(container: container, emData, emControl,
+				PowertrainPosition.BatteryElectricE2);
+
+			//Connect Electric System
+			var es = GetMockElectricSystem();
+			electricMotor.Connect(es.Object);
+			return electricMotor;
+		}
+		
+		private Mock<ISimpleVehicleContainer> GetSimplePowertrain(
+			double[] ratios, 
+			Mock<IVehicleContainer> container, 
+			out Mock<ITestPowertrainTransmission> testGbx)
+		{
+			var simplePt = new Mock<ISimpleVehicleContainer>();
+			simplePt.Setup(s => s.IsTestPowertrain).Returns(true);
+			
+			
+			var components = new List<VectoSimulationComponent>();
+			
+			var runData = container.Object.RunData;
+			var em = GetTestPowertrainElectricMotor(simplePt.Object, runData.ElectricMachinesData.Single().Item2);
+			var emDict = new Dictionary<PowertrainPosition, IElectricMotorInfo>() {
+				{ PowertrainPosition.BatteryElectricE2, em },
+			};
+			simplePt.Setup(r => r.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2))
+				.Returns(em);
+
+			//BatteryInfo
+			simplePt.Setup(s => s.BatteryInfo.InternalVoltage).Returns(700.SI<Volt>());
+
+			simplePt.Setup(s => s.ElectricMotors).Returns(emDict);
+
+			simplePt.Setup(s => s.PowertrainInfo.HasCombustionEngine).Returns(false);
+			
+			simplePt.Setup(s => s.RunData).Returns(runData);
+
+			testGbx = GetTestGearbox(simplePt.Object, em, runData.GearboxData.Gears);
+			
+			simplePt.Setup(s => s.GearboxCtl).Returns(testGbx.Object);
+			simplePt.Setup(s => s.GearboxInfo).Returns(testGbx.Object);
+			simplePt.Setup(s => s.GearboxOutPort).Returns(testGbx.Object);
+			
+			simplePt.Setup(s => s.SimulationComponents()).Returns(components);
+			simplePt.Setup(s => s.Brakes).Returns(new Mock<IBrakes>().Object);
+
+			//Take from real powertrain
+			simplePt.Setup(s => s.VehicleInfo).Returns(container.Object.VehicleInfo);
+			simplePt.Setup(s => s.DriverInfo).Returns(container.Object.DriverInfo);
+			
+			return simplePt;
+		}
+
+		Mock<ITestPowertrainTransmission> GetTestGearbox(
+			ISimpleVehicleContainer simpleContainer,
+			TestPowertrainElectricMotor em,
+			Dictionary<uint, GearData> ratios)
+		{
+			Mock<IAMTGearbox> amtGearbox = new Mock<IAMTGearbox>();
+			amtGearbox.Name = "PEVAMT_TestGearbox";
+			Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
+			
+			gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+			gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+			GearshiftPosition gear = null;
+			gbx.SetupGet(g => g.Gear).Returns(() => gear);
+			gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+				.Callback<GearshiftPosition>(p => {
+					gear = p;
+				});
+
+		
+			GearshiftPosition nextGear = null;
+			gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+			gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+				.Callback<GearshiftPosition>(p => nextGear = p);
+				
+			
+			gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+				It.IsAny<PerSecond>())).Returns((NewtonMeter outTorque, PerSecond outSpeed) => {
+				var ratio =
+					gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+				
+				var inSpeed = outSpeed * ratio;
+				var inTorque = outTorque / ratio;
+				
+				em.Initialize(inTorque, inSpeed);
+				return new ResponseSuccess(this)
+				{
+					
+				};
+			});
+			gbx.Setup(p => p.Request(
+				It.IsAny<Second>(),
+				It.IsAny<Second>(),
+				It.IsAny<NewtonMeter>(),
+				It.IsAny<PerSecond>(),
+				true)).Returns((
+				Second absTime,
+				Second dt,
+				NewtonMeter outTorque,
+				PerSecond outSpeed,
+				bool dryRun) => {
+		
+				var ratio =
+					gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+
+				var inSpeed = outSpeed * ratio;
+				var inTorque = outTorque / ratio;
+
+				var emResponse = em.Request(absTime, dt, inTorque, inSpeed, dryRun);
+				return dryRun
+					? new ResponseDryRun(this, emResponse) {
+						// Engine = {
+						// 	PowerRequest = n * t, EngineSpeed = n * ratio,
+						// 	DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						// 	TotalTorqueDemand = t,
+						// },
+						// ElectricMotor = emResponse.ElectricMotor,
+						Gearbox = {
+							Gear = gbx.Object.Gear,
+							InputSpeed = inSpeed,
+							InputTorque = inTorque,
+							OutputSpeed = outSpeed,
+							OutputTorque = outTorque,
+							PowerRequest = outSpeed * outTorque,
+						},
+						Clutch = { PowerRequest = outSpeed * outTorque },
+						DeltaFullLoad = outSpeed * outTorque / 2 * (-1)
+					}
+					: new ResponseSuccess(this) {
+						Gearbox = {
+							Gear = gbx.Object.Gear,
+							InputSpeed = inSpeed,
+							InputTorque = inTorque,
+						},
+						Clutch = { PowerRequest = outSpeed * outTorque }
+					};
+			});
+			return gbx;
+		}
+
+
+		private VectoRunData GetRunData(double[] ratios)
+		{
+			var runData = new VectoRunData();
+
+			//GearShiftParameters
+			var gearshiftParameters = new ShiftStrategyParameters() {
+				TorqueReserve = 0.0,
+				TimeBetweenGearshifts = 2.SI<Second>(),
+				DownshiftAfterUpshiftDelay = 2.SI<Second>(),
+				UpshiftAfterDownshiftDelay = 2.SI<Second>(),
+				UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>(),
+				StartSpeed = 0.KMPHtoMeterPerSecond(),
+				RatingFactorCurrentGear = 1,
+				AllowedGearRangeFC = 2,
+				MinEngineSpeedPostUpshift = 0.RPMtoRad(),
+			};
+			runData.GearshiftParameters = gearshiftParameters;
+
+			runData.ElectricMachinesData = GetElectricMachinesData();
+			var emData = runData.ElectricMachinesData.Single(i => i.Item1 == PowertrainPosition.BatteryElectricE2)
+				.Item2;
+			//VehicleData
+			var vehicleData = new VehicleData() {
+				DynamicTyreRadius = 0.492.SI<Meter>(),
+            };
+			runData.VehicleData = vehicleData;
+
+			//CycleData 
+			var mockCycle = new Mock<IDrivingCycleData>();
+			mockCycle.Setup(cd => cd.Entries).Returns(
+				new List<DrivingCycleData.DrivingCycleEntry>() {
+					new DrivingCycleData.DrivingCycleEntry() {
+						RoadGradient = 0.SI<Radian>()
+					}
+				});
+			runData.Cycle = mockCycle.Object;
+			
+
+            //Gearboxdata
+			var gearboxInputData = new Mock<IGearboxDeclarationInputData>();
+
+			var gearsInputData = new List<Mock<ITransmissionInputData>>();
+
+			gearboxInputData.Setup(
+				d => d.Gears)
+				.Returns(gearsInputData.Select(m => m.Object)
+				.ToList());
+
+
+			var gearboxData = new GearboxData() {
+				Gears = new Dictionary<uint, GearData>(ratios.Length),
+				InputData = gearboxInputData.Object,
+				Type = GearboxType.AMT,
+				TractionInterruption = 1.SI<Second>(),
+				Inertia = 0.SI<KilogramSquareMeter>(),
+			};
+			
+
+
+
+			
+			runData.GearboxData = gearboxData;
+			for (uint i = 1; i < ratios.Length; i++) {
+				gearboxData.Gears[i] = new GearData
+				{
+					Ratio = ratios[i],
+					LossMap = TransmissionLossMapReader.Create(0.96, ratios[i], $"Gear {i}"),
+
+				};
+			}
+			var axlRatio = 3.240355;
+			var gearsInput = gearboxData.Gears.Select(x => {
+				var r = new Mock<ITransmissionInputData>();
+				r.Setup(g => g.Ratio).Returns(x.Value.Ratio);
+				r.Setup(g => g.MaxTorque).Returns(x.Value.MaxTorque);
+				r.Setup(g => g.MaxInputSpeed).Returns(x.Value.MaxSpeed);
+				
+				return r.Object;
+			}).ToList();
+			foreach (var entry in gearboxData.Gears) {
+				var gearIdx = (int)entry.Key - 1;
+				var dynamicTyreRadius = 0.5.SI<Meter>();
+
+				var shiftPolygon = DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(
+					gearIdx,
+					emData,
+					gearsInput);
+					
+				entry.Value.ShiftPolygon = shiftPolygon;
+
+			}
+
+
+			return runData;
+		}
+
+		private IList<Tuple<PowertrainPosition, ElectricMotorData>> GetElectricMachinesData()
+		{
+			//Nr of electric machines
+			const int emCount = 2;
+			//ElectricMachines
+			// var electricMotorData = new ElectricMotorData() {
+			// 	
+			// };
+			var emDataAdapter = new ElectricMachinesDataAdapter();
+			var emInputData = new Mock<IElectricMotorDeclarationInputData>();
+
+			var powerMapMock = new Mock<IElectricMotorPowerMap>();
+			powerMapMock.Setup(pm => pm.Gear).Returns(0);
+			powerMapMock.Setup(pm => pm.PowerMap).Returns(GetEfficiencyMapData());
+			
+			var voltageLevels = new List<IElectricMotorVoltageLevel>() {
+				new ElectricMotorVoltageLevel(){
+					VoltageLevel = 100.SI<Volt>(),
+					ContinuousTorque = 450.SI<NewtonMeter>(),
+					ContinuousTorqueSpeed = 2460.RPMtoRad(),
+					OverloadTorque = 485.SI<NewtonMeter>(),
+					OverloadTestSpeed = 2460.RPMtoRad(),
+					OverloadTime = 120.SI<Second>(),
+					FullLoadCurve = GetFullLoadCurveData(),
+					PowerMap = new List<IElectricMotorPowerMap>(){powerMapMock.Object}
+				},
+				new ElectricMotorVoltageLevel(){
+					VoltageLevel = 1000.SI<Volt>(),
+					ContinuousTorque = 450.SI<NewtonMeter>(),
+					ContinuousTorqueSpeed = 2460.RPMtoRad(),
+					OverloadTorque = 485.SI<NewtonMeter>(),
+					OverloadTestSpeed = 2460.RPMtoRad(),
+					OverloadTime = 120.SI<Second>(),
+					FullLoadCurve = GetFullLoadCurveData(),
+					PowerMap = new List<IElectricMotorPowerMap>(){powerMapMock.Object}
+				}
+			};
+			
+			emInputData.Setup(em => em.CertificationMethod).Returns(CertificationMethod.Measured);
+			emInputData.Setup(em => em.Inertia).Returns(0.225.SI<KilogramSquareMeter>());
+			emInputData.Setup(em => em.R85RatedPower).Returns(250E3.SI<Watt>());
+			emInputData.Setup(em => em.ElectricMachineType).Returns(ElectricMachineType.ASM);
+			emInputData.Setup(em => em.VoltageLevels).Returns(voltageLevels);
+			emInputData.Setup(em => em.DragCurve).Returns(GetDragCurveData);
+			
+			var adcInputData = new Mock<IADCDeclarationInputData>();
+			adcInputData.Setup(adc => adc.Ratio).Returns(1.0f);
+			
+			var emsInputData = new Mock<IElectricMachinesDeclarationInputData>();
+			emsInputData.Setup(em => em.Entries).Returns(
+				new List<ElectricMachineEntry<IElectricMotorDeclarationInputData>>() {
+					new ElectricMachineEntry<IElectricMotorDeclarationInputData>() {
+						Count = emCount,
+						Position = PowertrainPosition.BatteryElectricE2,
+						ElectricMachine = emInputData.Object,
+						ADC = adcInputData.Object,
+						RatioADC = 2.0,
+						MechanicalTransmissionEfficiency = 0.97,
+					}
+				});
+			
+			var avgVoltage = 200.SI<Volt>();
+			IDictionary<PowertrainPosition, IList<Tuple<Volt, TableData>>> torqueLimits = new Dictionary<PowertrainPosition, IList<Tuple<Volt, TableData>>>();
+			
+			var electricMachinesData = emDataAdapter.CreateElectricMachines(emsInputData.Object, torqueLimits:torqueLimits, 
+				avgVoltage, null);
+
+			
+			
+			
+
+			return electricMachinesData;
+		
+		}
+
+		private TableData GetDragCurveData()
+		{
+			return InputDataHelper.InputDataAsTableData(
+				"n [rpm] , T_drag [Nm]",
+				"0       , -6.06",
+				"7363.77    , -30.31");
+		}
+
+
+		private TableData GetFullLoadCurveData()
+		{
+			return InputDataHelper.InputDataAsTableData("n [rpm] , T_drive [Nm] , T_drag [Nm]",
+				#region data
+				"0,485,-485",
+"2461.158914,485,-485",
+"2452.135493,485,-485",
+"2466.863034,483.8845,-483.8845",
+"2481.590574,481.010875,-481.010875",
+"2496.318115,478.173625,-478.173625",
+"2503.681885,476.767125,-476.767125",
+"2577.319588,463.138625,-463.138625",
+"2650.95729,450.274,-450.274",
+"2724.594993,438.1005,-438.1005",
+"2798.232695,426.58175,-426.58175",
+"2871.870398,415.645,-415.645",
+"2945.5081,405.253875,-405.253875",
+"3019.145803,395.359875,-395.359875",
+"3092.783505,385.950875,-385.950875",
+"3166.421208,376.978375,-376.978375",
+"3240.05891,368.406,-368.406",
+"3313.696613,360.221625,-360.221625",
+"3387.334315,352.388875,-352.388875",
+"3460.972018,344.895625,-344.895625",
+"3534.60972,337.7055,-337.7055",
+"3608.247423,330.8185,-330.8185",
+"3681.885125,324.19825,-324.19825",
+"3755.522828,317.84475,-317.84475",
+"3829.16053,311.73375,-311.73375",
+"3902.798233,305.853125,-305.853125",
+"3976.435935,300.178625,-300.178625",
+"4050.073638,294.722375,-294.722375",
+"4123.71134,289.460125,-289.460125",
+"4197.349043,284.37975,-284.37975",
+"4270.986745,279.48125,-279.48125",
+"4344.624448,274.740375,-274.740375",
+"4418.26215,270.16925,-270.16925",
+"4491.899853,265.7315,-265.7315",
+"4565.537555,261.451375,-261.451375",
+"4639.175258,257.304625,-257.304625",
+"4712.81296,253.279125,-253.279125",
+"4786.450663,249.387,-249.387",
+"4860.088365,245.604,-245.604",
+"4933.726068,241.94225,-241.94225",
+"5007.36377,238.3775,-238.3775",
+"5081.001473,234.921875,-234.921875",
+"5154.639175,231.575375,-231.575375",
+"5228.276878,228.31375,-228.31375",
+"5301.91458,225.137,-225.137",
+"5375.552283,222.05725,-222.05725",
+"5449.189985,219.05025,-219.05025",
+"5522.827688,216.128125,-216.128125",
+"5596.46539,213.290875,-213.290875",
+"5670.103093,210.51425,-210.51425",
+"5743.740795,207.8225,-207.8225",
+"5817.378498,205.191375,-205.191375",
+"5891.0162,202.620875,-202.620875",
+"5964.653903,200.123125,-200.123125",
+"6038.291605,197.686,-197.686",
+"6111.929308,195.297375,-195.297375",
+"6185.56701,192.969375,-192.969375",
+"6259.204713,190.702,-190.702",
+"6332.842415,188.483125,-188.483125",
+"6406.480118,186.324875,-186.324875",
+"6480.11782,184.203,-184.203",
+"6553.755523,182.129625,-182.129625",
+"6627.393225,180.10475,-180.10475",
+"6701.030928,178.128375,-178.128375",
+"6774.66863,176.2005,-176.2005",
+"6848.306333,174.296875,-174.296875",
+"6921.944035,172.44175,-172.44175",
+"6995.581738,170.635125,-170.635125",
+"7069.21944,168.85275,-168.85275",
+"7142.857143,167.10675,-167.10675",
+"7216.494845,165.40925,-165.40925",
+"7290.132548,163.736,-163.736",
+"7363.77025,162.099125,-162.099125"
+				#endregion data
+			);
+		}
+		private ElectricMotorFullLoadCurve GetFullLoadCurve(int count)
+		{
+			var inputData = GetFullLoadCurveData();
+			return ElectricFullLoadCurveReader.Create(inputData, count);
+		}
+		private TableData GetEfficiencyMapData()
+		{
+			return InputDataHelper.InputDataAsTableData(
+				"n [rpm] , T [Nm] , P_el [kW]",
+				#region entries
+				"0, -485, 0.000",
+"0, -461, 0.000",
+"0, -437, 0.000",
+"0, -412, 0.000",
+"0, -388, 0.000",
+"0, -364, 0.000",
+"0, -340, 0.000",
+"0, -315, 0.000",
+"0, -291, 0.000",
+"0, -267, 0.000",
+"0, -243, 0.000",
+"0, -218, 0.000",
+"0, -194, 0.000",
+"0, -170, 0.000",
+"0, -146, 0.000",
+"0, -121, 0.000",
+"0, -97, 0.000",
+"0, -73, 0.000",
+"0, -48, 0.000",
+"0, -24, 0.000",
+"0, -5, 0.000",
+"0, 5, 0.000",
+"0, 24, 0.000",
+"0, 48, 0.000",
+"0, 73, 0.000",
+"0, 97, 0.000",
+"0, 121, 0.000",
+"0, 146, 0.000",
+"0, 170, 0.000",
+"0, 194, 0.000",
+"0, 218, 0.000",
+"0, 243, 0.000",
+"0, 267, 0.000",
+"0, 291, 0.000",
+"0, 315, 0.000",
+"0, 340, 0.000",
+"0, 364, 0.000",
+"0, 388, 0.000",
+"0, 412, 0.000",
+"0, 437, 0.000",
+"0, 461, 0.000",
+"0, 485, 0.000",
+"49, -485, 0.000",
+"49, -461, 0.000",
+"49, -437, 0.000",
+"49, -412, 0.000",
+"49, -388, 0.000",
+"49, -364, 0.000",
+"49, -340, -0.045",
+"49, -315, -0.111",
+"49, -291, -0.166",
+"49, -267, -0.211",
+"49, -243, -0.245",
+"49, -218, -0.268",
+"49, -194, -0.280",
+"49, -170, -0.281",
+"49, -146, -0.272",
+"49, -121, -0.252",
+"49, -97, -0.221",
+"49, -73, -0.179",
+"49, -48, -0.126",
+"49, -24, -0.062",
+"49, -5, -0.004",
+"49, 5, 0.048",
+"49, 24, 0.193",
+"49, 48, 0.384",
+"49, 73, 0.587",
+"49, 97, 0.802",
+"49, 121, 1.029",
+"49, 146, 1.267",
+"49, 170, 1.518",
+"49, 194, 1.779",
+"49, 218, 2.053",
+"49, 243, 2.338",
+"49, 267, 2.636",
+"49, 291, 2.944",
+"49, 315, 3.265",
+"49, 340, 3.597",
+"49, 364, 3.941",
+"49, 388, 4.297",
+"49, 412, 4.665",
+"49, 437, 5.044",
+"49, 461, 5.435",
+"49, 485, 5.838",
+"492, -485, -20.733",
+"492, -461, -19.800",
+"492, -437, -18.856",
+"492, -412, -17.900",
+"492, -388, -16.932",
+"492, -364, -15.953",
+"492, -340, -14.962",
+"492, -315, -13.959",
+"492, -291, -12.945",
+"492, -267, -11.919",
+"492, -243, -10.881",
+"492, -218, -9.832",
+"492, -194, -8.771",
+"492, -170, -7.699",
+"492, -146, -6.614",
+"492, -121, -5.519",
+"492, -97, -4.411",
+"492, -73, -3.292",
+"492, -48, -2.161",
+"492, -24, -1.019",
+"492, -5, -0.097",
+"492, 5, 0.416",
+"492, 24, 1.498",
+"492, 48, 2.863",
+"492, 73, 4.240",
+"492, 97, 5.630",
+"492, 121, 7.033",
+"492, 146, 8.448",
+"492, 170, 9.876",
+"492, 194, 11.316",
+"492, 218, 12.769",
+"492, 243, 14.235",
+"492, 267, 15.713",
+"492, 291, 17.204",
+"492, 315, 18.708",
+"492, 340, 20.224",
+"492, 364, 21.753",
+"492, 388, 23.294",
+"492, 412, 24.848",
+"492, 437, 26.415",
+"492, 461, 27.994",
+"492, 485, 29.586",
+"984, -485, -44.101",
+"984, -461, -42.013",
+"984, -437, -39.910",
+"984, -412, -37.794",
+"984, -388, -35.664",
+"984, -364, -33.520",
+"984, -340, -31.362",
+"984, -315, -29.190",
+"984, -291, -27.004",
+"984, -267, -24.805",
+"984, -243, -22.591",
+"984, -218, -20.363",
+"984, -194, -18.122",
+"984, -170, -15.867",
+"984, -146, -13.597",
+"984, -121, -11.314",
+"984, -97, -9.017",
+"984, -73, -6.706",
+"984, -48, -4.381",
+"984, -24, -2.042",
+"984, -5, -0.161",
+"984, 5, 0.867",
+"984, 24, 2.993",
+"984, 48, 5.663",
+"984, 73, 8.349",
+"984, 97, 11.049",
+"984, 121, 13.765",
+"984, 146, 16.496",
+"984, 170, 19.242",
+"984, 194, 22.003",
+"984, 218, 24.779",
+"984, 243, 27.571",
+"984, 267, 30.377",
+"984, 291, 33.198",
+"984, 315, 36.035",
+"984, 340, 38.887",
+"984, 364, 41.754",
+"984, 388, 44.635",
+"984, 412, 47.532",
+"984, 437, 50.445",
+"984, 461, 53.372",
+"984, 485, 56.314",
+"1477, -485, -67.122",
+"1477, -461, -63.906",
+"1477, -437, -60.673",
+"1477, -412, -57.422",
+"1477, -388, -54.153",
+"1477, -364, -50.867",
+"1477, -340, -47.563",
+"1477, -315, -44.241",
+"1477, -291, -40.902",
+"1477, -267, -37.545",
+"1477, -243, -34.170",
+"1477, -218, -30.778",
+"1477, -194, -27.368",
+"1477, -170, -23.941",
+"1477, -146, -20.496",
+"1477, -121, -17.033",
+"1477, -97, -13.552",
+"1477, -73, -10.054",
+"1477, -48, -6.539",
+"1477, -24, -3.005",
+"1477, -5, -0.166",
+"1477, 5, 1.383",
+"1477, 24, 4.552",
+"1477, 48, 8.530",
+"1477, 73, 12.528",
+"1477, 97, 16.545",
+"1477, 121, 20.581",
+"1477, 146, 24.636",
+"1477, 170, 28.710",
+"1477, 194, 32.804",
+"1477, 218, 36.916",
+"1477, 243, 41.048",
+"1477, 267, 45.199",
+"1477, 291, 49.369",
+"1477, 315, 53.558",
+"1477, 340, 57.766",
+"1477, 364, 61.994",
+"1477, 388, 66.240",
+"1477, 412, 70.506",
+"1477, 437, 74.791",
+"1477, 461, 79.095",
+"1477, 485, 83.418",
+"1969, -485, -89.780",
+"1969, -461, -85.464",
+"1969, -437, -81.126",
+"1969, -412, -76.766",
+"1969, -388, -72.382",
+"1969, -364, -67.976",
+"1969, -340, -63.546",
+"1969, -315, -59.094",
+"1969, -291, -54.620",
+"1969, -267, -50.122",
+"1969, -243, -45.602",
+"1969, -218, -41.058",
+"1969, -194, -36.492",
+"1969, -170, -31.904",
+"1969, -146, -27.292",
+"1969, -121, -22.658",
+"1969, -97, -18.000",
+"1969, -73, -13.320",
+"1969, -48, -8.618",
+"1969, -24, -3.892",
+"1969, -5, -0.095",
+"1969, 5, 1.980",
+"1969, 24, 6.193",
+"1969, 48, 11.483",
+"1969, 73, 16.796",
+"1969, 97, 22.135",
+"1969, 121, 27.498",
+"1969, 146, 32.886",
+"1969, 170, 38.299",
+"1969, 194, 43.736",
+"1969, 218, 49.199",
+"1969, 243, 54.686",
+"1969, 267, 60.197",
+"1969, 291, 65.734",
+"1969, 315, 71.295",
+"1969, 340, 76.881",
+"1969, 364, 82.492",
+"1969, 388, 88.127",
+"1969, 412, 93.787",
+"1969, 437, 99.472",
+"1969, 461, 105.182",
+"1969, 485, 110.916",
+"2461, -485, -112.056",
+"2461, -461, -106.670",
+"2461, -437, -101.254",
+"2461, -412, -95.808",
+"2461, -388, -90.334",
+"2461, -364, -84.830",
+"2461, -340, -79.296",
+"2461, -315, -73.733",
+"2461, -291, -68.141",
+"2461, -267, -62.519",
+"2461, -243, -56.868",
+"2461, -218, -51.188",
+"2461, -194, -45.478",
+"2461, -170, -39.738",
+"2461, -146, -33.970",
+"2461, -121, -28.172",
+"2461, -97, -22.344",
+"2461, -73, -16.487",
+"2461, -48, -10.601",
+"2461, -24, -4.685",
+"2461, -5, 0.000",
+"2461, 5, 2.679",
+"2461, 24, 7.937",
+"2461, 48, 14.539",
+"2461, 73, 21.173",
+"2461, 97, 27.839",
+"2461, 121, 34.536",
+"2461, 146, 41.266",
+"2461, 170, 48.027",
+"2461, 194, 54.820",
+"2461, 218, 61.646",
+"2461, 243, 68.503",
+"2461, 267, 75.392",
+"2461, 291, 82.313",
+"2461, 315, 89.265",
+"2461, 340, 96.250",
+"2461, 364, 103.267",
+"2461, 388, 110.315",
+"2461, 412, 117.396",
+"2461, 437, 124.508",
+"2461, 461, 131.652",
+"2461, 485, 138.828",
+"2953, -485, -133.934",
+"2953, -461, -127.504",
+"2953, -437, -121.037",
+"2953, -412, -114.532",
+"2953, -388, -107.990",
+"2953, -364, -101.411",
+"2953, -340, -94.794",
+"2953, -315, -88.140",
+"2953, -291, -81.448",
+"2953, -267, -74.719",
+"2953, -243, -67.952",
+"2953, -218, -61.148",
+"2953, -194, -54.306",
+"2953, -170, -47.427",
+"2953, -146, -40.511",
+"2953, -121, -33.557",
+"2953, -97, -26.566",
+"2953, -73, -19.537",
+"2953, -48, -12.471",
+"2953, -24, -5.367",
+"2953, -5, 0.000",
+"2953, 5, 3.497",
+"2953, 24, 9.801",
+"2953, 48, 17.718",
+"2953, 73, 25.676",
+"2953, 97, 33.674",
+"2953, 121, 41.713",
+"2953, 146, 49.793",
+"2953, 170, 57.913",
+"2953, 194, 66.074",
+"2953, 218, 74.275",
+"2953, 243, 82.517",
+"2953, 267, 90.800",
+"2953, 291, 99.123",
+"2953, 315, 107.487",
+"2953, 340, 115.892",
+"2953, 364, 124.337",
+"2953, 388, 132.823",
+"2953, 412, 141.349",
+"2953, 437, 149.916",
+"2953, 461, 158.524",
+"2953, 485, 167.172",
+"3446, -485, -155.396",
+"3446, -461, -147.951",
+"3446, -437, -140.460",
+"3446, -412, -132.921",
+"3446, -388, -125.335",
+"3446, -364, -117.703",
+"3446, -340, -110.023",
+"3446, -315, -102.297",
+"3446, -291, -94.524",
+"3446, -267, -86.703",
+"3446, -243, -78.836",
+"3446, -218, -70.922",
+"3446, -194, -62.961",
+"3446, -170, -54.953",
+"3446, -146, -46.898",
+"3446, -121, -38.797",
+"3446, -97, -30.648",
+"3446, -73, -22.452",
+"3446, -48, -14.210",
+"3446, -24, -5.921",
+"3446, -5, 0.000",
+"3446, 5, 4.454",
+"3446, 24, 11.805",
+"3446, 48, 21.040",
+"3446, 73, 30.325",
+"3446, 97, 39.661",
+"3446, 121, 49.049",
+"3446, 146, 58.487",
+"3446, 170, 67.976",
+"3446, 194, 77.516",
+"3446, 218, 87.107",
+"3446, 243, 96.749",
+"3446, 267, 106.442",
+"3446, 291, 116.185",
+"3446, 315, 125.980",
+"3446, 340, 135.826",
+"3446, 364, 145.722",
+"3446, 388, 155.669",
+"3446, 412, 165.668",
+"3446, 437, 175.717",
+"3446, 461, 185.817",
+"3446, 485, 195.968",
+"3938, -485, -176.425",
+"3938, -461, -167.994",
+"3938, -437, -159.504",
+"3938, -412, -150.956",
+"3938, -388, -142.351",
+"3938, -364, -133.687",
+"3938, -340, -124.966",
+"3938, -315, -116.187",
+"3938, -291, -107.351",
+"3938, -267, -98.456",
+"3938, -243, -89.503",
+"3938, -218, -80.493",
+"3938, -194, -71.425",
+"3938, -170, -62.299",
+"3938, -146, -53.115",
+"3938, -121, -43.873",
+"3938, -97, -34.574",
+"3938, -73, -25.217",
+"3938, -48, -15.801",
+"3938, -24, -6.328",
+"3938, -5, 0.000",
+"3938, 5, 5.568",
+"3938, 24, 13.967",
+"3938, 48, 24.521",
+"3938, 73, 35.138",
+"3938, 97, 45.818",
+"3938, 121, 56.561",
+"3938, 146, 67.366",
+"3938, 170, 78.235",
+"3938, 194, 89.166",
+"3938, 218, 100.159",
+"3938, 243, 111.216",
+"3938, 267, 122.335",
+"3938, 291, 133.517",
+"3938, 315, 144.762",
+"3938, 340, 156.070",
+"3938, 364, 167.440",
+"3938, 388, 178.873",
+"3938, 412, 190.369",
+"3938, 437, 201.927",
+"3938, 461, 213.549",
+"3938, 485, 225.233",
+"4430, -485, -197.004",
+"4430, -461, -187.614",
+"4430, -437, -178.152",
+"4430, -412, -168.621",
+"4430, -388, -159.020",
+"4430, -364, -149.348",
+"4430, -340, -139.606",
+"4430, -315, -129.794",
+"4430, -291, -119.912",
+"4430, -267, -109.959",
+"4430, -243, -99.936",
+"4430, -218, -89.844",
+"4430, -194, -79.680",
+"4430, -170, -69.447",
+"4430, -146, -59.144",
+"4430, -121, -48.770",
+"4430, -97, -38.326",
+"4430, -73, -27.812",
+"4430, -48, -17.228",
+"4430, -24, -6.573",
+"4430, -5, 0.000",
+"4430, 5, 6.859",
+"4430, 24, 16.305",
+"4430, 48, 28.182",
+"4430, 73, 40.135",
+"4430, 97, 52.164",
+"4430, 121, 64.269",
+"4430, 146, 76.450",
+"4430, 170, 88.707",
+"4430, 194, 101.041",
+"4430, 218, 113.451",
+"4430, 243, 125.937",
+"4430, 267, 138.499",
+"4430, 291, 151.138",
+"4430, 315, 163.852",
+"4430, 340, 176.643",
+"4430, 364, 189.510",
+"4430, 388, 202.453",
+"4430, 412, 215.472",
+"4430, 437, 228.567",
+"4430, 461, 241.739",
+"4430, 485, 254.986",
+"4922, -485, -217.116",
+"4922, -461, -206.794",
+"4922, -437, -196.388",
+"4922, -412, -185.899",
+"4922, -388, -175.325",
+"4922, -364, -164.667",
+"4922, -340, -153.925",
+"4922, -315, -143.099",
+"4922, -291, -132.190",
+"4922, -267, -121.196",
+"4922, -243, -110.118",
+"4922, -218, -98.956",
+"4922, -194, -87.710",
+"4922, -170, -76.381",
+"4922, -146, -64.967",
+"4922, -121, -53.469",
+"4922, -97, -41.887",
+"4922, -73, -30.221",
+"4922, -48, -18.472",
+"4922, -24, -6.638",
+"4922, -5, 0.000",
+"4922, 5, 8.344",
+"4922, 24, 18.839",
+"4922, 48, 32.040",
+"4922, 73, 45.333",
+"4922, 97, 58.716",
+"4922, 121, 72.191",
+"4922, 146, 85.757",
+"4922, 170, 99.413",
+"4922, 194, 113.161",
+"4922, 218, 127.001",
+"4922, 243, 140.931",
+"4922, 267, 154.952",
+"4922, 291, 169.065",
+"4922, 315, 183.269",
+"4922, 340, 197.564",
+"4922, 364, 211.950",
+"4922, 388, 226.427",
+"4922, 412, 240.995",
+"4922, 437, 255.655",
+"4922, 461, 270.406",
+"4922, 485, 285.247",
+"5415, -485, -236.743",
+"5415, -461, -225.518",
+"5415, -437, -214.194",
+"5415, -412, -202.771",
+"5415, -388, -191.249",
+"5415, -364, -179.627",
+"5415, -340, -167.906",
+"5415, -315, -156.086",
+"5415, -291, -144.167",
+"5415, -267, -132.149",
+"5415, -243, -120.031",
+"5415, -218, -107.814",
+"5415, -194, -95.497",
+"5415, -170, -83.082",
+"5415, -146, -70.567",
+"5415, -121, -57.953",
+"5415, -97, -45.240",
+"5415, -73, -32.428",
+"5415, -48, -19.516",
+"5415, -24, -6.505",
+"5415, -5, 0.000",
+"5415, 5, 10.043",
+"5415, 24, 21.588",
+"5415, 48, 36.116",
+"5415, 73, 50.751",
+"5415, 97, 65.495",
+"5415, 121, 80.346",
+"5415, 146, 95.305",
+"5415, 170, 110.371",
+"5415, 194, 125.545",
+"5415, 218, 140.827",
+"5415, 243, 156.217",
+"5415, 267, 171.714",
+"5415, 291, 187.319",
+"5415, 315, 203.031",
+"5415, 340, 218.852",
+"5415, 364, 234.779",
+"5415, 388, 250.815",
+"5415, 412, 266.958",
+"5415, 437, 283.209",
+"5415, 461, 299.568",
+"5415, 485, 316.034",
+"5907, -485, -255.867",
+"5907, -461, -243.768",
+"5907, -437, -231.553",
+"5907, -412, -219.222",
+"5907, -388, -206.774",
+"5907, -364, -194.211",
+"5907, -340, -181.532",
+"5907, -315, -168.738",
+"5907, -291, -155.827",
+"5907, -267, -142.800",
+"5907, -243, -129.657",
+"5907, -218, -116.399",
+"5907, -194, -103.024",
+"5907, -170, -89.534",
+"5907, -146, -75.928",
+"5907, -121, -62.205",
+"5907, -97, -48.367",
+"5907, -73, -34.413",
+"5907, -48, -20.343",
+"5907, -24, -6.157",
+"5907, -5, 0.000",
+"5907, 5, 11.974",
+"5907, 24, 24.569",
+"5907, 48, 40.426",
+"5907, 73, 56.409",
+"5907, 97, 72.518",
+"5907, 121, 88.753",
+"5907, 146, 105.113",
+"5907, 170, 121.599",
+"5907, 194, 138.211",
+"5907, 218, 154.949",
+"5907, 243, 171.813",
+"5907, 267, 188.802",
+"5907, 291, 205.917",
+"5907, 315, 223.158",
+"5907, 340, 240.525",
+"5907, 364, 258.017",
+"5907, 388, 275.635",
+"5907, 412, 293.379",
+"5907, 437, 311.249",
+"5907, 461, 329.245",
+"5907, 485, 347.366",
+"6399, -485, -274.473",
+"6399, -461, -261.527",
+"6399, -437, -248.447",
+"6399, -412, -235.232",
+"6399, -388, -221.884",
+"6399, -364, -208.402",
+"6399, -340, -194.786",
+"6399, -315, -181.036",
+"6399, -291, -167.151",
+"6399, -267, -153.133",
+"6399, -243, -138.981",
+"6399, -218, -124.694",
+"6399, -194, -110.274",
+"6399, -170, -95.719",
+"6399, -146, -81.031",
+"6399, -121, -66.208",
+"6399, -97, -51.252",
+"6399, -73, -36.161",
+"6399, -48, -20.936",
+"6399, -24, -5.577",
+"6399, -5, 0.000",
+"6399, 5, 14.156",
+"6399, 24, 27.802",
+"6399, 48, 44.991",
+"6399, 73, 62.325",
+"6399, 97, 79.805",
+"6399, 121, 97.430",
+"6399, 146, 115.201",
+"6399, 170, 133.117",
+"6399, 194, 151.179",
+"6399, 218, 169.386",
+"6399, 243, 187.738",
+"6399, 267, 206.236",
+"6399, 291, 224.879",
+"6399, 315, 243.668",
+"6399, 340, 262.602",
+"6399, 364, 281.682",
+"6399, 388, 300.907",
+"6399, 412, 320.277",
+"6399, 437, 339.793",
+"6399, 461, 359.455",
+"6399, 485, 379.261",
+"6891, -485, -292.541",
+"6891, -461, -278.777",
+"6891, -437, -264.858",
+"6891, -412, -250.787",
+"6891, -388, -236.561",
+"6891, -364, -222.182",
+"6891, -340, -207.650",
+"6891, -315, -192.963",
+"6891, -291, -178.124",
+"6891, -267, -163.130",
+"6891, -243, -147.983",
+"6891, -218, -132.683",
+"6891, -194, -117.228",
+"6891, -170, -101.621",
+"6891, -146, -85.859",
+"6891, -121, -69.944",
+"6891, -97, -53.876",
+"6891, -73, -37.653",
+"6891, -48, -21.278",
+"6891, -24, -4.748",
+"6891, -5, 0.000",
+"6891, 5, 16.608",
+"6891, 24, 31.306",
+"6891, 48, 49.829",
+"6891, 73, 68.518",
+"6891, 97, 87.374",
+"6891, 121, 106.397",
+"6891, 146, 125.587",
+"6891, 170, 144.943",
+"6891, 194, 164.466",
+"6891, 218, 184.155",
+"6891, 243, 204.011",
+"6891, 267, 224.034",
+"6891, 291, 244.223",
+"6891, 315, 264.580",
+"6891, 340, 285.102",
+"6891, 364, 305.792",
+"6891, 388, 326.648",
+"6891, 412, 347.671",
+"6891, 437, 368.860",
+"6891, 461, 390.216",
+"6891, 485, 411.739",
+"7383, -485, -310.056",
+"7383, -461, -295.501",
+"7383, -437, -280.771",
+"7383, -412, -265.867",
+"7383, -388, -250.788",
+"7383, -364, -235.535",
+"7383, -340, -220.106",
+"7383, -315, -204.504",
+"7383, -291, -188.726",
+"7383, -267, -172.775",
+"7383, -243, -156.648",
+"7383, -218, -140.347",
+"7383, -194, -123.871",
+"7383, -170, -107.221",
+"7383, -146, -90.396",
+"7383, -121, -73.397",
+"7383, -97, -56.222",
+"7383, -73, -38.874",
+"7383, -48, -21.350",
+"7383, -24, -3.653",
+"7383, -5, 0.000",
+"7383, 5, 19.348",
+"7383, 24, 35.099",
+"7383, 48, 54.958",
+"7383, 73, 75.007",
+"7383, 97, 95.245",
+"7383, 121, 115.672",
+"7383, 146, 136.289",
+"7383, 170, 157.095",
+"7383, 194, 178.091",
+"7383, 218, 199.276",
+"7383, 243, 220.651",
+"7383, 267, 242.215",
+"7383, 291, 263.969",
+"7383, 315, 285.912",
+"7383, 340, 308.044",
+"7383, 364, 330.366",
+"7383, 388, 352.878",
+"7383, 412, 375.578",
+"7383, 437, 398.469",
+"7383, 461, 421.549",
+"7383, 485, 444.818",
+"7876, -485, -327.000",
+"7876, -461, -311.682",
+"7876, -437, -296.167",
+"7876, -412, -280.456",
+"7876, -388, -264.547",
+"7876, -364, -248.442",
+"7876, -340, -232.139",
+"7876, -315, -215.639",
+"7876, -291, -198.942",
+"7876, -267, -182.048",
+"7876, -243, -164.958",
+"7876, -218, -147.670",
+"7876, -194, -130.185",
+"7876, -170, -112.503",
+"7876, -146, -94.624",
+"7876, -121, -76.548",
+"7876, -97, -58.274",
+"7876, -73, -39.804",
+"7876, -48, -21.137",
+"7876, -24, -2.273",
+"7876, -5, 0.000",
+"7876, 5, 22.396",
+"7876, 24, 39.201",
+"7876, 48, 60.398",
+"7876, 73, 81.810",
+"7876, 97, 103.435",
+"7876, 121, 125.274",
+"7876, 146, 147.327",
+"7876, 170, 169.593",
+"7876, 194, 192.074",
+"7876, 218, 214.768",
+"7876, 243, 237.676",
+"7876, 267, 260.798",
+"7876, 291, 284.134",
+"7876, 315, 307.683",
+"7876, 340, 331.447",
+"7876, 364, 355.424",
+"7876, 388, 379.615",
+"7876, 412, 404.019",
+"7876, 437, 428.638",
+"7876, 461, 453.470",
+"7876, 485, 478.516",
+"8368, -485, -343.355",
+"8368, -461, -327.303",
+"8368, -437, -311.030",
+"8368, -412, -294.536",
+"8368, -388, -277.822",
+"8368, -364, -260.886",
+"8368, -340, -243.730",
+"8368, -315, -226.352",
+"8368, -291, -208.754",
+"8368, -267, -190.935",
+"8368, -243, -172.895",
+"8368, -218, -154.634",
+"8368, -194, -136.152",
+"8368, -170, -117.449",
+"8368, -146, -98.525",
+"8368, -121, -79.380",
+"8368, -97, -60.014",
+"8368, -73, -40.428",
+"8368, -48, -20.620",
+"8368, -24, -0.592",
+"8368, -5, 0.000",
+"8368, 5, 25.770",
+"8368, 24, 43.629",
+"8368, 48, 66.167",
+"8368, 73, 88.946",
+"8368, 97, 111.964",
+"8368, 121, 135.221",
+"8368, 146, 158.719",
+"8368, 170, 182.456",
+"8368, 194, 206.433",
+"8368, 218, 230.649",
+"8368, 243, 255.106",
+"8368, 267, 279.802",
+"8368, 291, 304.738",
+"8368, 315, 329.913",
+"8368, 340, 355.328",
+"8368, 364, 380.983",
+"8368, 388, 406.878",
+"8368, 412, 433.012",
+"8368, 437, 459.386",
+"8368, 461, 486.000",
+"8368, 485, 512.853",
+"8860, -485, -359.104",
+"8860, -461, -342.346",
+"8860, -437, -325.341",
+"8860, -412, -308.091",
+"8860, -388, -290.594",
+"8860, -364, -272.851",
+"8860, -340, -254.862",
+"8860, -315, -236.626",
+"8860, -291, -218.144",
+"8860, -267, -199.416",
+"8860, -243, -180.442",
+"8860, -218, -161.221",
+"8860, -194, -141.755",
+"8860, -170, -122.042",
+"8860, -146, -102.082",
+"8860, -121, -81.877",
+"8860, -97, -61.425",
+"8860, -73, -40.727",
+"8860, -48, -19.783",
+"8860, -24, 0.000",
+"8860, -5, 0.000",
+"8860, 5, 29.489",
+"8860, 24, 48.402",
+"8860, 48, 72.284",
+"8860, 73, 96.433",
+"8860, 97, 120.849",
+"8860, 121, 145.533",
+"8860, 146, 170.484",
+"8860, 170, 195.701",
+"8860, 194, 221.186",
+"8860, 218, 246.939",
+"8860, 243, 272.958",
+"8860, 267, 299.245",
+"8860, 291, 325.798",
+"8860, 315, 352.619",
+"8860, 340, 379.708",
+"8860, 364, 407.063",
+"8860, 388, 434.685",
+"8860, 412, 462.575",
+"8860, 437, 490.732",
+"8860, 461, 519.156",
+"8860, 485, 547.847",
+"9352, -485, -374.230",
+"9352, -461, -356.794",
+"9352, -437, -339.084",
+"9352, -412, -321.102",
+"9352, -388, -302.847",
+"9352, -364, -284.319",
+"9352, -340, -265.517",
+"9352, -315, -246.443",
+"9352, -291, -227.096",
+"9352, -267, -207.475",
+"9352, -243, -187.582",
+"9352, -218, -167.416",
+"9352, -194, -146.976",
+"9352, -170, -126.264",
+"9352, -146, -105.279",
+"9352, -121, -84.021",
+"9352, -97, -62.489",
+"9352, -73, -40.685",
+"9352, -48, -18.608",
+"9352, -24, 0.000",
+"9352, -5, 0.000",
+"9352, 5, 33.571",
+"9352, 24, 53.540",
+"9352, 48, 78.768",
+"9352, 73, 104.291",
+"9352, 97, 130.111",
+"9352, 121, 156.228",
+"9352, 146, 182.640",
+"9352, 170, 209.349",
+"9352, 194, 236.354",
+"9352, 218, 263.655",
+"9352, 243, 291.252",
+"9352, 267, 319.146",
+"9352, 291, 347.335",
+"9352, 315, 375.821",
+"9352, 340, 404.604",
+"9352, 364, 433.682",
+"9352, 388, 463.057",
+"9352, 412, 492.728",
+"9352, 437, 522.695",
+"9352, 461, 552.958",
+"9352, 485, 583.518",
+"9845, -485, -388.716",
+"9845, -461, -370.630",
+"9845, -437, -352.242",
+"9845, -412, -333.553",
+"9845, -388, -314.563",
+"9845, -364, -295.272",
+"9845, -340, -275.680",
+"9845, -315, -255.786",
+"9845, -291, -235.591",
+"9845, -267, -215.095",
+"9845, -243, -194.298",
+"9845, -218, -173.200",
+"9845, -194, -151.800",
+"9845, -170, -130.099",
+"9845, -146, -108.097",
+"9845, -121, -85.794",
+"9845, -97, -63.190",
+"9845, -73, -40.284",
+"9845, -48, -17.077",
+"9845, -24, 0.000",
+"9845, -5, 0.000",
+"9845, 5, 38.036",
+"9845, 24, 59.061",
+"9845, 48, 85.637",
+"9845, 73, 112.539",
+"9845, 97, 139.768",
+"9845, 121, 167.324",
+"9845, 146, 195.207",
+"9845, 170, 223.417",
+"9845, 194, 251.953",
+"9845, 218, 280.816",
+"9845, 243, 310.007",
+"9845, 267, 339.523",
+"9845, 291, 369.367",
+"9845, 315, 399.538",
+"9845, 340, 430.035",
+"9845, 364, 460.859",
+"9845, 388, 492.010",
+"9845, 412, 523.488",
+"9845, 437, 555.293",
+"9845, 461, 587.424",
+"9845, 485, 619.883"
+				#endregion data
+				).ApplyFactor(ElectricMotorMapReader.Fields.PowerElectrical, 1E3); //Convert from kW to W
+		}
+
+		private EfficiencyMap GetEfficiencyMap(int count)
+		{
+			return ElectricMotorMapReader.Create(GetEfficiencyMapData(), count, ExecutionMode.Declaration);
+		}
+		private void SetVelocityDropLookupData(PEVAMTShiftStrategy shiftStrategy)
+		{
+			//"StartVelocity [km/h], Gradient [-], EndVelocity [km/h]"
+			var data = new[] {
+				new[] { 5.0, -0.0997, 9.061522965237558 },
+				new[] { 5.0, -0.0798, 7.76698080079411 },
+				new[] { 5.0, -0.0599, 6.46583777913701 },
+				new[] { 5.0, -0.0400, 5.1596021788785045 },
+				new[] { 5.0, -0.0200, 3.8498121019126907 },
+				new[] { 5.0, 0.0000, 2.5380265159468918 },
+				new[] { 5.0, 0.0200, 1.2258160477557427 },
+				new[] { 5.0, 0.0400, 0.0 },
+				new[] { 5.0, 0.0599, 0.0 },
+				new[] { 5.0, 0.0798, 0.0 },
+				new[] { 5.0, 0.0997, 0.0 },
+				new[] { 10.0, -0.0997, 14.807789640888302 },
+				new[] { 10.0, -0.0798, 13.474253785811362 },
+				new[] { 10.0, -0.0599, 12.133880027250777 },
+				new[] { 10.0, -0.0400, 10.788221550084467 },
+				new[] { 10.0, -0.0200, 9.438862432338068 },
+				new[] { 10.0, 0.0000, 8.087408432114643 },
+				new[] { 10.0, 0.0200, 6.735477499784416 },
+				new[] { 10.0, 0.0400, 5.384690105076845 },
+				new[] { 10.0, 0.0599, 4.036659549786269 },
+				new[] { 10.0, 0.0798, 2.6929823705748137 },
+				new[] { 10.0, 0.0997, 1.3552289800549435 },
+				new[] { 20.0, -0.0997, 25.061542153872097 },
+				new[] { 20.0, -0.0798, 23.72002987685605 },
+				new[] { 20.0, -0.0599, 22.371630788642932 },
+				new[] { 20.0, -0.0400, 21.017907257116025 },
+				new[] { 20.0, -0.0200, 19.660452757813403 },
+				new[] { 20.0, 0.0000, 18.30088261992287 },
+				new[] { 20.0, 0.0200, 16.94082447048767 },
+				new[] { 20.0, 0.0400, 15.581908518759507 },
+				new[] { 20.0, 0.0599, 14.225757795590708 },
+				new[] { 20.0, 0.0798, 12.873978508374211 },
+				new[] { 20.0, 0.0997, 11.528150617530041 },
+				new[] { 30.000000000000004, -0.0997, 35.091774208140095 },
+				new[] { 30.000000000000004, -0.0798, 33.750904327320896 },
+				new[] { 30.000000000000004, -0.0599, 32.40315158162777 },
+				new[] { 30.000000000000004, -0.0400, 31.050077596965064 },
+				new[] { 30.000000000000004, -0.0200, 29.69327509188113 },
+				new[] { 30.000000000000004, 0.0000, 28.33435862498606 },
+				new[] { 30.000000000000004, 0.0200, 26.974955046566407 },
+				new[] { 30.000000000000004, 0.0400, 25.616693776603913 },
+				new[] { 30.000000000000004, 0.0599, 24.261197065863925 },
+				new[] { 30.000000000000004, 0.0798, 22.91007034016412 },
+				new[] { 30.000000000000004, 0.0997, 21.56489279686667 },
+				new[] { 40.0, -0.0997, 45.024018797189854 },
+				new[] { 40.0, -0.0798, 43.68636622428101 },
+				new[] { 40.0, -0.0599, 42.34185052441486 },
+				new[] { 40.0, -0.0400, 40.99202962224952 },
+				new[] { 40.0, -0.0200, 39.63849244500093 },
+				new[] { 40.0, 0.0000, 38.282849690992855 },
+				new[] { 40.0, 0.0200, 36.926724305651554 },
+				new[] { 40.0, 0.0400, 35.57174178507285 },
+				new[] { 40.0, 0.0599, 34.21952045137207 },
+				new[] { 40.0, 0.0798, 32.87166183129923 },
+				new[] { 40.0, 0.0997, 31.5297412694979 },
+				new[] { 50.0, -0.0997, 54.652157586769704 },
+				new[] { 50.0, -0.0798, 53.319266704395716 },
+				new[] { 50.0, -0.0599, 51.97954186606304 },
+				new[] { 50.0, -0.0400, 50.634535516787736 },
+				new[] { 50.0, -0.0200, 49.28583097196263 },
+				new[] { 50.0, 0.0000, 47.93503321632867 },
+				new[] { 50.0, 0.0200, 46.583759417454765 },
+				new[] { 50.0, 0.0400, 45.23362925944123 },
+				new[] { 50.0, 0.0599, 43.88625525588574 },
+				new[] { 50.0, 0.0798, 42.54323315977748 },
+				new[] { 50.0, 0.0997, 41.20613261641401 },
+				new[] { 60.00000000000001, -0.0997, 64.2503607025971 },
+				new[] { 60.00000000000001, -0.0798, 62.91932863058169 },
+				new[] { 60.00000000000001, -0.0599, 61.58156853535776 },
+				new[] { 60.00000000000001, -0.0400, 60.23862904729555 },
+				new[] { 60.00000000000001, -0.0200, 58.89369896300112 },
+				new[] { 60.00000000000001, 0.0000, 57.547040626925885 },
+				new[] { 60.00000000000001, 0.0200, 56.199911833784675 },
+				new[] { 60.00000000000001, 0.0400, 54.85392730356455 },
+				new[] { 60.00000000000001, 0.0599, 53.510694584916905 },
+				new[] { 60.00000000000001, 0.0798, 52.17180450267632 },
+				new[] { 60.00000000000001, 0.0997, 50.83882182989668 },
+				new[] { 70.0, -0.0997, 73.78388063954164 },
+				new[] { 70.0, -0.0798, 72.45700102808648 },
+				new[] { 70.0, -0.0599, 71.12341092304165 },
+				new[] { 70.0, -0.0400, 69.78459543842656 },
+				new[] { 70.0, -0.0200, 68.44188526693415 },
+				new[] { 70.0, 0.0000, 67.09719334997524 },
+				new[] { 70.0, 0.0200, 65.75212749798493 },
+				new[] { 70.0, 0.0400, 64.40829754257321 },
+				new[] { 70.0, 0.0599, 63.06730571969745 },
+				new[] { 70.0, 0.0798, 61.73073716025881 },
+				new[] { 70.0, 0.0997, 60.40015062055851 },
+				new[] { 80.0, -0.0997, 83.25457689135129 },
+				new[] { 80.0, -0.0798, 81.93182852399568 },
+				new[] { 80.0, -0.0599, 80.60238880559001 },
+				new[] { 80.0, -0.0400, 79.2676325992058 },
+				new[] { 80.0, -0.0200, 77.92916666616652 },
+				new[] { 80.0, 0.0000, 76.58872134590663 },
+				new[] { 80.0, 0.0200, 75.24790011046437 },
+				new[] { 80.0, 0.0400, 73.90830846424944 },
+				new[] { 80.0, 0.0599, 72.57154434889891 },
+				new[] { 80.0, 0.0798, 71.23918865436896 },
+				new[] { 80.0, 0.0997, 69.91277394305271 },
+			};
+			var entries = new List<VelocitySpeedGearshiftPreprocessor.Entry>();
+			foreach (var d in data) {
+				entries.Add(new VelocitySpeedGearshiftPreprocessor.Entry() {
+					StartVelocity = d[0].KMPHtoMeterPerSecond(),
+					Gradient = d[1].SI<Radian>(),
+					EndVelocity = d[2].KMPHtoMeterPerSecond(),
+				});
+			}
+
+			shiftStrategy.VelocityDropData.Data = entries.ToArray();
+
+		}
+		
+	}
+}
+
+        
\ No newline at end of file
-- 
GitLab


From c29469f62348fced31e38d9900e776e7349a2e8b Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <martini@ivt.tugraz.at>
Date: Tue, 25 Mar 2025 11:10:09 +0100
Subject: [PATCH 22/22] updated shiftstrategy testcases make sure mock
 gearboxes are used

---
 .../AMTShiftStrategyOptimizedTests.cs         |   33 +-
 .../AMTShiftStrategyTests.cs                  |  200 +-
 .../APTNShiftStrategyTests.cs                 |   25 +-
 .../ATShiftStrategyOptimizedTests.cs          | 1994 +++++++----------
 .../GearShiftStrategy/MTShiftStrategyTests.cs |   26 +-
 .../PEVAMTShiftStrategyTests.cs               |   46 +-
 .../Models/SimulationComponent/IGearbox.cs    |    7 +-
 .../Impl/Gearbox/APTGearbox.cs                |    4 +
 .../Impl/Shiftstrategies/AMTShiftStrategy.cs  |   24 +-
 .../ATShiftStrategyOptimized.cs               |    7 +-
 .../Impl/TorqueConverter.cs                   |    2 +-
 11 files changed, 1048 insertions(+), 1320 deletions(-)

diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs
index 886a5e6340..45ca4700fb 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyOptimizedTests.cs	
@@ -190,22 +190,22 @@ TestCase(8, 4, 15000, 200, true),]
  //    }
  //
  //
-	[TestCase]
-	public void GetMocksTest()
-	{
-		// the first element 0.0 is just a placeholder for axlegear, not used in this test
-		var ratios = new[] { 0.0, 6.38, 4.63, 3.84, 2.59, 1.86, 1.35, 1, 0.76 };
-
-		var mockContainer = GetMocks(ratios,
-			out var runData,
-			out var testPowertrain);
-
-		var container = mockContainer.Object;
-		var createdTestPowertrain = container.SimplePowertrainBuilder.CreateTestPowertrain(container, false);
-		
-		Assert.NotNull(createdTestPowertrain.Container.GearboxOutPort);
-		Assert.NotNull(createdTestPowertrain);
-	}
+	// [TestCase]
+	// public void GetMocksTest()
+	// {
+	// 	// the first element 0.0 is just a placeholder for axlegear, not used in this test
+	// 	var ratios = new[] { 0.0, 6.38, 4.63, 3.84, 2.59, 1.86, 1.35, 1, 0.76 };
+	//
+	// 	var mockContainer = GetMocks(ratios,
+	// 		out var runData,
+	// 		out var testPowertrain);
+	//
+	// 	var container = mockContainer.Object;
+	// 	var createdTestPowertrain = container.SimplePowertrainBuilder.CreateTestPowertrain(container, false);
+	// 	
+	// 	Assert.NotNull(createdTestPowertrain.Container.GearboxOutPort);
+	// 	Assert.NotNull(createdTestPowertrain);
+	// }
 
 
 	[TestCase(1, 2, 100, 900, true)]
@@ -621,7 +621,6 @@ TestCase(8, 4, 15000, 200, true),]
 		var amtGearbox = new Mock<IAMTGearbox>(MockBehavior.Strict);
 		amtGearbox.Name = "AMT_Gearbox";
 		var gbx = amtGearbox.As<IGearbox>();
-
 		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
 		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
 		return gbx;
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs
index 19c047ba8c..fdf9359028 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/AMTShiftStrategyTests.cs	
@@ -1,9 +1,9 @@
-using Moq;
+using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+using Moq;
 using NUnit.Framework;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.InputData.Reader.ComponentData;
 using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Declaration;
@@ -20,6 +20,7 @@ using TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
 using TUGraz.VectoCore.Tests.Utils;
 using Assert = NUnit.Framework.Assert;
+using Constants = TUGraz.VectoCore.Configuration.Constants;
 
 namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy;
 
@@ -330,37 +331,83 @@ TestCase(8, 4, 15000, 200, true),]
 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
     }
 
+	private Mock<ISimpleVehicleContainer> GetSimpleVehicleContainer(VectoRunData runData, out Mock<ITestPowertrainTransmission> gbx)
+	{
+		var simpleContainer = new Mock<ISimpleVehicleContainer>();
+
+		simpleContainer.Setup(c => c.RunData).Returns(runData);
+		simpleContainer.Setup(c => c.PowertrainInfo.HasCombustionEngine).Returns(true);
+
+		gbx = GetTestGearbox(runData.GearboxData.Gears);
+		
+		simpleContainer.Setup(c => c.GearboxOutPort).Returns(gbx.Object);
+
+		return simpleContainer;
+	}
+
+	private Mock<ITestPowertrainTransmission> GetTestGearbox(Dictionary<uint, GearData> ratios)
+	{
+		var gbx = new Mock<ITestPowertrainTransmission>();
+		
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+		GearshiftPosition gear = null;
+		gbx.SetupGet(g => g.Gear).Returns(() => {
+			
+			return gear;
+		});
+		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => {
+				gear = p;
+			});
+
+
+		GearshiftPosition nextGear = null;
+		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => nextGear = p);
+			
+		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			return new ResponseSuccess(this)
+			{
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		
+		
+		gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
+				It.IsAny<bool>()))
+			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
+				var ratio = gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+				return dryRun
+					? new ResponseDryRun(this) {
+						Engine = {
+							PowerRequest = n * t, EngineSpeed = n * ratio,
+							DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						},
+						Clutch = { PowerRequest = n * t }
+					}
+					: new ResponseSuccess(this) {
+						Engine = { PowerRequest = n * t, EngineSpeed = n * ratio },
+						Clutch = { PowerRequest = n * t }
+					};
+			});
+		return gbx;
+	}
     private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData)
     {
         var testPt = new Mock<ITestPowertrain>();
-        var tCnt = new Mock<ISimpleVehicleContainer>();
-        tCnt.Setup(c => c.RunData).Returns(runData);
-        var tPi = new Mock<IPowertainInfo>();
-        tPi.Setup(p => p.HasCombustionEngine).Returns(true);
-        tCnt.Setup(c => c.PowertrainInfo).Returns(tPi.Object);
-        var tGbx = new Mock<ITestPowertrainTransmission>();
-        testPt.Setup(t => t.Gearbox).Returns(tGbx.Object);
-        tGbx.Setup(g => g.Initialize(It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>()))
-            .Returns((NewtonMeter t, PerSecond n) => new ResponseSuccess(this) {
-                Engine = { PowerRequest = n * t, EngineSpeed = n },
-                Clutch = { PowerRequest = n * t }
-            });
-        tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
-                It.IsAny<bool>()))
-            .Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => new ResponseSuccess(this) {
-                Engine = { PowerRequest = n * t, EngineSpeed = n },
-                Clutch = { PowerRequest = n * t }
-            });
-		tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
-				It.IsAny<bool>()))
-			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => dryRun ? 
-			new ResponseDryRun(this) {
-				Engine = { PowerRequest = n * t, EngineSpeed = n },
-				Clutch = { PowerRequest = n * t }
-			}: new ResponseSuccess(this) {
-				Engine = { PowerRequest = n * t, EngineSpeed = n },
-				Clutch = { PowerRequest = n * t }
-			});
+
+		var simpleContainer = GetSimpleVehicleContainer(runData, out var gbx);
+        // var tCnt = new Mock<ISimpleVehicleContainer>();
+		testPt.Setup(t => t.Container).Returns(simpleContainer.Object);
+		testPt.Setup(t => t.Gearbox).Returns(gbx.Object);
+		
         var tEng = new Mock<ITestpowertrainCombustionEngine>();
         testPt.Setup(t => t.CombustionEngine).Returns(tEng.Object);
         tEng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
@@ -375,13 +422,11 @@ TestCase(8, 4, 15000, 200, true),]
         var veh = new Mock<IVehicleInfo>();
         veh.Setup(v => v.VehicleSpeed).Returns(10.SI<MeterPerSecond>());
         container.Setup(c => c.VehicleInfo).Returns(veh.Object);
-        var eng = new Mock<IEngineInfo>();
-        container.Setup(c => c.EngineInfo).Returns(eng.Object);
-        eng.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
-        eng.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
-        eng.Setup(e => e.EngineN95hSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
-		eng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
-			.Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+		
+		//EngineInfo
+        var eng = GetEngineInfo(runData);
+		container.Setup(c => c.EngineInfo).Returns(eng.Object);
+		
         var ci = new Mock<IDrivingCycleInfo>();
         container.Setup(c => c.DrivingCycleInfo).Returns(ci.Object);
         var di = new Mock<IDriverInfo>();
@@ -396,14 +441,11 @@ TestCase(8, 4, 15000, 200, true),]
 		var pi = new Mock<IPowertainInfo>();
         pi.Setup(p => p.HasCombustionEngine).Returns(true);
         container.Setup(c => c.PowertrainInfo).Returns(pi.Object);
-        var vi = new Mock<IVehicleInfo>();
-		vi.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
-			.Returns(0.SI<Newton>());
-		vi.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
-		vi.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
-		vi.Setup(v => v.VehicleSpeed).Returns(30.KMPHtoMeterPerSecond());
-		vi.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+		
+        var vi = GetVehicleInfo();
 		container.Setup(c => c.VehicleInfo).Returns(vi.Object);
+		
+		
 		var wi = new Mock<IWheelsInfo>();
 		container.Setup(c => c.WheelsInfo).Returns(wi.Object);
 		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
@@ -413,13 +455,65 @@ TestCase(8, 4, 15000, 200, true),]
         return container;
     }
 
-	private Mock<AMTGearbox> GetMockGearbox(Mock<IVehicleContainer> container)
+	private static Mock<IVehicleInfo> GetVehicleInfo()
+	{
+		var vi = new Mock<IVehicleInfo>();
+		vi.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
+			.Returns(0.SI<Newton>());
+		vi.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vi.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vi.Setup(v => v.VehicleSpeed).Returns(30.KMPHtoMeterPerSecond());
+		vi.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+		return vi;
+	}
+
+	private static Mock<IEngineInfo> GetEngineInfo(VectoRunData runData)
 	{
-		var gbx = new Mock<AMTGearbox>(container.Object, null);
-        var ratios = container.Object.RunData.GearboxData.Gears;
+		var eng = new Mock<IEngineInfo>();
+
+		eng.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
+		eng.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
+		eng.Setup(e => e.EngineN95hSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
+		eng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
+			.Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+		return eng;
+	}
+
+	private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
+	{
+		var gbx = new Mock<ITestPowertrainTransmission>();
+		
 		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
 		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
-		gbx.SetupProperty(g => g.Gear);
+
+		GearshiftPosition gear = null;
+		gbx.SetupGet(g => g.Gear).Returns(() => {
+			
+			return gear;
+		});
+		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => {
+				gear = p;
+			});
+
+
+		GearshiftPosition nextGear = null;
+		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => nextGear = p);
+			
+		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			return new ResponseSuccess(this)
+			{
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		
+		
 		gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
 				It.IsAny<bool>()))
 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
@@ -439,6 +533,16 @@ TestCase(8, 4, 15000, 200, true),]
 			});
 		return gbx;
 	}
+	
+
+	private Mock<IAMTGearbox> GetMockGearbox(Mock<IVehicleContainer> container)
+	{
+		//Make sure no method that is not explicitly mocked is called
+		var gbx = new Mock<IAMTGearbox>(MockBehavior.Strict);
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+		return gbx;
+	}
 
     private static VectoRunData GetRunData(double[] ratios)
     {
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs
index 69476d7097..d3d72531ab 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/APTNShiftStrategyTests.cs	
@@ -377,27 +377,20 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 		
 		
 		
-		private PEVAMTShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container, out IEPCGearbox gearbox)
+		private APTNShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container, out Mock<IIEPCGearbox> gearbox)
 		{
 			var shiftStrategy = new APTNShiftStrategy(container.Object);
 
-			var gbxFactory = new Mock<IIEPCGearboxFactory>();
-			gbxFactory.Setup(g => g.CreateIEPCGearbox(
-				false,
-				It.IsAny<IVehicleContainer>(),
-				It.IsAny<IShiftStrategy>())).Returns(
-				(bool singleSpeed, IVehicleContainer container, IShiftStrategy shiftStrategy) => {
-					return new IEPCGearboxMultipleGears(container, shiftStrategy);
-				});
+			var gbx = new Mock<IIEPCGearbox>(MockBehavior.Strict);
+			gbx.Name = "MockGearbox";
+			gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+			gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
 			
-			gearbox = new IEPCGearbox(container.Object, 
-				shiftStrategy, gbxFactory.Object);
-
+			shiftStrategy.Gearbox = gbx.Object;
 			SetVelocityDropLookupData(shiftStrategy);
-			
-			container.Setup(c => c.GearboxInfo).Returns(gearbox);
-			
-			
+			container.Setup(c => c.GearboxInfo).Returns(gbx.Object);
+
+			gearbox = gbx;
 			return shiftStrategy;
 		}
 
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs
index 7e05644e5c..5ce9fd15e7 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/ATShiftStrategyOptimizedTests.cs	
@@ -2,6 +2,7 @@
 using System.Globalization;
 using System.Reflection.Metadata;
 using System.Reflection.Metadata.Ecma335;
+using System.Runtime.CompilerServices;
 using System.Security.Cryptography;
 using Moq;
 using NUnit.Framework;
@@ -57,12 +58,11 @@ public class ATShiftStrategyOptimizedTests
 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
 		var vehicleContainer = GetMockVehicleContainer(
 			speedKmh: vehicleSpeed,
-			DrivingBehavior.Accelerating,
-			gearRatios,
-			out _,
-			out var runData,
-			out _,
-			out _);
+			driverBehavior: DrivingBehavior.Accelerating,
+			gearRatios: gearRatios,
+			inputData: out _,
+			runData: out var runData,
+			simplePt: out _);
 
 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx, out _);
 		var angularVelocity = GetAngularVelocityBySpeed(vehicleSpeed, runData);
@@ -74,488 +74,97 @@ public class ATShiftStrategyOptimizedTests
 
 		Assert.AreEqual(expectedGear, response.Gear);
 	}
+	
+	
 
-	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
-		double[] gearRatios,
-		out Mock<IVehicleDeclarationInputData> inputData, out VectoRunData runData, out GearboxData gearboxData,
-		out Mock<ISimpleVehicleContainer> simplePt)
-	{
-		var vehicleContainer = new Mock<IVehicleContainer>();
-
-		inputData = GetMockInputData(gearRatios);
-		runData = GetDummyVectoRunData(inputData.Object);
-		
-		vehicleContainer.Setup(c => c.RunData).Returns(runData);
-
-		
-		//Testpowertrain
-		var testPowertrain = GetMockTestPowertrain(
-			runData,
-			out simplePt);
-
-		vehicleContainer.Setup(c => c.SimplePowertrainBuilder.CreateTestPowertrain(It.IsAny<IVehicleContainer>(),
-			It.IsAny<bool>())).Returns(testPowertrain.Object);
-
-		//VehicleInfo
-		vehicleContainer.Setup(c => c.VehicleInfo)
-			.Returns(GetVehicleInfo(speedKmh.KMPHtoMeterPerSecond()).Object);
-
-		//EngineInfo
-		vehicleContainer.Setup(c => c.EngineInfo).Returns(GetEngineInfo(vehicleContainer, runData));
-		
-		//AxleGearInfo
-		var axleGearInfo = new Mock<IAxlegearInfo>();
-		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
-		axleGearInfo.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
-
-		//WheelsInfo
-		var wi = new Mock<IWheelsInfo>();
-		vehicleContainer.Setup(c => c.WheelsInfo).Returns(wi.Object);
-		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
-
-		//Cycle Info
-		var cycleInfo = new Mock<IDrivingCycleInfo>();
-		vehicleContainer.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
-		cycleInfo.Setup(c => c.CycleData).Returns(
-			GetCycleData());
-		cycleInfo.Setup(c => c.RoadGradient).Returns(0.SI<Radian>());
-
-
-		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry() {
-			Altitude = 0.SI<Meter>()
-		});
-		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
-
-		//DriverINfo
-		vehicleContainer.Setup(v => v.DriverInfo.DriverBehavior).Returns(driverBehavior);
-		var acc = 0.SI<MeterPerSquareSecond>();
-		switch (driverBehavior) {
-			case DrivingBehavior.Accelerating:
-				acc = 1.SI<MeterPerSquareSecond>();
-				break;
-			case DrivingBehavior.Braking:
-				acc = -1.SI<MeterPerSquareSecond>();
-				break;
-			case DrivingBehavior.Halted:
-				acc = 0.SI<MeterPerSquareSecond>();
-				break;
-			default:
-				throw new ArgumentOutOfRangeException();
-		}
-
-
-
-
-
-		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(acc);
-		gearboxData = new GearboxData();
-		return vehicleContainer;
-	}
-
-	private IEngineInfo GetEngineInfo(Mock<IVehicleContainer> vehicleContainer, VectoRunData runData)
-	{
-		        //EngineInfo
-        var engineInfo = new Mock<IEngineInfo>();
-		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
-		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
-		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
-
-		engineInfo.Setup(e => e.EngineSpeed).Returns(1400.RPMtoRad());
-		engineInfo.Setup(e => e.EngineN95hSpeed).Returns
-			(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
-		engineInfo.Setup(e => e.EngineN80hSpeed).Returns(
-			runData.EngineData.FullLoadCurves.First().Value.N80hSpeed);
-		engineInfo.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>())).Returns((PerSecond n) =>
-			runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
-		return engineInfo.Object;
-	}
-
-	private CycleData GetCycleData()
-	{
-		return new CycleData() {
-			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
-				PTOActive = PTOActivity.Inactive,
-				VehicleTargetSpeed = 10.KMPHtoMeterPerSecond()
-			}
-		};
-	}
-
-	private Mock<IVehicleInfo> GetVehicleInfo(MeterPerSecond speed)
-	{
-		var vehicleInfo = new Mock<IVehicleInfo>();
-		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(speed);
-		vehicleInfo.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
-			.Returns(0.SI<Newton>());
-		vehicleInfo.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
-		vehicleInfo.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
-		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
-		return vehicleInfo;
-	}
-
-	private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData,
-		out Mock<ISimpleVehicleContainer> simpleContainer)
-	{
-		var testPt = new Mock<ITestPowertrain>();
-		simpleContainer = GetSimplePowertrain(runData,
-			out var testGearbox);
-
-
-
-		testPt.Setup(t => t.Container).Returns(simpleContainer.Object);
-		testPt.Setup(t => t.Gearbox).Returns(testGearbox.Object);
-
-		//Vehicle
-		var vehicle = new Mock<ITestPowertrainVehicle>();
-		vehicle.Setup(v => v.Initialize(
-			It.IsAny<MeterPerSecond>(),
-			It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
-		testPt.Setup(t => t.Vehicle).Returns(vehicle.Object);
-
-
-		return testPt;
-	}
-
-	private Mock<IVehicleDeclarationInputData> GetMockInputData(double[]? gearRatios)
-	{
-		var input = new Mock<IVehicleDeclarationInputData>();
-		var components = new Mock<IVehicleComponentsDeclaration>();
-		input.Setup(i => i.Components).Returns(components.Object);
-		var gbx = new Mock<IGearboxDeclarationInputData>();
-		var tc = new Mock<ITorqueConverterDeclarationInputData>();
-
-		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
-		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
-		gearRatios = gearRatios ?? new double[] { };
-		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
-		var efficiency = 0.98;
-		var data = new List<string>();
-
-		foreach (var speed in new[] { 0, 10000 }) {
-			foreach (var tq in new[] { 1e5, -1e5, 0 }) {
-				data.Add(FormattableString.Invariant($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}"));
-			}
-		}
-
-		var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
-		//lossmap.Columns
-		var gears = gearRatios.Select((x, idx) => {
-			var gear = new Mock<ITransmissionInputData>();
-			gear.Setup(g => g.Ratio).Returns(x);
-			gear.Setup(g => g.Gear).Returns(idx + 1);
-			//gear.Setup(g => g.Efficiency).Returns(0.98);
-			gear.Setup(g => g.LossMap).Returns(lossmap);
-			gear.Setup(g => g.MaxInputSpeed).Returns(2000.RPMtoRad());
-			return gear.Object;
-		}).ToList();
-		gbx.Setup(g => g.Type).Returns(GearboxType.ATSerial);
-		gbx.Setup(g => g.Gears).Returns(gears);
-
-		var tcData = InputDataHelper.InputDataAsTableData(TcHeader, TcData);
-		tc.Setup(t => t.TCData).Returns(tcData);
-		return input;
-	}
-
-	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
-	{
-		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
-		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
-		var fld = FullLoadCurveReader.Create(fldData);
-
-		// create gearbox data
-		var tcDataAdapter = new TorqueConverterDataAdapter();
-
-		// fuel data
-		var fuelData = new CombustionEngineFuelData() {
-			ConsumptionMap = FuelConsumptionMapReader.Create(
-				InputDataHelper.InputDataAsTableData(
-					"engine speed [rpm] ,torque [Nm] ,fuel consumption [g/h] ,whr power electrical [W]",
-					"500,-131,0,0",
-					"500,95.6,1814.959,0",
-					"500,573.6,9771.095,0",
-					"2453,-209.12,0,0",
-					"2453,764.8,39097.94,0"
-				)),
-			FuelData = DeclarationData.FuelData.Lookup(FuelType.DieselCI),
-		};
-
-		var runData = new VectoRunData() {
-			VehicleData = new VehicleData() {
-				DynamicTyreRadius = 0.465.SI<Meter>(),
-				GrossVehicleMass = 12_000.SI<Kilogram>(),
-				CurbMass = 10_000.SI<Kilogram>(),
-			},
-			EngineData = new CombustionEngineData() {
-				Inertia = 0.SI<KilogramSquareMeter>(),
-				FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(),
-				IdleSpeed = 600.RPMtoRad(),
-				RatedSpeedDeclared = 2000.RPMtoRad(),
-				Fuels = new List<CombustionEngineFuelData>() {
-					fuelData,
-				}
-			},
-			Cycle = new DrivingCycleData() {
-				CycleType = CycleType.DistanceBased
-			}
-		};
-		for (uint i = 0; i <= nrOfGears; i++) {
-			runData.EngineData.FullLoadCurves[i] = fld;
-		}
-
-		var gbxDataAdapter = new GearboxDataAdapter(tcDataAdapter);
-		var gbxTypes = new[] {
-			GearboxType.ATSerial, GearboxType.ATPowerSplit
-		};
-
-		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData,
-			new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
-				GearboxType.ATSerial,
-				GearboxType.ATPowerSplit
-			});
-
-		var gearShiftParams =
-			gbxDataAdapter.CreateGearshiftData(1.0, runData.EngineData.IdleSpeed, GearboxType.ATSerial, nrOfGears);
-
-		runData.GearboxData = gearboxData;
-		runData.GearshiftParameters = gearShiftParams;
-		return runData;
-	}
-
-	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData,
-		out Mock<ITestPowertrainTransmission> testGearbox)
-	{
-		var simplePt = new Mock<ISimpleVehicleContainer>();
-
-		testGearbox = GetMockTestGearbox(runData.GearboxData.Gears);
-
-
-		simplePt.Setup(s => s.GearboxInfo).Returns(testGearbox.Object);
-		simplePt.Setup(s => s.GearboxOutPort).Returns(testGearbox.Object);
-
-
-
-
-		//VehiclePort
-		return simplePt;
-	}
-
-	private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
-	{
-		Mock<IAPTGearbox> amtGearbox = new Mock<IAPTGearbox>();
-		amtGearbox.Name = "APT_TestGearbox";
-		Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
-
-
-
-		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
-		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
-
-		GearshiftPosition gear = null;
-		gbx.SetupGet(g => g.Gear).Returns(() => { return gear; });
-		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
-			.Callback<GearshiftPosition>(p => { gear = p; });
-
-
-		GearshiftPosition nextGear = null;
-		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
-		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
-			.Callback<GearshiftPosition>(p => nextGear = p);
-
-		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-			return new ResponseSuccess(this) {
-				Engine = {
-					EngineSpeed = rpm,
-					PowerRequest = tq * rpm,
-				},
-			};
-		});
-		gbx.Setup(p => p.Request(
-			It.IsAny<Second>(),
-			It.IsAny<Second>(),
-			It.IsAny<NewtonMeter>(),
-			It.IsAny<PerSecond>(),
-			true)).Returns((
-			Second absTime,
-			Second dt,
-			NewtonMeter t,
-			PerSecond n,
-			bool dryRun) => {
-
-			var ratio =
-				gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
-			return dryRun
-				? new ResponseDryRun(this) {
-					Engine = {
-						PowerRequest = n * t, EngineSpeed = n * ratio,
-						DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
-						TotalTorqueDemand = t,
-						TorqueOutDemand = t,
-					},
-					Clutch = { PowerRequest = n * t },
-					DeltaFullLoad = n * t / 2 * (-1)
-				}
-				: new ResponseSuccess(this) {
-					Engine = {
-						PowerRequest = n * t,
-						EngineSpeed = n * ratio
-
-					},
-					Clutch = { PowerRequest = n * t }
-				};
-		});
-		return gbx;
-	}
-
-	private static PerSecond GetAngularVelocityBySpeed(double speedKmh, VectoRunData runData)
-	{
-		// r_dyn = 0.465m, i_axle = 6.2
-		var angularVelocity =
-			speedKmh.KMPHtoMeterPerSecond()
-			/ runData.VehicleData.DynamicTyreRadius * 6.2;
-		return angularVelocity;
-	}
-
-
-
-
-
-
-	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
-
-	public static readonly string[] TcData = new[] {
-		"0.0,1.80,377.80",
-		"0.1,1.71,365.21",
-		"0.2,1.61,352.62",
-		"0.3,1.52,340.02",
-		"0.4,1.42,327.43",
-		"0.5,1.33,314.84",
-		"0.6,1.23,302.24",
-		"0.7,1.14,264.46",
-		"0.8,1.04,226.68",
-		"0.9,1.02,188.90",
-		"1.0,1.0,0.00",
-		"1.100,0.999,-40.34",
-		"1.222,0.998,-80.34",
-		"1.375,0.997,-136.11",
-		"1.571,0.996,-216.52",
-		"1.833,0.995,-335.19",
-		"2.200,0.994,-528.77",
-		"2.750,0.993,-883.40",
-		"4.400,0.992,-2462.17",
-		"11.000,0.991,-16540.98",
-	};
-
-	public const string EngineFldHeader = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
-
-	public static readonly string[] EngineFldData = new[] {
-		"560,1180,-149,0.6",
-		"600,1282,-148,0.6",
-		"799.9999999,1791,-149,0.6",
-		"1000,2300,-160,0.6",
-		"1200,2300,-179,0.6",
-		"1400,2300,-203,0.6",
-		"1599.999999,2079,-235,0.49",
-		"1800,1857,-264,0.25",
-		"2000.000001,1352,-301,0.25",
-		"2100,1100,-320,0.25",
-	};
 	
 	[TestCase(1, 1, 1000, 1500, 0, Description = "Engage 0-> 1C")]
 	public void Gearbox_Engage(int gear, int newGear, double tqNm, double nRPM, double speedKmh)
 	{
 		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
-
+		
 		var vehicleContainer = GetMockVehicleContainer(speedKmh, DrivingBehavior.Accelerating, gearRatios, 
 			inputData: out _,
-			runData: out var runData,
-			gearboxData: out _, simplePt: out _);
-
+			runData: out var runData, simplePt: out _);
+		
 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData: runData);
-
-		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-
-
-
+		
+		
+		
 		var absTime = 0.SI<Second>();
 		var dt = 2.SI<Second>();
-
-
+		
+		
 		var expectedN = nRPM.RPMtoRad();
 		angularVelocity = expectedN / gearRatios[gear];
-
-
-		gbx.CurrentState = new ATGearboxState()
-		{
-			Gear = gbx.Gear,
-		};
-
+		
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		SetCurrentGear(gbx, initGear);
+		
 		var expectedT = tqNm.SI<NewtonMeter>();
 		var torque = expectedT * gearRatios[gear];
-
+		
 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
 			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
-
+		
 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
-
+		
 		var shiftExpected = gear != newGear; //Different Gear
-		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-
+		var disengaged = gbx.Object.Disengaged;
+		shiftExpected = shiftRequired || disengaged; //Gearbox was disengaged
+		
 		Assert.AreEqual(shiftExpected, shiftRequired);
 	}
 
 	[TestCase(2, 1, -1000, 1500, 4, DrivingBehavior.Braking, Description = "_ -> 0: disengage before halting")]
 	public void Gearbox_Disengange(int gear, int newGear, double tqNm, double nRPM, double speedKmh,
 		DrivingBehavior driverBehavior)
-	{
-		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
-
-		var vehicleContainer = GetMockVehicleContainer(speedKmh,
-			driverBehavior,
-			gearRatios,
-			out var inputData,
-			out var runData,
-			out var gearboxData, out _);
-
+	{
+		// Assert.Ignore("Work in Progress");
+		var gearRatios = new[] { 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
+		
+		var vehicleContainer = GetMockVehicleContainer(speedKmh, driverBehavior, gearRatios, 
+			inputData: out _,
+			runData: out var runData, simplePt: out _);
+		
 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-
-		gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-
-
+		
 		var absTime = 0.SI<Second>();
 		var dt = 2.SI<Second>();
-
-
+		
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		SetCurrentGear(gbx, initGear);
+		
 		var expectedN = nRPM.RPMtoRad();
 		angularVelocity = expectedN / gearRatios[gear];
-
+		
 		//Called in gbx initialize
 		//var gearShiftPosition = shiftStrategy.InitGear(absTime, Constants.SimulationSettings.TargetTimeInterval, 1.SI<NewtonMeter>(),
 		//    angularVelocity);
 		var engagedPosition = shiftStrategy.Engage(absTime, dt, null, null);
-
-
 		Assert.IsTrue(engagedPosition.Engaged);
-
-		gbx.CurrentState = new ATGearboxState()
-		{
-			Disengaged = gbx.Disengaged,
-			Gear = gbx.Gear,
-		};
-
+		
+		// gbx.CurrentState = new ATGearboxState()
+		// {
+		// 	Disengaged = gbx.Disengaged,
+		// 	Gear = gbx.Gear,
+		// };
+		
 		var expectedT = tqNm.SI<NewtonMeter>();
 		var torque = expectedT * gearRatios[gear];
-
-
+		
+		
 		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, torque, angularVelocity, expectedT, expectedN,
 			new GearshiftPosition((uint)gear), -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
-
+		
 		Assert.AreEqual(newGear, shiftStrategy.NextGear.Gear);
-
+		
 		var shiftExpected = gear != newGear; //Different Gear
-		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-
+		var disengaged = false;
+		shiftExpected = shiftRequired || disengaged; //Gearbox was disengaged
+		
 		Assert.AreEqual(shiftExpected, shiftRequired);
 	}
 
@@ -565,64 +174,250 @@ public class ATShiftStrategyOptimizedTests
     [TestCase(1, false, 1, true, 100, 500, 1, Description = "EarlyUpshift-TC", TestName="EarlyUpshift-TC")]
     public void Gearbox_Upshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
 	{
+		// Assert.Ignore("Work in Progress");
         var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-
+  
         var vehicleContainer = GetMockVehicleContainer(
 			speedKmh, 
 			DrivingBehavior.Accelerating, 
 			gearRatios, 
-			out var inputData, out var runData, out var gearboxData, out var simplePt);
-
-
+			out var inputData, out var runData, out var simplePt);
+  
+  
+		
 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
 		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
 
-		var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-
-		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-
-
-        var absTime = 0.SI<Second>();
-        var dt = 2.SI<Second>();
-
-        gbx.CurrentState = new ATGearboxState()
-        {
-            Disengaged = gbx.Disengaged,
-            Gear = gbx.Gear,
-        };
-
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+		
+		var gbxObj = gbx.Object;
+		// var gbxResponse = gbx.Object.Initialize(0.SI<NewtonMeter>(), angularVelocity);
 
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		
+		
+		Assert.AreEqual((uint)gear, initGear.Gear);
+		Assert.That(initGear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+
+		SetCurrentGear(gbx, initGear);
+
+  
+        // gbx.CurrentState = new ATGearboxState()
+        // {
+        //     Disengaged = gbx.Disengaged,
+        //     Gear = gbx.Gear,
+        // };
+  
+  
 		var inAngularVelocity = nRPM.RPMtoRad();
 		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-
+  
         var inTorque = tqNm.SI<NewtonMeter>();
         var outTortque = inTorque * gearRatios[gear];
-
+  
 		var response = new ResponseSuccess(this);
 		response.Engine.DynamicFullLoadTorque = 50.SI<NewtonMeter>();
 		response.Engine.EngineSpeed = inAngularVelocity;
 		response.Engine.TorqueOutDemand = inTorque;
-
-
+  
+  
 		runData.GearshiftParameters.RatingFactorCurrentGear = 1.1;
+  
+  
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, initGear, -double.MaxValue.SI<Second>(), response);
+  
+  
+		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+  
+        var shiftExpected = gear != newGear; //Different Gear
+		
+        shiftExpected = shiftRequired || gbx.Object.Disengaged; //Gearbox was disengaged
+  
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
 
+	private void SetCurrentGear(Mock<IAPTGearbox> gbx, GearshiftPosition initGear)
+	{
+		gbx.Setup(g => g.Gear).Returns(initGear);
+		gbx.SetupGet(g => g.TorqueConverterLocked).Returns(initGear.TorqueConverterLocked ?? false);
+	}
 
-        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
-
+	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked")]
+	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC")]
+	public void Gearbox_EarlyUpshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+	{
+		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+		
+		var vehicleContainer = GetMockVehicleContainer(
+			speedKmh,
+			DrivingBehavior.Accelerating,
+			gearRatios,
+			out var inputData, out var runData, out _);
+		
+		
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+				
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		SetCurrentGear(gbx, initGear);
+		
+		Assert.AreEqual((uint)gear, initGear.Gear);
+		Assert.That(initGear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+		
 
+		
+		
+		var inAngularVelocity = nRPM.RPMtoRad();
+		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+		
+		var inTorque = tqNm.SI<NewtonMeter>();
+		var outTortque = inTorque * gearRatios[gear];
+		
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, initGear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+		
+		
 		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
 		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+		
+		var shiftExpected = gear != newGear; //Different Gear
+		shiftExpected = shiftRequired || gbx.Object.Disengaged; //Gearbox was disengaged
+		
+		Assert.AreEqual(shiftExpected, shiftRequired);
+	}
 
-        var shiftExpected = gear != newGear; //Different Gear
-        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+//
+    [TestCase(1, false, 2, false, 100, 1000, 1, Description = "Upshift-TC")]
+    public void Gearbox_Upshift_TC_TC(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+    {
+        var gearRatios = new[] { 3.4, 1.3, 1.1, 1.0, 0.7, 0.62 };
+  
+        var vehicleContainer = GetMockVehicleContainer(
+            speedKmh,
+            DrivingBehavior.Accelerating,
+            gearRatios,
+            out var inputData, out var runData, out _);
+  
+  
+        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+
+
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+				
+		Assert.That(runData.GearboxData.GearList.First(p => p.Gear == 2).TorqueConverterLocked, Is.False, "Expected 2nd gear with TC");
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		SetCurrentGear(gbx, initGear);
+		
 
+		
+        var inAngularVelocity = nRPM.RPMtoRad();
+        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+  
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+  
+		var response = new ResponseSuccess(this);
+		response.Engine.EngineSpeed = inAngularVelocity;
+		response.Engine.TorqueOutDemand = inTorque;
+  
+  
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, initGear, -double.MaxValue.SI<Second>(), response);
+  
+  
+        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+  
+        var shiftExpected = gear != newGear; //Different Gear
+        shiftExpected = shiftRequired || gbx.Object.Disengaged; //Gearbox was disengaged
+  
         Assert.AreEqual(shiftExpected, shiftRequired);
     }
+//
+//
+//
+//
+    [TestCase(3, true, 2, true, 900, 600, 15, Description = "Downshift", TestName="Gearbox_DownShift_1")]
+    public void Gearbox_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+    {
+		// Assert.Ignore("Work in Progress");
+		
+        var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+  
+        var vehicleContainer = GetMockVehicleContainer(
+            speedKmh,
+            DrivingBehavior.Accelerating,
+            gearRatios,
+            out var inputData,
+			out var runData,
+			out var simplePt);
+  
+		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+  
+        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+  
+ 
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+		
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		
+        Assert.AreEqual((uint)gear, initGear.Gear);
+        Assert.That(initGear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+  
+ 
 
-	[TestCase(2, true, 3, true, 100, 1800, 13, Description = "Upshift-TCLocked")]
-	[TestCase(1, false, 1, true, 100, 1000, 1, Description = "Upshift-TC")]
-	public void Gearbox_EarlyUpshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+		
+        var inAngularVelocity = nRPM.RPMtoRad();
+        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+  
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+  
+		var response = new ResponseSuccess(this);
+		response.Engine.EngineSpeed = inAngularVelocity;
+		response.Engine.TorqueOutDemand = inTorque;
+  
+  
+		var mockPort = new Mock<ITnOutPort>();
+		
+		simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
+		mockPort.Setup(p => p.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true
+		)).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
+			var response = new ResponseDryRun(this);
+			response.Engine.PowerRequest = outTorque * outAngularVelocity;
+			return response;
+		});
+  //
+  //
+  //
+  //
+		// var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+  //
+  //
+  //       Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+  //       Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+  //
+  //       var shiftExpected = gear != newGear; //Different Gear
+		// var disengaged = false; //gbx.Disengaged;
+  //       shiftExpected = shiftRequired || disengaged; //Gearbox was disengaged
+  //
+  //       Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+//
+	[TestCase(3, true, 2, true, 200, 700, 15, Description = "Downshift_3", TestName = "Gearbox_DownShift_3")]
+	public void Gearbox_Downshift_2(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM,
+		double speedKmh)
 	{
 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
 
@@ -630,813 +425,638 @@ public class ATShiftStrategyOptimizedTests
 			speedKmh,
 			DrivingBehavior.Accelerating,
 			gearRatios,
-			out var inputData, out var runData, out var gearboxData, out _);
+			out var inputData,
+			out var runData,
+			out var simplePt);
 
+		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
 
-		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+		// Condition from ATShiftStrategy
+		//if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() &&
+		//	DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>())
+		vehicleContainer.Setup(v => v.DrivingCycleInfo.CycleData).Returns(new CycleData() {
+			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+				VehicleTargetSpeed = 30.KMPHtoMeterPerSecond()
+			}
+		});
+
+		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(-0.1.SI<MeterPerSquareSecond>());
 
-		var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
 
-		Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-		Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+		runData.EngineData.Inertia = 1.SI<KilogramSquareMeter>();
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx, out var gbxNextComponent);
+		
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+		
 
 
 		var absTime = 0.SI<Second>();
 		var dt = 2.SI<Second>();
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		SetCurrentGear(gbx, initGear);
 
-		gbx.CurrentState = new ATGearboxState()
-		{
-			Disengaged = gbx.Disengaged,
-			Gear = gbx.Gear,
-		};
+		
+        Assert.AreEqual((uint)gear, initGear.Gear);
+        Assert.That(initGear.TorqueConverterLocked, Is.EqualTo(tcLocked));
 
+		
+		var dryRunResponse = new ResponseDryRun(this);
+		dryRunResponse.Engine.EngineSpeed =
+			vehicleContainer.Object.EngineInfo.EngineN95hSpeed - 1.SI<PerSecond>();
+		dryRunResponse.DeltaFullLoad = 40_000.SI<Watt>();
+		
+		// gbx.Setup(g => g)
+		var testPt =
+			vehicleContainer.Object.SimplePowertrainBuilder.CreateTestPowertrain(vehicleContainer.Object, false);
+		
+		var mockGb = Mock.Get(testPt.Gearbox);
+		mockGb.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(), true)).Returns(dryRunResponse);
+		
+		
+        var inAngularVelocity = nRPM.RPMtoRad();
+        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
 
-		var inAngularVelocity = nRPM.RPMtoRad();
-		var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+        var inTorque = tqNm.SI<NewtonMeter>();
+        var outTortque = inTorque * gearRatios[gear];
+
+        var shiftRequired = shiftStrategy.ShiftRequired(absTime, 
+			dt, 
+			outTortque, outAngularVelocity, inTorque, inAngularVelocity, initGear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+
+
+        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+
+        var shiftExpected = gear != newGear; //Different Gear
+        shiftExpected = shiftRequired || gbx.Object.Disengaged; //Gearbox was disengaged
+
+        Assert.AreEqual(shiftExpected, shiftRequired);
+    }
+
+    // [TestCase(3, true, 2, true, 1700, 700, 15, Description = "Downshift", TestName = "Gearbox_Early_DownShift_1")]
+	[TestCase(6, true, 5, true, -100, 700, 45, Description = "Downshift", TestName = "Gearbox_Early_DownShift_1")]
+    public void Gearbox_Early_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
+	{
+		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+		
+		var vehicleContainer = GetMockVehicleContainer(
+		    speedKmh,
+		    DrivingBehavior.Accelerating,
+		    gearRatios,
+		    out var inputData, out var runData, out var simplePt);
+		
+		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+		
+		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
+		var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+		
+				
+		
+		var absTime = 0.SI<Second>();
+		var dt = 2.SI<Second>();
+		var initGear = shiftStrategy.InitGear(absTime, dt, 0.SI<NewtonMeter>(), angularVelocity);
+		SetCurrentGear(gbx, initGear);
+		
+		Assert.AreEqual((uint)gear, initGear.Gear);
+		Assert.That(initGear.TorqueConverterLocked, Is.EqualTo(tcLocked));
 
+		var gearIdx = gear - 1;
+		var inAngularVelocity = nRPM.RPMtoRad();
+		var outAngularVelocity = inAngularVelocity / gearRatios[gearIdx];
+		
 		var inTorque = tqNm.SI<NewtonMeter>();
-		var outTortque = inTorque * gearRatios[gear];
+		var outTortque = inTorque * gearRatios[gearIdx];
+		
+		var response = new ResponseSuccess(this);
+		response.Engine.EngineSpeed = inAngularVelocity;
+		response.Engine.TorqueOutDemand = inTorque;
+		
+		
+		var mockPort = new Mock<ITnOutPort>();
+		
+		// simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
+		// mockPort.Setup(p => p.Request(
+		//     It.IsAny<Second>(),
+		//     It.IsAny<Second>(),
+		//     It.IsAny<NewtonMeter>(),
+		//     It.IsAny<PerSecond>(),
+		//     true
+		// )).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
+		//     var response = new ResponseDryRun(this);
+		//     response.Engine.PowerRequest = outTorque * outAngularVelocity;
+		//     return response;
+		// });
+		
+		
+		runData.GearshiftParameters.RatingFactorCurrentGear = 2;
+		
+		var shiftRequired = shiftStrategy.ShiftRequired(absTime,
+			dt,
+		outTortque, 
+		outAngularVelocity,
+		inTorque, 
+		inAngularVelocity,
+		initGear, -double.MaxValue.SI<Second>(), response);
+		
+		
+		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
+		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+		
+		var shiftExpected = gear != newGear; //Different Gear
+		shiftRequired = shiftRequired || gbx.Object.Disengaged; //Gearbox was disengaged
+		
+		Assert.AreEqual(shiftExpected, shiftRequired);
+	}
+	
+	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
+		double[] gearRatios,
+		out Mock<IVehicleDeclarationInputData> inputData, out VectoRunData runData,
+		out Mock<ISimpleVehicleContainer> simplePt)
+	{
+		var vehicleContainer = new Mock<IVehicleContainer>();
 
-		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
+		inputData = GetMockInputData(gearRatios);
+		runData = GetDummyVectoRunData(inputData.Object);
+		
+		vehicleContainer.Setup(c => c.RunData).Returns(runData);
 
+		
+		//Testpowertrain
+		var testPowertrain = GetMockTestPowertrain(
+			runData,
+			out simplePt);
 
-		Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-		Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+		vehicleContainer.Setup(c => c.SimplePowertrainBuilder.CreateTestPowertrain(It.IsAny<IVehicleContainer>(),
+			It.IsAny<bool>())).Returns(testPowertrain.Object);
 
-		var shiftExpected = gear != newGear; //Different Gear
-		shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+		//VehicleInfo
+		vehicleContainer.Setup(c => c.VehicleInfo)
+			.Returns(GetVehicleInfo(speedKmh.KMPHtoMeterPerSecond()).Object);
 
-		Assert.AreEqual(shiftExpected, shiftRequired);
-	}
+		//EngineInfo
+		vehicleContainer.Setup(c => c.EngineInfo).Returns(GetEngineInfo(vehicleContainer, runData));
+		
+		//AxleGearInfo
+		var axleGearInfo = new Mock<IAxlegearInfo>();
+		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
+		axleGearInfo.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
 
-//
-    [TestCase(1, false, 2, false, 100, 1000, 1, Description = "Upshift-TC")]
-    public void Gearbox_Upshift_TC_TC(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-    {
-        var gearRatios = new[] { 3.4, 1.3, 1.1, 1.0, 0.7, 0.62 };
+		//WheelsInfo
+		var wi = new Mock<IWheelsInfo>();
+		vehicleContainer.Setup(c => c.WheelsInfo).Returns(wi.Object);
+		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
 
-        var vehicleContainer = GetMockVehicleContainer(
-            speedKmh,
-            DrivingBehavior.Accelerating,
-            gearRatios,
-            out var inputData, out var runData, out var gearboxData, out _);
+		//Cycle Info
+		var cycleInfo = new Mock<IDrivingCycleInfo>();
+		vehicleContainer.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
+		cycleInfo.Setup(c => c.CycleData).Returns(
+			GetCycleData());
+		cycleInfo.Setup(c => c.RoadGradient).Returns(0.SI<Radian>());
 
 
-        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry() {
+			Altitude = 0.SI<Meter>()
+		});
+		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
 
-        var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+		//DriverINfo
+		vehicleContainer.Setup(v => v.DriverInfo.DriverBehavior).Returns(driverBehavior);
+		var acc = 0.SI<MeterPerSquareSecond>();
+		switch (driverBehavior) {
+			case DrivingBehavior.Accelerating:
+				acc = 1.SI<MeterPerSquareSecond>();
+				break;
+			case DrivingBehavior.Braking:
+				acc = -1.SI<MeterPerSquareSecond>();
+				break;
+			case DrivingBehavior.Halted:
+				acc = 0.SI<MeterPerSquareSecond>();
+				break;
+			default:
+				throw new ArgumentOutOfRangeException();
+		}
 
-        Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-        Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
 
 
-        var absTime = 0.SI<Second>();
-        var dt = 2.SI<Second>();
 
-        gbx.CurrentState = new ATGearboxState()
-        {
-            Disengaged = gbx.Disengaged,
-            Gear = gbx.Gear,
-        };
 
-		Assert.That(gbx.ModelData.GearList.First(p => p.Gear == 2).TorqueConverterLocked, Is.False, "Expected 2nd gear with TC");
-        var inAngularVelocity = nRPM.RPMtoRad();
-        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(acc);
+		return vehicleContainer;
+	}
 
-        var inTorque = tqNm.SI<NewtonMeter>();
-        var outTortque = inTorque * gearRatios[gear];
+	private IEngineInfo GetEngineInfo(Mock<IVehicleContainer> vehicleContainer, VectoRunData runData)
+	{
+		        //EngineInfo
+        var engineInfo = new Mock<IEngineInfo>();
+		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
+		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed);
+		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(runData.EngineData.FullLoadCurves.First().Value.RatedSpeed);
 
-		var response = new ResponseSuccess(this);
-		response.Engine.EngineSpeed = inAngularVelocity;
-		response.Engine.TorqueOutDemand = inTorque;
+		engineInfo.Setup(e => e.EngineSpeed).Returns(1400.RPMtoRad());
+		engineInfo.Setup(e => e.EngineN95hSpeed).Returns
+			(runData.EngineData.FullLoadCurves.First().Value.N95hSpeed);
+		engineInfo.Setup(e => e.EngineN80hSpeed).Returns(
+			runData.EngineData.FullLoadCurves.First().Value.N80hSpeed);
+		engineInfo.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>())).Returns((PerSecond n) =>
+			runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
+		return engineInfo.Object;
+	}
 
+	private CycleData GetCycleData()
+	{
+		return new CycleData() {
+			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
+				PTOActive = PTOActivity.Inactive,
+				VehicleTargetSpeed = 10.KMPHtoMeterPerSecond()
+			}
+		};
+	}
 
-        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+	private Mock<IVehicleInfo> GetVehicleInfo(MeterPerSecond speed)
+	{
+		var vehicleInfo = new Mock<IVehicleInfo>();
+		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(speed);
+		vehicleInfo.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
+			.Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
+		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
+		return vehicleInfo;
+	}
 
+	private Mock<ITestPowertrain> GetMockTestPowertrain(VectoRunData runData,
+		out Mock<ISimpleVehicleContainer> simpleContainer)
+	{
+		var testPt = new Mock<ITestPowertrain>();
+		simpleContainer = GetSimplePowertrain(runData,
+			out var testGearbox);
 
-        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
 
-        var shiftExpected = gear != newGear; //Different Gear
-        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
 
-        Assert.AreEqual(shiftExpected, shiftRequired);
-    }
-//
-//
-//
-//
-    [TestCase(3, true, 2, true, 900, 600, 15, Description = "Downshift", TestName="Gearbox_DownShift_1")]
-    public void Gearbox_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-    {
-        var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
+		testPt.Setup(t => t.Container).Returns(simpleContainer.Object);
+		testPt.Setup(t => t.Gearbox).Returns(testGearbox.Object);
 
-        var vehicleContainer = GetMockVehicleContainer(
-            speedKmh,
-            DrivingBehavior.Accelerating,
-            gearRatios,
-            out var inputData, out var runData, out var gearboxData, out var simplePt);
+		//Vehicle
+		var vehicle = new Mock<ITestPowertrainVehicle>();
+		vehicle.Setup(v => v.Initialize(
+			It.IsAny<MeterPerSecond>(),
+			It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
+		testPt.Setup(t => t.Vehicle).Returns(vehicle.Object);
 
-		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
 
-        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+		return testPt;
+	}
 
-        var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
+	private Mock<IVehicleDeclarationInputData> GetMockInputData(double[]? gearRatios)
+	{
+		var input = new Mock<IVehicleDeclarationInputData>();
+		var components = new Mock<IVehicleComponentsDeclaration>();
+		input.Setup(i => i.Components).Returns(components.Object);
+		var gbx = new Mock<IGearboxDeclarationInputData>();
+		var tc = new Mock<ITorqueConverterDeclarationInputData>();
 
-        Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-        Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
+		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
+		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
+		gearRatios = gearRatios ?? new double[] { };
+		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
+		var efficiency = 0.98;
+		var data = new List<string>();
 
+		foreach (var speed in new[] { 0, 10000 }) {
+			foreach (var tq in new[] { 1e5, -1e5, 0 }) {
+				data.Add(FormattableString.Invariant($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}"));
+			}
+		}
 
-        var absTime = 0.SI<Second>();
-        var dt = 2.SI<Second>();
+		var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
+		//lossmap.Columns
+		var gears = gearRatios.Select((x, idx) => {
+			var gear = new Mock<ITransmissionInputData>();
+			gear.Setup(g => g.Ratio).Returns(x);
+			gear.Setup(g => g.Gear).Returns(idx + 1);
+			//gear.Setup(g => g.Efficiency).Returns(0.98);
+			gear.Setup(g => g.LossMap).Returns(lossmap);
+			gear.Setup(g => g.MaxInputSpeed).Returns(2000.RPMtoRad());
+			return gear.Object;
+		}).ToList();
+		gbx.Setup(g => g.Type).Returns(GearboxType.ATSerial);
+		gbx.Setup(g => g.Gears).Returns(gears);
 
-        gbx.CurrentState = new ATGearboxState()
-        {
-            Disengaged = gbx.Disengaged,
-            Gear = gbx.Gear,
-        };
+		var tcData = InputDataHelper.InputDataAsTableData(TcHeader, TcData);
+		tc.Setup(t => t.TCData).Returns(tcData);
+		return input;
+	}
 
+	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
+	{
+		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
+		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
+		var fld = FullLoadCurveReader.Create(fldData);
 
-        var inAngularVelocity = nRPM.RPMtoRad();
-        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+		// create gearbox data
+		var tcDataAdapter = new TorqueConverterDataAdapter();
 
-        var inTorque = tqNm.SI<NewtonMeter>();
-        var outTortque = inTorque * gearRatios[gear];
+		// fuel data
+		var fuelData = new CombustionEngineFuelData() {
+			ConsumptionMap = FuelConsumptionMapReader.Create(
+				InputDataHelper.InputDataAsTableData(
+					"engine speed [rpm] ,torque [Nm] ,fuel consumption [g/h] ,whr power electrical [W]",
+					"500,-131,0,0",
+					"500,95.6,1814.959,0",
+					"500,573.6,9771.095,0",
+					"2453,-209.12,0,0",
+					"2453,764.8,39097.94,0"
+				)),
+			FuelData = DeclarationData.FuelData.Lookup(FuelType.DieselCI),
+		};
 
-		var response = new ResponseSuccess(this);
-		response.Engine.EngineSpeed = inAngularVelocity;
-		response.Engine.TorqueOutDemand = inTorque;
+		var runData = new VectoRunData() {
+			VehicleData = new VehicleData() {
+				DynamicTyreRadius = 0.465.SI<Meter>(),
+				GrossVehicleMass = 12_000.SI<Kilogram>(),
+				CurbMass = 10_000.SI<Kilogram>(),
+			},
+			EngineData = new CombustionEngineData() {
+				Inertia = 0.SI<KilogramSquareMeter>(),
+				FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(),
+				IdleSpeed = 600.RPMtoRad(),
+				RatedSpeedDeclared = 2000.RPMtoRad(),
+				Fuels = new List<CombustionEngineFuelData>() {
+					fuelData,
+				}
+			},
+			Cycle = new DrivingCycleData() {
+				CycleType = CycleType.DistanceBased
+			}
+		};
+		for (uint i = 0; i <= nrOfGears; i++) {
+			runData.EngineData.FullLoadCurves[i] = fld;
+		}
 
+		var gbxDataAdapter = new GearboxDataAdapter(tcDataAdapter);
+		var gbxTypes = new[] {
+			GearboxType.ATSerial, GearboxType.ATPowerSplit
+		};
 
-		var mockPort = new Mock<ITnOutPort>();
-		
-		simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
-		mockPort.Setup(p => p.Request(
-			It.IsAny<Second>(),
-			It.IsAny<Second>(),
-			It.IsAny<NewtonMeter>(),
-			It.IsAny<PerSecond>(),
-			true
-		)).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
-			var response = new ResponseDryRun(this);
-			response.Engine.PowerRequest = outTorque * outAngularVelocity;
-			return response;
-		});
+		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData,
+			new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
+				GearboxType.ATSerial,
+				GearboxType.ATPowerSplit
+			});
 
+		var gearShiftParams =
+			gbxDataAdapter.CreateGearshiftData(1.0, runData.EngineData.IdleSpeed, GearboxType.ATSerial, nrOfGears);
 
+		runData.GearboxData = gearboxData;
+		runData.GearshiftParameters = gearShiftParams;
+		return runData;
+	}
 
+	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(VectoRunData runData,
+		out Mock<ITestPowertrainTransmission> testGearbox)
+	{
+		var simplePt = new Mock<ISimpleVehicleContainer>();
 
-		var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
+		testGearbox = GetMockTestGearbox(runData.GearboxData.Gears);
 
 
-        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+		simplePt.Setup(s => s.GearboxInfo).Returns(testGearbox.Object);
+		simplePt.Setup(s => s.GearboxOutPort).Returns(testGearbox.Object);
 
-        var shiftExpected = gear != newGear; //Different Gear
-        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
 
-        Assert.AreEqual(shiftExpected, shiftRequired);
-    }
-//
-// 	[TestCase(3, true, 2, true, 200, 700, 15, Description = "Downshift_3", TestName = "Gearbox_DownShift_3")]
-// 	public void Gearbox_Downshift_2(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM,
-// 		double speedKmh)
-// 	{
-// 		var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
-//
-// 		var vehicleContainer = GetMockVehicleContainer(
-// 			speedKmh,
-// 			DrivingBehavior.Accelerating,
-// 			gearRatios,
-// 			out var inputData, out var runData, out var gearboxData, out _);
-//
-// 		vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
-//
-// 		// Condition from ATShiftStrategy
-// 		//if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() &&
-// 		//	DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>())
-// 		vehicleContainer.Setup(v => v.DrivingCycleInfo.CycleData).Returns(new CycleData() {
-// 			LeftSample = new DrivingCycleData.DrivingCycleEntry() {
-// 				VehicleTargetSpeed = 30.KMPHtoMeterPerSecond()
-// 			}
-// 		});
-//
-// 		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(-0.1.SI<MeterPerSquareSecond>());
-//
-//
-// 		runData.EngineData.Inertia = 1.SI<KilogramSquareMeter>();
-// 		var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx, out var gbxNextComponent);
-//
-//
-// 		var dryRunResponse = new ResponseDryRun(this);
-// 		dryRunResponse.Engine.EngineSpeed =
-// 			vehicleContainer.Object.EngineInfo.EngineN95hSpeed - 1.SI<PerSecond>();
-// 		dryRunResponse.DeltaFullLoad = 40_000.SI<Watt>();
-//
-//
-// 		gbxNextComponent.Setup(c => c.Request(
-// 			It.IsAny<Second>(),
-// 			It.IsAny<Second>(),
-// 			It.IsAny<NewtonMeter>(),
-// 			It.IsAny<PerSecond>(), true)).Returns(
-// 			dryRunResponse);
-//
-// 	var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
-//
-//         var response = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
-//
-//         Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-//         Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
-//
-//
-//         var absTime = 0.SI<Second>();
-//         var dt = 2.SI<Second>();
-//
-//         gbx.CurrentState = new ATGearbox.ATGearboxState()
-//         {
-//             Disengaged = gbx.Disengaged,
-//             Gear = gbx.Gear,
-//         };
-//
-//
-//         var inAngularVelocity = nRPM.RPMtoRad();
-//         var outAngularVelocity = inAngularVelocity / gearRatios[gear];
-//
-//         var inTorque = tqNm.SI<NewtonMeter>();
-//         var outTortque = inTorque * gearRatios[gear];
-//
-//         var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), new ResponseSuccess(this));
-//
-//
-//         Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-//         Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
-//
-//         var shiftExpected = gear != newGear; //Different Gear
-//         shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
-//
-//         Assert.AreEqual(shiftExpected, shiftRequired);
-//     }
-//
-    [TestCase(3, true, 2, true, 1700, 700, 15, Description = "Downshift", TestName = "Gearbox_Early_DownShift_1")]
-    public void Gearbox_Early_Downshift(int gear, bool tcLocked, int newGear, bool newTcLocked, double tqNm, double nRPM, double speedKmh)
-    {
-        var gearRatios = new[] { 3.4, 1.9, 1.42, 1.0, 0.7, 0.62 };
 
-        var vehicleContainer = GetMockVehicleContainer(
-            speedKmh,
-            DrivingBehavior.Accelerating,
-            gearRatios,
-            out var inputData, out var runData, out var gearboxData, out var simplePt);
 
-        vehicleContainer.Setup(v => v.DriverInfo.DrivingAction).Returns(DrivingAction.Accelerate);
+		//VehiclePort
+		return simplePt;
+	}
 
-        var shiftStrategy = GetShiftStrategyAndGearbox(vehicleContainer, out var gbx);
-        var angularVelocity = GetAngularVelocityBySpeed(speedKmh, runData);
+	private Mock<ITestPowertrainTransmission> GetMockTestGearbox(Dictionary<uint, GearData> ratios)
+	{
+		Mock<IAPTGearbox> amtGearbox = new Mock<IAPTGearbox>();
+		amtGearbox.Name = "APT_TestGearbox";
+		TestContext.WriteLine(amtGearbox.Name);
+		Mock<ITestPowertrainTransmission> gbx = amtGearbox.As<ITestPowertrainTransmission>();
 
-        var gbxResponse = gbx.Initialize(0.SI<NewtonMeter>(), angularVelocity);
 
-        Assert.AreEqual((uint)gear, gbx.Gear.Gear);
-        Assert.That(gbx.Gear.TorqueConverterLocked, Is.EqualTo(tcLocked));
 
+		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
 
-        var absTime = 0.SI<Second>();
-        var dt = 2.SI<Second>();
+		GearshiftPosition gear = null;
+		gbx.SetupGet(g => g.Gear).Returns(() => { return gear; });
+		gbx.SetupSet(g => g.SetGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => { gear = p; });
 
-        gbx.CurrentState = new ATGearboxState()
-        {
-            Disengaged = gbx.Disengaged,
-            Gear = gbx.Gear,
-        };
 
+		GearshiftPosition nextGear = null;
+		gbx.SetupGet(g => g.NextGear).Returns(() => nextGear);
+		gbx.SetupSet(g => g.SetNextGear = It.IsAny<GearshiftPosition>())
+			.Callback<GearshiftPosition>(p => nextGear = p);
 
-        var inAngularVelocity = nRPM.RPMtoRad();
-        var outAngularVelocity = inAngularVelocity / gearRatios[gear];
+		gbx.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+			return new ResponseSuccess(this) {
+				Engine = {
+					EngineSpeed = rpm,
+					PowerRequest = tq * rpm,
+				},
+			};
+		});
+		gbx.Setup(p => p.Request(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			true)).Returns((
+			Second absTime,
+			Second dt,
+			NewtonMeter t,
+			PerSecond n,
+			bool dryRun) => {
 
-        var inTorque = tqNm.SI<NewtonMeter>();
-        var outTortque = inTorque * gearRatios[gear];
+			var gear = gbx.Object.Gear.Gear;
+			var ratio = (gbx.Object.Gear.TorqueConverterLocked ?? false)
+				? ratios[gear].Ratio
+				: ratios[gear].TorqueConverterRatio;
 
-        var response = new ResponseSuccess(this);
-        response.Engine.EngineSpeed = inAngularVelocity;
-        response.Engine.TorqueOutDemand = inTorque;
+				
+			
+			// var ratio =
+			// 	gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
+			return dryRun
+				? new ResponseDryRun(this) {
+					Engine = {
+						PowerRequest = n * t, EngineSpeed = n * ratio,
+						DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
+						TotalTorqueDemand = t,
+						TorqueOutDemand = t,
+					},
+					Clutch = { PowerRequest = n * t },
+					DeltaFullLoad = n * t / 2 * (-1)
+				}
+				: new ResponseSuccess(this) {
+					Engine = {
+						PowerRequest = n * t,
+						EngineSpeed = n * ratio
 
+					},
+					Clutch = { PowerRequest = n * t }
+				};
+		});
+		return gbx;
+	}
 
-        var mockPort = new Mock<ITnOutPort>();
+	private static PerSecond GetAngularVelocityBySpeed(double speedKmh, VectoRunData runData)
+	{
+		// r_dyn = 0.465m, i_axle = 6.2
+		var angularVelocity =
+			speedKmh.KMPHtoMeterPerSecond()
+			/ runData.VehicleData.DynamicTyreRadius * 6.2;
+		return angularVelocity;
+	}
 
-        simplePt.Setup(s => s.GearboxOutPort).Returns(mockPort.Object);
-        mockPort.Setup(p => p.Request(
-            It.IsAny<Second>(),
-            It.IsAny<Second>(),
-            It.IsAny<NewtonMeter>(),
-            It.IsAny<PerSecond>(),
-            true
-        )).Returns((Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) => {
-            var response = new ResponseDryRun(this);
-            response.Engine.PowerRequest = outTorque * outAngularVelocity;
-            return response;
-        });
 
 
 
 
-        var shiftRequired = shiftStrategy.ShiftRequired(absTime, dt, outTortque, outAngularVelocity, inTorque, inAngularVelocity, gbx.Gear, -double.MaxValue.SI<Second>(), response);
 
+	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
 
-        Assert.That(shiftStrategy.NextGear.Gear, Is.EqualTo(newGear));
-        Assert.That(shiftStrategy.NextGear.TorqueConverterLocked ?? true, Is.EqualTo(newTcLocked));
+	public static readonly string[] TcData = new[] {
+		"0.0,1.80,377.80",
+		"0.1,1.71,365.21",
+		"0.2,1.61,352.62",
+		"0.3,1.52,340.02",
+		"0.4,1.42,327.43",
+		"0.5,1.33,314.84",
+		"0.6,1.23,302.24",
+		"0.7,1.14,264.46",
+		"0.8,1.04,226.68",
+		"0.9,1.02,188.90",
+		"1.0,1.0,0.00",
+		"1.100,0.999,-40.34",
+		"1.222,0.998,-80.34",
+		"1.375,0.997,-136.11",
+		"1.571,0.996,-216.52",
+		"1.833,0.995,-335.19",
+		"2.200,0.994,-528.77",
+		"2.750,0.993,-883.40",
+		"4.400,0.992,-2462.17",
+		"11.000,0.991,-16540.98",
+	};
 
-        var shiftExpected = gear != newGear; //Different Gear
-        shiftExpected = shiftRequired || gbx.Disengaged; //Gearbox was disengaged
+	public const string EngineFldHeader = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
 
-        Assert.AreEqual(shiftExpected, shiftRequired);
-    }
-	
+	public static readonly string[] EngineFldData = new[] {
+		"560,1180,-149,0.6",
+		"600,1282,-148,0.6",
+		"799.9999999,1791,-149,0.6",
+		"1000,2300,-160,0.6",
+		"1200,2300,-179,0.6",
+		"1400,2300,-203,0.6",
+		"1599.999999,2079,-235,0.49",
+		"1800,1857,-264,0.25",
+		"2000.000001,1352,-301,0.25",
+		"2100,1100,-320,0.25",
+	};
 
 	private ATShiftStrategyOptimized GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer,
-		out APTGearbox gbx)
+		out Mock<IAPTGearbox> gbx)
 	{
 		return GetShiftStrategyAndGearbox(vehicleContainer, out gbx, out _);
 	}
 
 	private ATShiftStrategyOptimized GetShiftStrategyAndGearbox(Mock<IVehicleContainer> vehicleContainer,
-		out APTGearbox gbx,
+		out Mock<IAPTGearbox> gbx,
 		out Mock<ITnOutPort> gbxNextComponent)
 	{
 		var shiftStrategy = new ATShiftStrategyOptimized(vehicleContainer.Object);
 		
-		var gbxMock = new Mock<APTGearbox>(vehicleContainer.Object, shiftStrategy) {
-			CallBase = true
-		};
-		
-		gbx = gbxMock.Object;
-		shiftStrategy.Gearbox = gbx;
-		
-		var mockPort = new Mock<ITnOutPort>();
-		NewtonMeter tqRequest = null;
-		PerSecond rpmRequest = null;
-
-		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-			tqRequest = tq;
-			rpmRequest = rpm;
-			return new ResponseSuccess(this) {
-				Engine = {
-					EngineSpeed = rpm,
-					PowerRequest = tq * rpm,
-				},
-			};
-		});
-		
-		mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
-			It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
+		gbx = GetGearbox(vehicleContainer.Object.RunData);
 
-		var idleController = new Mock<IIdleController>();
 
+		gbxNextComponent = null;
 
-		gbx.IdleController = idleController.Object;
-		gbx.Connect(mockPort.Object);
 
-		gbxNextComponent = mockPort;
+		shiftStrategy.Gearbox = gbx.Object;
 		return shiftStrategy;
+
+		// var gbxMock = new Mock<APTGearbox>(vehicleContainer.Object, shiftStrategy) {
+		// 	CallBase = true
+		// };
+		//
+		// gbx = gbxMock.Object;
+		// shiftStrategy.Gearbox = gbx;
+		//
+		// var mockPort = new Mock<ITnOutPort>();
+		// NewtonMeter tqRequest = null;
+		// PerSecond rpmRequest = null;
+		//
+		// mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
+		// 	tqRequest = tq;
+		// 	rpmRequest = rpm;
+		// 	return new ResponseSuccess(this) {
+		// 		Engine = {
+		// 			EngineSpeed = rpm,
+		// 			PowerRequest = tq * rpm,
+		// 		},
+		// 	};
+		// });
+		//
+		// mockPort.Setup(p => p.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(),
+		// 	It.IsAny<PerSecond>(), true)).Returns(new ResponseDryRun(this));
+		//
+		// var idleController = new Mock<IIdleController>();
+		//
+		//
+		// gbx.IdleController = idleController.Object;
+		// gbx.Connect(mockPort.Object);
+		//
+		// gbxNextComponent = mockPort;
+		// return shiftStrategy;
 	}
-}
-
-// 	private Mock<IVehicleContainer> GetMockVehicleContainer(double speedKmh, DrivingBehavior driverBehavior,
-// 		double[] gearRatios,
-// 		out IVehicleDeclarationInputData inputData, out VectoRunData runData, out GearboxData gearboxData,
-// 		out Mock<ISimpleVehicleContainer> simplePt)
-// 	{
-// 		inputData = GetMockInputData(gearRatios);
-// 		var gbxTypes = new[] {
-// 			GearboxType.ATSerial
-// 		};
-// 		var runDataLocal = GetDummyVectoRunData(inputData);
-// 		var shiftPolygonCalc = GetShiftPolygonCalculator(true);
-// 		
-//
-//         //Setup VehicleContainer
-//         var vehicleContainer = new Mock<IVehicleContainer>();
-// 		var vehicleInfo = new Mock<IVehicleInfo>();
-//
-// 		vehicleContainer.Setup(c => c.RunData).Returns(runDataLocal);
-// 		vehicleContainer.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
-// 		
-//
-//         //EngineInfo
-//         var engineInfo = new Mock<IEngineInfo>();
-// 		vehicleContainer.Setup(c => c.EngineInfo).Returns(engineInfo.Object);
-// 		engineInfo.Setup(e => e.EngineIdleSpeed).Returns(runDataLocal.EngineData.IdleSpeed);
-// 		engineInfo.Setup(e => e.EngineRatedSpeed).Returns(runDataLocal.EngineData.FullLoadCurves.First().Value.RatedSpeed);
-//
-// 		engineInfo.Setup(e => e.EngineSpeed).Returns(1400.RPMtoRad());
-// 		engineInfo.Setup(e => e.EngineN95hSpeed).Returns
-// 			(runDataLocal.EngineData.FullLoadCurves.First().Value.N95hSpeed);
-// 		engineInfo.Setup(e => e.EngineN80hSpeed).Returns(
-// 			runDataLocal.EngineData.FullLoadCurves.First().Value.N80hSpeed);
-// 		engineInfo.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>())).Returns((PerSecond n) =>
-// 			runDataLocal.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
-//
-//         //VehicleInfo
-//         vehicleInfo.Setup(v => v.VehicleSpeed).Returns(speedKmh.KMPHtoMeterPerSecond());
-// 		vehicleInfo.Setup(v => v.AirDragResistance(It.IsAny<MeterPerSecond>(), It.IsAny<MeterPerSecond>()))
-// 			.Returns(0.SI<Newton>());
-// 		vehicleInfo.Setup(v => v.RollingResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
-// 		vehicleInfo.Setup(v => v.SlopeResistance(It.IsAny<Radian>())).Returns(0.SI<Newton>());
-// 		vehicleInfo.Setup(v => v.TotalMass).Returns(12000.SI<Kilogram>());
-//
-// 		//AxleGearInfo
-// 		var axleGearInfo = new Mock<IAxlegearInfo>();
-// 		vehicleContainer.Setup(c => c.AxlegearInfo).Returns(axleGearInfo.Object);
-// 		axleGearInfo.Setup(a => a.AxlegearLoss()).Returns(0.SI<Watt>());
-//
-// 		//WheelsInfo
-// 		var wi = new Mock<IWheelsInfo>();
-// 		vehicleContainer.Setup(c => c.WheelsInfo).Returns(wi.Object);
-// 		wi.Setup(w => w.ReducedMassWheels).Returns(0.SI<Kilogram>());
-//
-// 		//Cycle Info
-// 		var cycleInfo = new Mock<IDrivingCycleInfo>();
-// 		vehicleContainer.Setup(c => c.DrivingCycleInfo).Returns(cycleInfo.Object);
-// 		cycleInfo.Setup(c => c.CycleData).Returns(
-// 			GetCycleData());
-// 		cycleInfo.Setup(c => c.RoadGradient).Returns(0.SI<Radian>());
-//
-//
-// 		cycleInfo.Setup(c => c.CycleLookAhead(It.IsAny<Meter>())).Returns(new DrivingCycleData.DrivingCycleEntry()
-// 		{
-// 			Altitude = 0.SI<Meter>()
-// 		});
-// 		cycleInfo.Setup(c => c.Altitude).Returns(0.SI<Meter>());
-//
-// 		//DriverINfo
-// 		vehicleContainer.Setup(v => v.DriverInfo.DriverBehavior).Returns(driverBehavior);
-// 		var acc = 0.SI<MeterPerSquareSecond>();
-// 		switch (driverBehavior)
-// 		{
-// 			case DrivingBehavior.Accelerating:
-// 				acc = 1.SI<MeterPerSquareSecond>();
-// 				break;
-// 			case DrivingBehavior.Braking:
-// 				acc = -1.SI<MeterPerSquareSecond>();
-// 				break;
-// 			case DrivingBehavior.Halted:
-// 				acc = 0.SI<MeterPerSquareSecond>();
-// 				break;
-// 			default:
-// 				throw new ArgumentOutOfRangeException();
-// 		}
-//
-//
-//
-//
-// 		vehicleContainer.Setup(v => v.DriverInfo.DriverAcceleration).Returns(acc);
-// 		runData = runDataLocal;
-// 		gearboxData = runData.GearboxData;
-//
-//
-//         //TestPowertrain
-// 		//TestPowertrainBuilder
-// 		var testPt = GetMockTestPowertrain(runData);
-//
-// 		var ptBuilder = new Mock<ISimplePowertrainBuilder>();
-// 		ptBuilder.Setup(p => p.CreateTestPowertrain<Gearbox>(It.IsAny<ISimpleVehicleContainer>(), It.IsAny<IDataBus>()))
-// 			.Returns(testPt.Object);
-// 		simplePt = GetSimplePowertrain(inputData);
-// 		ptBuilder.Setup(ptBuilder => ptBuilder.BuildSimplePowertrain(It.IsAny<VectoRunData>()))
-// 			.Returns(simplePt.Object);
-//
-//
-//         vehicleContainer.Setup(c => c.SimplePowertrainBuilder).Returns(ptBuilder.Object);
-//
-//         return vehicleContainer;
-// 	}
-//
-// 	private Mock<IPowertainInfo> GetPowertrainInfo()
-// 	{
-// 		var powerTrainInfo = new Mock<IPowertainInfo>();
-// 		powerTrainInfo.Setup(p => p.HasCombustionEngine).Returns(true);
-// 		return powerTrainInfo;
-// 	}
-//
-//     private Mock<ITestPowertrain<Gearbox>> GetMockTestPowertrain(VectoRunData runData)
-// 	{
-// 		var testPt = new Mock<ITestPowertrain<Gearbox>>();
-// 		var tCnt = new Mock<ISimpleVehicleContainer>();
-// 		tCnt.Setup(c => c.RunData).Returns(runData);
-//
-// 		tCnt.Setup(c => c.PowertrainInfo).Returns(GetPowertrainInfo().Object);
-//
-//
-// 		var tGbx = new Mock<Gearbox>(tCnt.Object, null);
-// 		testPt.Setup(t => t.Gearbox).Returns(tGbx.Object);
-// 		tGbx.Setup(g => g.Initialize(It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>()))
-// 			.Returns((NewtonMeter t, PerSecond n) => new ResponseSuccess(this)
-// 			{
-// 				Engine = { PowerRequest = n * t, EngineSpeed = n },
-// 				Clutch = { PowerRequest = n * t }
-// 			});
-// 		tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
-// 				It.IsAny<bool>()))
-// 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => new ResponseSuccess(this)
-// 			{
-// 				Engine = { PowerRequest = n * t, EngineSpeed = n },
-// 				Clutch = { PowerRequest = n * t }
-// 			});
-// 		tGbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
-// 				It.IsAny<bool>()))
-// 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => dryRun ?
-// 				new ResponseDryRun(this)
-// 				{
-// 					Engine = { PowerRequest = n * t, EngineSpeed = n },
-// 					Clutch = { PowerRequest = n * t }
-// 				} : new ResponseSuccess(this)
-// 				{
-// 					Engine = { PowerRequest = n * t, EngineSpeed = n },
-// 					Clutch = { PowerRequest = n * t }
-// 				});
-// 		var tEng = new Mock<ICombustionEngine>();
-// 		testPt.Setup(t => t.CombustionEngine).Returns(tEng.Object);
-// 		tEng.Setup(e => e.EngineStationaryFullPower(It.IsAny<PerSecond>()))
-// 			.Returns((PerSecond n) => runData.EngineData.FullLoadCurves[0].FullLoadStationaryPower(n));
-// 		return testPt;
-//     }
-//
-// 	private CycleData GetCycleData()
-// 	{
-// 		return new CycleData()
-// 		{
-// 			LeftSample = new DrivingCycleData.DrivingCycleEntry()
-// 			{
-// 				PTOActive = PTOActivity.Inactive,
-// 				VehicleTargetSpeed = 10.KMPHtoMeterPerSecond()
-// 			}
-// 		};
-// 	}
-//
-//
-//
-// 	private static VectoRunData GetDummyVectoRunData(IVehicleDeclarationInputData inputData)
-// 	{
-// 		var nrOfGears = inputData.Components.GearboxInputData.Gears.Count;
-// 		var fldData = InputDataHelper.InputDataAsTableData(EngineFldHeader, EngineFldData);
-// 		var fld = FullLoadCurveReader.Create(fldData);
-//
-//
-// 		// create gearbox data
-// 		var tcDataAdapter = new TorqueConverterDataAdapter();
-//
-//
-//
-// 		// fuel data
-//         var fuelData = new CombustionEngineFuelData() {
-// 			ConsumptionMap = FuelConsumptionMapReader.Create(
-// 				InputDataHelper.InputDataAsTableData(
-// 					"engine speed [rpm] ,torque [Nm] ,fuel consumption [g/h] ,whr power electrical [W]",
-// 					"500,-131,0,0",
-// 						"500,95.6,1814.959,0",
-// 						"500,573.6,9771.095,0",
-// 						"2453,-209.12,0,0",
-// 						"2453,764.8,39097.94,0"
-//                     )),
-// 			FuelData = DeclarationData.FuelData.Lookup(FuelType.DieselCI),
-//
-//
-// 		};
-//
-// 		var runData = new VectoRunData() {
-// 			VehicleData = new VehicleData() {
-// 				DynamicTyreRadius = 0.465.SI<Meter>(),
-// 				GrossVehicleMass = 12_000.SI<Kilogram>(),
-// 				CurbMass = 10_000.SI<Kilogram>(),
-// 			},
-// 			EngineData = new CombustionEngineData() {
-// 				Inertia = 0.SI<KilogramSquareMeter>(),
-// 				FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(),
-// 				IdleSpeed = 600.RPMtoRad(),
-// 				RatedSpeedDeclared = 2000.RPMtoRad(),
-// 				Fuels = new List<CombustionEngineFuelData>() {
-// 					fuelData,
-// 				}
-// 			},
-// 			Cycle = new DrivingCycleData() {
-// 				CycleType = CycleType.DistanceBased
-// 			}
-// 		};
-// 		for (uint i = 0; i <= nrOfGears; i++) {
-// 			runData.EngineData.FullLoadCurves[i] = fld;
-// 		}
-//
-// 		var gbxDataAdapter = new GearboxDataAdapter(tcDataAdapter);
-// 		var gbxTypes = new[] {
-// 			GearboxType.ATSerial, GearboxType.ATPowerSplit
-// 		};
-//
-// 		var gearboxData = gbxDataAdapter.CreateGearboxData(inputData, runData, new ATShiftStrategyOptimizedPolygonCalculator(), new GearboxType[] {
-// 			GearboxType.ATSerial,
-// 			GearboxType.ATPowerSplit
-// 		});
-//
-// 		var gearShiftParams =
-// 			gbxDataAdapter.CreateGearshiftData(1.0, runData.EngineData.IdleSpeed, GearboxType.ATSerial, nrOfGears);
-//
-// 		runData.GearboxData = gearboxData;
-// 		runData.GearshiftParameters = gearShiftParams;
-//         return runData;
-// 	}
-//
-// 	private static IShiftPolygonCalculator GetShiftPolygonCalculator(bool optimized)
-// 	{
-//
-// 		IShiftPolygonCalculator shiftPolygonCalc = optimized ? new ATShiftStrategyOptimizedPolygonCalculator() :  new ATShiftStrategyPolygonCalculator();
-//
-// 		return shiftPolygonCalc;
-// 	}
-//
-// 	// private static IShiftPolygonCalculator GetMockShiftPolygonCalc()
-// 	// {
-// 	// 	var shiftPolygonCalc = new Mock<IShiftPolygonCalculator>();
-// 	// 	var downshift = new List<ShiftPolygon.ShiftPolygonEntry>() { };
-// 	// 	var upshift = new List<ShiftPolygon.ShiftPolygonEntry>() { };
-// 	// 	var shiftpolygon = new ShiftPolygon(downshift, upshift);
-// 	// 	shiftPolygonCalc.Setup(s => s.ComputeDeclarationShiftPolygon(It.IsIn(GearboxType.ATSerial), It.IsAny<int>(),
-// 	// 			It.IsAny<EngineFullLoadCurve>(), It.IsAny<IList<ITransmissionInputData>>(),
-// 	// 			It.IsAny<CombustionEngineData>(), It.IsAny<double>(), It.IsAny<Meter>(), It.IsAny<ElectricMotorData>()))
-// 	// 		.Returns(shiftpolygon);
-// 	// 	return shiftPolygonCalc.Object;
-// 	// }
-//
-// 	private Mock<ISimpleVehicleContainer> GetSimplePowertrain(IVehicleDeclarationInputData inputData)
-// 	{
-// 		var simplePt = new Mock<ISimpleVehicleContainer>();
-// 		simplePt.Setup(s => s.RunData).Returns(GetDummyVectoRunData(inputData));
-// 		simplePt.Setup(s => s.AddComponent(It.IsAny<VectoSimulationComponent>()));
-// 		simplePt.Setup(s => s.PowertrainInfo).Returns(GetPowertrainInfo().Object);
-// 		simplePt.Setup(s => s.GearboxCtl).Returns(GetMockGearbox(simplePt.Object).Object);
-//
-// 		//Vehicle Info
-// 		var vehicleInfo = new Mock<IVehicleInfo>();
-// 		simplePt.Setup(c => c.VehicleInfo).Returns(vehicleInfo.Object);
-// 		vehicleInfo.Setup(v => v.VehicleSpeed).Returns(1.KMPHtoMeterPerSecond());
-//
-//
-// 		//VehiclePort
-// 		var vehiclePort = new Mock<IDriverDemandOutPort>();
-// 		vehiclePort.Setup(port => port.Initialize(
-// 			It.IsAny<MeterPerSecond>(), It.IsAny<Radian>())).Returns(new ResponseSuccess(this));
-//
-// 		simplePt.Setup(c => c.VehiclePort).Returns(vehiclePort.Object);
-//
-// 		var mockPort = new Mock<ITnOutPort>();
-//
-// 		mockPort.Setup(p => p.Initialize(It.IsAny<NewtonMeter>(),
-// 			It.IsAny<PerSecond>())).Returns((NewtonMeter tq, PerSecond rpm) => {
-// 			return new ResponseSuccess(this)
-// 			{
-// 				Engine = {
-// 					EngineSpeed = rpm,
-// 					PowerRequest = tq * rpm,
-// 				},
-// 			};
-// 		});
-// 		mockPort.Setup(p => p.Request(
-// 			It.IsAny<Second>(),
-// 			It.IsAny<Second>(),
-// 			It.IsAny<NewtonMeter>(),
-// 			It.IsAny<PerSecond>(),
-// 			true)).Returns((
-// 			Second absTime,
-// 			Second dt,
-// 			NewtonMeter tq,
-// 			PerSecond ang,
-// 			bool dryRun) => {
-// 			return new ResponseDryRun(this) {
-// 				Engine = {
-// 					EngineSpeed = ang,
-// 					PowerRequest = tq * ang,
-// 					TorqueOutDemand = tq
-// 				},
-// 				DeltaFullLoad = 10_000.SI<Watt>(),
-// 			};
-// 		});
-//
-// 		simplePt.Setup(c => c.GearboxOutPort).Returns(mockPort.Object);
-//         return simplePt;
-// 	}
-// 	private Mock<ATGearbox> GetMockGearbox(IVehicleContainer container)
-// 	{
-// 		var gbx = new Mock<ATGearbox>(container, null);
-// 		var ratios = container.RunData.GearboxData.Gears;
-//
-//
-// 		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
-// 		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
-// 		gbx.SetupProperty(g => g.Gear);
-// 		gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
-// 				It.IsAny<bool>()))
-// 			.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
-// 				var ratio = gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
-// 				return dryRun
-// 					? new ResponseDryRun(this)
-// 					{
-// 						Engine = {
-// 							PowerRequest = n * t, EngineSpeed = n * ratio,
-// 							DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
-// 						},
-// 						Clutch = { PowerRequest = n * t },
-// 						DeltaFullLoad = 10.SI<Watt>()
-// 					}
-// 					: new ResponseSuccess(this)
-// 					{
-// 						Engine = { PowerRequest = n * t, EngineSpeed = n * ratio },
-// 						Clutch = { PowerRequest = n * t }
-// 					};
-// 			});
-// 		return gbx;
-// 	}
-//
-//
-//     private IVehicleDeclarationInputData GetMockInputData(double[]? gearRatios)
-// 	{
-// 		var input = new Mock<IVehicleDeclarationInputData>();
-// 		var components = new Mock<IVehicleComponentsDeclaration>();
-// 		input.Setup(i => i.Components).Returns(components.Object);
-// 		var gbx = new Mock<IGearboxDeclarationInputData>();
-// 		var tc = new Mock<ITorqueConverterDeclarationInputData>();
-//
-// 		components.Setup(c => c.GearboxInputData).Returns(gbx.Object);
-// 		components.Setup(c => c.TorqueConverterInputData).Returns(tc.Object);
-// 		gearRatios = gearRatios ?? new double[] {
-//
-// 		};
-// 		var header = "Input Speed [rpm],Input Torque [Nm],Torque Loss [Nm]";
-// 		var efficiency = 0.98;
-// 		var data = new List<string>();
-// 		
-// 		foreach (var speed in new[] {0, 10000}) {
-// 			foreach (var tq in new[] {1e5, -1e5, 0}) {
-// 				data.Add(FormattableString.Invariant($"{speed:f2}, {tq:f2}, {(1 - efficiency) * Math.Abs(tq)}"));
-// 			}
-// 		}
-//         var lossmap = InputDataHelper.InputDataAsTableData(header, data.ToArray());
-// 		//lossmap.Columns
-// 		var gears = gearRatios.Select((x, idx) => {
-// 			var gear = new Mock<ITransmissionInputData>();
-// 			gear.Setup(g => g.Ratio).Returns(x);
-// 			gear.Setup(g => g.Gear).Returns(idx + 1);
-// 			//gear.Setup(g => g.Efficiency).Returns(0.98);
-// 			gear.Setup(g => g.LossMap).Returns(lossmap);
-// 			gear.Setup(g => g.MaxInputSpeed).Returns(2000.RPMtoRad());
-// 			return gear.Object;
-// 		}).ToList();
-// 		gbx.Setup(g => g.Type).Returns(GearboxType.ATSerial);
-// 		gbx.Setup(g => g.Gears).Returns(gears);
-//
-// 		var tcData = InputDataHelper.InputDataAsTableData(TcHeader, TcData);
-// 		tc.Setup(t => t.TCData).Returns(tcData);
-// 		return input.Object;
-// 	}
-//
-// 	public const string TcHeader = "Speed Ratio, Torque Ratio,MP1000";
-//
-// 	public static readonly string[] TcData = new[] {
-// 		"0.0,1.80,377.80",
-// 		"0.1,1.71,365.21",
-// 		"0.2,1.61,352.62",
-// 		"0.3,1.52,340.02",
-// 		"0.4,1.42,327.43",
-// 		"0.5,1.33,314.84",
-// 		"0.6,1.23,302.24",
-// 		"0.7,1.14,264.46",
-// 		"0.8,1.04,226.68",
-// 		"0.9,1.02,188.90",
-// 		"1.0,1.0,0.00",
-// 		"1.100,0.999,-40.34",
-// 		"1.222,0.998,-80.34",
-// 		"1.375,0.997,-136.11",
-// 		"1.571,0.996,-216.52",
-// 		"1.833,0.995,-335.19",
-// 		"2.200,0.994,-528.77",
-// 		"2.750,0.993,-883.40",
-// 		"4.400,0.992,-2462.17",
-// 		"11.000,0.991,-16540.98",
-// 	};
-//
-// 	public const string EngineFldHeader = "engine speed [1/min],full load torque [Nm],motoring torque [Nm],PT1 [s]";
-//
-// 	public static readonly string[] EngineFldData = new[] {
-// 		"560,1180,-149,0.6",
-// 		"600,1282,-148,0.6",
-// 		"799.9999999,1791,-149,0.6",
-// 		"1000,2300,-160,0.6",
-// 		"1200,2300,-179,0.6",
-// 		"1400,2300,-203,0.6",
-// 		"1599.999999,2079,-235,0.49",
-// 		"1800,1857,-264,0.25",
-// 		"2000.000001,1352,-301,0.25",
-// 		"2100,1100,-320,0.25",
-// 	};
-//
-//
-// }
\ No newline at end of file
+
+	private static Mock<IAPTGearbox> GetGearbox(VectoRunData objectRunData)
+	{
+		Mock<IAPTGearbox> gbx;
+		gbx = new Mock<IAPTGearbox>(MockBehavior.Strict);
+		gbx.Name = "MockGearbox";
+		TestContext.WriteLine(gbx.Name);
+		bool disengaged = false;
+		gbx.SetupGet(g => g.Disengaged).Returns(() => disengaged);
+		gbx.SetupSet(g => g.Disengaged = It.IsAny<bool>()).Callback((bool value) => disengaged = value);
+
+		gbx.Setup(g => g.ComputeShiftLosses(
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>(),
+			It.IsAny<GearshiftPosition>())).Returns((NewtonMeter outT, PerSecond outN, GearshiftPosition gear) => 
+		{
+			return 0.SI<WattSecond>();
+		});
+		gbx.Setup(g => g.EngineInertia).Returns(objectRunData.EngineData.Inertia);
+		
+		//TorqueConverter
+		var tq = new Mock<ITorqueConverter>(MockBehavior.Strict);
+		gbx.Setup(g => g.TorqueConverter).Returns(tq.Object);
+		tq.Setup(tq => tq.FindOperatingPoint(
+			It.IsAny<Second>(),
+			It.IsAny<Second>(),
+			It.IsAny<NewtonMeter>(),
+			It.IsAny<PerSecond>())).Returns((Second t, Second dt, NewtonMeter outTorque, PerSecond outSpeed) => {
+			var speedRatio = 1.0;
+			var torqueRatio = 1.0;
+			return new TorqueConverterOperatingPoint() {
+				Creeping = false,
+				InAngularVelocity = speedRatio * outSpeed,
+				OutAngularVelocity = outSpeed,
+				InTorque = torqueRatio * outTorque,
+				OutTorque = outTorque,
+				SpeedRatio = speedRatio,
+				TorqueRatio = torqueRatio
+			};
+		});
+		return gbx;
+	}
+}
\ No newline at end of file
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs
index 098055db3f..ea2e1b9504 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/MTShiftStrategyTests.cs	
@@ -335,37 +335,13 @@ public class MTShiftStrategyTests
 
 	private Mock<IGearbox> GetMockGearbox()
 	{
-		var mtGbx = new Mock<IMTGearbox>();
+		var mtGbx = new Mock<IMTGearbox>(MockBehavior.Strict);
 		var gbx = mtGbx.As<IGearbox>();
 		
 		gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
 		gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
 		
 		return gbx;
-		// var gbx = new Mock<DeclarationData.Gearbox>(container, null);
-		// var ratios = container.RunData.GearboxData.Gears;
-
-		//
-
-		// gbx.SetupProperty(g => g.Gear);
-		// gbx.Setup(g => g.Request(It.IsAny<Second>(), It.IsAny<Second>(), It.IsAny<NewtonMeter>(), It.IsAny<PerSecond>(),
-		// 		It.IsAny<bool>()))
-		// 	.Returns((Second absTime, Second dt, NewtonMeter t, PerSecond n, bool dryRun) => {
-		// 		var ratio = gbx.Object.Gear == null ? 1.0 : ratios[gbx.Object.Gear.Gear].Ratio;
-		// 		return dryRun
-		// 			? new ResponseDryRun(this) {
-		// 				Engine = {
-		// 					PowerRequest = n * t, EngineSpeed = n * ratio,
-		// 					DynamicFullLoadPower = (t / ratio + 2300.SI<NewtonMeter>()) * n * ratio,
-		// 				},
-		// 				Clutch = { PowerRequest = n * t }
-		// 			}
-		// 			: new ResponseSuccess(this) {
-		// 				Engine = { PowerRequest = n * t, EngineSpeed = n * ratio },
-		// 				Clutch = { PowerRequest = n * t }
-		// 			};
-		// 	});
-		// return gbx;
 	}
 
 
diff --git a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs
index e140fa06e3..e6c7260548 100644
--- a/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs	
+++ b/Testing/UnitTests/Vecto UnitTests/TestCases/Components/GearShiftStrategy/PEVAMTShiftStrategyTests.cs	
@@ -141,8 +141,8 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			var shiftRequired = currentGear != expectedGear;
 			
 			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
-			var gear = new GearshiftPosition((uint)currentGear);
-			gearbox.Gear = gear;
+			// var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
 			
 			var absTime = 0.SI<Second>();
 			var dt = 0.5.SI<Second>();
@@ -209,8 +209,8 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			var shiftRequired = currentGear != expectedGear;
 			
 			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
-			var gear = new GearshiftPosition((uint)currentGear);
-			gearbox.Gear = gear;
+			// var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
 			
 			var absTime = 0.SI<Second>();
 			var dt = 0.5.SI<Second>();
@@ -344,8 +344,8 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			var shiftRequired = currentGear != expectedGear;
 			
 			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
-			var gear = new GearshiftPosition((uint)currentGear);
-			gearbox.Gear = gear;
+			// var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
 			
 			var absTime = 0.SI<Second>();
 			var dt = 0.5.SI<Second>();
@@ -423,8 +423,8 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 			var shiftRequired = currentGear != expectedGear;
 			
 			var shiftStrategy = GetShiftStrategyAndGearbox(container, out var gearbox);
-			var gear = new GearshiftPosition((uint)currentGear);
-			gearbox.Gear = gear;
+			// var gear = new GearshiftPosition((uint)currentGear);
+			// gearbox.Gear = gear;
 			
 			var absTime = 0.SI<Second>();
 			var dt = 0.5.SI<Second>();
@@ -480,20 +480,36 @@ namespace TUGraz.Vecto.UnitTests.TestCases.Components.GearShiftStrategy
 		
 		
 		
-		private PEVAMTShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container, out PEVGearbox gearbox)
+		private PEVAMTShiftStrategy GetShiftStrategyAndGearbox(Mock<IVehicleContainer> container,
+			out Mock<IPEVGearbox> gearbox)
 		{
 			var shiftStrategy = new PEVAMTShiftStrategy(container.Object);
-			gearbox = new PEVGearbox(container.Object, shiftStrategy);
+			
+			// gearbox = new PEVGearbox(container.Object, shiftStrategy);
 
 			SetVelocityDropLookupData(shiftStrategy);
-			
-			gearbox.Gear = new GearshiftPosition(0);
-			container.Setup(c => c.GearboxInfo).Returns(gearbox);
-			
-			
+
+			var gbx = GetGearbox();
+			// gearbox.Gear = new GearshiftPosition(0);
+			// container.Setup(c => c.GearboxInfo).Returns(gearbox);
+
+			gearbox = gbx;
+
+			shiftStrategy.Gearbox = gbx.Object;
 			return shiftStrategy;
 		}
 
+		private Mock<IPEVGearbox> GetGearbox()
+		{
+			var gbx = new Mock<IPEVGearbox>(MockBehavior.Strict);
+			gbx.Setup(g => g.LastUpshift).Returns(-double.MaxValue.SI<Second>());
+			gbx.Setup(g => g.LastDownshift).Returns(-double.MaxValue.SI<Second>());
+
+			
+
+			return gbx;
+		}
+
 		private Mock<IVehicleContainer> GetMocks(double[] ratios)
 		{
 			var container = new Mock<IVehicleContainer>();
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
index 81aa795e99..0514204f9c 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IGearbox.cs
@@ -66,7 +66,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 
 		new bool Disengaged { get; set; }
 		KilogramSquareMeter EngineInertia { get; }
-		TorqueConverter TorqueConverter { get; }
+		ITorqueConverter TorqueConverter { get; }
 
 		WattSecond ComputeShiftLosses(NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition nextGearPos);
 	}
@@ -77,5 +77,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 
 	public interface IIEPCGearbox : ITypedGearbox { }
 
-	public interface ITorqueConverter : ITorqueConverterInfo, ITorqueConverterControl, IUpdateable { }
+	public interface ITorqueConverter : ITorqueConverterInfo, ITorqueConverterControl, IUpdateable
+	{
+		TorqueConverterOperatingPoint FindOperatingPoint(Second absTime, Second dt, NewtonMeter nextGearboxInTorque, PerSecond nextGearboxInSpeed);
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
index 47c608f540..034dcf053e 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox/APTGearbox.cs
@@ -61,6 +61,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Gearbox
         //set { CurrentState.TorqueConverterLocked = value; }
         public override bool TCLocked => Gear.TorqueConverterLocked.Value;
 
+        ITorqueConverter IAPTGearbox.TorqueConverter
+        {
+            get => TorqueConverter;
+        }
         public TorqueConverter TorqueConverter
         {
             get;
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs
index e87e0803c3..29cd502e7e 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs
@@ -56,7 +56,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		
 		protected ITestPowertrain TestPowertrain;
 
-		protected AMTGearbox _gearbox;
+		protected IAMTGearbox _gearbox;
 
         public AMTShiftStrategy(IVehicleContainer container) : base(container)
 		{
@@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		public override IGearbox Gearbox {
 			get => _gearbox;
 			set {
-				if (value is AMTGearbox gbx) {
+				if (value is IAMTGearbox gbx) {
 					_gearbox = gbx;
 					return;
 				}
@@ -376,10 +376,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		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;
+			// var tmpGear = Gearbox.Gear;
+			// _gearbox.Gear = tryNextGear;
+			// var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+			// _gearbox.Gear = tmpGear;
+			
+			
+			
+			LogEnabled = false;
+			TestPowertrain.UpdateComponents();
+			TestPowertrain.Gearbox.SetDisengaged = false;
+			TestPowertrain.Gearbox.SetGear = tryNextGear;
+
+			TestPowertrain.Container.GearboxOutPort.Initialize(outTorque, outAngularVelocity);
+			var response = (ResponseDryRun)TestPowertrain.Container.GearboxOutPort.Request(
+				0.SI<Second>(), dt, outTorque, outAngularVelocity, true);
+			LogEnabled = true;
 			return response;
 		}
 	}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
index 59737053e1..d46b0c35ee 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
@@ -38,7 +38,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		protected List<SchmittTrigger> LoadStageSteps = new List<SchmittTrigger>();
 		protected ShiftLineSet UpshiftLineTCLocked = new ShiftLineSet();
 
-		protected APTGearbox _gearbox;
+		protected IAPTGearbox _gearbox;
 
         public ATShiftStrategyOptimized(IVehicleContainer container) : base(container)
 		{
@@ -68,7 +68,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 		public override IGearbox Gearbox {
 			get => _gearbox;
 			set {
-				if (value is APTGearbox gbx) {
+				if (value is IAPTGearbox gbx) {
 					_gearbox = gbx;
 					return;
 				}
@@ -151,7 +151,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 			}
 
 			foreach (var gear in Gears.Reverse()) {
-				var response = _gearbox.Initialize(gear, torque, outAngularVelocity);
+				var response = RequestDryRunWithGear(absTime, dt, torque, outAngularVelocity, gear);
+				//var response = _gearbox.Initialize(gear, torque, outAngularVelocity);
 
 				if (response.Engine.EngineSpeed > Container.EngineInfo.EngineRatedSpeed || response.Engine.EngineSpeed < Container.EngineInfo.EngineIdleSpeed) {
 					continue;
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
index c085ed588e..49834ecee4 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
@@ -426,7 +426,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return retVal;
 		}
 
-		protected internal TorqueConverterOperatingPoint FindOperatingPoint(Second absTime, Second dt,
+		public TorqueConverterOperatingPoint FindOperatingPoint(Second absTime, Second dt,
 			NewtonMeter outTorque,
 			PerSecond outAngularVelocity)
 		{
-- 
GitLab