From 40972defc689f467876c9ae01f5ede7157903acc Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Wed, 21 Oct 2020 17:55:10 +0200
Subject: [PATCH] refactoring hybrid strategy and testcontainer for AT
 transmissions

---
 .../Simulation/Impl/PowertrainBuilder.cs      |  21 +-
 .../Impl/HybridController.cs                  |  10 +-
 .../Strategies/HybridStrategy.cs              | 262 ++++++++++--------
 .../Strategies/TestPowertrain.cs              |  12 +-
 .../VectoCore/Utils/ProviderExtensions.cs     |   7 +-
 .../Integration/Hybrid/ParallelHybridTest.cs  |   2 +-
 6 files changed, 178 insertions(+), 136 deletions(-)

diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
index 95d8e9dff1..37f2941d55 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
@@ -388,11 +388,19 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			var aux = new ElectricAuxiliary(container);
 			aux.AddConstant("P_aux_el", data.ElectricAuxDemand ?? 0.SI<Watt>());
 			es.Connect(aux);
-			
-			var strategy = new HybridStrategy(data, container);
-			var clutch = data.GearboxData.Type.AutomaticTransmission() ? null : new SwitchableClutch(container, data.EngineData);
 
-			var ctl = new HybridController(container, strategy, es, clutch);
+			HybridController ctl;
+			SwitchableClutch clutch = null;
+			if (data.GearboxData.Type.ManualTransmission()) {
+				var strategy = new HybridStrategy(data, container);
+				clutch = new SwitchableClutch(container, data.EngineData);
+				
+				ctl = new HybridController(container, strategy, es);
+			} else {
+				var strategy = new HybridStrategyAT(data, container);
+				
+				ctl = new HybridController(container, strategy, es);
+			}
 
 			// add engine before gearbox so that gearbox can obtain if an ICE is available already in constructor
 			var engine = new StopStartCombustionEngine(container, data.EngineData);
@@ -427,6 +435,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 				.AddComponent(engine, idleController)
 				.AddAuxiliaries(container, data);
 
+			if (data.ElectricMachinesData.Any(x => x.Item1 == PowertrainPosition.HybridP1)) {
+				if (gearbox is ATGearbox atGbx) {
+					atGbx.IdleController = idleController;
+				}
+			}
 			cycle.IdleController = idleController as IdleControllerSwitcher;
 
 			
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
index faf2757c36..ea29ea2331 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
@@ -36,11 +36,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected DebugData DebugData = new DebugData();
 
 
-		public HybridController(IVehicleContainer container, IHybridControlStrategy strategy, IElectricSystem es,
-			SwitchableClutch clutch) : base(container)
+		public HybridController(IVehicleContainer container, IHybridControlStrategy strategy, IElectricSystem es) : base(container)
 		{
 			_electricMotorCtl = new Dictionary<PowertrainPosition, ElectricMotorController>();
-			_shiftStrategy = container.RunData.GearboxData.Type.AutomaticTransmission() ? new HybridCtlATShiftStrategy(this, container) : new HybridCtlShiftStrategy(this, container);
+			_shiftStrategy = container.RunData.GearboxData.Type.AutomaticTransmission()
+				? new HybridCtlATShiftStrategy(this, container)
+				: new HybridCtlShiftStrategy(this, container);
 			_hybridStrategy = strategy;
 			strategy.Controller = this;
 
@@ -282,6 +283,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 
 		///=======================================================================================
+		
 		public class HybridCtlShiftStrategy : ShiftStrategy
 		{
 			protected HybridController _controller;
@@ -485,7 +487,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 
-		// - - - - - - - - - - - - - - - - 
+		///=======================================================================================
 
 		public class HybridCtlATShiftStrategy : HybridCtlShiftStrategy
 		{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
index 1e782411b0..aab9364b20 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
@@ -19,9 +19,140 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 {
+	public class HybridStrategy : AbstractHybridStrategy<Gearbox>
+	{
+		public HybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer) : base(runData,
+			vehicleContainer)
+		{
+			// register pre-processors
+			vehicleContainer.AddPreprocessor(GetGearshiftPreprocessor(runData));
+		}
+
+		protected ISimulationPreprocessor GetGearshiftPreprocessor(VectoRunData runData)
+		{
+			var maxG = runData.Cycle.Entries.Max(x => Math.Abs(x.RoadGradientPercent.Value())) + 1;
+			var grad = Convert.ToInt32(maxG / 2) * 2;
+			if (grad == 0) {
+				grad = 2;
+			}
+
+			var modData = new ModalDataContainer(runData, null, null);
+			var builder = new PowertrainBuilder(modData);
+			var testContainer = new SimplePowertrainContainer(runData);
+			builder.BuildSimpleHybridPowertrain(runData, testContainer);
+
+			return new VelocitySpeedGearshiftPreprocessor(VelocityDropData, runData.GearboxData.TractionInterruption,
+				testContainer, -grad, grad, 2);
+		}
+
+		protected override ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, HybridStrategyResponse cfg)
+		{
+			TestPowertrain.Gearbox.Gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear;
+			TestPowertrain.Gearbox.Disengaged = nextGear == 0;
+			TestPowertrain.Gearbox.DisengageGearbox = nextGear == 0;
+			TestPowertrain.Container.VehiclePort.Initialize(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
+			TestPowertrain.HybridController.ApplyStrategySettings(cfg);
+			TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity);
+			TestPowertrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses);
+			TestPowertrain.Battery?.Initialize(DataBus.BatteryInfo.StateOfCharge);
+			TestPowertrain.SuperCap?.Initialize(DataBus.BatteryInfo.StateOfCharge);
+
+			var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear;
+
+			if (nextGear != 0 && nextGear != currentGear) {
+				if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) {
+					return null;
+				}
+
+				if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear].Ratio >= ModelData.GearshiftParameters.RatioEarlyDownshiftFC) {
+					return null;
+				}
+
+				var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
+				if (!AllowEmergencyShift && !estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) {
+					return null;
+				}
+
 
+				var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift;
+				var vehicleSpeedPostShift = estimatedVelocityPostShift; // DataBus.VehicleInfo.VehicleSpeed - vDrop * ModelData.GearshiftParameters.VelocityDropFactor;
+				TestPowertrain.Gearbox.Gear = nextGear;
+				var init = TestPowertrain.Container.VehiclePort.Initialize(
+					vehicleSpeedPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
+				if (!AllowEmergencyShift && init.Engine.EngineSpeed.IsSmaller(ModelData.EngineData.IdleSpeed)) {
+					return null;
+				}
+			}
+
+			if (nextGear == 0) {
+				TestPowertrain.Gearbox._nextGear = Controller.ShiftStrategy.NextGear;
+				TestPowertrain.Gearbox.Disengaged = nextGear == 0;
+			}
+
+			//if (!PreviousState.GearboxEngaged) {
+			TestPowertrain.CombustionEngine.Initialize(
+				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorque,
+				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed);
+			TestPowertrain.CombustionEngine.PreviousState.EngineOn = //true;
+					(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineOn;
+			TestPowertrain.CombustionEngine.PreviousState.EnginePower =
+					(DataBus.EngineInfo as CombustionEngine).PreviousState.EnginePower;
+			TestPowertrain.CombustionEngine.PreviousState.dt = (DataBus.EngineInfo as CombustionEngine).PreviousState.dt;
+			TestPowertrain.CombustionEngine.PreviousState.EngineSpeed =
+				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed;
+			TestPowertrain.CombustionEngine.PreviousState.EngineTorque =
+				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorque;
+			TestPowertrain.CombustionEngine.PreviousState.EngineTorqueOut =
+				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorqueOut;
+			TestPowertrain.CombustionEngine.PreviousState.DynamicFullLoadTorque =
+				(DataBus.EngineInfo as CombustionEngine).PreviousState.DynamicFullLoadTorque;
+
+			TestPowertrain.Gearbox.PreviousState.InAngularVelocity =
+				(DataBus.GearboxInfo as Gearbox).PreviousState.InAngularVelocity;
+
+			TestPowertrain.Clutch.PreviousState.InAngularVelocity =
+				(DataBus.ClutchInfo as SwitchableClutch).PreviousState.InAngularVelocity;
+
+			//}
 
-	public class HybridStrategy : LoggingObject, IHybridControlStrategy
+			var pos = ModelData.ElectricMachinesData.FirstOrDefault().Item1;
+			TestPowertrain.ElectricMotor.ThermalBuffer =
+				(DataBus.ElectricMotorInfo(pos) as ElectricMotor).ThermalBuffer;
+			TestPowertrain.ElectricMotor.DeRatingActive =
+				(DataBus.ElectricMotorInfo(pos) as ElectricMotor).DeRatingActive;
+
+			if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP2 != null) {
+				TestPowertrain.ElectricMotorP2.PreviousState.OutAngularVelocity =
+					DataBus.ElectricMotorInfo(PowertrainPosition.HybridP2).ElectricMotorSpeed;
+			}
+			if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP3 != null) {
+				TestPowertrain.ElectricMotorP3.PreviousState.OutAngularVelocity =
+					DataBus.ElectricMotorInfo(PowertrainPosition.HybridP3).ElectricMotorSpeed;
+			}
+
+			var retVal = TestPowertrain.HybridController.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true);
+
+			return retVal as ResponseDryRun;
+		}
+
+	}
+
+	public class HybridStrategyAT : AbstractHybridStrategy<ATGearbox>
+	{
+		public HybridStrategyAT(VectoRunData runData, IVehicleContainer vehicleContainer) : base(runData,
+			vehicleContainer)
+		{
+
+		}
+
+		protected override ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			uint nextGear, HybridStrategyResponse cfg)
+		{
+			throw new NotImplementedException();
+		}
+	}
+
+	public abstract class AbstractHybridStrategy<T> : LoggingObject, IHybridControlStrategy where T: class, IHybridControlledGearbox 
 	{
 
 		public class StrategyState
@@ -51,33 +182,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			public HybridResultEntry Solution { get; set; }
 		}
 
-		private VectoRunData ModelData;
-		private IDataBus DataBus;
+		protected VectoRunData ModelData;
+		protected IDataBus DataBus;
 
 		protected Dictionary<PowertrainPosition, Tuple<PerSecond, NewtonMeter>> ElectricMotorsOff;
 
-		private bool ElectricMotorCanPropellDuringTractionInterruption;
+		protected bool ElectricMotorCanPropellDuringTractionInterruption;
 
 		//private Second lastShiftTime;
 
-		private TestPowertrain TestPowertrain;
+		protected TestPowertrain<T> TestPowertrain;
 
 		protected readonly VelocityRollingLookup VelocityDropData = new VelocityRollingLookup();
 
 
 		protected StrategyState CurrentState = new StrategyState();
 		protected StrategyState PreviousState = new StrategyState();
-		private double IceRampUpCosts;
-		private double IceIdlingCosts;
+		protected double IceRampUpCosts;
+		protected double IceIdlingCosts;
 
 		protected HybridStrategyParameters StrategyParameters;
 
 		protected DebugData DebugData = new DebugData();
-		private WattSecond BatteryDischargeEnergyThreshold;
+		protected WattSecond BatteryDischargeEnergyThreshold;
 
 		protected DryRunSolutionState DryRunSolution;
 
-		public HybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer)
+		public AbstractHybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer)
 		{
 			DataBus = vehicleContainer;
 			ModelData = runData;
@@ -112,10 +243,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			var testContainer = new SimplePowertrainContainer(runData);
 			builder.BuildSimpleHybridPowertrain(runData, testContainer);
 
-			TestPowertrain = new TestPowertrain(testContainer, DataBus);
+			TestPowertrain = new TestPowertrain<T>(testContainer, DataBus);
+			
 			
-			// register pre-processors
-			vehicleContainer.AddPreprocessor(GetGearshiftPreprocessor(runData));
 
 			var shiftStrategyParameters = runData.GearshiftParameters;
 			if (shiftStrategyParameters == null) {
@@ -138,22 +268,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			AllowEmergencyShift = false;
 		}
 
-		protected ISimulationPreprocessor GetGearshiftPreprocessor(VectoRunData runData)
-		{
-			var maxG = runData.Cycle.Entries.Max(x => Math.Abs(x.RoadGradientPercent.Value())) + 1;
-			var grad = Convert.ToInt32(maxG / 2) * 2;
-			if (grad == 0) {
-				grad = 2;
-			}
-
-			var modData = new ModalDataContainer(runData, null, null);
-			var builder = new PowertrainBuilder(modData);
-			var testContainer = new SimplePowertrainContainer(runData);
-			builder.BuildSimpleHybridPowertrain(runData, testContainer);
-
-			return new VelocitySpeedGearshiftPreprocessor(VelocityDropData, runData.GearboxData.TractionInterruption,
-				testContainer, -grad, grad, 2);
-		}
 		
 		public virtual IHybridController Controller { protected get; set; }
 
@@ -283,6 +397,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			DryRunSolution = null;
 		}
 
+		protected abstract ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque,
+			PerSecond outAngularVelocity, uint nextGear, HybridStrategyResponse cfg);
+
 		private IHybridStrategyResponse HandleRequestExceedsMaxPower(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun)
 		{
 			// issue dry-run to get max available power from EM and ICE,
@@ -1200,95 +1317,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			return tmp;
 		}
 
-		private ResponseDryRun RequestDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, HybridStrategyResponse cfg)
-		{
-			TestPowertrain.Gearbox.Gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear;
-			TestPowertrain.Gearbox.Disengaged = nextGear == 0;
-			TestPowertrain.Gearbox.DisengageGearbox = nextGear == 0;
-			TestPowertrain.Container.VehiclePort.Initialize(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
-			TestPowertrain.HybridController.ApplyStrategySettings(cfg);
-			TestPowertrain.HybridController.Initialize(Controller.PreviousState.OutTorque, Controller.PreviousState.OutAngularVelocity);
-			TestPowertrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses);
-			TestPowertrain.Battery?.Initialize(DataBus.BatteryInfo.StateOfCharge);
-			TestPowertrain.SuperCap?.Initialize(DataBus.BatteryInfo.StateOfCharge);
-
-			var currentGear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear;
-			
-			if (nextGear != 0 && nextGear != currentGear) {
-				if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear].Ratio > ModelData.GearshiftParameters.RatioEarlyUpshiftFC) {
-					return null;
-				}
-
-				if (!AllowEmergencyShift && ModelData.GearboxData.Gears[nextGear].Ratio >= ModelData.GearshiftParameters.RatioEarlyDownshiftFC) {
-					return null;
-				}
-
-				var estimatedVelocityPostShift = VelocityDropData.Interpolate(DataBus.VehicleInfo.VehicleSpeed, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
-				if (!AllowEmergencyShift && !estimatedVelocityPostShift.IsGreater(DeclarationData.GearboxTCU.MIN_SPEED_AFTER_TRACTION_INTERRUPTION)) {
-					return null;
-				}
-
-
-				var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift;
-				var vehicleSpeedPostShift = estimatedVelocityPostShift; // DataBus.VehicleInfo.VehicleSpeed - vDrop * ModelData.GearshiftParameters.VelocityDropFactor;
-				TestPowertrain.Gearbox.Gear = nextGear;
-				var init = TestPowertrain.Container.VehiclePort.Initialize(
-					vehicleSpeedPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
-				if (!AllowEmergencyShift && init.Engine.EngineSpeed.IsSmaller(ModelData.EngineData.IdleSpeed)) {
-					return null;
-				}
-			}
-
-			if (nextGear == 0) {
-				TestPowertrain.Gearbox._nextGear = Controller.ShiftStrategy.NextGear;
-				TestPowertrain.Gearbox.Disengaged = nextGear == 0;
-			}
-
-			//if (!PreviousState.GearboxEngaged) {
-			TestPowertrain.CombustionEngine.Initialize(
-				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorque,
-				(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed);
-			TestPowertrain.CombustionEngine.PreviousState.EngineOn = //true;
-					(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineOn;
-			TestPowertrain.CombustionEngine.PreviousState.EnginePower =
-					(DataBus.EngineInfo as CombustionEngine).PreviousState.EnginePower;
-				TestPowertrain.CombustionEngine.PreviousState.dt = (DataBus.EngineInfo as CombustionEngine).PreviousState.dt;
-				TestPowertrain.CombustionEngine.PreviousState.EngineSpeed =
-					(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed;
-				TestPowertrain.CombustionEngine.PreviousState.EngineTorque =
-					(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorque;
-				TestPowertrain.CombustionEngine.PreviousState.EngineTorqueOut =
-					(DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorqueOut;
-				TestPowertrain.CombustionEngine.PreviousState.DynamicFullLoadTorque =
-					(DataBus.EngineInfo as CombustionEngine).PreviousState.DynamicFullLoadTorque;
-
-				TestPowertrain.Gearbox.PreviousState.InAngularVelocity =
-					(DataBus.GearboxInfo as Gearbox).PreviousState.InAngularVelocity;
-
-				TestPowertrain.Clutch.PreviousState.InAngularVelocity =
-					(DataBus.ClutchInfo as SwitchableClutch).PreviousState.InAngularVelocity;
-				
-			//}
-
-			var pos = ModelData.ElectricMachinesData.FirstOrDefault().Item1;
-			TestPowertrain.ElectricMotor.ThermalBuffer =
-				(DataBus.ElectricMotorInfo(pos) as ElectricMotor).ThermalBuffer;
-			TestPowertrain.ElectricMotor.DeRatingActive =
-				(DataBus.ElectricMotorInfo(pos) as ElectricMotor).DeRatingActive;
-
-			if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP2 != null) {
-				TestPowertrain.ElectricMotorP2.PreviousState.OutAngularVelocity =
-					DataBus.ElectricMotorInfo(PowertrainPosition.HybridP2).ElectricMotorSpeed;
-			}
-			if (/*nextGear != DataBus.GearboxInfo.Gear && */TestPowertrain.ElectricMotorP3 != null) {
-				TestPowertrain.ElectricMotorP3.PreviousState.OutAngularVelocity =
-					DataBus.ElectricMotorInfo(PowertrainPosition.HybridP3).ElectricMotorSpeed;
-			}
-
-			var retVal = TestPowertrain.HybridController.NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, true);
-
-			return retVal as ResponseDryRun;
-		}
 
 		private void CalcualteCosts(IResponse resp, Second dt, HybridResultEntry tmp, bool allowIceOff, bool dryRun)
 		{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs
index 6b73ac25df..4e220c12d4 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs
@@ -11,11 +11,11 @@ using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies {
-	public class TestPowertrain
+	public class TestPowertrain<T> where T: class, IHybridControlledGearbox
 	{
 		public SimplePowertrainContainer Container;
-		public Gearbox Gearbox;
-		public ATGearbox ATGearbox;
+		public T Gearbox;
+		
 		public SimpleHybridController HybridController;
 		public Battery Battery;
 		public SuperCap SuperCap;
@@ -33,8 +33,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies {
 		public TestPowertrain(SimplePowertrainContainer container, IDataBus realContainer)
 		{
 			Container = container;
-			Gearbox = Container.GearboxCtl as Gearbox;
-			ATGearbox = container.GearboxCtl as ATGearbox;
+			Gearbox = Container.GearboxCtl as T;
+			
 			HybridController = Container.HybridController as SimpleHybridController;
 			Battery = Container.BatteryInfo as Battery;
 			SuperCap = Container.BatteryInfo as SuperCap;
@@ -47,7 +47,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies {
 			ElectricMotorP3 = container.ElectricMotors.ContainsKey(PowertrainPosition.HybridP3)
 				? container.ElectricMotors[PowertrainPosition.HybridP3] as ElectricMotor
 				: null;
-			if (Gearbox == null && ATGearbox == null) {
+			if (Gearbox == null) {
 				throw new VectoException("Unknown gearboxtype in TestContainer: {0}", Container.GearboxCtl.GetType().FullName);
 			}
 
diff --git a/VectoCore/VectoCore/Utils/ProviderExtensions.cs b/VectoCore/VectoCore/Utils/ProviderExtensions.cs
index 614d0baa47..66573e5f23 100644
--- a/VectoCore/VectoCore/Utils/ProviderExtensions.cs
+++ b/VectoCore/VectoCore/Utils/ProviderExtensions.cs
@@ -99,12 +99,11 @@ namespace TUGraz.VectoCore.Utils
 				idleController = next.IdleController;
 			}
 
-			var clutch = prev as IClutch;
-			if (clutch != null) {
+			if (prev is IClutch clutch) {
 				clutch.IdleController = idleController;
 			}
-			var atGbx = prev as ATGearbox;
-			if (atGbx != null) {
+
+			if (prev is ATGearbox atGbx) {
 				atGbx.IdleController = idleController;
 			}
 
diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
index 9e52f797e7..23f3e5ad48 100644
--- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
@@ -1005,7 +1005,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			battery.Initialize(initialBatCharge);
 
 			var clutch = new SwitchableClutch(container, runData.EngineData);
-			var ctl = new HybridController(container, strategy, es, clutch);
+			var ctl = new HybridController(container, strategy, es);
 
 			es.Connect(battery);
 
-- 
GitLab