From eb27a5a070a735b329381a69e93770e2dc1e8615 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Mon, 26 Jun 2017 15:52:31 +0200
Subject: [PATCH] refactor default strategy: extract method

---
 VECTO/GUI/GearboxForm.vb                      |   3 +-
 .../Impl/DefaultDriverStrategy.cs             | 136 ++++++++++--------
 2 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/VECTO/GUI/GearboxForm.vb b/VECTO/GUI/GearboxForm.vb
index e3f15ef78e..f700e0d254 100644
--- a/VECTO/GUI/GearboxForm.vb
+++ b/VECTO/GUI/GearboxForm.vb
@@ -928,9 +928,10 @@ Public Class GearboxForm
 			If _
 				gbx(i).SubItems(GearboxTbl.Ratio).Text <> "" AndAlso Double.TryParse(gbx(i).SubItems(GearboxTbl.Ratio).Text, value) _
 				Then
+				Dim maxSpeed As PerSecond = If(String.IsNullOrWhiteSpace(gbx(i).SubItems(GearboxTbl.MaxSpeed).Text), Nothing, gbx(i).SubItems(GearboxTbl.MaxSpeed).Text.ToDouble().RPMtoRad())
 				retVal.Add(
 					New TransmissionInputData() _
-							With {.Ratio = value})
+							With {.Ratio = value, .MaxInputSpeed = maxSpeed})
 
 			End If
 		Next
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
index b9791e6430..b5e072d232 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
@@ -538,66 +538,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		{
 			IResponse response = null;
 			if (DataBus.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed) {
-				if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
-					if (DataBus.VehicleSpeed.IsGreater(0)) {
-						response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-					} else {
-						if (RetryDistanceExceeded) {
-							response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
-						} else {
-							RetryDistanceExceeded = true;
-							return new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
-						}
-					}
-				} else {
-					response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-				}
-				response.Switch().
-					Case<ResponseGearShift>(() => {
-						response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
-						response.Switch().
-							Case<ResponseUnderload>(r => {
-								// under-load may happen if driver limits acceleration when rolling downhill
-								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-									gradient, r);
-							}).
-							Case<ResponseSpeedLimitExceeded>(() => {
-								response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
-									gradient);
-							});
-					}).
-					Case<ResponseSpeedLimitExceeded>(() => {
-						response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
-							gradient);
-					}).
-					Case<ResponseUnderload>(r => {
-						response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-							gradient, r);
-						response.Switch().
-							Case<ResponseGearShift>(() => {
-								DataBus.BrakePower = 0.SI<Watt>();
-								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-									gradient, r);
-							}).
-							Case<ResponseOverload>(() => {
-								DataBus.BrakePower = 0.SI<Watt>();
-								if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
-									if (DataBus.VehicleSpeed.IsGreater(0)) {
-										response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-									} else {
-										if (RetryDistanceExceeded) {
-											response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
-										} else {
-											RetryDistanceExceeded = true;
-											response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
-										}
-									}
-								} else {
-									response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-								}
-							});
-					});
-				return response;
+				return HandleTargetspeedReached(absTime, ds, targetVelocity, gradient);
 			}
 			var currentDistance = DataBus.Distance;
 
@@ -665,7 +606,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
 							}
 						}).
-						Case<ResponseGearShift>(r => { response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); });
+						Case<ResponseGearShift>(r => { response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); }).
+						Case<ResponseEngineSpeedTooHigh>(r => {
+							response = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r);
+						});
 					// handle the SpeedLimitExceeded Response separately in case it occurs in one of the requests in the second try
 					response.Switch().
 						Case<ResponseSpeedLimitExceeded>(() => {
@@ -732,6 +676,76 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return response;
 		}
 
+		private IResponse HandleTargetspeedReached(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
+		{
+			IResponse response;
+			if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
+				if (DataBus.VehicleSpeed.IsGreater(0)) {
+					response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+				} else {
+					if (RetryDistanceExceeded) {
+						response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
+					} else {
+						RetryDistanceExceeded = true;
+						return new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
+					}
+				}
+			} else {
+				response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+			}
+			var i = 0;
+			do {
+				response.Switch().
+					Case<ResponseGearShift>(() => {
+						response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
+						response.Switch().
+							Case<ResponseUnderload>(r => {
+								// under-load may happen if driver limits acceleration when rolling downhill
+								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+									gradient, r);
+							}).
+							Case<ResponseSpeedLimitExceeded>(() => {
+								response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
+									gradient);
+							});
+					}).
+					Case<ResponseSpeedLimitExceeded>(() => {
+						response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
+							gradient);
+					}).
+					Case<ResponseUnderload>(r => {
+						//response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+						//	gradient, r);
+						response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval,
+							gradient, r);
+						response.Switch().
+							Case<ResponseGearShift>(() => {
+								DataBus.BrakePower = 0.SI<Watt>();
+								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+									gradient, r);
+							}).
+							Case<ResponseOverload>(() => {
+								DataBus.BrakePower = 0.SI<Watt>();
+								if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
+									if (DataBus.VehicleSpeed.IsGreater(0)) {
+										response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+									} else {
+										if (RetryDistanceExceeded) {
+											response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
+										} else {
+											RetryDistanceExceeded = true;
+											response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
+										}
+									}
+								} else {
+									response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+								}
+							});
+					});
+			} while (!(response is ResponseSuccess) && i++ < 3); 
+			return response;
+		}
+
 		protected override IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds,
 			MeterPerSecond targetVelocity, Radian gradient, IResponse response, out Meter newds)
 		{
-- 
GitLab