From a6b4a69eac31a422a8bf61a7aedb0b891831fbcc Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Wed, 24 Aug 2016 16:17:39 +0200
Subject: [PATCH] ComputeAcceleration: more intuitive formulas

---
 .../Models/SimulationComponent/Impl/Driver.cs | 61 ++++++++++---------
 1 file changed, 32 insertions(+), 29 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs
index c7cd5a46c9..e1cb4c6766 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs
@@ -527,7 +527,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					deltaPower = nextResp.GearboxPowerRequest;
 				}).
 				Case<ResponseUnderload>(r =>
-					deltaPower = DataBus.ClutchClosed(absTime) ? r.Delta : r.GearboxPowerRequest).
+						deltaPower = DataBus.ClutchClosed(absTime) ? r.Delta : r.GearboxPowerRequest).
 				Default(r => { throw new UnexpectedResponseException("cannot use response for searching braking power!", r); });
 
 			try {
@@ -588,39 +588,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 						return actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad);
 					},
 					evaluateFunction:
-						acc => {
-							// calculate new time interval only when vehiclespeed and acceleration are != 0
-							// else: use same timeinterval as before.
-							if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) {
-								var tmp = ComputeTimeInterval(acc, ds);
-								if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) {
-									throw new VectoSearchAbortedException("next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc,
-										DataBus.VehicleSpeed, tmp.SimulationInterval);
-								}
-								retVal.Acceleration = tmp.Acceleration;
-								retVal.SimulationInterval = tmp.SimulationInterval;
-								retVal.SimulationDistance = tmp.SimulationDistance;
+					acc => {
+						// calculate new time interval only when vehiclespeed and acceleration are != 0
+						// else: use same timeinterval as before.
+						if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) {
+							var tmp = ComputeTimeInterval(acc, ds);
+							if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) {
+								throw new VectoSearchAbortedException("next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc,
+									DataBus.VehicleSpeed, tmp.SimulationInterval);
 							}
-							IterationStatistics.Increment(this, "SearchOperatingPoint");
-							DriverAcceleration = acc;
-							var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true);
-							response.OperatingPoint = retVal;
-							return response;
-						},
+							retVal.Acceleration = tmp.Acceleration;
+							retVal.SimulationInterval = tmp.SimulationInterval;
+							retVal.SimulationDistance = tmp.SimulationDistance;
+						}
+						IterationStatistics.Increment(this, "SearchOperatingPoint");
+						DriverAcceleration = acc;
+						var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true);
+						response.OperatingPoint = retVal;
+						return response;
+					},
 					criterion: response => {
 						var r = (ResponseDryRun)response;
 						delta = actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad);
 						return delta.Value();
 					},
 					abortCriterion:
-						(response, cnt) => {
-							var r = (ResponseDryRun)response;
-							if (r == null) {
-								return false;
-							}
+					(response, cnt) => {
+						var r = (ResponseDryRun)response;
+						if (r == null) {
+							return false;
+						}
 
-							return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance);
-						});
+						return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance);
+					});
 			} catch (VectoSearchAbortedException) {
 				// search aborted, try to go ahead with the last acceleration
 			} catch (Exception) {
@@ -650,9 +650,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var currentSpeed = DataBus.VehicleSpeed;
 			var retVal = new OperatingPoint() { SimulationDistance = ds };
 
-			var requiredAverageSpeed = (targetVelocity + currentSpeed) / 2.0;
-			var requiredAcceleration =
-				(((targetVelocity - currentSpeed) * requiredAverageSpeed) / ds).Cast<MeterPerSquareSecond>();
+			// Δx = (v0+v1)/2 * Δt
+			// => Δt = 2*Δx/(v0+v1) 
+			var dt = 2 * ds / (currentSpeed + targetVelocity);
+
+			// a = Δv / Δt
+			var requiredAcceleration = (targetVelocity - currentSpeed) / dt;
 
 			if (!limitByDriverModel) {
 				return ComputeTimeInterval(requiredAcceleration, ds);
-- 
GitLab