From 0edd8d317a30f36e319c929c0a5385a62cdec095 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Fri, 29 Jul 2016 13:01:56 +0200
Subject: [PATCH] allow extrapolation of fuel-map in engineering mode

---
 .../Data/Engine/FuelConsumptionMap.cs          | 18 +++++++++++++++---
 .../Impl/BusAuxiliariesAdapter.cs              |  2 +-
 .../Impl/CombustionEngine.cs                   |  8 +++++++-
 .../FuelConsumptionMapTest.cs                  |  2 +-
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
index bbc64f3d86..2acbfd9277 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
@@ -32,6 +32,7 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 using System.Data;
+using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using TUGraz.VectoCommon.Exceptions;
@@ -53,18 +54,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 		/// <summary>
 		/// Calculates the fuel consumption based on the given fuel map, the angularVelocity and the torque.
 		/// </summary>
-		public KilogramPerSecond GetFuelConsumption(NewtonMeter torque, PerSecond angularVelocity,
+		public FuelConsumptionResult GetFuelConsumption(NewtonMeter torque, PerSecond angularVelocity,
 			bool allowExtrapolation = false)
 		{
+			var result = new FuelConsumptionResult();
 			// delaunay map needs is initialised with rpm, therefore the angularVelocity has to be converted.
 			var value = _fuelMap.Interpolate(torque.Value(), angularVelocity.AsRPM);
 			if (value.HasValue) {
-				return value.Value.SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>();
+				result.Value = value.Value.SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>();
+				return result;
 			}
 
 			if (allowExtrapolation) {
-				return
+				result.Value =
 					_fuelMap.Extrapolate(torque.Value(), angularVelocity.AsRPM).SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>();
+				result.Extrapolated = true;
+				return result;
 			}
 
 			throw new VectoException("FuelConsumptionMap: Interpolation failed. torque: {0}, n: {1}", torque.Value(),
@@ -125,6 +130,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			#endregion
 		}
 
+		[DebuggerDisplay("{Value} (extrapolated: {Extrapolated})")]
+		public class FuelConsumptionResult
+		{
+			public KilogramPerSecond Value;
+			public bool Extrapolated;
+		}
+
 		#region Equality members
 
 		protected bool Equals(FuelConsumptionMap other)
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs
index c4aed9a981..7a83449f43 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs
@@ -275,7 +275,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			public KilogramPerSecond GetFuelConsumption(NewtonMeter torque, PerSecond angularVelocity)
 			{
-				return FcMap.GetFuelConsumption(torque, angularVelocity, AllowExtrapolation);
+				return FcMap.GetFuelConsumption(torque, angularVelocity, AllowExtrapolation).Value;
 			}
 		}
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
index 5cfd09c19c..f058ce1e32 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
@@ -344,8 +344,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			container[ModalResultField.Tq_full] = CurrentState.DynamicFullLoadTorque;
 			container[ModalResultField.Tq_drag] = CurrentState.FullDragTorque;
 
-			var fc = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed);
+			var result = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed,
+				DataBus.ExecutionMode != ExecutionMode.Declaration);
+			if (DataBus.ExecutionMode != ExecutionMode.Declaration && result.Extrapolated) {
+				Log.Warn("FuelConsumptionMap was extrapolated: range for FC-Map is not sufficient: n: {0}, torque: {2}",
+					avgEngineSpeed.Value(), CurrentState.EngineTorque.Value());
+			}
 
+			var fc = result.Value;
 			//TODO mk-2015-11-11: calculate aux start stop correction
 			var fcAux = fc;
 
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
index 517e1508d5..fc7427d407 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
@@ -66,7 +66,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 				var entry = lines[i].Split(',').Select(x => double.Parse(x, CultureInfo.InvariantCulture)).ToArray();
 
 				Assert.AreEqual(entry[2].SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Value(),
-					map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad(), true).Value(), Tolerance);
+					map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad(), true).Value.Value(), Tolerance);
 			}
 		}
 	}
-- 
GitLab