From cd422511cc4524c8564825cdf08b4b98e006473c Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Mon, 21 Sep 2015 18:09:21 +0200
Subject: [PATCH] introduce IDriverInfo to distinguish if the vehicle has
 stopped selecting startgear when stopped works.

---
 .../Models/Simulation/DataBus/IDataBus.cs     |  2 +-
 .../Models/Simulation/DataBus/IDriverInfo.cs  |  7 ++++
 .../Simulation/Impl/VehicleContainer.cs       | 11 +++++
 .../Models/SimulationComponent/Impl/Brakes.cs |  4 +-
 .../Models/SimulationComponent/Impl/Clutch.cs | 40 +++++++++----------
 .../Models/SimulationComponent/Impl/Driver.cs | 21 +++++++---
 .../SimulationComponent/Impl/Gearbox.cs       |  3 ++
 VectoCore/VectoCore.csproj                    |  1 +
 .../GearboxPowertrainTest.cs                  | 23 ++++++++++-
 9 files changed, 82 insertions(+), 30 deletions(-)
 create mode 100644 VectoCore/Models/Simulation/DataBus/IDriverInfo.cs

diff --git a/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/Models/Simulation/DataBus/IDataBus.cs
index 669d39c602..e5549e0537 100644
--- a/VectoCore/Models/Simulation/DataBus/IDataBus.cs
+++ b/VectoCore/Models/Simulation/DataBus/IDataBus.cs
@@ -6,5 +6,5 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus
 	/// Defines interfaces for all different cockpits to access shared data of the powertrain.
 	/// </summary>
 	public interface IDataBus : IGearboxInfo, IEngineInfo, IVehicleInfo, IMileageCounter, IClutchInfo, IBrakes,
-		IRoadLookAhead {}
+		IRoadLookAhead, IDriverInfo {}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs b/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs
new file mode 100644
index 0000000000..ae113cce4e
--- /dev/null
+++ b/VectoCore/Models/Simulation/DataBus/IDriverInfo.cs
@@ -0,0 +1,7 @@
+namespace TUGraz.VectoCore.Models.Simulation.DataBus
+{
+	public interface IDriverInfo
+	{
+		bool VehicleStopped { get; }
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
index f32ea44cd2..98cc3cc9e1 100644
--- a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
+++ b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
@@ -18,6 +18,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 		internal IGearboxInfo Gearbox;
 		internal IVehicleInfo Vehicle;
 		internal IBrakes Brakes;
+		internal IDriverInfo Driver;
 
 		internal IMileageCounter MilageCounter;
 
@@ -128,6 +129,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 				Engine = engine;
 			}
 
+			var driver = component as IDriverInfo;
+			if (driver != null) {
+				Driver = driver;
+			}
+
 			var gearbox = component as IGearboxInfo;
 			if (gearbox != null) {
 				Gearbox = gearbox;
@@ -230,5 +236,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			}
 			return Clutch.ClutchClosed(absTime);
 		}
+
+		public bool VehicleStopped
+		{
+			get { return Driver.VehicleStopped; }
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/SimulationComponent/Impl/Brakes.cs b/VectoCore/Models/SimulationComponent/Impl/Brakes.cs
index 18154abd78..d37861b0e3 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Brakes.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Brakes.cs
@@ -49,7 +49,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		{
 			BreakPower = 0.SI<Watt>();
 			BreakTorque = 0.SI<NewtonMeter>();
-			return NextComponent.Initialize(torque, angularVelocity);
+			return DataBus.VehicleStopped
+				? NextComponent.Initialize(0.SI<NewtonMeter>(), 0.SI<PerSecond>())
+				: NextComponent.Initialize(torque, angularVelocity);
 		}
 
 
diff --git a/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
index 80992b1928..434635f0d3 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
@@ -94,28 +94,28 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 
 			// @@@quam
-			//if (DataBus.Gear == 0) {
-			//	_clutchState = SimulationComponent.ClutchState.ClutchOpened;
-			//	engineSpeedIn = _idleSpeed;
-			//	torqueIn = 0.SI<NewtonMeter>();
-			//} else {
-			var engineSpeedNorm = (angularVelocity - _idleSpeed) /
-								(_ratedSpeed - _idleSpeed);
-			if ( /*DataBus.Gear == 1 && */ engineSpeedNorm < Constants.SimulationSettings.CluchNormSpeed) {
-				_clutchState = SimulationComponent.ClutchState.ClutchSlipping;
-
-				var engineSpeed0 = VectoMath.Max(_idleSpeed, angularVelocity);
-				var clutchSpeedNorm = Constants.SimulationSettings.CluchNormSpeed /
-									((_idleSpeed + Constants.SimulationSettings.CluchNormSpeed * (_ratedSpeed - _idleSpeed)) / _ratedSpeed);
-				engineSpeedIn =
-					((clutchSpeedNorm * engineSpeed0 / _ratedSpeed) * (_ratedSpeed - _idleSpeed) + _idleSpeed).Radian
-						.Cast<PerSecond>();
-
-				torqueIn = Formulas.PowerToTorque(Formulas.TorqueToPower(torque, angularVelocity) / ClutchEff, engineSpeedIn);
+			if (DataBus.VehicleStopped) {
+				_clutchState = SimulationComponent.ClutchState.ClutchOpened;
+				engineSpeedIn = _idleSpeed;
+				torqueIn = 0.SI<NewtonMeter>();
 			} else {
-				_clutchState = SimulationComponent.ClutchState.ClutchClosed;
+				var engineSpeedNorm = (angularVelocity - _idleSpeed) /
+									(_ratedSpeed - _idleSpeed);
+				if (engineSpeedNorm < Constants.SimulationSettings.CluchNormSpeed) {
+					_clutchState = SimulationComponent.ClutchState.ClutchSlipping;
+
+					var engineSpeed0 = VectoMath.Max(_idleSpeed, angularVelocity);
+					var clutchSpeedNorm = Constants.SimulationSettings.CluchNormSpeed /
+										((_idleSpeed + Constants.SimulationSettings.CluchNormSpeed * (_ratedSpeed - _idleSpeed)) / _ratedSpeed);
+					engineSpeedIn =
+						((clutchSpeedNorm * engineSpeed0 / _ratedSpeed) * (_ratedSpeed - _idleSpeed) + _idleSpeed).Radian
+							.Cast<PerSecond>();
+
+					torqueIn = Formulas.PowerToTorque(Formulas.TorqueToPower(torque, angularVelocity) / ClutchEff, engineSpeedIn);
+				} else {
+					_clutchState = SimulationComponent.ClutchState.ClutchClosed;
+				}
 			}
-			//}
 			Log.Debug("to Engine:   torque: {0}, angularVelocity: {1}, power {2}", torqueIn, engineSpeedIn,
 				Formulas.TorqueToPower(torqueIn, engineSpeedIn));
 		}
diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs
index 0134f5c76b..a7fa5e2086 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Driver.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Driver.cs
@@ -18,7 +18,8 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
-	public class Driver : VectoSimulationComponent, IDriver, IDrivingCycleOutPort, IDriverDemandInPort, IDriverActions
+	public class Driver : VectoSimulationComponent, IDriver, IDrivingCycleOutPort, IDriverDemandInPort, IDriverActions,
+		IDriverInfo
 	{
 		internal DriverState CurrentState = new DriverState();
 
@@ -57,21 +58,26 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					"LookAhead Coasting Deceleration is lower than Driver's min. Deceleration. Coasting may start too late. Lookahead dec.: {0}, Driver min. deceleration: {1}",
 					DriverData.LookAheadCoasting.Deceleration, DriverData.AccelerationCurve.MinDeceleration());
 			}
+			VehicleStopped = vehicleSpeed.IsEqual(0);
 			return NextComponent.Initialize(vehicleSpeed, roadGradient);
 		}
 
 		public IResponse Initialize(MeterPerSecond vehicleSpeed, MeterPerSquareSecond startAcceleration, Radian roadGradient)
 		{
-			return NextComponent.Initialize(vehicleSpeed, startAcceleration, roadGradient);
+			VehicleStopped = vehicleSpeed.IsEqual(0);
+			var retVal = NextComponent.Initialize(vehicleSpeed, startAcceleration, roadGradient);
+
+			return retVal;
 		}
 
 
 		public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
 		{
+			VehicleStopped = false;
 			Log.Debug("==== DRIVER Request ====");
 			Log.Debug(
-				"Request: absTime: {0},  ds: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5} gear: {6}",
-				absTime, ds, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.Gear);
+				"Request: absTime: {0},  ds: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5} gear: {6}, vehicle stopped: {7}",
+				absTime, ds, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.Gear, VehicleStopped);
 
 			var retVal = DriverStrategy.Request(absTime, ds, targetVelocity, gradient);
 			//DoHandleRequest(absTime, ds, targetVelocity, gradient);
@@ -86,10 +92,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public IResponse Request(Second absTime, Second dt, MeterPerSecond targetVelocity, Radian gradient)
 		{
+			VehicleStopped = true;
 			Log.Debug("==== DRIVER Request ====");
 			Log.Debug(
-				"Request: absTime: {0},  dt: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5} gear: {6}",
-				absTime, dt, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.Gear);
+				"Request: absTime: {0},  dt: {1}, targetVelocity: {2}, gradient: {3} | distance: {4}, velocity: {5} gear: {6}: vehicle stopped: {7}",
+				absTime, dt, targetVelocity, gradient, DataBus.Distance, DataBus.VehicleSpeed, DataBus.Gear, VehicleStopped);
 
 			var retVal = DriverStrategy.Request(absTime, dt, targetVelocity, gradient);
 
@@ -794,5 +801,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			LimitDecelerationDriver = 0x2,
 			LimitDecelerationLookahead = 0x4
 		}
+
+		public bool VehicleStopped { get; protected set; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 3290f4ea60..de3ad046ff 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -191,6 +191,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// </returns>
 		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed, bool dryRun)
 		{
+			if (DataBus.VehicleStopped) {
+				_shiftTime = absTime;
+			}
 			IResponse retVal;
 			if (ClutchClosed(absTime)) {
 				retVal = RequestGearEngaged(absTime, dt, outTorque, outEngineSpeed, dryRun);
diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj
index f5315735a7..2505b4398f 100644
--- a/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore.csproj
@@ -164,6 +164,7 @@
     <Compile Include="Models\SimulationComponent\IShiftStrategy.cs" />
     <Compile Include="Models\SimulationComponent\Impl\ShiftStrategy.cs" />
     <Compile Include="Models\Simulation\DataBus\IClutchInfo.cs" />
+    <Compile Include="Models\Simulation\DataBus\IDriverInfo.cs" />
     <Compile Include="Models\Simulation\Data\AuxiliaryDemandType.cs" />
     <Compile Include="Models\SimulationComponent\Data\AuxiliaryType.cs" />
     <Compile Include="Models\SimulationComponent\Data\FullLoadCurve.cs" />
diff --git a/VectoCoreTest/Models/SimulationComponent/GearboxPowertrainTest.cs b/VectoCoreTest/Models/SimulationComponent/GearboxPowertrainTest.cs
index ba4021f0dd..d85995518c 100644
--- a/VectoCoreTest/Models/SimulationComponent/GearboxPowertrainTest.cs
+++ b/VectoCoreTest/Models/SimulationComponent/GearboxPowertrainTest.cs
@@ -52,12 +52,15 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 			var ds = 1.SI<Meter>();
 
 			retVal = container.Cycle.Request(absTime, ds);
+			container.CommitSimulationStep(absTime, retVal.SimulationInterval);
 			absTime += retVal.SimulationInterval;
 
 			AssertHelper.AreRelativeEqual(560.RPMtoRad(), container.EngineSpeed);
+
 			container.Cycle.Request(absTime, ds);
+			container.CommitSimulationStep(absTime, retVal.SimulationInterval);
 
-			AssertHelper.AreRelativeEqual(593.RPMtoRad(), container.EngineSpeed);
+			AssertHelper.AreRelativeEqual(593.202.RPMtoRad(), container.EngineSpeed);
 		}
 
 		[TestMethod]
@@ -65,13 +68,29 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 		{
 			var cycle = CreateCycleData(new[] {
 				// <s>,<v>,<grad>,<stop>
-				"  0,   0, 2.95016969027809,     0",
+				"  0,   0, 2.95016969027809,     1",
 				"1000, 60, 2.95016969027809,     0",
 			});
 			var container = CreatePowerTrain(cycle, "Gearbox_Initialize.vmod", 7500.0.SI<Kilogram>(), 19300.SI<Kilogram>());
 			var retVal = container.Cycle.Initialize();
 			Assert.AreEqual(4u, container.Gear);
 			Assert.IsInstanceOfType(retVal, typeof(ResponseSuccess));
+
+			AssertHelper.AreRelativeEqual(560.RPMtoRad(), container.EngineSpeed);
+
+			var absTime = 0.SI<Second>();
+			var ds = 1.SI<Meter>();
+
+			retVal = container.Cycle.Request(absTime, ds);
+			container.CommitSimulationStep(absTime, retVal.SimulationInterval);
+			absTime += retVal.SimulationInterval;
+
+			AssertHelper.AreRelativeEqual(560.RPMtoRad(), container.EngineSpeed);
+
+			container.Cycle.Request(absTime, ds);
+			container.CommitSimulationStep(absTime, retVal.SimulationInterval);
+
+			AssertHelper.AreRelativeEqual(593.202.RPMtoRad(), container.EngineSpeed);
 		}
 
 
-- 
GitLab