From 5971880effae1eb76cbdb9acb8c61a926a118b0d Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Fri, 26 Jun 2020 14:13:35 +0200
Subject: [PATCH] more work on hybrid strategy

---
 .../Models/HybridStrategyResponse.cs          |  14 ++
 VectoCommon/VectoCommon/Models/IResponse.cs   |   7 +
 VectoCommon/VectoCommon/VectoCommon.csproj    |   1 +
 .../Models/Connector/Ports/Impl/Response.cs   |   8 +-
 .../Models/Simulation/DataBus/IEngineInfo.cs  |   1 +
 .../Models/Simulation/DataBus/IGearboxInfo.cs |   1 +
 .../IHybridControlStrategy.cs                 |  12 +-
 .../SimulationComponent/Impl/ATGearbox.cs     |   4 +
 .../Impl/AbstractGearbox.cs                   |   1 +
 .../Models/SimulationComponent/Impl/Clutch.cs |   2 +-
 .../Impl/CombustionEngine.cs                  |  11 +-
 .../SimulationComponent/Impl/CycleGearbox.cs  |   6 +
 .../Impl/DefaultDriverStrategy.cs             |  10 +-
 .../SimulationComponent/Impl/Gearbox.cs       |  18 +-
 .../Impl/HybridController.cs                  |  20 ++-
 .../Impl/StopStartCombustionEngine.cs         |   7 +-
 .../Strategies/HybridStrategy.cs              | 156 ++++++++++++++----
 .../SimulationComponent/SwitchableClutch.cs   |   3 +-
 .../CO2Standards/MissionProfileWeights.csv    |   2 +
 .../Integration/Hybrid/ParallelHybridTest.cs  |   2 +-
 .../Models/SimulationComponent/ClutchTest.cs  |   5 +
 VectoCore/VectoCoreTest/Utils/MockGearbox.cs  |   5 +-
 VectoCore/VectoCoreTest/Utils/MockPorts.cs    |   5 +
 .../Utils/MockVehicleContainer.cs             |  10 ++
 24 files changed, 246 insertions(+), 65 deletions(-)
 create mode 100644 VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs

diff --git a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs
new file mode 100644
index 0000000000..192b32070c
--- /dev/null
+++ b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Utils;
+
+namespace TUGraz.VectoCommon.Models {
+	public class HybridStrategyResponse
+	{
+		public Dictionary<PowertrainPosition, NewtonMeter> MechanicalAssistPower;
+		public bool ShiftRequired { get; set; }
+		public uint NextGear { get; set; }
+		public bool GearboxInNeutral { get; set; }
+		public bool CombustionEngineOn { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/VectoCommon/VectoCommon/Models/IResponse.cs b/VectoCommon/VectoCommon/Models/IResponse.cs
index 8c830e8518..b49ed32d4d 100644
--- a/VectoCommon/VectoCommon/Models/IResponse.cs
+++ b/VectoCommon/VectoCommon/Models/IResponse.cs
@@ -177,6 +177,13 @@ namespace TUGraz.VectoCommon.Models
 		ElectricMotorResponse ElectricMotor { get; }
 
 		IElectricSystemResponse ElectricSystem { get; set; }
+
+		HybridControllerResponse HybridController { get; set; }
+	}
+
+	public class HybridControllerResponse
+	{
+		public HybridStrategyResponse StrategySettings { get; set; }
 	}
 
 	public interface IBatteryResponse
diff --git a/VectoCommon/VectoCommon/VectoCommon.csproj b/VectoCommon/VectoCommon/VectoCommon.csproj
index f9cc0d41d1..8603d24595 100644
--- a/VectoCommon/VectoCommon/VectoCommon.csproj
+++ b/VectoCommon/VectoCommon/VectoCommon.csproj
@@ -81,6 +81,7 @@
     <Compile Include="Hashing\VectoComponents.cs" />
     <Compile Include="InputData\DataSourceType.cs" />
     <Compile Include="InputData\DigestData.cs" />
+    <Compile Include="Models\HybridStrategyResponse.cs" />
     <Compile Include="Models\PowertrainPosition.cs" />
     <Compile Include="InputData\TableData.cs">
       <SubType>Component</SubType>
diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs
index 7e4049b402..73c3ddf680 100644
--- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs
+++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs
@@ -57,6 +57,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 			ElectricMotor = new ElectricMotorResponse();
 			//ElectricSystem = new
 			TorqueConverter = new TorqueConverterResponse();
+			HybridController = new HybridControllerResponse();
 		}
 
 		public AbstractResponse(object source, IResponse subResponse)
@@ -74,6 +75,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 			ElectricMotor = subResponse.ElectricMotor;
 			ElectricSystem = subResponse.ElectricSystem;
 			TorqueConverter = subResponse.TorqueConverter;
+			HybridController = subResponse.HybridController;
 		}
 
 		public Second AbsTime { get; set; }
@@ -102,7 +104,9 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 
 		public IElectricSystemResponse ElectricSystem { get; set; }
 
-		
+		public HybridControllerResponse HybridController { get; set; }
+
+
 		public override string ToString()
 		{
 			var t = GetType();
@@ -181,6 +185,8 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 	internal class ResponseGearShift : AbstractResponse
 	{
 		public ResponseGearShift(object source) : base(source) { }
+
+		public ResponseGearShift(object source, IResponse subResponse) : base(source, subResponse) { }
 	}
 
 /*
diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineInfo.cs
index def5398f94..a4d03b5798 100644
--- a/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineInfo.cs
+++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IEngineInfo.cs
@@ -61,5 +61,6 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus
 		PerSecond EngineN95hSpeed { get; }
 
 		PerSecond EngineN80hSpeed { get; }
+		bool EngineOn { get; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs
index 48254bf68a..2c2325016c 100644
--- a/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs
+++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IGearboxInfo.cs
@@ -82,6 +82,7 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus
 	public interface IGearboxControl
 	{
 		bool DisengageGearbox { set; }
+		void TriggerGearshift(Second absTime, Second dt);
 	}
 
 	public interface ITorqueConverterControl
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs
index 9d2802bf11..1116d9c0a7 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Strategies;
@@ -7,15 +6,6 @@ using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent
 {
-	public class HybridStrategyResponse
-	{
-		public Dictionary<PowertrainPosition, NewtonMeter> MechanicalAssistPower;
-		public bool ShiftRequired { get; set; }
-		public uint NextGear { get; set; }
-		public bool GearboxInNeutral { get; set; }
-		public bool CombustionEngineOn { get; set; }
-	}
-
 	public interface IHybridControlStrategy
 	{
 		HybridStrategyResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun);
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
index fdbe493f5b..1febc15a1c 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
@@ -137,6 +137,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		public override bool DisengageGearbox { get; set; }
+		public override void TriggerGearshift(Second absTime, Second dt)
+		{
+			throw new System.NotImplementedException();
+		}
 
 		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
 		{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
index fe08d6b0d8..c215e4fded 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AbstractGearbox.cs
@@ -168,6 +168,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		#region Implementation of IGearboxControl
 
 		public abstract bool DisengageGearbox { get; set; }
+		public abstract void TriggerGearshift(Second absTime, Second dt);
 
 		#endregion
 	}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
index df474ac2a1..4a42501fc4 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
@@ -163,7 +163,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			NewtonMeter torqueIn;
 			PerSecond angularVelocityIn;
 
-			var startClutch = DataBus.VehicleInfo.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0); // || (PreviousState.ClutchLoss.IsEqual(0) && outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed));
+			var startClutch = DataBus.VehicleInfo.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0) || (outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineSpeed) && !DataBus.EngineInfo.EngineOn); // || (PreviousState.ClutchLoss.IsEqual(0) && outAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed));
 			var slippingClutchWhenDriving = (DataBus.GearboxInfo.Gear <= 2 && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Braking);
 			var slippingClutchDuringBraking = DataBus.GearboxInfo.Gear == 1 && DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking && outTorque > 0 && DataBus.Brakes.BrakePower.IsEqual(0);
 			//var slippingClutchWhenDriving = (DataBus.Gear == 1 && outTorque > 0);
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
index 511ea303b6..36491db598 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
@@ -85,6 +85,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		#region IEngineCockpit
 
+		public virtual bool EngineOn
+		{
+			get { return PreviousState.EngineOn; }
+		}
+
 		public PerSecond EngineSpeed
 		{
 			get { return PreviousState.EngineSpeed; }
@@ -417,7 +422,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			container[ModalResultField.P_ice_drag] = CurrentState.FullDragTorque * avgEngineSpeed;
 			container[ModalResultField.T_ice_full] = CurrentState.DynamicFullLoadTorque;
 			container[ModalResultField.T_ice_drag] = CurrentState.FullDragTorque;
-			container[ModalResultField.ICEOn] = CurrentState.IgnitionOn;
+			container[ModalResultField.ICEOn] = CurrentState.EngineOn;
 
 			WriteWHRPower(container, avgEngineSpeed, CurrentState.EngineTorque);
 
@@ -577,7 +582,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		{
 			public EngineState()
 			{
-				IgnitionOn = true;
+				EngineOn = true;
 			}
 
 			// ReSharper disable once InconsistentNaming
@@ -599,7 +604,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			public NewtonMeter FullDragTorque { get; set; }
 
-			public bool IgnitionOn { get; set; }
+			public bool EngineOn { get; set; }
 
 			public Watt AuxPowerEngineOff { get; set; }
 		}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
index 18e01c8ec7..52d5fc7803 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
@@ -29,6 +29,7 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using TUGraz.VectoCommon.Exceptions;
@@ -524,6 +525,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			set { throw new System.NotImplementedException(); }
 		}
 
+		public override void TriggerGearshift(Second absTime, Second dt)
+		{
+			throw new NotSupportedException();
+		}
+
 		#endregion
 
 		public class CycleGearboxState : GearboxState
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
index b551eb0b66..775d1ccea3 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
@@ -200,10 +200,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				HandleEcoRoll(absTime, targetVelocity);
 			}
 
-			if (EcoRollState.State != EcoRollStates.EcoRollOn && PCCState != PCCStates.UseCase1 &&
-				PCCState != PCCStates.UseCase2) {
-				EngineOffTimestamp = null;
-				Driver.DataBus.EngineCtl.CombustionEngineOn = true;
+			if (ADAS.EcoRoll != EcoRollType.None) {
+				if (EcoRollState.State != EcoRollStates.EcoRollOn && PCCState != PCCStates.UseCase1 &&
+					PCCState != PCCStates.UseCase2) {
+					EngineOffTimestamp = null;
+					Driver.DataBus.EngineCtl.CombustionEngineOn = true;
+				}
 			}
 
 			if (CurrentDrivingMode == DrivingMode.DrivingModeBrake) {
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 017dcdc51e..df7ec5cb36 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -81,6 +81,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		// controlled by driver (PCC / EcoRoll)
 		public override bool DisengageGearbox { get; set; }
 
+		public override void TriggerGearshift(Second absTime, Second dt)
+		{
+			EngageTime = absTime + ModelData.TractionInterruption;
+			Disengaged = true;
+			_strategy.Disengage(absTime, dt, null, null);
+			Log.Info("Gearshift triggered - Gearbox disengaged");
+		}
+
 		public Gearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) : base(container,
 			runData)
 		{
@@ -147,7 +155,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			}
 
 			var response =
-				(ResponseDryRun)
 				NextComponent.Request(absTime, Constants.SimulationSettings.TargetTimeInterval, inTorque,
 					inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity);
 			//response.Switch().
@@ -400,19 +407,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					_strategy.Disengage(absTime, dt, outTorque, outAngularVelocity);
 					Log.Info("Gearbox disengaged");
 
-					return new ResponseGearShift(this) {
+					return new ResponseGearShift(this, response) {
 						SimulationInterval = ModelData.TractionInterruption,
 						Gearbox = {
 							PowerRequest =
 								outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0,
 							Gear = Gear
 						},
-						Engine = {
-							EngineSpeed = response.Engine.EngineSpeed,
-							TorqueOutDemand = response.Engine.TorqueOutDemand,
-							TotalTorqueDemand = response.Engine.TotalTorqueDemand,
-							PowerRequest = response.Engine.PowerRequest
-						}
+						
 					};
 				}
 			}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
index 4b1789c3f7..af1f9af876 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
@@ -68,6 +68,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			Gearbox.SwitchToNeutral = strategySettings.GearboxInNeutral;
 			Engine.CombustionEngineOn = strategySettings.CombustionEngineOn;
 			_electricMotorTorque = strategySettings.MechanicalAssistPower;
+			if (strategySettings.ShiftRequired) {
+				_shiftStrategy.SetNextGear(strategySettings.NextGear);
+			}
 		}
 
 		SimpleComponentState IHybridController.PreviousState
@@ -94,7 +97,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				CurrentState.SetState(outTorque, outAngularVelocity, outTorque, outAngularVelocity);
 				CurrentState.StrategyResponse = strategySettings;
 			}
-			return NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun);
+			if (!DataBus.EngineInfo.EngineOn && strategySettings.ShiftRequired) {
+				DataBus.GearboxCtl.TriggerGearshift(absTime, dt);
+				return new ResponseGearShift(this);
+			}
+			var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun);
+			retVal.HybridController.StrategySettings = strategySettings;
+			return retVal;
 		}
 
 		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
@@ -281,6 +290,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			protected uint InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity)
 			{
+				if (!DataBus.EngineCtl.CombustionEngineOn) {
+					return _nextGear;
+				}
+
 				for (var gear = MaxStartGear; gear > 1; gear--) {
 					var inAngularSpeed = outAngularVelocity * ModelData.Gears[gear].Ratio;
 
@@ -355,6 +368,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			{
 				get { return new GearInfo(_nextGear, false); }
 			}
+
+			public void SetNextGear(uint nextGear)
+			{
+				_nextGear = nextGear;
+			}
 		}
 
 		
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs
index fba8022dcb..57be84629f 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/StopStartCombustionEngine.cs
@@ -50,9 +50,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
 				}
 				throw new VectoSimulationException("Combustion engine cannot supply outtorque when switched off (T_out: {0})", outTorque);
 			}
-			CurrentState.IgnitionOn = false;
+			CurrentState.EngineOn = false;
 			CurrentState.EngineSpeed = ModelData.IdleSpeed;
 			CurrentState.EngineTorque = 0.SI<NewtonMeter>();
+			CurrentState.EngineTorqueOut = 0.SI<NewtonMeter>();
 			CurrentState.EnginePower = 0.SI<Watt>();
 			CurrentState.dt = dt;
 
@@ -93,7 +94,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
 		{
 			if (CombustionEngineOn) {
 				base.DoWriteModalResults(time, simulationInterval, container);
-				var engineStart = !PreviousState.IgnitionOn && CurrentState.IgnitionOn;
+				var engineStart = !PreviousState.EngineOn && CurrentState.EngineOn;
 				container[ModalResultField.P_ice_start] = engineStart ? EngineStartEnergy / CurrentState.dt : 0.SI<Watt>();
 				container[ModalResultField.P_aux_ice_off] = 0.SI<Watt>();
 			} else {
@@ -120,7 +121,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
 			container[ModalResultField.T_ice_full] = 0.SI<NewtonMeter>();
 			container[ModalResultField.T_ice_drag] = 0.SI<NewtonMeter>();
 
-			container[ModalResultField.ICEOn] = CurrentState.IgnitionOn;
+			container[ModalResultField.ICEOn] = CurrentState.EngineOn;
 			container[ModalResultField.P_aux_ice_off] = (CurrentState.AuxPowerEngineOff ?? 0.SI<Watt>());
 
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
index da91b3aa31..6c81ba20d9 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
@@ -15,6 +15,7 @@ using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.Simulation.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 {
@@ -48,6 +49,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 
 	public class HybridStrategy : LoggingObject, IHybridControlStrategy
 	{
+		public static readonly Second MIN_ICE_ON_TIME = 3.SI<Second>();
+
 		public class StrategyState
 		{
 			public HybridStrategyResponse Response { get; set; }
@@ -55,6 +58,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			public HybridResultEntry Solution { get; set; }
 
 			public bool GearboxEngaged;
+
+			public Second ICEStartTStmp { get; set; }
 		}
 
 		private VectoRunData ModelData;
@@ -74,6 +79,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 
 		protected StrategyState CurrentState = new StrategyState();
 		protected StrategyState PreviousState = new StrategyState();
+		private double IceRampUpCosts;
+		private double IceIdlingCosts;
 
 		public HybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer)
 		{
@@ -90,6 +97,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			ElectricMotorCanPropellDuringTractionInterruption =
 				emPos == PowertrainPosition.HybridP4 || emPos == PowertrainPosition.HybridP3;
 
+			var engineRampUpEnergy = Formulas.InertiaPower(ModelData.EngineData.IdleSpeed, 0.RPMtoRad(), ModelData.EngineData.Inertia, ModelData.EngineData.EngineStartTime) * ModelData.EngineData.EngineStartTime;
+			var engineDragEnergy = VectoMath.Abs(ModelData.EngineData.FullLoadCurves[0].DragLoadStationaryTorque(ModelData.EngineData.IdleSpeed)) *
+									ModelData.EngineData.IdleSpeed / 2.0 * ModelData.EngineData.EngineStartTime;
+
+			IceRampUpCosts = (engineRampUpEnergy + engineDragEnergy).Value() / DeclarationData.AlternaterEfficiency / DeclarationData.AlternaterEfficiency;
+
+			IceIdlingCosts = ModelData.EngineData.Fuels.Sum(
+				x => (x.ConsumptionMap.GetFuelConsumptionValue(0.SI<NewtonMeter>(), ModelData.EngineData.IdleSpeed)
+					* x.FuelData.LowerHeatingValueVecto * MIN_ICE_ON_TIME).Value());
+
+			// create testcontainer
 			var modData = new ModalDataContainer(runData, null, new[] { FuelData.Diesel }, null, false);
 			var builder = new PowertrainBuilder(modData);
 			var testContainer = new SimplePowertrainContainer(runData);
@@ -153,7 +171,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 					Response = null,
 					Setting = new HybridStrategyResponse() {
 						GearboxInNeutral = false,
-						CombustionEngineOn = true,
+						CombustionEngineOn = DataBus.EngineInfo.EngineOn,
 						MechanicalAssistPower = ElectricMotorsOff
 					},
 					FuelCosts = double.NaN
@@ -163,27 +181,42 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 				eval.Add(MaxRecuperationSetting(absTime, dt, outTorque, outAngularVelocity));
 			}
 
-			var best = eval.Where(x => !double.IsNaN(x.Score)).OrderBy(x => x.Score).FirstOrDefault() ?? eval.FirstOrDefault();
+			var best = eval.Where(x => !double.IsNaN(x.Score)).OrderBy(x => x.Score).FirstOrDefault(); // ?? eval.FirstOrDefault();
 			if (best == null) {
-				// TODO!
+				best = eval.FirstOrDefault();
+				var allOverload = eval.Where(x => x.Response != null).All(
+					x => x.Response.Engine.TotalTorqueDemand.IsGreater(x.Response.Engine.DynamicFullLoadTorque));
+				if (DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate && allOverload) {
+					if (ElectricMotorCanPropellDuringTractionInterruption || DataBus.GearboxInfo.GearEngaged(absTime)) {
+						// overload, EM can support - use solution with max EM power
+						best = eval.MinBy(x => x.Setting.MechanicalAssistPower.Sum(e => e.Value ?? 0.SI<NewtonMeter>()));
+					}
+				}
 			}
+			
 			Tuple<bool, uint> gs = null;
-			if (best?.Response != null) {
+			if (best?.Response != null && !best.ICEOff) {
 				gs = HandleGearshift(absTime, best);
 			}
 
 			var retVal = new HybridStrategyResponse() {
-				CombustionEngineOn = best.Setting.CombustionEngineOn,
+				CombustionEngineOn = !best.ICEOff,
 				GearboxInNeutral = best.Setting.GearboxInNeutral,
 				MechanicalAssistPower = best.Setting.MechanicalAssistPower,
 				ShiftRequired = gs?.Item1 ?? false,
 				NextGear = gs?.Item2 ?? 0,
 			};
+			if (!DataBus.EngineInfo.EngineOn && !best.ICEOff && retVal.ShiftRequired) {
+				CurrentState.ICEStartTStmp = absTime + dt;
+			}
 			CurrentState.Response = dryRun ? null : retVal;
 			if (!dryRun) {
 				CurrentState.Solution = best;
 				CurrentState.Evaluations = eval;
 				CurrentState.GearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime);
+				if (!DataBus.EngineCtl.CombustionEngineOn && !best.ICEOff) {
+					CurrentState.ICEStartTStmp = absTime;
+				}
 			}
 			return retVal;
 		}
@@ -199,10 +232,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			};
 			var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, first);
 
-		
+			var allowICEOff = PreviousState.ICEStartTStmp == null ||
+							PreviousState.ICEStartTStmp.IsSmaller(absTime + MIN_ICE_ON_TIME);
+
+
 			var emPos = ModelData.ElectricMachinesData.First().Item1;
 			var emTorque = firstResponse.ElectricMotor.MaxRecuperationTorque;
-			return TryConfiguration(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, emPos, emTorque, double.NaN);
+			return TryConfiguration(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, emPos, emTorque, double.NaN, allowICEOff);
 		}
 
 		private List<HybridResultEntry> FindSolution(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
@@ -214,6 +250,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			};
 			var firstResponse = RequestDryRun(absTime, dt, outTorque, outAngularVelocity, DataBus.GearboxInfo.Gear, first);
 
+			var allowICEOff = PreviousState.ICEStartTStmp == null ||
+							PreviousState.ICEStartTStmp.IsSmaller(absTime + MIN_ICE_ON_TIME);
+
 			//var gearboxEngaged = DataBus.GearboxInfo.GearEngaged(absTime);
 			var emPos = ModelData.ElectricMachinesData.First().Item1;
 			var emTqReq = (firstResponse.ElectricMotor.PowerRequest + firstResponse.ElectricMotor.InertiaPowerDemand)  / firstResponse.ElectricMotor.AngularVelocity;
@@ -226,7 +265,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 				Gear = DataBus.GearboxInfo.Gear,
 				//Score = CalcualteCosts(firstResponse, dt)
 			};
-			CalcualteCosts(firstResponse, dt, entry);
+			CalcualteCosts(firstResponse, dt, entry, allowICEOff);
 			responses.Add(entry);
 
 			if (firstResponse.Gearbox.Gear == 0 && !ElectricMotorCanPropellDuringTractionInterruption) {
@@ -243,7 +282,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 				gearRangeUpshift = 0;
 			}
 
-			var gear = DataBus.GearboxInfo.Gear;
+			var gear = PreviousState.GearboxEngaged ? DataBus.GearboxInfo.Gear : Controller.ShiftStrategy.NextGear.Gear; // DataBus.GearboxInfo.Gear;
 			var numGears = ModelData.GearboxData.Gears.Count;
 			for (uint nextGear = (uint)Math.Max(1, gear - gearRangeDownshift);
 				nextGear <= Math.Min(numGears, gear + gearRangeUpshift);
@@ -265,20 +304,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 					Setting = first,
 					Gear = nextGear
 				};
-				CalcualteCosts(baseResponse, dt, gearEntry);
+				CalcualteCosts(baseResponse, dt, gearEntry, allowICEOff);
 				responses.Add(gearEntry);
-				IterateEMTorque(absTime, dt, outTorque, outAngularVelocity, nextGear, baseResponse, emTqReq, emPos, responses);
+				IterateEMTorque(absTime, dt, outTorque, outAngularVelocity, nextGear, allowICEOff, baseResponse, emTqReq, emPos, responses);
 			}
 
 			return responses;
 		}
 
-		private void IterateEMTorque(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, ResponseDryRun firstResponse, NewtonMeter emTqReq, PowertrainPosition emPos, List<HybridResultEntry> responses)
+		private void IterateEMTorque(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, bool allowIceOff, ResponseDryRun firstResponse, NewtonMeter emTqReq, PowertrainPosition emPos, List<HybridResultEntry> responses)
 		{
 			const double stepSize = 0.1;
 
 			// iterate over 'EM provides torque'. allow EM to provide more torque in order to overcome ICE inertia
-			var maxU = Math.Min((firstResponse.ElectricMotor.MaxDriveTorque ?? 0.SI<NewtonMeter>()) / emTqReq, -1.0);
+			var maxEmTorque = firstResponse.ElectricMotor.MaxDriveTorque ?? 0.SI<NewtonMeter>();
+			var maxU = allowIceOff
+				? -1.0
+				: Math.Min((maxEmTorque) / emTqReq, -1.0);
 			if (firstResponse.ElectricMotor.MaxDriveTorque != null) {
 				for (var u = 0.0; u >= maxU; u -= stepSize * (u < -4 ? 10 : (u < -2 ? 5 : 1))) {
 					var emTorque = emTqReq.Abs() * u;
@@ -287,15 +329,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 						continue;
 					}
 
-					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorque, u);
+					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorque, u, allowIceOff);
 					responses.Add(tmp);
 				}
 
 				// make sure the max drive point is also covered.
 				var emTorqueM = emTqReq * maxU;
-				if (emTorqueM.IsBetween(
+				if (!responses.Any(x => x.Gear == nextGear && x.U.IsEqual(maxU)) && emTorqueM.IsBetween(
 					0.SI<NewtonMeter>(), firstResponse.ElectricMotor.MaxDriveTorque)) {
-					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorqueM, maxU);
+					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorqueM, maxU, allowIceOff);
+					responses.Add(tmp);
+				}
+				if (maxEmTorque.IsSmaller(0) && emTqReq.IsGreater(-maxEmTorque)) {
+					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, maxEmTorque, maxEmTorque / emTqReq, allowIceOff);
 					responses.Add(tmp);
 				}
 			}
@@ -309,13 +355,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 						continue;
 					}
 
-					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorque, u);
+					var tmp = TryConfiguration(absTime, dt, outTorque, outAngularVelocity, nextGear, emPos, emTorque, u, allowIceOff);
 					responses.Add(tmp);
 				}
 			}
 		}
 
-		private HybridResultEntry TryConfiguration(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, PowertrainPosition emPos, NewtonMeter emTorque, double u)
+		private HybridResultEntry TryConfiguration(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, uint nextGear, PowertrainPosition emPos, NewtonMeter emTorque, double u, bool allowIceOff)
 		{
 			var cfg = new HybridStrategyResponse() {
 				CombustionEngineOn = true,
@@ -332,7 +378,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 				Response = resp,
 				Gear = nextGear,
 			};
-			CalcualteCosts(resp, dt, tmp);
+			CalcualteCosts(resp, dt, tmp, allowIceOff);
 			return tmp;
 		}
 
@@ -345,6 +391,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			TestPoweretrain.Clutch.Initialize(DataBus.ClutchInfo.ClutchLosses);
 			TestPoweretrain.Battery.Initialize(DataBus.BatteryInfo.StateOfCharge);
 
+			TestPoweretrain.CombustionEngine.PreviousState.EngineOn = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineOn;
 			TestPoweretrain.CombustionEngine.PreviousState.EnginePower = (DataBus.EngineInfo as CombustionEngine).PreviousState.EnginePower;
 			TestPoweretrain.CombustionEngine.PreviousState.dt = (DataBus.EngineInfo as CombustionEngine).PreviousState.dt;
 			TestPoweretrain.CombustionEngine.PreviousState.EngineSpeed = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed;
@@ -374,6 +421,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 					vehicleSpeedPostShift, DataBus.DrivingCycleInfo.RoadGradient ?? 0.SI<Radian>());
 			}
 
+			TestPoweretrain.CombustionEngine.PreviousState.EngineOn = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineOn;
+			TestPoweretrain.CombustionEngine.PreviousState.EnginePower = (DataBus.EngineInfo as CombustionEngine).PreviousState.EnginePower;
+			TestPoweretrain.CombustionEngine.PreviousState.dt = (DataBus.EngineInfo as CombustionEngine).PreviousState.dt;
+			TestPoweretrain.CombustionEngine.PreviousState.EngineSpeed = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineSpeed;
+			TestPoweretrain.CombustionEngine.PreviousState.EngineTorque = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorque;
+			TestPoweretrain.CombustionEngine.PreviousState.EngineTorqueOut = (DataBus.EngineInfo as CombustionEngine).PreviousState.EngineTorqueOut;
+			TestPoweretrain.CombustionEngine.PreviousState.DynamicFullLoadTorque = (DataBus.EngineInfo as CombustionEngine).PreviousState.DynamicFullLoadTorque;
+
 			// AMT EffShift: estimatedVelocityPostShift < MIN_SPEED => no shift
 
 			// AMT EffShift: engine torqueOut close to dragCurve => no shift
@@ -395,21 +450,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			return retVal as ResponseDryRun;
 		}
 
-		private void CalcualteCosts(ResponseDryRun resp, Second dt, HybridResultEntry tmp)
+		private void CalcualteCosts(ResponseDryRun resp, Second dt, HybridResultEntry tmp, bool allowIceOff)
 		{
 			if (resp == null) {
 				tmp.FuelCosts = double.NaN;
+				tmp.IgnoreReason = "no response";
 				return;
 			}
 			if (!resp.Engine.TotalTorqueDemand.IsBetween(
 				resp.Engine.DragTorque, resp.Engine.DynamicFullLoadTorque)) {
 				tmp.FuelCosts = double.NaN;
+				tmp.IgnoreReason = "torque demand exceeded";
+				return;
+			}
+
+			if (resp.Engine.EngineSpeed.IsGreaterOrEqual(
+					VectoMath.Min(
+						ModelData.GearboxData.Gears[resp.Gearbox.Gear].MaxSpeed,
+						DataBus.EngineInfo.EngineN95hSpeed)) ||
+				resp.Engine.EngineSpeed.IsSmallerOrEqual(ModelData.EngineData.IdleSpeed)) {
+				tmp.FuelCosts = double.NaN;
+				tmp.IgnoreReason = "engine speed exceeded";
 				return;
 			}
 
-			tmp.FuelCosts = ModelData.EngineData.Fuels.Sum(
-				x => (x.ConsumptionMap.GetFuelConsumptionValue(resp.Engine.TotalTorqueDemand, resp.Engine.EngineSpeed)
-					 * x.FuelData.LowerHeatingValueVecto * dt).Value());
+			if (allowIceOff && resp.Engine.TorqueOutDemand.IsEqual(0)) {
+				// no torque from ICE requested, ICE could be turned off
+				tmp.FuelCosts = 0;
+				tmp.ICEOff = true;
+			} else {
+				tmp.FuelCosts = ModelData.EngineData.Fuels.Sum(
+					x => (x.ConsumptionMap.GetFuelConsumptionValue(resp.Engine.TotalTorqueDemand, resp.Engine.EngineSpeed)
+						* x.FuelData.LowerHeatingValueVecto * dt).Value());
+			}
 			tmp.BatCosts = -(resp.ElectricSystem.ConsumerPower * dt).Value();
 			tmp.SoCPenalty = 1 - Math.Pow((DataBus.BatteryInfo.StateOfCharge - ModelData.BatteryData.TargetSoC) / (0.5 * (ModelData.BatteryData.MaxSOC - ModelData.BatteryData.MinSOC)), 5);
 
@@ -417,12 +490,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			tmp.GearshiftPenalty = resp.Gearbox.Gear != DataBus.GearboxInfo.Gear
 				? ModelData.GearshiftParameters.RatingFactorCurrentGear
 				: 1;
+
+			if (!DataBus.EngineCtl.CombustionEngineOn && !tmp.ICEOff) {
+				tmp.ICEStartPenalty1 = IceRampUpCosts;
+				tmp.ICEStartPenalty2 = IceIdlingCosts;
+			} else {
+				tmp.ICEStartPenalty1 = 0;
+				tmp.ICEStartPenalty2 = 0;
+			}
 		}
 
 		private Tuple<bool, uint> HandleGearshift(Second absTime, HybridResultEntry config)
 		{
+			var minimumShiftTimePassed = (DataBus.GearboxInfo.LastShift + ModelData.GearboxData.ShiftTime).IsSmallerOrEqual(absTime);
+			
 			// search for EM operating point already selected another gear
-			if (config.Gear != DataBus.GearboxInfo.Gear) {
+			if (minimumShiftTimePassed && config.Gear != DataBus.GearboxInfo.Gear) {
 				return Tuple.Create(true, config.Gear);
 			}
 			var response = config.Response;
@@ -448,8 +531,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			}
 
 			// normal shift when all requirements are fullfilled ------------------
-
-			var minimumShiftTimePassed = (DataBus.GearboxInfo.LastShift + ModelData.GearboxData.ShiftTime).IsSmallerOrEqual(absTime);
 			if (!minimumShiftTimePassed) {
 				return retVal;
 			}
@@ -505,6 +586,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 		{
 			PreviousState = CurrentState;
 			CurrentState = new StrategyState();
+			CurrentState.ICEStartTStmp = PreviousState.ICEStartTStmp;
 		}
 
 		public void WriteModalResults(Second time, Second simulationInterval, IModalDataContainer container)
@@ -518,15 +600,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 					string.Join(
 						" | ", CurrentState.Evaluations.Select(
 							x => {
-								var foo = string.Join(" ",  x.Setting.MechanicalAssistPower.Select(e => $"{e.Key.GetName()}: {e.Value}"));
-								return $"{x.U}: G{x.Gear} ({x.FuelCosts} + {x.EqualityFactor} * {x.BatCosts} * {x.SoCPenalty} = {x.Score}) * {x.GearshiftPenalty} ({foo})";
+								var foo = string.Join(" ",  x.Setting.MechanicalAssistPower.Select(e => $"{e.Key.GetName()} - {e.Value}"));
+								var ice = "====";
+								if (x.Response != null) {
+									ice =
+										$"{x.Response.Engine.TorqueOutDemand}, {x.Response.Engine.TotalTorqueDemand}, {x.Response.Engine.DynamicFullLoadTorque}";
+								}
+								return
+									$"{x.U:F2}: {x.Score:F2}; G{x.Gear}; ({x.FuelCosts:F2} + {x.EqualityFactor:F2} * ({x.BatCosts:F2} + {x.ICEStartPenalty1:F2}) * {x.SoCPenalty:F2} + {x.ICEStartPenalty2:F2}) / {x.GearshiftPenalty:F2} = {x.Score:F2} ({foo} ICE: {ice}); {x.IgnoreReason}";
 							})
 						)
 					);
 			}
 		}
 
-		[DebuggerDisplay("{U}: {Score} {Gear} {Setting.MechanicalAssistPower}")]
+		[DebuggerDisplay("{U}: {Score} - G{Gear}")]
 		public class HybridResultEntry
 		{
 			public double U { get; set; }
@@ -535,7 +623,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 
 			public ResponseDryRun Response { get; set; }
 
-			public double Score { get { return (FuelCosts + EqualityFactor * BatCosts * SoCPenalty) / GearshiftPenalty; } }
+			public double Score { get { return (FuelCosts + EqualityFactor * (BatCosts + ICEStartPenalty1) * SoCPenalty + ICEStartPenalty2) / GearshiftPenalty; } }
 
 			public double FuelCosts { get; set; }
 
@@ -547,7 +635,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 
 			public double GearshiftPenalty { get; set; }
 
+			public double ICEStartPenalty1 { get; set; }
+
+			public double ICEStartPenalty2 { get; set; }
+
 			public uint Gear { get; set; }
+
+			public bool ICEOff { get; set; }
+
+			public string IgnoreReason { get; set; }
 		}
 
 	}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs
index 5094390ca1..22646ba236 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/SwitchableClutch.cs
@@ -83,7 +83,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 
 			}
 
-			var retVal = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun);
+			var inAngularVelocity = 0.RPMtoRad();
+			var retVal = NextComponent.Request(absTime, dt, outTorque, inAngularVelocity, dryRun);
 
 			//if (retVal is ResponseEngineSpeedTooLow)
 			//{
diff --git a/VectoCore/VectoCore/Resources/Declaration/CO2Standards/MissionProfileWeights.csv b/VectoCore/VectoCore/Resources/Declaration/CO2Standards/MissionProfileWeights.csv
index 52a498d162..8d3d84493a 100644
--- a/VectoCore/VectoCore/Resources/Declaration/CO2Standards/MissionProfileWeights.csv
+++ b/VectoCore/VectoCore/Resources/Declaration/CO2Standards/MissionProfileWeights.csv
@@ -21,3 +21,5 @@ ML4van          , 0/0       , 0/0          , 0.25/0.25         , 0/0
 11              , 0.01/0.02 , 0/0          , 0.11/0.25         , 0/0                   , 0/0            , 0.08/0.19         , 0.09/0.25
 12              , 0.16/0.36 , 0/0          , 0.03/0.07         , 0/0                   , 0/0            , 0/0               , 0.11/0.27
 16              , 0/0       , 0/0          , 0/0               , 0/0                   , 0/0            , 0/0               , 0.30/0.70
+
+
diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
index f5fe4fe535..fffc26e6df 100644
--- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
@@ -139,7 +139,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 		{
 			var cycleData = string.Format(
 				@"   0, {0}, {1},    0
-				  5000, {0}, {1},    0", vmax, slope);
+				  7000, {0}, {1},    0", vmax, slope);
 			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
 
 			const bool largeMotor = true;
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs
index 1d8be840a9..f5e867faab 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/ClutchTest.cs
@@ -191,6 +191,11 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 		public PerSecond EngineN95hSpeed { get; set; }
 		public PerSecond EngineN80hSpeed { get; set; }
 
+		public bool EngineOn
+		{
+			get { throw new System.NotImplementedException(); }
+		}
+
 		protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container)
 		{
 			container[ModalResultField.P_ice_fcmap] = 0.SI<Watt>();
diff --git a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs
index 172ba27c88..26ef4dd591 100644
--- a/VectoCore/VectoCoreTest/Utils/MockGearbox.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockGearbox.cs
@@ -169,6 +169,9 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 
 		public bool DisengageGearbox { get; set; }
-
+		public void TriggerGearshift(Second absTime, Second dt)
+		{
+			throw new NotImplementedException();
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Utils/MockPorts.cs b/VectoCore/VectoCoreTest/Utils/MockPorts.cs
index a5316d8bcb..65df8f6a22 100644
--- a/VectoCore/VectoCoreTest/Utils/MockPorts.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockPorts.cs
@@ -153,6 +153,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 		public PerSecond EngineN95hSpeed { get; set; }
 		public PerSecond EngineN80hSpeed { get; set; }
+
+		public bool EngineOn
+		{
+			get { throw new NotImplementedException(); }
+		}
 	}
 
 	public class MockDrivingCycleOutPort : LoggingObject, IDrivingCycleOutPort
diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
index 098457ef40..3881c1538c 100644
--- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
@@ -218,6 +218,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 			get { return EngineInfo.EngineN80hSpeed; }
 		}
 
+		public bool EngineOn
+		{
+			get { return EngineInfo.EngineOn; }
+		}
+
 		public MeterPerSecond VehicleSpeed { get; set; }
 		public Kilogram VehicleMass { get; set; }
 		public Kilogram VehicleLoading { get; set; }
@@ -349,6 +354,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 		#region Implementation of IGearboxControl
 
 		public bool DisengageGearbox { get; set; }
+		public void TriggerGearshift(Second absTime, Second dt)
+		{
+			throw new NotImplementedException();
+		}
+
 		public bool GearEngaged(Second absTime)
 		{
 			return ClutchClosed(absTime);
-- 
GitLab