From d76ab585e3fea5248cebac6fc1ed22f87ebb93e5 Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Wed, 17 Aug 2016 16:52:19 +0200
Subject: [PATCH] Added classes for PTOLossMap and GearboxAuxiliary, Changed
 Auxiliary: AddConstant, AddCycle, AddMapping, Add

---
 .../ComponentData/PTOIdleLossMapReader.cs     |  8 +-
 .../Data/PTOTransmissionData.cs               |  8 ++
 .../Impl/EngineAuxiliary.cs                   | 78 ++++++++++---------
 .../Impl/GearboxAuxiliary.cs                  | 15 ++++
 .../VectoCore/Utils/ProviderExtensions.cs     | 11 ++-
 .../Models/Simulation/PTOIdleLossTest.cs      | 12 +--
 6 files changed, 84 insertions(+), 48 deletions(-)
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Data/PTOTransmissionData.cs
 create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/GearboxAuxiliary.cs

diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs
index 0f68e375a9..3d8d8cee0f 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs
@@ -16,7 +16,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 		/// </summary>
 		/// <param name="fileName"></param>
 		/// <returns></returns>
-		public static PTOIdleLossMap ReadFromFile(string fileName)
+		public static PTOLossMap ReadFromFile(string fileName)
 		{
 			try {
 				return Create(VectoCSVFile.Read(fileName));
@@ -28,7 +28,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 		/// <summary>
 		/// Create the pto idle loss map from an appropriate datatable. (2 columns: Engine Speed, PTO Torque)
 		/// </summary>
-		public static PTOIdleLossMap Create(DataTable data)
+		public static PTOLossMap Create(DataTable data)
 		{
 			if (data.Columns.Count != 2) {
 				throw new VectoException("PTO Idle LossMap Data File must consist of 2 columns: {0}, {1}", Fields.EngineSpeed,
@@ -47,8 +47,8 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 					Fields.EngineSpeed, Fields.PTOTorque, ", ".Join(data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
 			}
 
-			return new PTOIdleLossMap(data.Rows.Cast<DataRow>()
-				.Select(row => new PTOIdleLossMap.Entry {
+			return new PTOLossMap(data.Rows.Cast<DataRow>()
+				.Select(row => new PTOLossMap.Entry {
 					EngineSpeed = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(),
 					PTOTorque = row.ParseDouble(Fields.PTOTorque).SI<NewtonMeter>()
 				}).OrderBy(e => e.EngineSpeed).ToArray());
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/PTOTransmissionData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/PTOTransmissionData.cs
new file mode 100644
index 0000000000..5eaf34933d
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/PTOTransmissionData.cs
@@ -0,0 +1,8 @@
+namespace TUGraz.VectoCore.Models.SimulationComponent.Data
+{
+	public class PTOTransmissionData : SimulationComponentData
+	{
+		public string TransmissionType;
+		public ILossMap LossMap;
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs
index bb02bd0d48..365c185107 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/EngineAuxiliary.cs
@@ -41,13 +41,13 @@ using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
-	public class EngineAuxiliary : StatefulVectoSimulationComponent<EngineAuxiliary.EngineAuxState>, IAuxInProvider,
+	public class EngineAuxiliary : StatefulVectoSimulationComponent<EngineAuxiliary.State>, IAuxInProvider,
 		IAuxPort
 	{
-		public const string DirectAuxiliaryId = "";
+		private const string DirectAuxiliaryId = "";
 
-		private readonly Dictionary<string, Func<PerSecond, Watt>> _auxDict = new Dictionary<string, Func<PerSecond, Watt>>();
-		private Dictionary<string, Watt> _powerDemands = new Dictionary<string, Watt>();
+		private readonly Dictionary<string, Func<PerSecond, Watt>> _auxiliaries =
+			new Dictionary<string, Func<PerSecond, Watt>>();
 
 		public EngineAuxiliary(IVehicleContainer container) : base(container) {}
 
@@ -56,6 +56,38 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return this;
 		}
 
+		public void AddConstant(string auxId, Watt powerDemand)
+		{
+			Add(auxId, _ => powerDemand);
+		}
+
+		public void AddCycle()
+		{
+			Add(DirectAuxiliaryId, _ => DataBus.CycleData.LeftSample.AdditionalAuxPowerDemand);
+		}
+
+		public void AddMapping(string auxId, AuxiliaryData data)
+		{
+			if (!DataBus.CycleData.LeftSample.AuxiliarySupplyPower.ContainsKey("Aux_" + auxId)) {
+				var error = string.Format("driving cycle does not contain column for auxiliary: {0}", auxId);
+				Log.Error(error);
+				throw new VectoException(error);
+			}
+
+			Add(auxId, speed => {
+				var powerSupply = DataBus.CycleData.LeftSample.AuxiliarySupplyPower["Aux_" + auxId];
+				var nAuxiliary = speed * data.TransmissionRatio;
+				var powerAuxOut = powerSupply / data.EfficiencyToSupply;
+				var powerAuxIn = data.GetPowerDemand(nAuxiliary, powerAuxOut);
+				return powerAuxIn / data.EfficiencyToEngine;
+			});
+		}
+
+		public void Add(string auxId, Func<PerSecond, Watt> powerLoss)
+		{
+			_auxiliaries[auxId] = powerLoss;
+		}
+
 		public NewtonMeter PowerDemand(Second absTime, Second dt, NewtonMeter torquePowerTrain, NewtonMeter torqueEngine,
 			PerSecond angularSpeed, bool dryRun = false)
 		{
@@ -72,18 +104,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		private Watt ComputePowerDemand(PerSecond engineSpeed)
 		{
-			_powerDemands = _auxDict.ToDictionary(kv => kv.Key, kv => kv.Value(engineSpeed));
-			return _powerDemands.Values.Sum(p => p);
+			CurrentState.PowerDemands = _auxiliaries.ToDictionary(kv => kv.Key, kv => kv.Value(engineSpeed));
+			return CurrentState.PowerDemands.Values.Sum(p => p);
 		}
 
 		protected override void DoWriteModalResults(IModalDataContainer container)
 		{
-			foreach (var kv in _powerDemands.Where(kv => !string.IsNullOrWhiteSpace(kv.Key))) {
+			foreach (var kv in CurrentState.PowerDemands.Where(kv => !string.IsNullOrWhiteSpace(kv.Key))) {
 				container[kv.Key] = kv.Value;
 			}
 			if (container[ModalResultField.P_aux] == null || container[ModalResultField.P_aux] == DBNull.Value) {
 				// don't overwrite if someone else already wrote the total aux power
-				container[ModalResultField.P_aux] = _powerDemands.Values.Sum(p => p);
+				container[ModalResultField.P_aux] = CurrentState.PowerDemands.Values.Sum(p => p);
 			}
 		}
 
@@ -92,36 +124,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			AdvanceState();
 		}
 
-		public void AddConstant(string auxId, Watt powerDemand)
-		{
-			_auxDict[auxId] = speed => powerDemand;
-		}
-
-		public void AddDirect()
-		{
-			_auxDict[DirectAuxiliaryId] = speed => DataBus.CycleData.LeftSample.AdditionalAuxPowerDemand;
-		}
-
-		public void AddMapping(string auxId, AuxiliaryData data)
-		{
-			if (!DataBus.CycleData.LeftSample.AuxiliarySupplyPower.ContainsKey("Aux_" + auxId)) {
-				var error = string.Format("driving cycle does not contain column for auxiliary: {0}", auxId);
-				Log.Error(error);
-				throw new VectoException(error);
-			}
-
-			_auxDict[auxId] = speed => {
-				var powerSupply = DataBus.CycleData.LeftSample.AuxiliarySupplyPower["Aux_" + auxId];
-				var nAuxiliary = speed * data.TransmissionRatio;
-				var powerAuxOut = powerSupply / data.EfficiencyToSupply;
-				var powerAuxIn = data.GetPowerDemand(nAuxiliary, powerAuxOut);
-				return powerAuxIn / data.EfficiencyToEngine;
-			};
-		}
-
-		public class EngineAuxState
+		public class State
 		{
 			public PerSecond AngularSpeed;
+			public Dictionary<string, Watt> PowerDemands;
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/GearboxAuxiliary.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/GearboxAuxiliary.cs
new file mode 100644
index 0000000000..412a855890
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/GearboxAuxiliary.cs
@@ -0,0 +1,15 @@
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.OutputData;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class GearboxAuxiliary : EngineAuxiliary
+	{
+		public GearboxAuxiliary(IVehicleContainer container) : base(container) {}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			//todo mk-2016-08-17: write gearbox auxiliaries to mod file?
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Utils/ProviderExtensions.cs b/VectoCore/VectoCore/Utils/ProviderExtensions.cs
index 7abcea559c..08e5343d56 100644
--- a/VectoCore/VectoCore/Utils/ProviderExtensions.cs
+++ b/VectoCore/VectoCore/Utils/ProviderExtensions.cs
@@ -33,6 +33,7 @@ using System;
 using System.Collections.Generic;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.Simulation.Impl;
@@ -102,9 +103,15 @@ namespace TUGraz.VectoCore.Utils
 			return next;
 		}
 
-		public static IPowerTrainComponent AddRetarderAndGearbox(this IPowerTrainComponent prev, RetarderData data,
-			IGearbox gearbox, IVehicleContainer container)
+		public static IPowerTrainComponent AddComponent(this IPowerTrainComponent prev, IGearbox gearbox, RetarderData data,
+			PTOTransmissionData pto, IVehicleContainer container)
 		{
+			if (pto != null) {
+				var aux = new GearboxAuxiliary(container);
+				aux.AddConstant("PTO_TRANSM", DeclarationData.PTOTransmission.Lookup(pto.TransmissionType));
+				aux.Add("PTO_IDLE", n => pto.LossMap.GetTorqueLoss(n) * n);
+			}
+
 			switch (data.Type) {
 				case RetarderType.TransmissionOutputRetarder:
 					return prev.AddComponent(new Retarder(container, data.LossMap, data.Ratio)).AddComponent(gearbox);
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/PTOIdleLossTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/PTOIdleLossTest.cs
index 0ad29a8b0f..3f95338fbd 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/PTOIdleLossTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/PTOIdleLossTest.cs
@@ -44,14 +44,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 		[TestCase]
 		public void PTOIdleLosses_FixPoints()
 		{
-			var entryList = new List<PTOIdleLossMap.Entry>();
+			var entryList = new List<PTOLossMap.Entry>();
 			for (var i = 0; i < 2000; i += 200) {
-				entryList.Add(new PTOIdleLossMap.Entry {
+				entryList.Add(new PTOLossMap.Entry {
 					EngineSpeed = i.RPMtoRad(),
 					PTOTorque = (Math.Sqrt(i) / 10).SI<NewtonMeter>()
 				});
 			}
-			var pto = new PTOIdleLossMap(entryList.ToArray());
+			var pto = new PTOLossMap(entryList.ToArray());
 
 			foreach (var entry in entryList) {
 				Assert.AreEqual(entry.PTOTorque, pto.GetTorqueLoss(entry.EngineSpeed));
@@ -61,14 +61,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 		[TestCase]
 		public void PTOIdleLosses_Interpolate()
 		{
-			var entryList = new List<PTOIdleLossMap.Entry>();
+			var entryList = new List<PTOLossMap.Entry>();
 			for (var i = 0; i < 2000; i += 200) {
-				entryList.Add(new PTOIdleLossMap.Entry {
+				entryList.Add(new PTOLossMap.Entry {
 					EngineSpeed = i.RPMtoRad(),
 					PTOTorque = (Math.Sqrt(i) / 10).SI<NewtonMeter>()
 				});
 			}
-			var pto = new PTOIdleLossMap(entryList.ToArray());
+			var pto = new PTOLossMap(entryList.ToArray());
 
 			for (var i = 1; i < entryList.Count; i++) {
 				var v1 = entryList[i - 1];
-- 
GitLab