From 2b2d2ef615530c78b6a17958e66f4855242fb744 Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Tue, 30 Aug 2016 13:00:33 +0200
Subject: [PATCH] Changed AddComponent extension for CombustionEngine (included
 PTO Idle Controller)

---
 .../Simulation/Impl/PowertrainBuilder.cs      | 53 ++++++++----
 .../VectoCore/Utils/ProviderExtensions.cs     | 69 ++++++++++++++--
 VectoCore/VectoCore/VectoCore.csproj          |  6 +-
 .../VectoCoreTest/Integration/ATPowerTrain.cs | 31 ++++---
 .../Integration/CoachAdvancedAuxPowertrain.cs | 20 ++---
 .../Integration/CoachPowerTrain.cs            | 20 ++---
 .../SimulationRuns/FullPowertrain.cs          | 21 +++--
 .../SimulationRuns/MinimalPowertrain.cs       | 80 +++++++++----------
 .../Integration/Truck40tPowerTrain.cs         |  2 +-
 9 files changed, 191 insertions(+), 111 deletions(-)

diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
index 839cf4107f..a5d6fa2d4f 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
@@ -103,13 +103,16 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			var gearbox = new CycleGearbox(container, data.GearboxData);
 
 			// PWheelCycle --> AxleGear --> CycleClutch --> Engine <-- Aux
-			new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio,
+			var powertrain = new PWheelCycle(container, data.Cycle, data.AxleGearData.AxleGear.Ratio,
 					gearbox.ModelData.Gears.ToDictionary(g => g.Key, g => g.Value.Ratio))
 				.AddComponent(new AxleGear(container, data.AxleGearData))
 				.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
-				.AddComponent(gearbox, data.Retarder, data.PTOTransmission, container)
-				.AddComponent(new CycleClutch(container))
-				.AddComponent(new CombustionEngine(container, data.EngineData, pt1Disabled: true))
+				.AddComponent(gearbox, data.Retarder, data.PTO, container)
+				.AddComponent(new CycleClutch(container));
+			var engine = new CombustionEngine(container, data.EngineData, pt1Disabled: true);
+			var idleController = GetIdleController(data.PTO, engine, container);
+
+			powertrain.AddComponent(engine, idleController, container)
 				.AddAuxiliaries(container, data);
 
 			return container;
@@ -125,17 +128,22 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 			// MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes 
 			// --> axleGear --> (retarder) --> CycleGearBox --> (retarder) --> CycleClutch --> engine <-- Aux
-			var powertrain = new MeasuredSpeedDrivingCycle(container, data.Cycle)
+			var cycle = new MeasuredSpeedDrivingCycle(container, data.Cycle);
+			var powertrain = cycle
 				.AddComponent(new Vehicle(container, data.VehicleData))
 				.AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia))
 				.AddComponent(new Brakes(container))
 				.AddComponent(new AxleGear(container, data.AxleGearData))
 				.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
-				.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTOTransmission, container);
+				.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTO, container);
 			if (data.GearboxData.Type.ManualTransmission()) {
 				powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData));
 			}
-			powertrain.AddComponent(new CombustionEngine(container, data.EngineData))
+
+			var engine = new CombustionEngine(container, data.EngineData);
+			var idleController = GetIdleController(data.PTO, engine, container);
+
+			powertrain.AddComponent(engine, idleController, container)
 				.AddAuxiliaries(container, data);
 			_modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission();
 
@@ -152,15 +160,17 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 			// MeasuredSpeedDrivingCycle --> vehicle --> wheels --> brakes 
 			// --> axleGear --> (retarder) --> CycleGearBox --> (retarder) --> CycleClutch --> engine <-- Aux
-			new MeasuredSpeedDrivingCycle(container, data.Cycle)
+			var powertrain = new MeasuredSpeedDrivingCycle(container, data.Cycle)
 				.AddComponent(new Vehicle(container, data.VehicleData))
 				.AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia))
 				.AddComponent(new Brakes(container))
 				.AddComponent(new AxleGear(container, data.AxleGearData))
 				.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
-				.AddComponent(new CycleGearbox(container, data.GearboxData), data.Retarder, data.PTOTransmission, container)
-				.AddComponent(new CycleClutch(container))
-				.AddComponent(new CombustionEngine(container, data.EngineData))
+				.AddComponent(new CycleGearbox(container, data.GearboxData), data.Retarder, data.PTO, container)
+				.AddComponent(new CycleClutch(container));
+
+			var engine = new CombustionEngine(container, data.EngineData);
+			powertrain.AddComponent(engine, GetIdleController(data.PTO, engine, container), container)
 				.AddAuxiliaries(container, data);
 
 			return container;
@@ -176,24 +186,37 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 			// DistanceBasedDrivingCycle --> driver --> vehicle --> wheels 
 			// --> axleGear --> (retarder) --> gearBox --> (retarder) --> clutch --> engine <-- Aux
-			var powertrain = new DistanceBasedDrivingCycle(container, data.Cycle)
-				.AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy()))
+			var cycle = new DistanceBasedDrivingCycle(container, data.Cycle);
+			var powertrain = cycle.AddComponent(new Driver(container, data.DriverData, new DefaultDriverStrategy()))
 				.AddComponent(new Vehicle(container, data.VehicleData))
 				.AddComponent(new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia))
 				.AddComponent(new Brakes(container))
 				.AddComponent(new AxleGear(container, data.AxleGearData))
 				.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
-				.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTOTransmission, container);
+				.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTO, container);
 			if (data.GearboxData.Type.ManualTransmission()) {
 				powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData));
 			}
-			powertrain.AddComponent(new CombustionEngine(container, data.EngineData)).AddAuxiliaries(container, data);
+
+			var engine = new CombustionEngine(container, data.EngineData);
+			var idleController = GetIdleController(data.PTO, engine, container);
+			cycle.IdleController = idleController as IdleControllerSwitcher;
+
+			powertrain.AddComponent(engine, idleController, container)
+				.AddAuxiliaries(container, data);
 
 			_modData.HasTorqueConverter = data.GearboxData.Type.AutomaticTransmission();
 
 			return container;
 		}
 
+		private static IIdleController GetIdleController(PTOData pto, CombustionEngine engine, IVehicleContainer container)
+		{
+			return pto == null
+				? engine.IdleController
+				: new IdleControllerSwitcher(engine.IdleController, new PTOCycleController(container, pto.PTOCycle));
+		}
+
 		internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container)
 		{
 			var conventionalAux = CreateAuxiliaries(data, container);
diff --git a/VectoCore/VectoCore/Utils/ProviderExtensions.cs b/VectoCore/VectoCore/Utils/ProviderExtensions.cs
index 9cab25a445..053a66714a 100644
--- a/VectoCore/VectoCore/Utils/ProviderExtensions.cs
+++ b/VectoCore/VectoCore/Utils/ProviderExtensions.cs
@@ -32,6 +32,7 @@
 using System;
 using System.Collections.Generic;
 using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.InputData.Reader;
 using TUGraz.VectoCore.Models.Connector.Ports;
 using TUGraz.VectoCore.Models.Declaration;
@@ -93,30 +94,30 @@ namespace TUGraz.VectoCore.Utils
 			return next;
 		}
 
-		public static CombustionEngine AddComponent(this IPowerTrainComponent prev, CombustionEngine next)
+		public static CombustionEngine AddComponent(this IPowerTrainComponent prev, CombustionEngine next,
+			IIdleController idleController, IVehicleContainer container)
 		{
 			prev.InPort().Connect(next.OutPort());
 
 			var clutch = prev as IClutch;
 			if (clutch != null) {
-				clutch.IdleController = next.IdleController;
+				clutch.IdleController = idleController;
 			}
 			var atGbx = prev as ATGearbox;
 			if (atGbx != null) {
-				atGbx.IdleController = next.IdleController;
+				atGbx.IdleController = idleController;
 			}
 
 			return next;
 		}
 
 		public static IPowerTrainComponent AddComponent(this IPowerTrainComponent prev, IGearbox gearbox, RetarderData data,
-			PTOTransmissionData pto, IVehicleContainer container)
+			PTOData pto, IVehicleContainer container)
 		{
 			if (pto != null) {
 				var aux = new GearboxAuxiliary(container);
 				aux.AddConstant("PTO_TRANSM", DeclarationData.PTOTransmission.Lookup(pto.TransmissionType));
 				aux.Add("PTO_IDLE", n => pto.LossMap.GetTorqueLoss(n) * n);
-				gearbox.PTOController = new PTOEngineCycleController(container, pto.PTOCycle);
 			}
 
 			switch (data.Type) {
@@ -133,4 +134,62 @@ namespace TUGraz.VectoCore.Utils
 			}
 		}
 	}
+
+	public class IdleControllerSwitcher : IIdleController
+	{
+		private readonly IIdleController _idleController;
+		private readonly PTOCycleController _ptoController;
+		private IIdleController _currentController;
+
+		public IdleControllerSwitcher(IIdleController idleController, PTOCycleController ptoController)
+		{
+			_idleController = idleController;
+			_ptoController = ptoController;
+
+			// default state is idleController
+			_currentController = _idleController;
+		}
+
+		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun = false)
+		{
+			return _currentController.Request(absTime, dt, outTorque, outAngularVelocity, dryRun);
+		}
+
+		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			throw new InvalidOperationException(string.Format("{0} cannot initialize.", GetType().FullName));
+		}
+
+		public ITnOutPort RequestPort
+		{
+			set
+			{
+				_idleController.RequestPort = value;
+				_ptoController.RequestPort = value;
+			}
+		}
+
+		public void Reset()
+		{
+			_idleController.Reset();
+			_ptoController.Reset();
+			_currentController = _idleController;
+		}
+
+		public void ActivatePTO()
+		{
+			_currentController = _ptoController;
+		}
+
+		public void ActivateIdle()
+		{
+			_currentController = _idleController;
+		}
+
+		public Second GetNextCycleTime()
+		{
+			return _ptoController.GetNextCycleTime();
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj
index 1b71ff4030..5b1eccc80b 100644
--- a/VectoCore/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore/VectoCore.csproj
@@ -142,7 +142,7 @@
     <Compile Include="InputData\Reader\ComponentData\TorqueConverterDataReader.cs" />
     <Compile Include="InputData\Reader\ComponentData\AuxiliaryDataReader.cs" />
     <Compile Include="Models\SimulationComponent\Data\Engine\FuelConsumptionMapReader.cs" />
-    <Compile Include="Models\SimulationComponent\Data\PTOTransmissionData.cs" />
+    <Compile Include="Models\SimulationComponent\Data\PTOData.cs" />
     <Compile Include="Models\SimulationComponent\ILossMap.cs" />
     <Compile Include="Models\SimulationComponent\Data\PTOLossMap.cs" />
     <Compile Include="Models\SimulationComponent\Impl\GearboxAuxiliary.cs" />
@@ -150,7 +150,7 @@
     <Compile Include="Models\SimulationComponent\Impl\ATGearbox.cs" />
     <Compile Include="Models\SimulationComponent\Impl\ATShiftStrategy.cs" />
     <Compile Include="Models\SimulationComponent\Impl\MeasuredSpeedDrivingCycle.cs" />
-    <Compile Include="Models\SimulationComponent\Impl\PTOEngineCycleController.cs" />
+    <Compile Include="Models\SimulationComponent\Impl\PTOCycleController.cs" />
     <Compile Include="Models\SimulationComponent\Impl\PWheelCycle.cs" />
     <Compile Include="Models\SimulationComponent\Impl\TorqueConverter.cs" />
     <Compile Include="Utils\ProviderExtensions.cs" />
@@ -186,7 +186,7 @@
     <Compile Include="Models\SimulationComponent\IAuxiliary.cs" />
     <Compile Include="Models\SimulationComponent\IAxlegear.cs" />
     <Compile Include="Models\SimulationComponent\IBrakes.cs" />
-    <Compile Include="Models\SimulationComponent\ICombustionEngineIdleController.cs" />
+    <Compile Include="Models\SimulationComponent\IIdleController.cs" />
     <Compile Include="Models\SimulationComponent\IDriverActions.cs" />
     <Compile Include="Models\SimulationComponent\IDriverStrategy.cs" />
     <Compile Include="Models\SimulationComponent\IDrivingCycleInfo.cs" />
diff --git a/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs
index 2c2db8674c..5ec64c0977 100644
--- a/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs
+++ b/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs
@@ -32,7 +32,6 @@ namespace TUGraz.VectoCore.Tests.Integration
 		public const string TorqueConverterPowerSplitFile = @"TestData\Components\AT_GBX\TorqueConverterPowerSplit.vtcc";
 		public const string GearboxShiftPolygonFile = @"TestData\Components\AT_GBX\AT-Shift.vgbs";
 
-
 		public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, GearboxType gbxType, string modFileName,
 			bool overspeed = false, KilogramSquareMeter gearBoxInertia = null)
 		{
@@ -72,7 +71,7 @@ namespace TUGraz.VectoCore.Tests.Integration
 				.AddComponent(new AxleGear(container, axleGearData))
 				.AddComponent(new DummyRetarder(container))
 				.AddComponent(new ATGearbox(container, gearboxData, new ATShiftStrategy(gearboxData, container)))
-				.AddComponent(engine);
+				.AddComponent(engine, null, container);
 
 			var aux = new EngineAuxiliary(container);
 			aux.AddConstant("", 0.SI<Watt>());
@@ -93,20 +92,20 @@ namespace TUGraz.VectoCore.Tests.Integration
 			return new GearboxData {
 				Type = gbxType == GearboxType.ATSerial ? GearboxType.ATSerial : GearboxType.ATPowerSplit,
 				Gears = ratios.Select((ratio, i) =>
-					Tuple.Create((uint)i,
-						new GearData {
-							//MaxTorque = 2300.SI<NewtonMeter>(),
-							LossMap = ratio.IsEqual(1)
-								? TransmissionLossMapReader.Create(0.96, ratio, string.Format("Gear {0}", i))
-								: TransmissionLossMapReader.Create(0.98, ratio, string.Format("Gear {0}", i)),
-							Ratio = ratio,
-							ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile),
-							TorqueConverterRatio = i == 0 ? (gbxType == GearboxType.ATPowerSplit ? 1.0 : ratio) : double.NaN,
-							TorqueConverterGearLossMap = i == 0
-								? TransmissionLossMapReader.Create(gbxType == GearboxType.ATPowerSplit ? 1.0 : 0.98, ratio,
-									string.Format("Gear {0}", i))
-								: null,
-						}))
+						Tuple.Create((uint)i,
+							new GearData {
+								//MaxTorque = 2300.SI<NewtonMeter>(),
+								LossMap = ratio.IsEqual(1)
+									? TransmissionLossMapReader.Create(0.96, ratio, string.Format("Gear {0}", i))
+									: TransmissionLossMapReader.Create(0.98, ratio, string.Format("Gear {0}", i)),
+								Ratio = ratio,
+								ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile),
+								TorqueConverterRatio = i == 0 ? (gbxType == GearboxType.ATPowerSplit ? 1.0 : ratio) : double.NaN,
+								TorqueConverterGearLossMap = i == 0
+									? TransmissionLossMapReader.Create(gbxType == GearboxType.ATPowerSplit ? 1.0 : 0.98, ratio,
+										string.Format("Gear {0}", i))
+									: null,
+							}))
 					.ToDictionary(k => k.Item1 + 1, v => v.Item2),
 				ShiftTime = 1.SI<Second>(),
 				Inertia = 0.SI<KilogramSquareMeter>(),
diff --git a/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs b/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs
index bc4a4b808f..58c13d773a 100644
--- a/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs
+++ b/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs
@@ -95,7 +95,7 @@ namespace TUGraz.VectoCore.Tests.Integration
 				.AddComponent(new DummyRetarder(container))
 				.AddComponent(new Gearbox(container, gearboxData, new AMTShiftStrategy(gearboxData, container)))
 				.AddComponent(new Clutch(container, engineData))
-				.AddComponent(engine);
+				.AddComponent(engine, null, container);
 
 			var aux = new BusAuxiliariesAdapter(container, AdvancedAuxFile, "Coach",
 				vehicleData.TotalVehicleWeight(), engineData.ConsumptionMap, engineData.IdleSpeed);
@@ -111,15 +111,15 @@ namespace TUGraz.VectoCore.Tests.Integration
 
 			return new GearboxData {
 				Gears = ratios.Select((ratio, i) =>
-					Tuple.Create((uint)i,
-						new GearData {
-							//MaxTorque = 2300.SI<NewtonMeter>(),
-							LossMap = ratio.IsEqual(1)
-								? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i))
-								: TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)),
-							Ratio = ratio,
-							ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile)
-						}))
+						Tuple.Create((uint)i,
+							new GearData {
+								//MaxTorque = 2300.SI<NewtonMeter>(),
+								LossMap = ratio.IsEqual(1)
+									? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i))
+									: TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)),
+								Ratio = ratio,
+								ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile)
+							}))
 					.ToDictionary(k => k.Item1 + 1, v => v.Item2),
 				ShiftTime = 2.SI<Second>(),
 				Inertia = 0.SI<KilogramSquareMeter>(),
diff --git a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs
index b832d2801c..163f6a9949 100644
--- a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs
+++ b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs
@@ -98,7 +98,7 @@ namespace TUGraz.VectoCore.Tests.Integration
 				.AddComponent(new DummyRetarder(container))
 				.AddComponent(new Gearbox(container, gearboxData, new AMTShiftStrategy(gearboxData, container)))
 				.AddComponent(clutch)
-				.AddComponent(engine);
+				.AddComponent(engine, null, container);
 
 			var aux = new EngineAuxiliary(container);
 			aux.AddConstant("", 0.SI<Watt>());
@@ -114,15 +114,15 @@ namespace TUGraz.VectoCore.Tests.Integration
 
 			return new GearboxData {
 				Gears = ratios.Select((ratio, i) =>
-					Tuple.Create((uint)i,
-						new GearData {
-							//MaxTorque = 2300.SI<NewtonMeter>(),
-							LossMap = ratio.IsEqual(1)
-								? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i))
-								: TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)),
-							Ratio = ratio,
-							ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile)
-						}))
+						Tuple.Create((uint)i,
+							new GearData {
+								//MaxTorque = 2300.SI<NewtonMeter>(),
+								LossMap = ratio.IsEqual(1)
+									? TransmissionLossMapReader.ReadFromFile(GearboxIndirectLoss, ratio, string.Format("Gear {0}", i))
+									: TransmissionLossMapReader.ReadFromFile(GearboxDirectLoss, ratio, string.Format("Gear {0}", i)),
+								Ratio = ratio,
+								ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile)
+							}))
 					.ToDictionary(k => k.Item1 + 1, v => v.Item2),
 				ShiftTime = 2.SI<Second>(),
 				Inertia = 0.SI<KilogramSquareMeter>(),
diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs
index 3baaded391..c40bb4b769 100644
--- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs
+++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs
@@ -90,8 +90,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 				.AddComponent(new AxleGear(container, axleGearData))
 				.AddComponent(new Gearbox(container, gearboxData, new AMTShiftStrategy(gearboxData, container)))
 				.AddComponent(new Clutch(container, engineData))
-				.AddComponent(new CombustionEngine(container, engineData));
-
+				.AddComponent(new CombustionEngine(container, engineData), null, container);
 
 			cyclePort.Initialize();
 
@@ -147,7 +146,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 				.AddComponent(new AxleGear(container, axleGearData))
 				.AddComponent(new Gearbox(container, gearboxData, new AMTShiftStrategy(gearboxData, container)))
 				.AddComponent(new Clutch(container, engineData))
-				.AddComponent(new CombustionEngine(container, engineData));
+				.AddComponent(new CombustionEngine(container, engineData), null, container);
 
 			cyclePort.Initialize();
 
@@ -217,7 +216,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 				.AddComponent(new AxleGear(container, axleGearData))
 				.AddComponent(new Gearbox(container, gearboxData, new AMTShiftStrategy(gearboxData, container)))
 				.AddComponent(new Clutch(container, engineData))
-				.AddComponent(new CombustionEngine(container, engineData));
+				.AddComponent(new CombustionEngine(container, engineData), null, container);
 
 			cyclePort.Initialize();
 
@@ -293,13 +292,13 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 
 			return new GearboxData {
 				Gears = ratios.Select((ratio, i) =>
-					Tuple.Create((uint)i,
-						new GearData {
-							MaxTorque = ratio > 5 ? 2300.SI<NewtonMeter>() : null,
-							LossMap = TransmissionLossMapReader.ReadFromFile(GearboxLossMap, ratio, string.Format("Gear {0}", i)),
-							Ratio = ratio,
-							ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile)
-						}))
+						Tuple.Create((uint)i,
+							new GearData {
+								MaxTorque = ratio > 5 ? 2300.SI<NewtonMeter>() : null,
+								LossMap = TransmissionLossMapReader.ReadFromFile(GearboxLossMap, ratio, string.Format("Gear {0}", i)),
+								Ratio = ratio,
+								ShiftPolygon = ShiftPolygonReader.ReadFromFile(GearboxShiftPolygonFile)
+							}))
 					.ToDictionary(k => k.Item1 + 1, v => v.Item2),
 				ShiftTime = 2.SI<Second>(),
 				Inertia = 0.SI<KilogramSquareMeter>(),
diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs
index 2eff2b8a78..cd4ae9eb25 100644
--- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs
+++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs
@@ -75,17 +75,17 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 
 			var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload");
 			var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", fileWriter);
-			var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData);
+			var container = new VehicleContainer(ExecutionMode.Engineering, modData);
 
-			var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy());
-			var engine = new CombustionEngine(vehicleContainer, engineData);
-			driver.AddComponent(new Vehicle(vehicleContainer, vehicleData))
-				.AddComponent(new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia))
-				.AddComponent(new AxleGear(vehicleContainer, axleGearData))
-				.AddComponent(new Clutch(vehicleContainer, engineData))
-				.AddComponent(engine);
+			var driver = new Driver(container, driverData, new DefaultDriverStrategy());
+			var engine = new CombustionEngine(container, engineData);
+			driver.AddComponent(new Vehicle(container, vehicleData))
+				.AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia))
+				.AddComponent(new AxleGear(container, axleGearData))
+				.AddComponent(new Clutch(container, engineData))
+				.AddComponent(engine, null, container);
 
-			var gbx = new MockGearbox(vehicleContainer);
+			var gbx = new MockGearbox(container);
 
 			var driverPort = driver.OutPort();
 
@@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 			//			time [s] , dist [m] , v_act [km/h] , v_targ [km/h] , acc [m/s²] , grad [%] , n_eng_avg [1/min] , T_eng_fcmap [Nm] , Tq_clutch [Nm] , Tq_full [Nm] , Tq_drag [Nm] , P_eng_out [kW] , P_eng_full [kW] , P_eng_drag [kW] , P_clutch_out [kW] , Pa Eng [kW] , P_aux [kW] , Gear [-] , Ploss GB [kW] , Ploss Diff [kW] , Ploss Retarder [kW] , Pa GB [kW] , Pa Veh [kW] , P_roll [kW] , P_air [kW] , P_slope [kW] , P_wheel_in [kW] , P_brake_loss [kW] , FC-Map [g/h] , FC-AUXc [g/h] , FC-WHTCc [g/h]
 			//			1.5      , 5        , 18           , 18            , 0          , 2.842372 , 964.1117  , 323.7562    , 323.7562       , 2208.664     , -158.0261    , 32.68693    , 222.9902     , -15.95456    , 32.68693       , 0           , 0         , 1        , 0             , 0               , 0                   , 0          , 0           , 5.965827   , 0.2423075 , 26.47879   , 32.68693    , 0           , 7574.113     , -             , -
 
-			AssertHelper.AreRelativeEqual(964.1117.RPMtoRad().Value(), vehicleContainer.Engine.EngineSpeed.Value());
+			AssertHelper.AreRelativeEqual(964.1117.RPMtoRad().Value(), container.Engine.EngineSpeed.Value());
 			Assert.AreEqual(2208.664, engine.PreviousState.StationaryFullLoadTorque.Value(), Tolerance);
 			Assert.AreEqual(-158.0261, engine.PreviousState.FullDragTorque.Value(), Tolerance);
 
@@ -121,20 +121,20 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 
 			var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain");
 			var modData = new ModalDataContainer("Coach_MinimalPowertrain", fileWriter);
-			var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData);
+			var container = new VehicleContainer(ExecutionMode.Engineering, modData);
 
-			var cycle = new DistanceBasedDrivingCycle(vehicleContainer, cycleData);
+			var cycle = new DistanceBasedDrivingCycle(container, cycleData);
 
-			cycle.AddComponent(new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()))
-				.AddComponent(new Vehicle(vehicleContainer, vehicleData))
-				.AddComponent(new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia))
-				.AddComponent(new Brakes(vehicleContainer))
-				.AddComponent(new AxleGear(vehicleContainer, axleGearData))
-				.AddComponent(new Clutch(vehicleContainer, engineData))
-				.AddComponent(new CombustionEngine(vehicleContainer, engineData));
+			cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy()))
+				.AddComponent(new Vehicle(container, vehicleData))
+				.AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia))
+				.AddComponent(new Brakes(container))
+				.AddComponent(new AxleGear(container, axleGearData))
+				.AddComponent(new Clutch(container, engineData))
+				.AddComponent(new CombustionEngine(container, engineData), null, container);
 			//engine.IdleController.RequestPort = clutch.IdleControlPort;
 
-			var gbx = new MockGearbox(vehicleContainer);
+			var gbx = new MockGearbox(container);
 
 			var cyclePort = cycle.OutPort();
 
@@ -146,23 +146,23 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 			var ds = Constants.SimulationSettings.DriveOffDistance;
 			var response = cyclePort.Request(absTime, ds);
 			Assert.IsInstanceOfType(response, typeof(ResponseSuccess));
-			vehicleContainer.CommitSimulationStep(absTime, response.SimulationInterval);
+			container.CommitSimulationStep(absTime, response.SimulationInterval);
 			absTime += response.SimulationInterval;
 
 			gbx.Gear = 1;
 			var cnt = 0;
-			while (!(response is ResponseCycleFinished) && vehicleContainer.Distance < 17000) {
+			while (!(response is ResponseCycleFinished) && container.Distance < 17000) {
 				response = cyclePort.Request(absTime, ds);
 				response.Switch().
 					Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance).
 					Case<ResponseCycleFinished>(r => { }).
 					Case<ResponseSuccess>(r => {
-						vehicleContainer.CommitSimulationStep(absTime, r.SimulationInterval);
+						container.CommitSimulationStep(absTime, r.SimulationInterval);
 						absTime += r.SimulationInterval;
 
-						ds = vehicleContainer.VehicleSpeed.IsEqual(0)
+						ds = container.VehicleSpeed.IsEqual(0)
 							? Constants.SimulationSettings.DriveOffDistance
-							: (Constants.SimulationSettings.TargetTimeInterval * vehicleContainer.VehicleSpeed)
+							: (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed)
 								.Cast<Meter>();
 
 						if (cnt++ % 100 == 0) {
@@ -193,19 +193,19 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 
 			var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload");
 			var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", fileWriter);
-			var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData);
-
-			var cycle = new DistanceBasedDrivingCycle(vehicleContainer, cycleData);
-			cycle.AddComponent(new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()))
-				.AddComponent(new Vehicle(vehicleContainer, vehicleData))
-				.AddComponent(new Wheels(vehicleContainer, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia))
-				.AddComponent(new Brakes(vehicleContainer))
-				.AddComponent(new AxleGear(vehicleContainer, axleGearData))
-				.AddComponent(new Clutch(vehicleContainer, engineData))
-				.AddComponent(new CombustionEngine(vehicleContainer, engineData));
+			var container = new VehicleContainer(ExecutionMode.Engineering, modData);
+
+			var cycle = new DistanceBasedDrivingCycle(container, cycleData);
+			cycle.AddComponent(new Driver(container, driverData, new DefaultDriverStrategy()))
+				.AddComponent(new Vehicle(container, vehicleData))
+				.AddComponent(new Wheels(container, vehicleData.DynamicTyreRadius, vehicleData.WheelsInertia))
+				.AddComponent(new Brakes(container))
+				.AddComponent(new AxleGear(container, axleGearData))
+				.AddComponent(new Clutch(container, engineData))
+				.AddComponent(new CombustionEngine(container, engineData), null, container);
 			//engine.IdleController.RequestPort = clutch.IdleControlPort;
 
-			var gbx = new MockGearbox(vehicleContainer);
+			var gbx = new MockGearbox(container);
 
 			var cyclePort = cycle.OutPort();
 
@@ -217,17 +217,17 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 
 			gbx.Gear = 1;
 			var ds = Constants.SimulationSettings.DriveOffDistance;
-			while (vehicleContainer.Distance < 100) {
+			while (container.Distance < 100) {
 				var response = cyclePort.Request(absTime, ds);
 				response.Switch().
 					Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance).
 					Case<ResponseSuccess>(r => {
-						vehicleContainer.CommitSimulationStep(absTime, r.SimulationInterval);
+						container.CommitSimulationStep(absTime, r.SimulationInterval);
 						absTime += r.SimulationInterval;
 
-						ds = vehicleContainer.VehicleSpeed.IsEqual(0)
+						ds = container.VehicleSpeed.IsEqual(0)
 							? Constants.SimulationSettings.DriveOffDistance
-							: (Constants.SimulationSettings.TargetTimeInterval * vehicleContainer.VehicleSpeed)
+							: (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed)
 								.Cast<Meter>();
 
 						modData.Finish(VectoRun.Status.Success);
diff --git a/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs
index 83d65c1a60..6704bad3a4 100644
--- a/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs
+++ b/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs
@@ -119,7 +119,7 @@ namespace TUGraz.VectoCore.Tests.Integration
 				.AddComponent(new DummyRetarder(container))
 				.AddComponent(new Gearbox(container, gearboxData, gbxStrategy))
 				.AddComponent(clutch)
-				.AddComponent(engine);
+				.AddComponent(engine, null, container);
 
 			var aux = new EngineAuxiliary(container);
 			aux.AddConstant("", 0.SI<Watt>());
-- 
GitLab