From 176511c7f4beb06f93637e04693067347ca8b550 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Fri, 13 May 2016 13:50:05 +0200
Subject: [PATCH] use WB2016 method to calculate starting point of coasting

---
 .../Impl/DefaultDriverStrategy.cs             | 91 +++++++++++++++----
 1 file changed, 72 insertions(+), 19 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
index 5671ed4ae6..b67fecf445 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
@@ -88,7 +88,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			if (CurrentDrivingMode == DrivingMode.DrivingModeDrive) {
 				var currentDistance = Driver.DataBus.Distance;
 
-				var coasting = CheckLookAheadCoasting(ds);
+				//var coasting = LookAheadCoasting(ds);
 
 				UpdateDrivingAction(currentDistance, ds);
 				if (NextDrivingAction != null) {
@@ -126,7 +126,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var dict = new Dictionary<string, object>();
 
 			// (1) & (2) : x_decelerationpoint - d_prev <= x_veh < x_decelerationpoint
-			var v_veh = Driver.DataBus.VehicleSpeed;
+			var v_veh = Driver.DataBus.CycleData.LeftSample.VehicleTargetSpeed; //Driver.DataBus.VehicleSpeed;
 			var d_prev = 10 * Driver.DataBus.VehicleSpeed.ConvertTo().Kilo.Meter.Per.Hour.Value();
 			var lookaheadData = Driver.DataBus.LookAhead(d_prev.SI<Meter>());
 			var nextActions = new SortedDictionary<Meter, DrivingCycleData.DrivingCycleEntry>();
@@ -159,13 +159,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 				// 3. CDP > DF_coasting
 				if (coastingPossible) {
-					var m = Driver.DataBus.VehicleMass;
+					var m = Driver.DataBus.TotalMass;
 					var g = Physics.GravityAccelleration;
 					var h_target = dec.Altitude;
 					dict["h_target"] = h_target.Value();
 
-					// todo mk-2016-05-11 left or right sample of cycle data?
-					var h_vehicle = Driver.DataBus.CycleData.LeftSample.Altitude;
+					var h_vehicle = Driver.DataBus.Altitude;
 					dict["h_vehicle"] = h_vehicle.Value();
 
 					var E_kin_veh = m * v_veh * v_veh / 2;
@@ -183,12 +182,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					var F_dec_average = delta_E / x_delta;
 					dict["F_dec_average"] = F_dec_average.Value();
 
-					var avgVelocity = (v_veh + v_target) / 2;
-					var acc = (v_target - v_veh) * (avgVelocity / ds);
-					var F_air = Driver.DataBus.AirDragResistance(v_veh, acc, ds / v_veh);
+					//var avgVelocity = (v_veh + v_target) / 2;
+					//var acc = (v_target - v_veh) * (avgVelocity / x_delta);
+					var F_air = Driver.DataBus.AirDragResistance(v_veh, v_target);
 					dict["F_air"] = F_air.Value();
 
-					var F_roll = Driver.DataBus.RollingResistance(Driver.DataBus.CycleData.LeftSample.RoadGradient);
+					var F_roll = Driver.DataBus.RollingResistance(((h_target - h_vehicle) / x_delta).Value().SI<Radian>());
 					dict["F_roll"] = F_roll.Value();
 
 					var F_enginedrag = Driver.DataBus.EngineDragPower(Driver.DataBus.EngineSpeed) / v_veh;
@@ -201,10 +200,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					var F_loss_ra = 0.SI<Newton>();
 					dict["F_loss_ra"] = F_loss_ra.Value();
 
-					var F_coasting = F_air + F_roll + F_enginedrag + F_loss_gb + F_loss_ra;
+					var F_coasting = F_enginedrag - F_air - F_roll - F_loss_gb - F_loss_ra;
 					dict["F_coasting"] = F_coasting.Value();
 
-					var CDP = F_dec_average / F_coasting;
+					var CDP = F_dec_average / -F_coasting;
 					dict["CDP"] = CDP.Value();
 
 					var DF_coasting = LACDecisionFactor.Lookup(v_target, v_veh - v_target);
@@ -236,9 +235,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				if (Driver.DataBus.VehicleSpeed > NextDrivingAction.NextTargetSpeed) {
 					switch (NextDrivingAction.Action) {
 						case DrivingBehavior.Coasting:
-							var coastingDistance = Formulas.DecelerationDistance(Driver.DataBus.VehicleSpeed,
-								NextDrivingAction.NextTargetSpeed,
-								Driver.DriverData.LookAheadCoasting.Deceleration);
+
+							//var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.NextTargetSpeed);
+							var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.CycleEntry);
 							NextDrivingAction.ActionDistance = NextDrivingAction.TriggerDistance - coastingDistance;
 							break;
 						case DrivingBehavior.Braking:
@@ -287,8 +286,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					? entry.VehicleTargetSpeed + Driver.DriverData.OverSpeedEcoRoll.OverSpeed
 					: entry.VehicleTargetSpeed;
 				if (nextTargetSpeed < currentSpeed) {
+					var coastingDistance = ComputeCoastingDistance(currentSpeed, entry);
 					if (!Driver.DriverData.LookAheadCoasting.Enabled ||
-						currentSpeed < Driver.DriverData.LookAheadCoasting.MinSpeed) {
+						currentSpeed < Driver.DriverData.LookAheadCoasting.MinSpeed ||
+						coastingDistance < 0) {
 						var brakingDistance = Driver.ComputeDecelerationDistance(nextTargetSpeed) + BrakingSafetyMargin;
 						Log.Debug(
 							"adding 'Braking' starting at distance {0}. brakingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}",
@@ -297,11 +298,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 							Action = DrivingBehavior.Braking,
 							ActionDistance = entry.Distance - brakingDistance,
 							TriggerDistance = entry.Distance,
-							NextTargetSpeed = nextTargetSpeed
+							NextTargetSpeed = nextTargetSpeed,
+							CycleEntry = entry,
 						});
 					} else {
-						var coastingDistance = Formulas.DecelerationDistance(currentSpeed, nextTargetSpeed,
-							Driver.DriverData.LookAheadCoasting.Deceleration);
+						//var coastingDistance = ComputeCoastingDistance(currentSpeed, nextTargetSpeed);
+
 						Log.Debug(
 							"adding 'Coasting' starting at distance {0}. coastingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}",
 							entry.Distance - coastingDistance, coastingDistance, entry.Distance, nextTargetSpeed);
@@ -310,7 +312,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 								Action = DrivingBehavior.Coasting,
 								ActionDistance = entry.Distance - coastingDistance,
 								TriggerDistance = entry.Distance,
-								NextTargetSpeed = nextTargetSpeed
+								NextTargetSpeed = nextTargetSpeed,
+								CycleEntry = entry,
 							});
 					}
 				}
@@ -319,6 +322,55 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return nextActions.Count == 0 ? null : nextActions.OrderBy(x => x.ActionDistance).First();
 		}
 
+		protected virtual Meter ComputeCoastingDistance(MeterPerSecond currentSpeed, MeterPerSecond nextTargetSpeed)
+		{
+			return Formulas.DecelerationDistance(currentSpeed, nextTargetSpeed,
+				Driver.DriverData.LookAheadCoasting.Deceleration);
+		}
+
+		protected virtual Meter ComputeCoastingDistance(MeterPerSecond v_veh, DrivingCycleData.DrivingCycleEntry actionEntry)
+		{
+			var v_target = OverspeedAllowed(actionEntry.RoadGradient, actionEntry.VehicleTargetSpeed)
+				? actionEntry.VehicleTargetSpeed + Driver.DriverData.OverSpeedEcoRoll.OverSpeed
+				: actionEntry.VehicleTargetSpeed;
+
+			var m = Driver.DataBus.TotalMass;
+			var g = Physics.GravityAccelleration;
+			var h_target = actionEntry.Altitude; //dec.Altitude;
+
+			var h_vehicle = Driver.DataBus.Altitude;
+
+			var E_kin_veh = m * v_veh * v_veh / 2;
+			var E_kin_target = m * v_target * v_target / 2;
+			var E_pot_target = m * g * h_target;
+			var E_pot_veh = m * g * h_vehicle;
+
+			var delta_E = (E_kin_veh + E_pot_veh) - (E_kin_target + E_pot_target);
+
+			//var F_dec_average = delta_E / x_delta;
+
+			var F_air = Driver.DataBus.AirDragResistance(v_veh, v_target);
+			var F_roll =
+				Driver.DataBus.RollingResistance(
+					((h_target - h_vehicle) / (actionEntry.Distance - Driver.DataBus.Distance)).Value().SI<Radian>());
+			var F_enginedrag = Driver.DataBus.EngineDragPower(Driver.DataBus.EngineSpeed) / v_veh;
+			var F_loss_gb = Driver.DataBus.GearboxLoss(Driver.DataBus.EngineSpeed, Driver.DataBus.EngineTorque) / v_veh;
+
+			// todo mk-2016-05-11 calculate ra loss
+			var F_loss_ra = 0.SI<Newton>();
+
+			var F_coasting = F_air + F_roll + F_loss_gb + F_loss_ra - F_enginedrag;
+
+			//var CDP = F_dec_average / -F_coasting;
+
+			var DF_coasting = LACDecisionFactor.Lookup(v_target, v_veh - v_target);
+
+			var delta_x = (delta_E / (DF_coasting * F_coasting)).Cast<Meter>();
+
+			return delta_x;
+		}
+
+
 		public bool OverspeedAllowed(Radian gradient, MeterPerSecond velocity)
 		{
 			return Driver.DriverData.OverSpeedEcoRoll.Mode == DriverMode.Overspeed &&
@@ -738,6 +790,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public MeterPerSecond NextTargetSpeed;
 		public Meter TriggerDistance;
 		public Meter ActionDistance;
+		public DrivingCycleData.DrivingCycleEntry CycleEntry;
 
 		public bool HasEqualTrigger(DrivingBehaviorEntry other)
 		{
-- 
GitLab