From 7191c602a899c7059970aa7ab93f937cfd24d669 Mon Sep 17 00:00:00 2001
From: "VKMTHD\\haraldmartini" <harald.martini@student.tugraz.at>
Date: Fri, 23 Sep 2022 17:08:59 +0200
Subject: [PATCH] added first implementation for conditioning

---
 .../VectoCommon/Models/AuxiliaryDemandType.cs |  3 +-
 .../AuxiliaryDataAdapter.cs                   | 86 +++++++++++++++++--
 ...PModeVectoRunDataFactoryHeavyBusPrimary.cs |  4 +-
 .../Declaration/Auxiliaries/Conditioning.cs   | 58 +++++++++++++
 .../Models/Declaration/DeclarationData.cs     |  1 +
 .../Models/Simulation/Data/VectoRunData.cs    |  5 +-
 .../Simulation/DataBus/IElectricMotorInfo.cs  |  2 +
 .../Simulation/Impl/PowertrainBuilder.cs      |  4 +-
 .../Impl/ElectricAuxiliaries.cs               | 35 ++++----
 .../SimulationComponent/Impl/ElectricMotor.cs |  5 ++
 .../SimulationComponent/Impl/Vehicle.cs       |  1 +
 11 files changed, 177 insertions(+), 27 deletions(-)
 create mode 100644 VectoCore/VectoCore/Models/Declaration/Auxiliaries/Conditioning.cs

diff --git a/VectoCommon/VectoCommon/Models/AuxiliaryDemandType.cs b/VectoCommon/VectoCommon/Models/AuxiliaryDemandType.cs
index 041793e823..3b2a7452ce 100644
--- a/VectoCommon/VectoCommon/Models/AuxiliaryDemandType.cs
+++ b/VectoCommon/VectoCommon/Models/AuxiliaryDemandType.cs
@@ -34,6 +34,7 @@ namespace TUGraz.VectoCommon.Models
 	public enum AuxiliaryDemandType
 	{
 		Direct,
-		Constant
+		Constant,
+		Dynamic
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs
index 6e53970899..f214af2d3d 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs
@@ -15,6 +15,7 @@ using TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.HVAC;
 using TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.Pneumatics;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents
@@ -44,8 +45,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 	}
 
 
-	
-
 	public abstract class AuxiliaryDataAdapter : ComponentDataAdapterBase, IAuxiliaryDataAdapter
 	{
 		public class ElectricConsumerEntry
@@ -65,8 +64,12 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 			public Ampere Current { get; set; }
 		}
 		public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesDeclarationInputData auxInputData,
-			IBusAuxiliariesDeclarationData busAuxData, MissionType mission, VehicleClass hvdClass, Meter vehicleLength,
-			int? numSteeredAxles, VectoSimulationJobType jobType)
+			IBusAuxiliariesDeclarationData busAuxData, 
+			MissionType mission, 
+			VehicleClass hvdClass, 
+			Meter vehicleLength,
+			int? numSteeredAxles, 
+			VectoSimulationJobType jobType)
 		{
 			CheckDeclarationMode(auxInputData, "AuxiliariesData");
 			return DoCreateAuxiliaryData(auxInputData, busAuxData, mission, hvdClass, vehicleLength, numSteeredAxles, jobType);
@@ -79,7 +82,14 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 			IBusAuxiliariesDeclarationData busAuxData, MissionType mission, VehicleClass hdvClass, Meter vehicleLength,
 			int? numSteeredAxles, VectoSimulationJobType jobType);
 
-
+		protected static bool CreateConditioningAux(VectoSimulationJobType jobType)
+		{
+			if (jobType == VectoSimulationJobType.ConventionalVehicle) {
+				return false;
+			} else {
+				return true;
+			}
+		}
 	}
 
 	public class HeavyLorryPEVAuxiliaryDataAdapter : HeavyLorryAuxiliaryDataAdapter
@@ -108,6 +118,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 			throw new System.NotImplementedException();
 		}
 
+		
+
 		protected override IList<VectoRunData.AuxData> DoCreateAuxiliaryData(
 			IAuxiliariesDeclarationInputData auxInputData, IBusAuxiliariesDeclarationData busAuxData,
 			MissionType mission, VehicleClass hdvClass, Meter vehicleLength, int? numSteeredAxles,
@@ -161,14 +173,76 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
 						break;
 					default: continue;
 				}
-				
 			}
 
+			if (CreateConditioningAux(jobType)) {
+				AddConditioning(mission, jobType, retVal, hdvClass);
+			}
+
+
 			
 
 			return retVal;
 		}
 
+		private static void AddConditioning(MissionType mission, VectoSimulationJobType jobType, List<VectoRunData.AuxData> auxDataList, VehicleClass hdv)
+		{
+
+
+			var aux = new VectoRunData.AuxData()
+			{
+				IsFullyElectric = true,
+				MissionType = mission,
+				DemandType = AuxiliaryDemandType.Dynamic,
+				ID = "Cond"
+			};
+
+
+			Func<IDataBus, Watt> parallelHybridPowerDemand = (dataBus) => {
+				var elInfo = dataBus.ElectricMotorInfo(dataBus.PowertrainInfo.ElectricMotorPositions.Single());
+				var iceInfo = dataBus.EngineInfo;
+				var emPower = elInfo.ElectricMotorSpeed * elInfo.ElectricMotorTorque;
+				var icePower = iceInfo.EngineSpeed * iceInfo.EngineTorque;
+
+				var xFactor = emPower.Abs() / (emPower.Abs() + icePower.Abs());
+				return DeclarationData.Conditioning.LookupPowerDemand(hdv, mission) * xFactor;
+			};
+
+			Func<IDataBus, Watt> powerDemandFunc = (dataBus) => {
+				var elInfo = dataBus.ElectricMotorInfo(dataBus.PowertrainInfo.ElectricMotorPositions.Single());
+				if (elInfo.EmOff)
+				{
+					return 0.SI<Watt>();
+				}
+				else
+				{
+					return DeclarationData.Conditioning.LookupPowerDemand(hdv, mission);
+				}
+			};
+			
+
+
+			switch (jobType) {
+				case VectoSimulationJobType.ConventionalVehicle:
+					throw new VectoException("Should not be created for conventional vehicles");
+				case VectoSimulationJobType.BatteryElectricVehicle:
+				case VectoSimulationJobType.SerialHybridVehicle:
+					aux.PowerDemandDataBusFunc = powerDemandFunc;
+					break;
+				case VectoSimulationJobType.ParallelHybridVehicle:
+					aux.PowerDemandDataBusFunc = parallelHybridPowerDemand;
+					break;
+				case VectoSimulationJobType.EngineOnlySimulation:
+				case VectoSimulationJobType.IEPC_E:
+				case VectoSimulationJobType.IEPC_S:
+				case VectoSimulationJobType.IHPC:
+				default:
+					throw new ArgumentOutOfRangeException(nameof(jobType), jobType, null);
+			}
+			auxDataList.Add(aux);
+		}
+
+
 		private static void AddElectricSystem(MissionType mission, VectoRunData.AuxData aux,
 			IAuxiliaryDeclarationInputData auxData, double alternatorEfficiency, List<VectoRunData.AuxData> auxDataList)
 		{
diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactoryHeavyBusPrimary.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactoryHeavyBusPrimary.cs
index a57aeaa420..7e5b08fe39 100644
--- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactoryHeavyBusPrimary.cs
+++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactoryHeavyBusPrimary.cs
@@ -163,7 +163,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
                 DemandType = AuxiliaryDemandType.Direct,
                 Technology = new List<string>() { busAux.PneumaticSupply.CompressorSize + " / " + busAux.PneumaticSupply.Clutch },
                 ID = Constants.Auxiliaries.IDs.PneumaticSystem,
-                PowerDemandMechFunc = cycleEntry =>
+                PowerDemandMechCycleFunc = cycleEntry =>
                 {
                     var cmp = psCompressor.Interpolate(cycleEntry.EngineSpeed * busAux.PneumaticSupply.Ratio);
                     return cycleEntry.VTPPSCompressorActive ? cmp.PowerOn : cmp.PowerOff;
@@ -177,7 +177,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
                 DemandType = AuxiliaryDemandType.Direct,
                 Technology = new List<string>() { "default" },
                 ID = Constants.Auxiliaries.IDs.Fan,
-                PowerDemandMechFunc = cycleEntry => engineFan.PowerDemand(cycleEntry.FanSpeed)
+                PowerDemandMechCycleFunc = cycleEntry => engineFan.PowerDemand(cycleEntry.FanSpeed)
             });
 
             return retVal;
diff --git a/VectoCore/VectoCore/Models/Declaration/Auxiliaries/Conditioning.cs b/VectoCore/VectoCore/Models/Declaration/Auxiliaries/Conditioning.cs
new file mode 100644
index 0000000000..29ed7fc927
--- /dev/null
+++ b/VectoCore/VectoCore/Models/Declaration/Auxiliaries/Conditioning.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Data;
+using System.Linq;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.Declaration.Auxiliaries
+{
+	public class Conditioning
+	{
+		private LorryConditioning _lorryConditioning = new LorryConditioning();
+		private BusConditioning _busConditioning = new BusConditioning();
+
+		public Watt LookupPowerDemand(VehicleClass hdvClass, MissionType mission)
+		{
+			return hdvClass.IsBus() ? _busConditioning.Lookup(mission).PowerDemand : _lorryConditioning.Lookup(mission).PowerDemand;
+		}
+
+
+		
+
+
+
+		private class LorryConditioning : LookupData<MissionType, AuxDemandEntry>
+		{
+			#region Overrides of LookupData
+
+			protected override string ResourceId => DeclarationData.DeclarationDataResourcePrefix + ".VAUX.Cond-Table.csv";
+			protected override void ParseData(DataTable table)
+			{
+				foreach (DataRow row in table.Rows) {
+					foreach(DataColumn col in table.Columns.Cast<DataColumn>().Skip(1))
+					{
+						Data[col.Caption.ParseEnum<MissionType>()] = new AuxDemandEntry()
+						{
+							PowerDemand = row.ParseDouble(col.Caption).SI<Watt>()
+						};
+					}
+				}
+			}
+
+			#endregion
+		}
+		private class BusConditioning : LorryConditioning
+		{
+			#region Overrides of LookupData
+			protected override string ResourceId => DeclarationData.DeclarationDataResourcePrefix + ".VAUXBus.Cond-Table.csv";
+			#endregion
+		}
+
+
+	}
+
+
+
+
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
index 650f52ff14..95af962560 100644
--- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
@@ -88,6 +88,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 		public static readonly WHTCCorrection WHTCCorrection = new WHTCCorrection();
 		public static readonly AirDrag AirDrag = new AirDrag();
 		public static readonly StandardBodies StandardBodies = new StandardBodies();
+		public static readonly Conditioning Conditioning = new Conditioning();
 		public static readonly Payloads Payloads = new Payloads();
 
 		public static readonly PTOTransmission PTOTransmission = new PTOTransmission();
diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
index a740bceebd..b001885665 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.DataObjectAdapter;
 using TUGraz.VectoCore.InputData.Reader.Impl;
 using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Battery;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
@@ -187,7 +188,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 			[SIRange(0, 100 * Constants.Kilo)] public Watt PowerDemandElectric;
 
 			[JsonIgnore]
-			public Func<DrivingCycleData.DrivingCycleEntry, Watt> PowerDemandMechFunc;
+			public Func<DrivingCycleData.DrivingCycleEntry, Watt> PowerDemandMechCycleFunc;
+
+			[JsonIgnore] public Func<IDataBus, Watt> PowerDemandDataBusFunc;
 
 
 
diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs
index 802703c7fa..fccde08b0d 100644
--- a/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs
+++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IElectricMotorInfo.cs
@@ -9,12 +9,14 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus
 		//NewtonMeter ElectricDragTorque(PerSecond electricMotorSpeed, Second simulationInterval, DrivingBehavior drivingBehavior);
 
 		PerSecond ElectricMotorSpeed { get; }
+		NewtonMeter ElectricMotorTorque { get; }
 		PowertrainPosition Position { get; }
 		PerSecond MaxSpeed { get; }
 		Watt DragPower(Volt volt, PerSecond electricMotorSpeed, GearshiftPosition gear);
 		Watt MaxPowerDrive(Volt volt, PerSecond inAngularVelocity, GearshiftPosition gear);
 		NewtonMeter GetTorqueForElectricPower(Volt volt, Watt electricPower, PerSecond avgEmSpeed, Second dt, GearshiftPosition gear, bool allowExtrapolation);
 
+		bool EmOff { get; }
 		bool DeRatingActive { get; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
index b9b5b672b3..c244bd3b36 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
@@ -230,10 +230,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 						aux.AddConstant(id, auxData.PowerDemandMech);
 						break;
 					case AuxiliaryDemandType.Direct:
-						if (auxData.PowerDemandMechFunc == null) {
+						if (auxData.PowerDemandMechCycleFunc == null) {
 							aux.AddCycle(id);
 						} else {
-							aux.AddCycle(id, auxData.PowerDemandMechFunc);
+							aux.AddCycle(id, auxData.PowerDemandMechCycleFunc);
 						}
 						break;
 					default:
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs
index 24847a9b28..c70468729b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricAuxiliaries.cs
@@ -22,6 +22,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		private IEnumerable<VectoRunData.AuxData> _auxData;
 
 		private IDictionary<string, string> _auxColumnName = new Dictionary<string, string>();
+		private IDictionary<string, Watt> _powerDemands = new Dictionary<string, Watt>();
 
 		#region Implementation of IElectricAuxPort
 
@@ -50,22 +51,26 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public Watt PowerDemand(Second absTime, Second dt, bool dryRun)
 		{
-			var left = VehicleContainer.DrivingCycleInfo.CycleData.LeftSample;
+			
 			
 			var sum = 0.SI<Watt>();
-			foreach (var auxData in _auxData) {
-				if (auxData.DemandType == AuxiliaryDemandType.Constant) {
-					sum += auxData.PowerDemandElectric;
-				} else {
-					sum += auxData.PowerDemandMechFunc(left);
-					throw new NotImplementedException("only constant electric auxiliaries implemented");
+			foreach (var aux in _auxData) {
+				var powerDemand = 0.SI<Watt>(); 
+				if (aux.DemandType == AuxiliaryDemandType.Constant) {
+					powerDemand = aux.PowerDemandElectric;
+				} else if(aux.DemandType == AuxiliaryDemandType.Dynamic) {
+					powerDemand = aux.PowerDemandDataBusFunc(DataBus);
+				}
+
+
+				if (!dryRun) {
+					_powerDemands[aux.ID] = powerDemand;
 				}
+
+				sum += powerDemand;
 			}
 
 			return sum;
-
-			//VehicleContainer.EngineInfo.EngineOn
-			VehicleContainer.ElectricMotorInfo(PowertrainPosition.BatteryElectricE3)
 		}
 
 		#endregion
@@ -78,15 +83,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		{
             foreach (var aux in _auxData)
             {
-				if (aux.DemandType == AuxiliaryDemandType.Constant) {
-					container[_auxColumnName[aux.ID]] = aux.PowerDemandElectric;
-				}
+				
+				container[_auxColumnName[aux.ID]] = _powerDemands[aux.ID];
+				
 			}
-        }
+		}
 
 		protected override void DoCommitSimulationStep(Second time, Second simulationInterval)
 		{
-			
+			_powerDemands.Clear();
 		}
 
 		#endregion
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
index cf4d1f6dd2..65f3440f5d 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
@@ -27,6 +27,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected internal Joule ThermalBuffer = 0.SI<Joule>();
 		
 		public bool DeRatingActive { get; protected internal set; }
+		public bool EmOff => PreviousState.EMTorque == null ? true : false;
 
 		public BusAuxiliariesAdapter BusAux { protected get; set; }
 
@@ -85,6 +86,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		}
 
+
+
+
 		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
 		{
 			var emOutAngularVelocity = outAngularVelocity * ModelData.RatioADC;
@@ -568,6 +572,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 
 		public PerSecond ElectricMotorSpeed => PreviousState.EMSpeed;
+		public NewtonMeter ElectricMotorTorque => PreviousState.EMTorque;
 
 		public void Connect(IElectricSystem powersupply)
 		{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
index e89bcbed9a..9a70a3d0db 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
@@ -142,6 +142,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public IResponse Request(Second absTime, Second dt, MeterPerSquareSecond acceleration, Radian gradient,
 			bool dryRun = false)
 		{
+
 			Log.Debug("Vehicle: acceleration: {0}", acceleration);
 			CurrentState.SimulationInterval = dt;
 			CurrentState.Acceleration = acceleration;
-- 
GitLab