From 4b0e02f0a6706b11548ee2b20b749dbf039bb7b3 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Mon, 28 Nov 2016 08:34:37 +0100
Subject: [PATCH] refactoring torque converter, use same torque converter in
 measured speed and target-speed cycles

---
 VECTO.sln                                     |  68 ++-
 .../Models/Simulation/DataBus/IGearboxInfo.cs |   5 +
 .../Simulation/Impl/VehicleContainer.cs       |  13 +-
 .../Data/Gearbox/TorqueConverterData.cs       |   9 +-
 .../SimulationComponent/Impl/ATGearbox.cs     |   5 +-
 .../Impl/AbstractGearbox.cs                   |   9 +-
 .../SimulationComponent/Impl/CycleGearbox.cs  | 402 +++++++++---------
 .../Impl/TorqueConverter.cs                   |  38 +-
 .../TorqueConverterDataTest.cs                |   2 +-
 VectoCore/VectoCoreTest/Utils/MockGearbox.cs  |   9 +-
 .../Utils/MockVehicleContainer.cs             |   9 +-
 11 files changed, 324 insertions(+), 245 deletions(-)

diff --git a/VECTO.sln b/VECTO.sln
index 5f1e46d783..aa4ad27873 100644
--- a/VECTO.sln
+++ b/VECTO.sln
@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
+VisualStudioVersion = 12.0.31101.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VECTO", "VECTO\VECTO.vbproj", "{AAC0F132-0A9F-45B3-B682-77AC9B24B352}"
 EndProject
@@ -44,6 +44,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelbasedTests", "VectoCor
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoLegacyTests", "Tools\VectoLegacyTests\VectoLegacyTests.csproj", "{49F0275A-4517-49FA-859E-77279B9C8B18}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoDB", "..\VECTO_API\VectoDB\VectoDB.csproj", "{2C58BA97-2954-4D19-920F-A24B78FC80A4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{E2F59611-1791-41C9-800B-30E4BEB6D887}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoXML", "..\VECTO_API\VectoXML\VectoXML.csproj", "{A5B6F376-5AAA-453E-8102-B2BA59B83403}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoAPI", "..\VECTO_API\VectoAPI\VectoAPI.csproj", "{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectoEngineeringAPI", "..\VECTO_API\VectoEngineeringAPI\VectoEngineeringAPI.csproj", "{41314A40-AB3E-4F43-B1A4-58443F4014F2}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -158,14 +168,6 @@ Global
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|Any CPU.Build.0 = Release|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|x64.ActiveCfg = Release|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|x86.ActiveCfg = Release|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Release|Any CPU.Build.0 = Release|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Release|x64.ActiveCfg = Release|Any CPU
-		{9CB799AC-5025-4F91-9DC5-5048F59DE004}.Release|x86.ActiveCfg = Release|Any CPU
 		{A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -182,22 +184,58 @@ Global
 		{49F0275A-4517-49FA-859E-77279B9C8B18}.Release|Any CPU.Build.0 = Release|Any CPU
 		{49F0275A-4517-49FA-859E-77279B9C8B18}.Release|x64.ActiveCfg = Release|Any CPU
 		{49F0275A-4517-49FA-859E-77279B9C8B18}.Release|x86.ActiveCfg = Release|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|x64.ActiveCfg = Release|Any CPU
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|x86.ActiveCfg = Release|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Release|x64.ActiveCfg = Release|Any CPU
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403}.Release|x86.ActiveCfg = Release|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|Any CPU.Build.0 = Release|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|x64.ActiveCfg = Release|Any CPU
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64}.Release|x86.ActiveCfg = Release|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|x64.ActiveCfg = Release|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
-		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D} = {B7C0A40B-E468-44DE-A784-7A5B8DAC1042}
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65} = {B7C0A40B-E468-44DE-A784-7A5B8DAC1042}
-		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2} = {CC93EA68-F3FE-4BCB-9292-1101F94A4D09}
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A} = {CC93EA68-F3FE-4BCB-9292-1101F94A4D09}
-		{A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C} = {CC93EA68-F3FE-4BCB-9292-1101F94A4D09}
+		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D} = {B7C0A40B-E468-44DE-A784-7A5B8DAC1042}
+		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2} = {CC93EA68-F3FE-4BCB-9292-1101F94A4D09}
+		{E23B3A9B-62E7-4476-849E-EEF1C3804A2F} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
+		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD} = {73A5BF70-6168-456F-95E5-A1402BFA488C}
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
 		{E8B0B447-1A54-4BEC-A160-AF0017000781} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
-		{E23B3A9B-62E7-4476-849E-EEF1C3804A2F} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
-		{49F0275A-4517-49FA-859E-77279B9C8B18} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
-		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD} = {73A5BF70-6168-456F-95E5-A1402BFA488C}
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4} = {73A5BF70-6168-456F-95E5-A1402BFA488C}
+		{A0256B2A-09F8-45AD-B46A-FD98D7AAAA0C} = {CC93EA68-F3FE-4BCB-9292-1101F94A4D09}
+		{49F0275A-4517-49FA-859E-77279B9C8B18} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
+		{2C58BA97-2954-4D19-920F-A24B78FC80A4} = {351FF7E8-B56B-445E-8E98-A61E07C990DA}
+		{A5B6F376-5AAA-453E-8102-B2BA59B83403} = {E2F59611-1791-41C9-800B-30E4BEB6D887}
+		{512C2CD1-E5BE-4F6B-943B-2BFA7E0CBD64} = {E2F59611-1791-41C9-800B-30E4BEB6D887}
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2} = {E2F59611-1791-41C9-800B-30E4BEB6D887}
 	EndGlobalSection
 EndGlobal
diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs
index c63e4e3fca..eea4cfd94c 100644
--- a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs
+++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs
@@ -31,6 +31,7 @@
 
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 
 namespace TUGraz.VectoCore.Models.Simulation.DataBus
 {
@@ -54,5 +55,9 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus
 		NewtonMeter GearMaxTorque { get; }
 
 		Watt GearboxLoss();
+
+        Second LastShift { get; }
+
+	    GearData GetGearData(uint gear);
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
index 1ed63f2fe0..fdc0969246 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
@@ -41,6 +41,7 @@ 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.Gearbox;
 using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
 
@@ -127,7 +128,17 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			return Gearbox.GearboxLoss();
 		}
 
-		#endregion
+	    public Second LastShift
+	    {
+	        get { return Gearbox.LastShift; }
+	    }
+
+	    public GearData GetGearData(uint gear)
+	    {
+	        return Gearbox.GetGearData(gear);
+	    }
+
+	    #endregion
 
 		#region IEngineCockpit
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs
index 2a724025da..3979f3df1f 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs
@@ -201,8 +201,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 			return FindOperatingPoint(inAngularVelocity, solutions.Max().SI<PerSecond>());
 		}
 
-		public TorqueConverterOperatingPoint FindOperatingPointForPowerDemand(Watt power, PerSecond prevInputSpeed,
-			PerSecond nextOutputSpeed, KilogramSquareMeter inertia, Second dt)
+		public TorqueConverterOperatingPoint FindOperatingPointForPowerDemand(Watt power, PerSecond prevInputSpeed, PerSecond nextOutputSpeed, KilogramSquareMeter inertia, Second dt, Watt previousPower)
 		{
 			var solutions = new List<double>();
 			var mpNorm = ReferenceSpeed.Value();
@@ -211,10 +210,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 				var mpEdge = Edge.Create(new Point(segment.Item1.SpeedRatio, segment.Item1.Torque.Value()),
 					new Point(segment.Item2.SpeedRatio, segment.Item2.Torque.Value()));
 
-				var a = mpEdge.OffsetXY / mpNorm / mpNorm;
-				var b = inertia.Value() / 2 / dt.Value() + mpEdge.SlopeXY * nextOutputSpeed.Value() / mpNorm / mpNorm;
+				var a = mpEdge.OffsetXY / (2 * mpNorm * mpNorm);
+				var b = inertia.Value() / (2 * dt.Value()) + mpEdge.SlopeXY * nextOutputSpeed.Value() / (2*mpNorm * mpNorm);
 				var c = 0;
-				var d = -inertia.Value() / 2 / dt.Value() * prevInputSpeed.Value() * prevInputSpeed.Value() - power.Value();
+				var d = -inertia.Value()* prevInputSpeed.Value() * prevInputSpeed.Value() / (2 * dt.Value())  - power.Value() + previousPower.Value() / 2;
 				var sol = VectoMath.CubicEquationSolver(a, b, c, d);
 
 				var selected = sol.Where(x => x > 0 && nextOutputSpeed / x >= mpEdge.P1.X && nextOutputSpeed / x < mpEdge.P2.X);
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
index 60f27de92a..b7bd8a5bcd 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
@@ -50,9 +50,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected internal readonly TorqueConverter TorqueConverter;
 		private IIdleController _idleController;
 
-		// state overlapping property
-		public Second LastShift { get; private set; }
-
 		public bool TorqueConverterLocked
 		{
 			get { return CurrentState.TorqueConverterLocked; }
@@ -291,7 +288,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			retval.ClutchPowerRequest = 0.SI<Watt>();
 			CurrentState.SetState(0.SI<NewtonMeter>(), 0.SI<PerSecond>(), outTorque, outAngularVelocity);
 
-			TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity);
+			TorqueConverter.Locked(CurrentState.InTorque, DataBus.EngineIdleSpeed);
 
 			CurrentState.Gear = 1;
 			CurrentState.TorqueConverterLocked = !ModelData.Gears[Gear].HasTorqueConverter;
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
index ae9372b50f..43bdfbe452 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
@@ -104,7 +104,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					PreviousState.InertiaTorqueLossOut / ratio) * PreviousState.InAngularVelocity;
 		}
 
-		#endregion
+	    public Second LastShift { get; protected set; }
+
+	    public GearData GetGearData(uint gear)
+	    {
+	        return ModelData.Gears[gear];
+	    }
+
+	    #endregion
 
 		public abstract bool ClutchClosed(Second absTime);
 	}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
index a92d7e22fd..93c49280bf 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
@@ -35,6 +35,7 @@ using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
 using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
@@ -50,23 +51,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	{
 		protected bool? TorqueConverterActive;
 
-		protected internal readonly TorqueConverterData TorqueConverter;
-		private readonly KilogramSquareMeter _engineInertia;
+		protected internal readonly TorqueConverter TorqueConverter;
 
-		public CycleGearbox(IVehicleContainer container, GearboxData gearboxModelData, KilogramSquareMeter engineInertia)
+	    public CycleGearbox(IVehicleContainer container, GearboxData gearboxModelData, KilogramSquareMeter engineInertia)
 			: base(container, gearboxModelData)
 		{
-			_engineInertia = engineInertia;
-			if (!gearboxModelData.Type.AutomaticTransmission()) {
+		    if (!gearboxModelData.Type.AutomaticTransmission()) {
 				return;
 			}
-			TorqueConverter = gearboxModelData.TorqueConverterData;
+		    var strategy = new CycleShiftStrategy();
+		    strategy.Gearbox = this;
+			TorqueConverter = new TorqueConverter(this, strategy, container, gearboxModelData.TorqueConverterData, engineInertia);
 			if (TorqueConverter == null) {
 				throw new VectoException("Torque Converter required for AT transmission!");
 			}
 		}
 
-		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+        public override void Connect(ITnOutPort other)
+        {
+            base.Connect(other);
+            TorqueConverter.NextComponent = other;
+        }
+
+	    public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
 		{
 			var dt = Constants.SimulationSettings.TargetTimeInterval;
 
@@ -77,9 +84,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!");
 			}
 
-			PerSecond inAngularVelocity;
-			NewtonMeter inTorque;
-
+			PerSecond inAngularVelocity =DataBus.EngineIdleSpeed;
+			NewtonMeter inTorque = 0.SI<NewtonMeter>();
+	        IResponse response;
+	    
 			if (Gear != 0) {
 				inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
 				var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
@@ -93,24 +101,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 				inTorque += torqueLossInertia;
 
-				if (TorqueConverterActive != null && TorqueConverterActive.Value) {
-					var operatingPoint = FindOperatingPoint(inTorque, inAngularVelocity);
-					if (inTorque.IsGreater(operatingPoint.OutTorque)) {
-						//Log.Warn("torque converter operating point does not match!");
-						throw new VectoException("Failed to initialize: Torque Converter can't provide requested torque.");
-					}
-					inTorque = operatingPoint.InTorque;
-					inAngularVelocity = operatingPoint.InAngularVelocity;
-				}
-			} else {
-				inTorque = 0.SI<NewtonMeter>();
-				inAngularVelocity = DataBus.EngineIdleSpeed;
-			}
+				response = (TorqueConverterActive != null && TorqueConverterActive.Value) ? 
+                    TorqueConverter.Initialize(inTorque, inAngularVelocity):
+			        NextComponent.Initialize(inTorque, inAngularVelocity);
+			} 
+            CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
 			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
 			PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>();
 			PreviousState.Gear = Gear;
 
-			var response = NextComponent.Initialize(inTorque, inAngularVelocity);
+			response = NextComponent.Initialize(inTorque, inAngularVelocity);
 			response.GearboxPowerRequest = inTorque * inAngularVelocity;
 			return response;
 		}
@@ -205,7 +205,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			if (dryRun) {
 				if (TorqueConverter != null && !torqueConverterLocked) {
-					return RequestTorqueConverter(absTime, dt, inTorque, inAngularVelocity, true);
+					return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true);
 				}
 				if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
 					//Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear,
@@ -228,80 +228,84 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			if (TorqueConverter != null && !torqueConverterLocked) {
 				CurrentState.TorqueConverterActive = true;
-				return RequestTorqueConverter(absTime, dt, inTorque, inAngularVelocity);
+				return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity);
 			}
-			if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+            if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
 				Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear,
 					DataBus.VehicleSpeed);
 				Gear = 0;
 				return RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
 			}
+            if (TorqueConverter != null)
+                TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity);
 			var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity);
 			response.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
 			return response;
 		}
 
-		/// <summary>
-		/// Handle Requests when Torque Converter is active
-		/// </summary>
-		/// <param name="absTime"></param>
-		/// <param name="dt"></param>
-		/// <param name="outTorque">torque at the output of the torque converter (to the mechanical gear)</param>
-		/// <param name="outAngularVelocity">angular velocity at the output of the torque converter (to the mechanical gear)</param>
-		/// <param name="dryRun"></param>
-		/// <returns></returns>
-		private IResponse RequestTorqueConverter(Second absTime, Second dt, NewtonMeter outTorque,
-			PerSecond outAngularVelocity, bool dryRun = false)
-		{
-			if (dryRun) {
-				return RequestTorqueConverterDryRun(absTime, dt, outTorque, outAngularVelocity);
-			}
-			var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
-			CurrentState.TorqueConverterOperatingPoint = operatingPoint;
-			if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) {
-				// a different operating point was found...
-				var delta = (outTorque - operatingPoint.OutTorque) *
-							(PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0;
-				if (!delta.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) {
-					if (delta > 0) {
-						return new ResponseOverload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
-					}
-					return new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
-				}
-			}
-			var tcResponse = NextComponent.Request(absTime, dt, operatingPoint.InTorque, operatingPoint.InAngularVelocity);
-			return tcResponse;
-		}
-
-		/// <summary>
-		/// Handle Requests when searching an operating point and torque converter is active
-		/// </summary>
-		/// <param name="absTime"></param>
-		/// <param name="dt"></param>
-		/// <param name="outTorque"></param>
-		/// <param name="outAngularVelocity"></param>
-		/// <returns></returns>
-		private IResponse RequestTorqueConverterDryRun(Second absTime, Second dt, NewtonMeter outTorque,
-			PerSecond outAngularVelocity)
-		{
-			var dryOperatingPoint1 = FindOperatingPoint(outTorque, outAngularVelocity);
-			var engineResponse = (ResponseDryRun)
-				NextComponent.Request(absTime, dt, dryOperatingPoint1.InTorque, dryOperatingPoint1.InAngularVelocity, true);
-
-			var dryOperatingPoint2 = outTorque.IsGreater(0) && DataBus.BrakePower.IsEqual(0)
-				? GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse)
-				: GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse);
-
-			var delta = (outTorque - dryOperatingPoint2.OutTorque) *
-						(PreviousState.OutAngularVelocity + dryOperatingPoint2.OutAngularVelocity) / 2.0;
-
-			return new ResponseDryRun() {
-				Source = this,
-				DeltaFullLoad = delta,
-				DeltaDragLoad = delta,
-				TorqueConverterOperatingPoint = dryOperatingPoint2
-			};
-		}
+        ///// <summary>
+        ///// Handle Requests when Torque Converter is active
+        ///// </summary>
+        ///// <param name="absTime"></param>
+        ///// <param name="dt"></param>
+        ///// <param name="outTorque">torque at the output of the torque converter (to the mechanical gear)</param>
+        ///// <param name="outAngularVelocity">angular velocity at the output of the torque converter (to the mechanical gear)</param>
+        ///// <param name="dryRun"></param>
+        ///// <returns></returns>
+        //private IResponse RequestTorqueConverter(Second absTime, Second dt, NewtonMeter outTorque,
+        //    PerSecond outAngularVelocity, bool dryRun = false)
+        //{
+        //    if (dryRun) {
+        //        return RequestTorqueConverterDryRun(absTime, dt, outTorque, outAngularVelocity);
+        //    }
+        //    var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
+        //    CurrentState.TorqueConverterOperatingPoint = operatingPoint;
+        //    if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) {
+        //        // a different operating point was found...
+        //        var delta = (outTorque - operatingPoint.OutTorque) *
+        //                    (PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0;
+        //        if (!delta.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) {
+        //            if (delta > 0) {
+        //                return new ResponseOverload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
+        //            }
+        //            return new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
+        //        }
+        //    }
+        //    var avgPower = (PreviousState.TorqueConverterOperatingPoint.InAngularVelocity * PreviousState.TorqueConverterOperatingPoint.InTorque + CurrentState.TorqueConverterOperatingPoint.InAngularVelocity * CurrentState.TorqueConverterOperatingPoint.InTorque) / 2;
+        //    var inTorque = avgPower / ((PreviousState.TorqueConverterOperatingPoint.InAngularVelocity + CurrentState.TorqueConverterOperatingPoint.InAngularVelocity) / 2);
+        //    var tcResponse = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity);
+        //    return tcResponse;
+        //}
+
+        ///// <summary>
+        ///// Handle Requests when searching an operating point and torque converter is active
+        ///// </summary>
+        ///// <param name="absTime"></param>
+        ///// <param name="dt"></param>
+        ///// <param name="outTorque"></param>
+        ///// <param name="outAngularVelocity"></param>
+        ///// <returns></returns>
+        //private IResponse RequestTorqueConverterDryRun(Second absTime, Second dt, NewtonMeter outTorque,
+        //    PerSecond outAngularVelocity)
+        //{
+        //    var dryOperatingPoint1 = FindOperatingPoint(outTorque, outAngularVelocity);
+        //    var engineResponse = (ResponseDryRun)
+        //        NextComponent.Request(absTime, dt, dryOperatingPoint1.InTorque, dryOperatingPoint1.InAngularVelocity, true);
+
+        //    var dryOperatingPoint2 = outTorque.IsGreater(0) && DataBus.BrakePower.IsEqual(0)
+        //        ? GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse)
+        //        : GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse);
+
+        //    var delta = (outTorque - dryOperatingPoint2.OutTorque) *
+        //                (PreviousState.OutAngularVelocity + dryOperatingPoint2.OutAngularVelocity) / 2.0;
+
+        //    return new ResponseDryRun() {
+        //        Source = this,
+        //        DeltaFullLoad = delta,
+        //        DeltaDragLoad = delta,
+        //        TorqueConverterOperatingPoint = dryOperatingPoint2
+        //    };
+        //}
 
 		/// <summary>
 		/// Handles Requests when no gear is disengaged
@@ -345,87 +349,89 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			CurrentState.SetState(0.SI<NewtonMeter>(), 0.SI<PerSecond>(), outTorque, outAngularVelocity);
 			CurrentState.Gear = Gear;
+            if (TorqueConverter != null)
+                TorqueConverter.Locked(CurrentState.InTorque, DataBus.EngineIdleSpeed);
 
 			var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
 			disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
 			return disengagedResponse;
 		}
 
-		private TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
-			PerSecond outAngularVelocity)
-		{
-			var operatingPointList = TorqueConverter.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed);
-			if (operatingPointList.Count == 0) {
-				Log.Debug("CycleGearbox: Failed to find torque converter operating point, fallback: creeping");
-				var tqOperatingPoint = TorqueConverter.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
-				return tqOperatingPoint;
-			}
-
-			var operatingPoint = SelectOperatingPoint(operatingPointList);
-			if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
-				operatingPoint = TorqueConverter.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
-			}
-			return operatingPoint;
-		}
-
-		private TorqueConverterOperatingPoint SelectOperatingPoint(IList<TorqueConverterOperatingPoint> operatingPointList)
-		{
-			if (operatingPointList.Count == 1) {
-				return operatingPointList[0];
-			}
-
-			var filtered = operatingPointList.Where(x =>
-					(x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity),
-						Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) &&
-					(x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity),
-						Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())
-			).ToArray();
-			if (filtered.Length == 1) {
-				return filtered.First();
-			}
-			return operatingPointList[0];
-		}
-
-		private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
-			ResponseDryRun engineResponse)
-		{
-			try {
-				var operatingPoint =
-					ModelData.TorqueConverterData.FindOperatingPointForPowerDemand(
-						engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand,
-						DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt);
-				if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
-					operatingPoint = ModelData.TorqueConverterData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
-				}
-				if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
-					operatingPoint = ModelData.TorqueConverterData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
-				}
-				return operatingPoint;
-			} catch (VectoException ve) {
-				Log.Error(ve, "failed to find torque converter operating point for DragPower {0}", engineResponse.DragPower);
-				//throw;
-				return ModelData.TorqueConverterData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity);
-			}
-		}
-
-		private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
-			ResponseDryRun engineResponse)
-		{
-			try {
-				var operatingPoint =
-					ModelData.TorqueConverterData.FindOperatingPointForPowerDemand(
-						engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
-						DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt);
-				if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
-					operatingPoint = ModelData.TorqueConverterData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
-				}
-				return operatingPoint;
-			} catch (VectoException ve) {
-				Log.Error(ve, "failed to find torque converter operating point for MaxPower {0}",
-					engineResponse.DynamicFullLoadPower);
-				throw;
-			}
-		}
+        //private TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
+        //    PerSecond outAngularVelocity)
+        //{
+        //    var operatingPointList = TorqueConverter.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed);
+        //    if (operatingPointList.Count == 0) {
+        //        Log.Debug("CycleGearbox: Failed to find torque converter operating point, fallback: creeping");
+        //        var tqOperatingPoint = TorqueConverter.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
+        //        return tqOperatingPoint;
+        //    }
+
+        //    var operatingPoint = SelectOperatingPoint(operatingPointList);
+        //    if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
+        //        operatingPoint = TorqueConverter.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
+        //    }
+        //    return operatingPoint;
+        //}
+
+        //private TorqueConverterOperatingPoint SelectOperatingPoint(IList<TorqueConverterOperatingPoint> operatingPointList)
+        //{
+        //    if (operatingPointList.Count == 1) {
+        //        return operatingPointList[0];
+        //    }
+
+        //    var filtered = operatingPointList.Where(x =>
+        //            (x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity),
+        //                Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) &&
+        //            (x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity),
+        //                Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())
+        //    ).ToArray();
+        //    if (filtered.Length == 1) {
+        //        return filtered.First();
+        //    }
+        //    return operatingPointList[0];
+        //}
+
+        //private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
+        //    ResponseDryRun engineResponse)
+        //{
+        //    try {
+        //        var operatingPoint =
+        //            ModelData.TorqueConverterData.FindOperatingPointForPowerDemand(
+        //                engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand,
+        //                DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt);
+        //        if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
+        //            operatingPoint = ModelData.TorqueConverterData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
+        //        }
+        //        if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+        //            operatingPoint = ModelData.TorqueConverterData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
+        //        }
+        //        return operatingPoint;
+        //    } catch (VectoException ve) {
+        //        Log.Error(ve, "failed to find torque converter operating point for DragPower {0}", engineResponse.DragPower);
+        //        //throw;
+        //        return ModelData.TorqueConverterData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity);
+        //    }
+        //}
+
+        //private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
+        //    ResponseDryRun engineResponse)
+        //{
+        //    try {
+        //        var operatingPoint =
+        //            ModelData.TorqueConverterData.FindOperatingPointForPowerDemand(
+        //                engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
+        //                DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt);
+        //        if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
+        //            operatingPoint = ModelData.TorqueConverterData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
+        //        }
+        //        return operatingPoint;
+        //    } catch (VectoException ve) {
+        //        Log.Error(ve, "failed to find torque converter operating point for MaxPower {0}",
+        //            engineResponse.DynamicFullLoadPower);
+        //        throw;
+        //    }
+        //}
 
 		protected override void DoWriteModalResults(IModalDataContainer container)
 		{
@@ -438,46 +444,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			if (ModelData.Type.AutomaticTransmission()) {
 				container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive;
 			}
-			if (TorqueConverter != null) {
-				DoWriteTorqueConverterModalResults(container, avgInAngularSpeed);
-			}
+			// torque converter fields are written by TorqueConverter (if present), called from Vehicle container 
 		}
 
-		private void DoWriteTorqueConverterModalResults(IModalDataContainer container, PerSecond avgInAngularSpeed)
-		{
-			if (CurrentState.TorqueConverterOperatingPoint == null) {
-				container[ModalResultField.TorqueConverterTorqueRatio] = 1.0;
-				container[ModalResultField.TorqueConverterSpeedRatio] = 1.0;
-
-				container[ModalResultField.TC_TorqueIn] = CurrentState.InTorque;
-				container[ModalResultField.TC_TorqueOut] = CurrentState.InTorque;
-				container[ModalResultField.TC_angularSpeedIn] = CurrentState.InAngularVelocity;
-				container[ModalResultField.TC_angularSpeedOut] = CurrentState.OutAngularVelocity;
-
-				container[ModalResultField.P_TC_out] = CurrentState.InTorque * avgInAngularSpeed;
-				container[ModalResultField.P_TC_loss] = 0.SI<Watt>();
-			} else {
-				container[ModalResultField.TorqueConverterTorqueRatio] = CurrentState.TorqueConverterOperatingPoint.TorqueRatio;
-				container[ModalResultField.TorqueConverterSpeedRatio] = CurrentState.TorqueConverterOperatingPoint.SpeedRatio;
-
-				container[ModalResultField.TC_TorqueIn] = CurrentState.TorqueConverterOperatingPoint.InTorque;
-				container[ModalResultField.TC_TorqueOut] = CurrentState.TorqueConverterOperatingPoint.OutTorque;
-				container[ModalResultField.TC_angularSpeedIn] = CurrentState.TorqueConverterOperatingPoint.InAngularVelocity;
-				container[ModalResultField.TC_angularSpeedOut] = CurrentState.TorqueConverterOperatingPoint.OutAngularVelocity;
-
-				var avgOutVelocity = ((PreviousState.TorqueConverterOperatingPoint != null
-										? PreviousState.TorqueConverterOperatingPoint.OutAngularVelocity
-										: PreviousState.InAngularVelocity) +
-									CurrentState.TorqueConverterOperatingPoint.OutAngularVelocity) / 2.0;
-				var avgInVelocity = ((PreviousState.TorqueConverterOperatingPoint != null
-										? PreviousState.TorqueConverterOperatingPoint.InAngularVelocity
-										: PreviousState.InAngularVelocity) +
-									CurrentState.TorqueConverterOperatingPoint.InAngularVelocity) / 2.0;
-				container[ModalResultField.P_TC_out] = CurrentState.OutTorque * avgOutVelocity;
-				container[ModalResultField.P_TC_loss] = CurrentState.InTorque * avgInVelocity -
-														CurrentState.OutTorque * avgOutVelocity;
-			}
-		}
+		
 
 		protected override void DoCommitSimulationStep()
 		{
@@ -498,7 +468,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		#region ICluchInfo
 
-		public override bool ClutchClosed(Second absTime)
+	    public override bool ClutchClosed(Second absTime)
 		{
 			return (DataBus.DriverBehavior == DrivingBehavior.Braking
 						? DataBus.CycleData.LeftSample.Gear
@@ -510,7 +480,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public class CycleGearboxState : GearboxState
 		{
 			public bool TorqueConverterActive;
-			public TorqueConverterOperatingPoint TorqueConverterOperatingPoint;
+			//public TorqueConverterOperatingPoint TorqueConverterOperatingPoint;
 		}
+
+        public class CycleShiftStrategy : IShiftStrategy
+        {
+            public bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+                PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+            {
+                return false;
+            }
+
+            public uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
+            {
+                throw new System.NotImplementedException();
+            }
+
+            public uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+            {
+                throw new System.NotImplementedException();
+            }
+
+            public void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+            {
+                throw new System.NotImplementedException();
+            }
+
+            public IGearbox Gearbox { get; set; }
+        }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
index 40711b1c59..1517afd224 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
@@ -39,6 +39,7 @@ using TUGraz.VectoCore.Models.Connector.Ports;
 using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.OutputData;
 
@@ -47,7 +48,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>,
 		ITnInPort, ITnOutPort
 	{
-		protected readonly ATGearbox Gearbox;
+		protected readonly IGearboxInfo Gearbox;
 
 		protected readonly IShiftStrategy ShiftStrategy;
 
@@ -58,7 +59,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public ITnOutPort NextComponent { protected internal get; set; }
 
-		public TorqueConverter(ATGearbox gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container,
+		public TorqueConverter(IGearboxInfo gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container,
 			TorqueConverterData tcData, KilogramSquareMeter engineInertia) : base(container)
 		{
 			Gearbox = gearbox;
@@ -97,16 +98,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
 			bool dryRun = false)
 		{
+            //var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity)/ 2;
 			if (dryRun) {
 				var dryOperatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
 				var engineResponse = (ResponseDryRun)
 					NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque, dryOperatingPoint.InAngularVelocity, true);
 
 				dryOperatingPoint = outTorque.IsGreater(0) && DataBus.BrakePower.IsEqual(0)
-					? GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse)
-					: GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse);
-				engineResponse = (ResponseDryRun)NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque,
-					dryOperatingPoint.InAngularVelocity, true);
+					? GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse, PreviousState.InPower())
+					: GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse, PreviousState.InPower());
+
+                var dryAvgPower = (PreviousState.InAngularVelocity * PreviousState.InTorque + dryOperatingPoint.InAngularVelocity * dryOperatingPoint.InTorque) / 2;
+                var dryInTorque = dryAvgPower / ((PreviousState.InAngularVelocity + dryOperatingPoint.InAngularVelocity) / 2);
+				var engineResponse2 = (ResponseDryRun)NextComponent.Request(absTime, dt, dryInTorque, dryOperatingPoint.InAngularVelocity, true);
 
 				var delta = (outTorque - dryOperatingPoint.OutTorque) *
 							(PreviousState.OutAngularVelocity + dryOperatingPoint.OutAngularVelocity) / 2.0;
@@ -119,7 +123,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				};
 			}
 			var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
-			var ratio = Gearbox.ModelData.Gears[Gearbox.Gear].TorqueConverterRatio;
+			var ratio = Gearbox.GetGearData(Gearbox.Gear).TorqueConverterRatio;
 			if (ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, operatingPoint.InTorque,
 				operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) {
 				return new ResponseGearShift() { Source = this };
@@ -136,19 +140,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				}
 			}
 
-			CurrentState.SetState(operatingPoint.InTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity);
+            //var inAngularVelocity = 2 * operatingPoint.InAngularVelocity - PreviousState.InAngularVelocity;
+            CurrentState.SetState(operatingPoint.InTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity);
 			CurrentState.OperatingPoint = operatingPoint;
-			var retVal = NextComponent.Request(absTime, dt, operatingPoint.InTorque, operatingPoint.InAngularVelocity);
+            var avgPower = (PreviousState.InAngularVelocity * PreviousState.InTorque + CurrentState.InAngularVelocity * CurrentState.InTorque)/2;
+		    var inTorque = avgPower / ((PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2);
+		    var retVal = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity);
 			return retVal;
 		}
 
 		private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
-			ResponseDryRun engineResponse)
+            ResponseDryRun engineResponse, Watt previousPower)
 		{
 			try {
 				var operatingPoint =
 					ModelData.FindOperatingPointForPowerDemand(engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand,
-						DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt);
+						DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower);
 				if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
 					operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
 				}
@@ -164,13 +171,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
-			ResponseDryRun engineResponse)
+			ResponseDryRun engineResponse, Watt previousPower)
 		{
 			try {
 				var operatingPoint =
 					ModelData.FindOperatingPointForPowerDemand(
 						engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
-						DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt);
+						DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower);
 				if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
 					operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
 				}
@@ -258,6 +265,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public class TorqueConverterComponentState : SimpleComponentState
 		{
 			public TorqueConverterOperatingPoint OperatingPoint;
+
+		    public Watt InPower()
+		    {
+		        return InAngularVelocity * InTorque;
+		    }
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs
index 1eba4e81be..5e2a6c8f91 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs
@@ -273,7 +273,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 					tqInput), 1000.RPMtoRad(), tqLimit);
 
 			var operatingPoint = tqData.FindOperatingPointForPowerDemand(20000.SI<Watt>(), 113.5.SI<PerSecond>(),
-				1200.RPMtoRad(), 4.SI<KilogramSquareMeter>(), 0.5.SI<Second>());
+                1200.RPMtoRad(), 4.SI<KilogramSquareMeter>(), 0.5.SI<Second>(), 20000.SI<Watt>());
 
 			var tmp = tqData.FindOperatingPoint(operatingPoint.OutTorque, operatingPoint.OutAngularVelocity, 0.RPMtoRad());
 			var backward = tmp.First();
diff --git a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs
index edebdf3b3b..1840962ff8 100644
--- a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs
@@ -37,6 +37,7 @@ using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.OutputData;
 
@@ -81,7 +82,13 @@ namespace TUGraz.VectoCore.Tests.Utils
 			return 0.SI<Watt>();
 		}
 
-		public void Connect(ITnOutPort other)
+	    public Second LastShift { get; private set; }
+	    public GearData GetGearData(uint gear)
+	    {
+	        throw new NotImplementedException();
+	    }
+
+	    public void Connect(ITnOutPort other)
 		{
 			_outPort = other;
 		}
diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
index 32893d5634..3b8d39875c 100644
--- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
@@ -39,6 +39,7 @@ 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.Gearbox;
 using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Tests.Utils
@@ -66,7 +67,13 @@ namespace TUGraz.VectoCore.Tests.Utils
 			throw new System.NotImplementedException();
 		}
 
-		public PerSecond EngineSpeed { get; set; }
+	    public Second LastShift { get; private set; }
+	    public GearData GetGearData(uint gear)
+	    {
+	        throw new System.NotImplementedException();
+	    }
+
+	    public PerSecond EngineSpeed { get; set; }
 		public NewtonMeter EngineTorque { get; set; }
 
 		public Watt EngineStationaryFullPower(PerSecond angularSpeed)
-- 
GitLab