From 8deb8d3070c6dc5962ba5f7e12083b5c94205379 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Tue, 30 Aug 2016 10:11:23 +0200
Subject: [PATCH] adding shift polygon for torque converter gear, adapt shift
 strategy to check for torque converter shift polygon, added rules for C->C
 shift

---
 .../EngineeringDataAdapter.cs                 |  6 +++++
 .../Models/Simulation/DataBus/IDataBus.cs     |  1 +
 .../Data/Gearbox/GearData.cs                  |  2 ++
 .../SimulationComponent/Impl/ATGearbox.cs     |  2 +-
 .../Impl/ATShiftStrategy.cs                   | 23 +++++++++++++++----
 .../Impl/TorqueConverter.cs                   |  3 ++-
 6 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
index b42a9df5b2..c28599bbbb 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
@@ -158,6 +158,9 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				}
 
 				var fullLoadCurve = IntersectFullLoadCurves(engineData.FullLoadCurve, gear.MaxTorque);
+				if (gearbox.Type.AutomaticTransmission() && gear.ShiftPolygon == null) {
+					throw new VectoException("Shiftpolygons are required for AT Gearboxes!");
+				}
 				var shiftPolygon = gear.ShiftPolygon != null
 					? ShiftPolygonReader.Create(gear.ShiftPolygon)
 					: DeclarationData.Gearbox.ComputeShiftPolygon((int)i, fullLoadCurve, gearbox.Gears, engineData, axlegearRatio,
@@ -174,6 +177,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 						// powersplit transmission: torque converter already contains ratio and losses
 						gearData.TorqueConverterRatio = 1;
 						gearData.TorqueConverterGearLossMap = TransmissionLossMapReader.Create(1, 1, string.Format("TCGear {0}", i + 1));
+						gearData.TorqueConverterShiftPolygon = ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon);
 					}
 				}
 				if (gearbox.Type == GearboxType.ATSerial) {
@@ -181,12 +185,14 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 						// torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode
 						gearData.TorqueConverterRatio = gearData.Ratio;
 						gearData.TorqueConverterGearLossMap = gearData.LossMap;
+						gearData.TorqueConverterShiftPolygon = ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon);
 					}
 					if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) {
 						// ratio between first and second gear is above threshold, torqueconverter is active in second gear as well
 						// -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear
 						gearData.TorqueConverterRatio = gearData.Ratio;
 						gearData.TorqueConverterGearLossMap = gearData.LossMap;
+						gearData.TorqueConverterShiftPolygon = ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon);
 						// NOTE: the lower gear in 'gears' dictionary has index i !!
 						gears[i].Ratio = double.NaN;
 						gears[i].LossMap = null;
diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs
index 6b68a67eec..d388216f1d 100644
--- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs
+++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs
@@ -30,6 +30,7 @@
 */
 
 using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Models.SimulationComponent;
 
 namespace TUGraz.VectoCore.Models.Simulation.DataBus
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/GearData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/GearData.cs
index 2edf6ed42e..74f32811f0 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/GearData.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/GearData.cs
@@ -68,5 +68,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 		public TransmissionLossMap TorqueConverterGearLossMap { get; internal set; }
 
 		public NewtonMeter MaxTorque { get; internal set; }
+
+		public ShiftPolygon TorqueConverterShiftPolygon { get; set; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
index acbcd04344..2827c77391 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
@@ -20,7 +20,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		protected internal readonly IShiftStrategy Strategy;
 
-		protected TorqueConverter TorqueConverter;
+		protected internal TorqueConverter TorqueConverter;
 
 		public Second LastShift { get; private set; }
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
index 72c73ccfee..da54ae418e 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
@@ -141,7 +141,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				if (nextEngineSpeed.IsEqual(0)) {
 					return false;
 				}
-				if (IsAboveUpShiftCurve(gear, enginePower / nextEngineSpeed, nextEngineSpeed) &&
+				if (IsAboveUpShiftCurve(gear, enginePower / nextEngineSpeed, nextEngineSpeed, _gearbox.TorqueConverterLocked) &&
 					enginePower.IsSmallerOrEqual(DataBus.EngineStationaryFullPower(nextEngineSpeed))) {
 					NextGear.SetState(absTime, false, nextGear, true);
 					return true;
@@ -149,7 +149,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			}
 			if (!_gearbox.TorqueConverterLocked && Data.Gears.ContainsKey(gear + 1) && Data.Gears[gear + 1].HasTorqueConverter) {
 				// C -> C upshift
-				// TODO!
+				var gearRatio = Data.Gears[gear + 1].Ratio / Data.Gears[gear].Ratio;
+				var minEnginseSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad()));
+				var nextGbxInSpeed = outAngularVelocity * Data.Gears[gear + 1].Ratio;
+				var nextGbxInTorque = outTorque / Data.Gears[gear + 1].Ratio;
+				var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGbxInTorque, nextGbxInSpeed);
+				if (tcOperatingPoint.InAngularVelocity.IsGreater(minEnginseSpeed) &&
+					DataBus.EngineStationaryFullPower(tcOperatingPoint.InAngularVelocity)
+						.IsGreater(0.7 * DataBus.EngineStationaryFullPower(inAngularVelocity))) {
+					return true;
+				}
 			}
 			return false;
 		}
@@ -233,10 +242,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// <param name="gear">The gear.</param>
 		/// <param name="inTorque">The in torque.</param>
 		/// <param name="inEngineSpeed">The in engine speed.</param>
+		/// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param>
 		/// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns>
-		protected virtual bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		protected virtual bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed,
+			bool torqueConverterLocked)
 		{
-			return gear < Data.Gears.Keys.Max() && Data.Gears[gear].ShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
+			if (torqueConverterLocked) {
+				return gear < Data.Gears.Keys.Max() && Data.Gears[gear].ShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
+			}
+			return gear < Data.Gears.Keys.Max() &&
+					Data.Gears[gear].TorqueConverterShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
 		}
 
 		protected class NextGearState
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
index 6ed745e984..cbeb7b2d1b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
@@ -110,7 +110,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return retVal;
 		}
 
-		protected TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		protected internal TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
+			PerSecond outAngularVelocity)
 		{
 			try {
 				var operatingPoint = ModelData.FindOperatingPoint(outTorque, outAngularVelocity);
-- 
GitLab