From 92c61c71d6f5299e7d459d107451866ec6c1ab71 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Wed, 1 Jul 2020 15:58:35 +0200
Subject: [PATCH] adding testcases for P3 hybrid configuration, P2 declaration
 cycles

---
 VectoCommon/VectoCommon/Models/IResponse.cs   |   2 +
 .../Reader/ComponentData/BatterySOCReader.cs  |   1 +
 .../EngineeringDataAdapter.cs                 |   1 +
 .../Connector/Ports/Impl/BatteryResponse.cs   |   2 +
 .../Models/Simulation/Data/VectoRunData.cs    |   5 +
 .../Simulation/Impl/PowertrainBuilder.cs      |  11 +-
 .../Data/Battery/BatteryData.cs               |   4 +-
 .../Data/HybridStrategyParameters.cs          |  12 +
 .../SimulationComponent/ElectricSystem.cs     |   1 +
 .../SimulationComponent/Impl/Battery.cs       |   1 +
 .../Strategies/HybridStrategy.cs              |  24 +-
 VectoCore/VectoCore/VectoCore.csproj          |   1 +
 .../Integration/Hybrid/ParallelHybridTest.cs  | 263 ++++++++++++------
 .../Utils/MockSimulationDataFactory.cs        |   1 +
 14 files changed, 240 insertions(+), 89 deletions(-)
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs

diff --git a/VectoCommon/VectoCommon/Models/IResponse.cs b/VectoCommon/VectoCommon/Models/IResponse.cs
index b49ed32d4d..b27f1c6e7f 100644
--- a/VectoCommon/VectoCommon/Models/IResponse.cs
+++ b/VectoCommon/VectoCommon/Models/IResponse.cs
@@ -219,6 +219,8 @@ namespace TUGraz.VectoCommon.Models
 
 		Watt MaxPowerDrag { get; }
 
+		Watt BatteryPowerDemand { get; set; }
+
 		object Source { get; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs
index c60f27cd7b..4a7d50b19d 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs
@@ -3,6 +3,7 @@ using System.Linq;
 using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.InputData.Reader.ComponentData {
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
index 394ba2d87f..041a466204 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
@@ -44,6 +44,7 @@ using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.SimulationComponent;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.Utils;
diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs
index 590030adf4..fedde47a01 100644
--- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs
+++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs
@@ -92,6 +92,8 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 			}
 		}
 
+		public Watt BatteryPowerDemand { get; set; }
+
 		public object Source { get; }
 
 		public override string ToString()
diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
index fa2fa503d0..254ed49bec 100644
--- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
@@ -45,6 +45,7 @@ using TUGraz.VectoCore.InputData.Reader.ComponentData;
 using TUGraz.VectoCore.InputData.Reader.Impl;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.OutputData;
 using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData;
@@ -137,6 +138,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 		// only used for factor method
 		public IResult PrimaryResult { get; set; }
 
+		public HybridStrategyParameters HybridStrategyParameters { get; internal set; }
+
+		public Watt ElectricAuxDemand { get; internal set; }
+
 		public class AuxData
 		{
 			// ReSharper disable once InconsistentNaming
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
index 954c55c70b..6ba53e39a1 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
@@ -369,7 +369,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 			var es = new ElectricSystem(container);
 			es.Connect(battery);
-
+			
+			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);
 
@@ -487,7 +491,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 			var es = new ElectricSystem(container);
 			es.Connect(battery);
-
+			var aux = new ElectricAuxiliary(container);
+			aux.AddConstant("P_aux_el", data.ElectricAuxDemand ?? 0.SI<Watt>());
+			es.Connect(aux);
+			
 			var clutch = data.GearboxData.Type.ManualTransmission() ? new SwitchableClutch(container, data.EngineData) : null;
 
 			var gearbox = GetSimpleGearbox(container, data);
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs
index e8391a1b93..25d59a7b75 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Battery/BatteryData.cs
@@ -3,7 +3,7 @@ using System.Linq;
 using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.Utils;
 
-namespace TUGraz.VectoCore.InputData.Reader.ComponentData {
+namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Battery {
 
 	public class BatteryData
 	{
@@ -25,7 +25,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData {
 
 		public double InitialSoC { get; internal set; }
 
-		public double TargetSoC { get; internal set; }
+		//public double TargetSoC { get; internal set; }
 	}
 
 	public class SOCMap
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs
new file mode 100644
index 0000000000..b1a0a865f5
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/HybridStrategyParameters.cs
@@ -0,0 +1,12 @@
+namespace TUGraz.VectoCore.Models.SimulationComponent.Data {
+	public class HybridStrategyParameters
+	{
+		public double EquivalenceFactor { get; set; }
+
+		public double MinSoC { get; set; }
+
+		public double MaxSoC { get; set; }
+
+		public double TargetSoC { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs b/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs
index 3dfda64680..e8c6c9eb05 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs
@@ -49,6 +49,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 			response.AbsTime = absTime;
 			response.SimulationInterval = dt;
 			response.BatteryResponse = batResponse;
+			response.BatteryPowerDemand = totalPowerDemand;
 			response.ConsumerPower = powerDemand;
 			response.AuxPower = auxDemand;
 			response.ChargingPower = chargePower;
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs
index 3e78dd9d2d..01749e979b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Battery.cs
@@ -8,6 +8,7 @@ using TUGraz.VectoCore.InputData.Reader.ComponentData;
 using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
 using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
index a4ae3a808e..057464681d 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
@@ -43,7 +43,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			Battery = Container.BatteryInfo as Battery;
 			Clutch = Container.ClutchInfo as Clutch;
 			CombustionEngine = Container.EngineInfo as StopStartCombustionEngine;
-			ElectricMotorP2 = container.ElectricMotors[PowertrainPosition.HybridP2] as ElectricMotor;
+			ElectricMotorP2 = container.ElectricMotors.ContainsKey(PowertrainPosition.HybridP2)
+				? container.ElectricMotors[PowertrainPosition.HybridP2] as ElectricMotor
+				: null;
 			if (Gearbox == null) {
 				throw new VectoException("Unknown gearboxtype in TestContainer: {0}", Container.GearboxCtl.GetType().FullName);
 			}
@@ -251,6 +253,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 		private double IceRampUpCosts;
 		private double IceIdlingCosts;
 
+		protected HybridStrategyParameters StrategyParameters;
+
 		public HybridStrategy(VectoRunData runData, IVehicleContainer vehicleContainer)
 		{
 			DataBus = vehicleContainer;
@@ -258,6 +262,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			if (ModelData.ElectricMachinesData.Select(x => x.Item1).Distinct().Count() > 1) {
 				throw new VectoException("More than one electric motors are currently not supported");
 			}
+			StrategyParameters = ModelData.HybridStrategyParameters;
+			if (StrategyParameters == null) {
+				throw new VectoException("Model parameters for hybrid strategy required!");
+			}
 
 			ElectricMotorsOff = ModelData.ElectricMachinesData
 										.Select(x => new KeyValuePair<PowertrainPosition, NewtonMeter>(x.Item1, null))
@@ -489,7 +497,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			var maxU = allowIceOff
 				? -1.0
 				: Math.Min((maxEmTorque) / emTqReq, -1.0);
-			if (firstResponse.ElectricMotor.MaxDriveTorque != null && (!ElectricMotorCanPropellDuringTractionInterruption && firstResponse.Gearbox.Gear != 0)) {
+			if (firstResponse.ElectricMotor.MaxDriveTorque != null && (ElectricMotorCanPropellDuringTractionInterruption || firstResponse.Gearbox.Gear != 0)) {
 				for (var u = 0.0; u >= maxU; u -= stepSize * (u < -4 ? 10 : (u < -2 ? 5 : 1))) {
 					var emTorque = emTqReq.Abs() * u;
 					if (!emTorque.IsBetween(
@@ -515,7 +523,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			}
 			
 			// iterate over 'EM recuperates' up to max available recuperation potential
-			if (firstResponse.ElectricMotor.MaxRecuperationTorque != null && (!ElectricMotorCanPropellDuringTractionInterruption && firstResponse.Gearbox.Gear != 0)) {
+			if (firstResponse.ElectricMotor.MaxRecuperationTorque != null && (ElectricMotorCanPropellDuringTractionInterruption || firstResponse.Gearbox.Gear != 0)) {
 				for (var u = stepSize; u <= 1.0; u += stepSize) {
 					var emTorque = firstResponse.ElectricMotor.MaxRecuperationTorque * u;
 					if (!(emTorque).IsBetween(
@@ -650,10 +658,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 							* 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);
+			tmp.BatCosts = -(resp.ElectricSystem.BatteryPowerDemand * dt).Value();
+			var maxSoC = Math.Min(ModelData.BatteryData.MaxSOC, StrategyParameters.MaxSoC);
+			var minSoC = Math.Max(ModelData.BatteryData.MinSOC, StrategyParameters.MinSoC);
+			tmp.SoCPenalty = 1 - Math.Pow((DataBus.BatteryInfo.StateOfCharge - StrategyParameters.TargetSoC) / (0.5 * (maxSoC - minSoC)), 5);
 
-			tmp.EqualityFactor = 2.5;
+			tmp.EqualityFactor = StrategyParameters.EquivalenceFactor;
 			tmp.GearshiftPenalty = resp.Gearbox.Gear != 0 && resp.Gearbox.Gear != DataBus.GearboxInfo.Gear
 				? ModelData.GearshiftParameters.RatingFactorCurrentGear
 				: 1;
@@ -726,7 +736,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 
 		public void WriteModalResults(Second time, Second simulationInterval, IModalDataContainer container)
 		{
-			container[ModalResultField.HybridStrategyScore] = CurrentState.Solution?.Score ?? 0;
+			container[ModalResultField.HybridStrategyScore] = (CurrentState.Solution?.Score ?? 0)/1e3;
 			container[ModalResultField.HybridStrategySolution] = CurrentState.Solution?.U ?? -100;
 
 			if (CurrentState.Evaluations != null) {
diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj
index cef7da6259..a9895d1920 100644
--- a/VectoCore/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore/VectoCore.csproj
@@ -390,6 +390,7 @@
     <Compile Include="Models\SimulationComponent\Data\ElectricMotor\ElectricMotorData.cs" />
     <Compile Include="Models\SimulationComponent\Data\Engine\WHRPowerMap.cs" />
     <Compile Include="InputData\Reader\ComponentData\WHRPowerReader.cs" />
+    <Compile Include="Models\SimulationComponent\Data\HybridStrategyParameters.cs" />
     <Compile Include="Models\SimulationComponent\ElectricSystem.cs" />
     <Compile Include="Models\SimulationComponent\IBattery.cs" />
     <Compile Include="Models\SimulationComponent\IElectricMotor.cs" />
diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
index 50fe83e02f..921e386803 100644
--- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
@@ -8,6 +8,7 @@ using TUGraz.VectoCommon.BusAuxiliaries;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.InputData.Impl;
 using TUGraz.VectoCore.InputData.Reader.ComponentData;
 using TUGraz.VectoCore.InputData.Reader.ShiftStrategy;
@@ -53,9 +54,9 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 		private void InitGraphWriter()
 		{
 			//#if TRACE
-			GraphWriter.Enable();
+			//GraphWriter.Enable();
 			//#else
-			//GraphWriter.Disable();
+			GraphWriter.Disable();
 			//#endif
 			GraphWriter.Xfields = new[] { ModalResultField.dist };
 
@@ -66,41 +67,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			GraphWriter.Series1Label = "Hybrid P2";
 			GraphWriter.PlotIgnitionState = true;
 		}
-		//[TestCase(30, 0.8, 200),
-		//TestCase(30, 0.3, 200),
-		//TestCase(30, 0.8, -200),
-		//TestCase(30, 0.8, 0),
-		//]
-		//public void P2HybridDirveOff_ElectricAndICE(double vmax, double initialSoC, double electricTorque)
-		//{
-		//	var cycleData = string.Format(
-		//		@"   0,   0, 0,    3
-		//		   700, {0}, 0,    0", vmax);
-		//	var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
-
-		//	const bool largeMotor = true;
-		//	var electricTq = electricTorque.SI<NewtonMeter>();
-		//	var run = CreateEngineeringRun(
-		//		cycle, string.Format("SimpleParallelHybrid_acc_{0}_{2}-{1}.vmod", vmax, initialSoC, electricTq.Value()),
-		//		initialSoC, PowertrainPosition.HybridP2);
-
-		//	var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController;
-		//	Assert.NotNull(hybridController);
-		//	//var strategy = (DelegateParallelHybridStrategy)hybridController.Strategy;
-		//	//Assert.NotNull(strategy);
-
-		//	var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
-
-		//	var nextState = new StrategyState();
-		//	var currentState = new StrategyState();
-
-
-
-		//	run.Run();
-		//	Assert.IsTrue(run.FinishedWithoutErrors);
-
-		//	Assert.IsTrue(modData.Rows.Count > 0);
-		//}
+		
 
 		[
 			TestCase(30, 0.7, 0, TestName = "P2 Hybrid DriveOff 30km/h SoC: 0.7, level"),
@@ -116,22 +83,15 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 
 			const bool largeMotor = true;
 
-			var modFilename = string.Format("SimpleParallelHybrid_acc_{0}-{1}_{2}.vmod", vmax, initialSoC, slope);
+			var modFilename = string.Format("SimpleParallelHybrid-P2_acc_{0}-{1}_{2}.vmod", vmax, initialSoC, slope);
 			const PowertrainPosition pos = PowertrainPosition.HybridP2;
 			var run = CreateEngineeringRun(
 				cycle, modFilename, initialSoC, pos, largeMotor: true);
 
 			var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController;
 			Assert.NotNull(hybridController);
-			//var strategy = (DelegateParallelHybridStrategy)hybridController.Strategy;
-			//Assert.NotNull(strategy);
-
-			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
-
-			var nextState = new StrategyState();
-			var currentState = new StrategyState();
-
 			
+			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
 
 			run.Run();
 			Assert.IsTrue(run.FinishedWithoutErrors);
@@ -145,9 +105,9 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 		TestCase(50, 0.7, 0, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.7, level"),
 		TestCase(80, 0.7, 0, 0, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.7, level"),
 
-		TestCase(30, 0.2, 0, 0, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.2, level"),
-		TestCase(50, 0.2, 0, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.2, level"),
-		TestCase(80, 0.2, 0, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.2, level"),
+		TestCase(30, 0.25, 0, 0, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.25, level"),
+		TestCase(50, 0.25, 0, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.25, level"),
+		TestCase(80, 0.25, 0, 0, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.25, level"),
 
 		TestCase(30, 0.5, 5, 0, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.5, UH 5%"),
 		TestCase(50, 0.5, 5, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.5, UH 5%"),
@@ -157,8 +117,8 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 		TestCase(50, 0.5, -5, 0, TestName = "P2 Hybrid ConstantSpeed 50km/h SoC: 0.5, DH 5%"),
 		TestCase(80, 0.5, -5, 0, TestName = "P2 Hybrid ConstantSpeed 80km/h SoC: 0.5, DH 5%"),
 
-		TestCase(30, 0.2, 0, 1000, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.2, level P_auxEl: 1kW"),
-			TestCase(30, 0.2, 0, 5000, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.2, level P_auxEl: 5kW"),
+		TestCase(30, 0.25, 0, 1000, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.25, level P_auxEl: 1kW"),
+			TestCase(30, 0.25, 0, 5000, TestName = "P2 Hybrid ConstantSpeed 30km/h SoC: 0.25, level P_auxEl: 5kW"),
 		]
 		public void P2HybridConstantSpeed(double vmax, double initialSoC, double slope, double  pAuxEl)
 		{
@@ -169,7 +129,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 
 			const bool largeMotor = true;
 
-			var modFilename = string.Format("SimpleParallelHybrid_constant_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, pAuxEl);
+			var modFilename = string.Format("SimpleParallelHybrid-P2_constant_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, pAuxEl);
 			const PowertrainPosition pos = PowertrainPosition.HybridP2;
 			var run = CreateEngineeringRun(
 				cycle, modFilename, initialSoC, pos, largeMotor: true, pAuxEl: pAuxEl);
@@ -180,9 +140,51 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
 
 			var data = run.GetContainer().RunData;
-			File.WriteAllText(
-				$"{modFilename}.json",
-				JsonConvert.SerializeObject(data, Formatting.Indented));
+			//File.WriteAllText(
+			//	$"{modFilename}.json",
+			//	JsonConvert.SerializeObject(data, Formatting.Indented));
+
+			run.Run();
+			Assert.IsTrue(run.FinishedWithoutErrors);
+
+			Assert.IsTrue(modData.Rows.Count > 0);
+			GraphWriter.Write(modFilename);
+		}
+
+		[
+			TestCase("LongHaul", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle LongHaul, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("RegionalDelivery", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle RegionalDelivery, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("UrbanDelivery", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle UrbanDelivery, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("Construction", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle UrbanDelivery, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("Urban", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle Urban, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("Suburban", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle SubUrban, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("Interurban", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle InterUrban, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+			TestCase("Coach", 2000, 0.5, 0, TestName = "P2 Hybrid DriveCycle Coach, SoC: 0.5 Payload: 2t P_auxEl: 0kW"),
+		]
+		public void P2HybriDriveCycle(string declarationMission, double payload, double initialSoC, double pAuxEl)
+		{
+			var cycleData = RessourceHelper.ReadStream(
+				DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." +
+				declarationMission +
+				Constants.FileExtensions.CycleFile);
+			var cycle = DrivingCycleDataReader.ReadFromStream(cycleData, CycleType.DistanceBased, "", false);
+
+			const bool largeMotor = true;
+
+			var modFilename = string.Format("SimpleParallelHybrid-P2_cycle_{0}-{1}_{2}_{3}.vmod", declarationMission, initialSoC, payload, pAuxEl);
+			const PowertrainPosition pos = PowertrainPosition.HybridP2;
+			var run = CreateEngineeringRun(
+				cycle, modFilename, initialSoC, pos, largeMotor: true, pAuxEl: pAuxEl, payload: payload.SI<Kilogram>());
+
+			var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController;
+			Assert.NotNull(hybridController);
+
+			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
+
+			var data = run.GetContainer().RunData;
+			//File.WriteAllText(
+			//	$"{modFilename}.json",
+			//	JsonConvert.SerializeObject(data, Formatting.Indented));
 
 			run.Run();
 			Assert.IsTrue(run.FinishedWithoutErrors);
@@ -214,11 +216,6 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 
 			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
 
-			var nextState = new StrategyState();
-			var currentState = new StrategyState();
-
-
-
 			run.Run();
 			Assert.IsTrue(run.FinishedWithoutErrors);
 
@@ -240,7 +237,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 
 			const bool largeMotor = true;
 
-			var modFilename = string.Format("SimpleParallelHybrid_stop_{0}-{1}_{2}.vmod", vmax, initialSoC, slope);
+			var modFilename = string.Format("SimpleParallelHybrid-P2_stop_{0}-{1}_{2}.vmod", vmax, initialSoC, slope);
 			const PowertrainPosition pos = PowertrainPosition.HybridP2;
 			var run = CreateEngineeringRun(
 				cycle, modFilename, initialSoC, pos, largeMotor: true);
@@ -252,10 +249,87 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 
 			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
 
-			var nextState = new StrategyState();
-			var currentState = new StrategyState();
+			run.Run();
+			Assert.IsTrue(run.FinishedWithoutErrors);
+
+			Assert.IsTrue(modData.Rows.Count > 0);
+			GraphWriter.Write(modFilename);
+		}
+
+		[
+			TestCase(30, 0.7, 0, 0, TestName = "P3 Hybrid ConstantSpeed 30km/h SoC: 0.7, level"),
+			TestCase(50, 0.7, 0, 0, TestName = "P3 Hybrid ConstantSpeed 50km/h SoC: 0.7, level"),
+			TestCase(80, 0.7, 0, 0, TestName = "P3 Hybrid ConstantSpeed 80km/h SoC: 0.7, level"),
+
+			TestCase(30, 0.25, 0, 0, TestName = "P3 Hybrid ConstantSpeed 30km/h SoC: 0.25, level"),
+			TestCase(50, 0.25, 0, 0, TestName = "P3 Hybrid ConstantSpeed 50km/h SoC: 0.25, level"),
+			TestCase(80, 0.25, 0, 0, TestName = "P3 Hybrid ConstantSpeed 80km/h SoC: 0.25, level"),
+
+			TestCase(30, 0.5, 5, 0, TestName = "P3 Hybrid ConstantSpeed 30km/h SoC: 0.5, UH 5%"),
+			TestCase(50, 0.5, 5, 0, TestName = "P3 Hybrid ConstantSpeed 50km/h SoC: 0.5, UH 5%"),
+			TestCase(80, 0.5, 5, 0, TestName = "P3 Hybrid ConstantSpeed 80km/h SoC: 0.5, UH 5%"),
+
+			TestCase(30, 0.5, -5, 0, TestName = "P3 Hybrid ConstantSpeed 30km/h SoC: 0.5, DH 5%"),
+			TestCase(50, 0.5, -5, 0, TestName = "P3 Hybrid ConstantSpeed 50km/h SoC: 0.5, DH 5%"),
+			TestCase(80, 0.5, -5, 0, TestName = "P3 Hybrid ConstantSpeed 80km/h SoC: 0.5, DH 5%"),
+
+			TestCase(30, 0.25, 0, 1000, TestName = "P3 Hybrid ConstantSpeed 30km/h SoC: 0.25, level P_auxEl: 1kW"),
+			TestCase(30, 0.25, 0, 5000, TestName = "P3 Hybrid ConstantSpeed 30km/h SoC: 0.25, level P_auxEl: 5kW"),
+		]
+		public void P3HybridConstantSpeed(double vmax, double initialSoC, double slope, double pAuxEl)
+		{
+			var cycleData = string.Format(
+				@"   0, {0}, {1},    0
+				  7000, {0}, {1},    0", vmax, slope);
+			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
+
+			const bool largeMotor = true;
+
+			var modFilename = string.Format("SimpleParallelHybrid-P3_constant_{0}-{1}_{2}_{3}.vmod", vmax, initialSoC, slope, pAuxEl);
+			const PowertrainPosition pos = PowertrainPosition.HybridP3;
+			var run = CreateEngineeringRun(
+				cycle, modFilename, initialSoC, pos, largeMotor: true, pAuxEl: pAuxEl);
+
+			var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController;
+			Assert.NotNull(hybridController);
+
+			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
+
+			var data = run.GetContainer().RunData;
+			//File.WriteAllText(
+			//	$"{modFilename}.json",
+			//	JsonConvert.SerializeObject(data, Formatting.Indented));
 
+			run.Run();
+			Assert.IsTrue(run.FinishedWithoutErrors);
 
+			Assert.IsTrue(modData.Rows.Count > 0);
+			GraphWriter.Write(modFilename);
+		}
+
+		[
+			TestCase(30, 0.7, 0, TestName = "P3 Hybrid DriveOff 30km/h SoC: 0.7, level"),
+			TestCase(80, 0.7, 0, TestName = "P3 Hybrid DriveOff 80km/h SoC: 0.7, level"),
+			TestCase(30, 0.22, 0, TestName = "P3 Hybrid DriveOff 30km/h SoC: 0.22, level")
+		]
+		public void P3HybridDriveOff(double vmax, double initialSoC, double slope)
+		{
+			var cycleData = string.Format(
+				@"   0,   0, {1},    3
+				   700, {0}, {1},    0", vmax, slope);
+			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
+
+			const bool largeMotor = true;
+
+			var modFilename = string.Format("SimpleParallelHybrid-P3_acc_{0}-{1}_{2}.vmod", vmax, initialSoC, slope);
+			const PowertrainPosition pos = PowertrainPosition.HybridP3;
+			var run = CreateEngineeringRun(
+				cycle, modFilename, initialSoC, pos, largeMotor: true);
+
+			var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController;
+			Assert.NotNull(hybridController);
+
+			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
 
 			run.Run();
 			Assert.IsTrue(run.FinishedWithoutErrors);
@@ -264,20 +338,46 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			GraphWriter.Write(modFilename);
 		}
 
-		public class StrategyState
+		[TestCase(50, 0.79, 0, TestName = "P3 Hybrid Brake Standstill 50km/h SoC: 0.79, level"),
+		TestCase(50, 0.25, 0, TestName = "P3 Hybrid Brake Standstill 50km/h SoC: 0.25, level"),
+		TestCase(50, 0.65, 0, TestName = "P3 Hybrid Brake Standstill 50km/h SoC: 0.65, level")
+		]
+		public void P3HybridBrakeStandstill(double vmax, double initialSoC, double slope)
 		{
-			public Second lastGearShift = -double.MaxValue.SI<Second>();
-			public Second requestTstmp = -double.MaxValue.SI<Second>();
-			public uint nextGear = 0u;
+			//var dst =
+			var cycleData = string.Format(
+				@"   0, {0}, {1},    0
+				   200,   0, {1},    3", vmax, slope);
+			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
+
+			const bool largeMotor = true;
+
+			var modFilename = string.Format("SimpleParallelHybrid-P3_stop_{0}-{1}_{2}.vmod", vmax, initialSoC, slope);
+			const PowertrainPosition pos = PowertrainPosition.HybridP3;
+			var run = CreateEngineeringRun(
+				cycle, modFilename, initialSoC, pos, largeMotor: true);
+
+			var hybridController = (HybridController)((VehicleContainer)run.GetContainer()).HybridController;
+			Assert.NotNull(hybridController);
+			//var strategy = (DelegateParallelHybridStrategy)hybridController.Strategy;
+			//Assert.NotNull(strategy);
+
+			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
+
+			run.Run();
+			Assert.IsTrue(run.FinishedWithoutErrors);
+
+			Assert.IsTrue(modData.Rows.Count > 0);
+			GraphWriter.Write(modFilename);
 		}
 
 		// =================================================
 
 		public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, double initialSoc, PowertrainPosition pos, bool largeMotor = false,
-			SummaryDataContainer sumData = null, double pAuxEl = 0)
+			SummaryDataContainer sumData = null, double pAuxEl = 0, Kilogram payload = null)
 		{
 			var container = CreateParallelHybridPowerTrain(
-				cycleData, Path.GetFileNameWithoutExtension(modFileName), initialSoc, largeMotor, sumData, pAuxEl, pos);
+				cycleData, Path.GetFileNameWithoutExtension(modFileName), initialSoc, largeMotor, sumData, pAuxEl, pos, payload);
 			return new DistanceRun(container);
 		}
 
@@ -290,12 +390,8 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 		}
 
 		public static VehicleContainer CreateParallelHybridPowerTrain(DrivingCycleData cycleData, string modFileName,
-			double initialBatCharge, bool largeMotor, SummaryDataContainer sumData, double pAuxEl, PowertrainPosition pos)
+			double initialBatCharge, bool largeMotor, SummaryDataContainer sumData, double pAuxEl, PowertrainPosition pos, Kilogram payload = null)
 		{
-			//var strategySettings = GetHybridStrategyParameters(largeMotor);
-
-			//strategySettings.StrategyName = "SimpleParallelHybridStrategy";
-
 			var fileWriter = new FileOutputWriter(modFileName);
 			var modDataFilter = new IModalDataFilter[] { }; //new IModalDataFilter[] { new ActualModalDataFilter(), };
 			var modData = new ModalDataContainer(
@@ -307,7 +403,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			var gearboxData = CreateGearboxData();
 			var axleGearData = CreateAxleGearData();
 
-			var vehicleData = CreateVehicleData(3300.SI<Kilogram>());
+			var vehicleData = CreateVehicleData(payload ??3300.SI<Kilogram>());
 			var airdragData = CreateAirdragData();
 			var driverData = CreateDriverData(AccelerationFile, true);
 
@@ -315,7 +411,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 				MockSimulationDataFactory.CreateElectricMotorData(largeMotor ? MotorFile240kW : MotorFile, pos);
 
 			var batteryData = MockSimulationDataFactory.CreateBatteryData(BatFile, initialBatCharge);
-			batteryData.TargetSoC = 0.5;
+			//batteryData.TargetSoC = 0.5;
 
 			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(
 				 Truck40tPowerTrain.EngineFile, gearboxData.Gears.Count);
@@ -341,8 +437,9 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 				ElectricMachinesData = electricMotorData,
 				EngineData = engineData,
 				BatteryData = batteryData,
-				//HybridStrategy = strategySettings
-				GearshiftParameters = CreateGearshiftData(gearboxData, axleGearData.AxleGear.Ratio, engineData.IdleSpeed)
+				GearshiftParameters = CreateGearshiftData(gearboxData, axleGearData.AxleGear.Ratio, engineData.IdleSpeed),
+				HybridStrategyParameters = CreateHybridStrategyData(),
+				ElectricAuxDemand = pAuxEl.SI<Watt>()
 			};
 			var container = new VehicleContainer(
 				ExecutionMode.Engineering, modData, x => { sumData?.Write(x, 1, 1, runData); });
@@ -397,6 +494,16 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			return container;
 		}
 
+		private static HybridStrategyParameters CreateHybridStrategyData()
+		{
+			return new HybridStrategyParameters() {
+				EquivalenceFactor = 2.5,
+				MinSoC = 0.22,
+				MaxSoC = 0.8,
+				TargetSoC = 0.5,
+			};
+		}
+
 
 		public static VehicleContainer CreateConventionalPowerTrain(DrivingCycleData cycleData, string modFileName,
 			SummaryDataContainer sumData, double pAuxEl)
diff --git a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs
index 86f674ba0a..b91024a86a 100644
--- a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs
@@ -45,6 +45,7 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.Tests.FileIO;
 using TUGraz.VECTO;
 using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
 
 namespace TUGraz.VectoCore.Tests.Utils
 {
-- 
GitLab