From 8a0fd905831209c30a58b2557ff43d791c9d05d8 Mon Sep 17 00:00:00 2001
From: Harald Martini <harald.martini@student.tugraz.at>
Date: Wed, 5 Oct 2022 09:04:41 +0200
Subject: [PATCH] added BatteryElectricIdleController

---
 .../SimulationComponent/IElectricMotor.cs     |  2 +-
 .../BatteryElectricIdleController.cs          | 70 +++++++++++++++++++
 .../Models/SimulationComponent/Impl/EPTO.cs   | 26 +++++++
 .../SimulationComponent/Impl/ElectricMotor.cs | 10 +++
 .../Impl/EngineAuxiliary.cs                   |  1 +
 .../Impl/PTOCycleController.cs                | 10 +--
 .../Impl/PowertrainDrivingCycle.cs            |  2 +
 .../HeavyLorry/HeavyLorrySimulation.cs        | 22 ++++--
 8 files changed, 134 insertions(+), 9 deletions(-)
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/Controller/BatteryElectricIdleController.cs
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/EPTO.cs

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotor.cs
index e02dc99ba0..b37a2062a1 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotor.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IElectricMotor.cs
@@ -7,7 +7,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 	public interface IElectricMotor : IPowerTrainComponent, IElectricMotorInfo
 	{
 		void Connect(IElectricSystem powersupply);
-		
+		IIdleController IdleController { get; }
 		BusAuxiliariesAdapter BusAux { set; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Controller/BatteryElectricIdleController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Controller/BatteryElectricIdleController.cs
new file mode 100644
index 0000000000..779782ff93
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Controller/BatteryElectricIdleController.cs
@@ -0,0 +1,70 @@
+using System;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Controller
+{
+    internal class BatteryElectricIdleController : LoggingObject, IIdleController
+	{
+		private Second _idleStart;
+		private ITnOutPort _requestPort;
+
+
+		#region Implementation of ITnOutPort
+
+		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun)
+		{
+			if (outAngularVelocity != null)
+			{
+				throw new VectoException("IdleController can only handle idle requests, i.e. angularVelocity == null!");
+			}
+			if (!outTorque.IsEqual(0, 5e-2))
+			{
+				throw new VectoException("Torque has to be 0 for idle requests! {0}", outTorque);
+			}
+
+			if (dryRun) {
+				throw new NotImplementedException();
+			}
+			if (_idleStart == null) {
+				_idleStart = absTime;
+			}
+
+			var retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), 0.SI<PerSecond>(), dryRun);
+
+			switch (retVal) {
+				case ResponseSuccess _:
+					break;
+				default:
+					throw new UnexpectedResponseException("Searching idling point", retVal);
+			}
+
+			return retVal;
+		}
+
+		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			throw new NotImplementedException();
+		}
+
+		#endregion
+
+		#region Implementation of IIdleController
+
+		public ITnOutPort RequestPort
+		{
+			set => _requestPort = value;
+			private get => _requestPort;
+		}
+
+		public void Reset()
+		{
+			_idleStart = null;
+		}
+
+		#endregion
+	}
+}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EPTO.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EPTO.cs
new file mode 100644
index 0000000000..f17b50dba3
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EPTO.cs
@@ -0,0 +1,26 @@
+using Microsoft.VisualBasic;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Auxiliaries;
+using Constants = TUGraz.VectoCore.Configuration.Constants;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class EPTO : IAuxDemand
+	{
+		#region Implementation of IAuxDemand
+
+		public Watt PowerDemand(IDataBus dataBus)
+		{
+			if (dataBus.DrivingCycleInfo.PTOActive) {
+				return dataBus.DrivingCycleInfo.CycleData.LeftSample.PTOElectricalPowerDemand ?? 0.SI<Watt>();
+			}
+
+			return 0.SI<Watt>();
+		}
+
+		public string AuxID => Constants.Auxiliaries.IDs.PTOConsumer;
+
+		#endregion
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
index 65f3440f5d..a89b300f6b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ElectricMotor.cs
@@ -9,6 +9,7 @@ using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Controller;
 using TUGraz.VectoCore.Models.SimulationComponent.Strategies;
 using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
@@ -26,11 +27,18 @@ 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; }
 
+        #region Implementation of IElectricMotor
+		private IIdleController _idleController;
+        public IIdleController IdleController => _idleController ?? (_idleController = new BatteryElectricIdleController());
+
+		#endregion
+
 		public ElectricMotor(IVehicleContainer container, ElectricMotorData data, IElectricMotorControl control, PowertrainPosition position) : base(container)
 		{
 			Control = control;
@@ -599,6 +607,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		#endregion
 	}
 
+	
+
 	public class ElectricMotorState // : SimpleComponentState
 	{
 		public ElectricMotorState()
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs
index f90aa85611..4ad1c9a5af 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs
@@ -83,6 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public void AddCycle(string auxId)
 		{
 			Add(auxId, (nEng, absTime, dt, dryRun) => DataBus.DrivingCycleInfo.CycleData.LeftSample.AdditionalAuxPowerDemand);
+
 		}
 
 		public void AddCycle(string auxId, Func<DrivingCycleData.DrivingCycleEntry, Watt> powerLossFunc, string columnName = null)
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs
index db93702f78..4514a8ad60 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOCycleController.cs
@@ -76,6 +76,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				PreviousState.InAngularVelocity = DataBus.EngineInfo.EngineSpeed;
 			}
 			return base.Request(absTime - IdleStart, dt);
+			
 		}
 
 		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
@@ -100,10 +101,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		protected override void DoWriteModalResults(Second time, Second simulationInterval, IModalDataContainer container)
 		{
-			base.DoWriteModalResults(time, simulationInterval, container);
-			container[Constants.Auxiliaries.IDs.PTOConsumer] = CurrentState.InTorque *
-																(PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2;
-			container[ModalResultField.P_ice_out] = 0.SI<Watt>();
+
+			//base.DoWriteModalResults(time, simulationInterval, container);
+			//container[Constants.Auxiliaries.IDs.PTOConsumer] = CurrentState.InTorque *
+			//													(PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2;
+			//container[ModalResultField.P_ice_out] = 0.SI<Watt>();
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs
index b97dc17087..931363ee46 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs
@@ -67,6 +67,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			CycleIterator = new DrivingCycleEnumerator(Data);
 
 			AbsTime = -1.SI<Second>();
+			
 		}
 
 		public virtual IResponse Initialize()
@@ -178,6 +179,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected override void DoCommitSimulationStep(Second time, Second simulationInterval)
 		{
 			CycleIterator.MoveNext();
+			
 			AdvanceState();
 		}
 
diff --git a/VectoCore/VectoCoreTest/Integration/Declaration/HeavyLorry/HeavyLorrySimulation.cs b/VectoCore/VectoCoreTest/Integration/Declaration/HeavyLorry/HeavyLorrySimulation.cs
index 2911857f99..1d29a34bd8 100644
--- a/VectoCore/VectoCoreTest/Integration/Declaration/HeavyLorry/HeavyLorrySimulation.cs
+++ b/VectoCore/VectoCoreTest/Integration/Declaration/HeavyLorry/HeavyLorrySimulation.cs
@@ -51,17 +51,31 @@ public class HeavyLorrySimulation
 		var runsFactory = SimulatorFactory.CreateSimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter);
 		var jobContainer = new JobContainer(new MockSumWriter()) { };
 		jobContainer.AddRuns(runsFactory);
-		PrintRuns(jobContainer);
+		PrintRuns(jobContainer, null);
 		jobContainer.Execute(multiThreaded);
 		jobContainer.WaitFinished();
-		PrintRuns(jobContainer);
+		PrintRuns(jobContainer, fileWriter);
+		PrintFiles(fileWriter);
 
 	}
 
-	private void PrintRuns(JobContainer jobContainer)
+	private void PrintRuns(JobContainer jobContainer, FileOutputWriter fileWriter = null)
 	{
 		foreach (var keyValuePair in jobContainer.GetProgress()) {
 			TestContext.WriteLine($"{keyValuePair.Key}: {keyValuePair.Value.CycleName} {keyValuePair.Value.RunName} {keyValuePair.Value.Error?.Message}" );
+			//if (fileWriter != null && keyValuePair.Value.Success) {
+			//	TestContext.AddTestAttachment(fileWriter.GetModDataFileName(keyValuePair.Value.RunName, keyValuePair.Value.CycleName, keyValuePair.Value.RunSuffix), keyValuePair.Value.RunName);
+   //         }
+	
 		}
 	}
-}
\ No newline at end of file
+
+	private void PrintFiles(FileOutputWriter fileWriter)
+	{
+		foreach (var keyValuePair in fileWriter.GetWrittenFiles()) {
+			TestContext.WriteLine($"{keyValuePair.Key} written to {keyValuePair.Value}");
+			TestContext.AddTestAttachment(keyValuePair.Value, keyValuePair.Key.ToString());
+		}
+		
+	}
+}
-- 
GitLab