From 98eef69e45b96c1f99fe8a62dcba25b1075bff93 Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Wed, 26 Aug 2015 09:14:19 +0200
Subject: [PATCH] further refinements for fullpowertrain test

---
 .../Models/Connector/Ports/Impl/Response.cs   |  7 +++
 .../Models/Simulation/Impl/DistanceRun.cs     |  2 +-
 .../Impl/DistanceBasedDrivingCycle.cs         |  7 +++
 .../Models/SimulationComponent/Impl/Driver.cs | 50 +++++++++++++------
 .../SimulationRuns/FullPowertrain.cs          | 12 +++--
 5 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/Models/Connector/Ports/Impl/Response.cs
index bbe2b2c24c..a16ebbb921 100644
--- a/VectoCore/Models/Connector/Ports/Impl/Response.cs
+++ b/VectoCore/Models/Connector/Ports/Impl/Response.cs
@@ -1,3 +1,4 @@
+using System.Linq;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
@@ -17,6 +18,12 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 		public Watt WheelsPowerRequest { get; set; }
 
 		public Watt VehiclePowerRequest { get; set; }
+
+		public override string ToString()
+		{
+			var t = GetType();
+			return string.Format("{0}{{{1}}}", t.Name, ", ".Join(t.GetProperties().Select(p => string.Format("{0}: {1}", p.Name, p.GetValue(this)))));
+		}
 	}
 
 	/// <summary>
diff --git a/VectoCore/Models/Simulation/Impl/DistanceRun.cs b/VectoCore/Models/Simulation/Impl/DistanceRun.cs
index 460271afe1..35a3e59e0b 100644
--- a/VectoCore/Models/Simulation/Impl/DistanceRun.cs
+++ b/VectoCore/Models/Simulation/Impl/DistanceRun.cs
@@ -13,7 +13,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 		protected override IResponse DoSimulationStep()
 		{
 			// estimate distance to be traveled within the next TargetTimeInterval
-			var ds = (Container.VehicleSpeed() * Constants.SimulationSettings.TargetTimeInterval).Cast<Meter>();
+			var ds = Container.VehicleSpeed() * Constants.SimulationSettings.TargetTimeInterval;
 
 			if (ds.IsEqual(0)) {
 				// vehicle stands still, drive a certain distance...
diff --git a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
index bef6f27ce4..68e21ca8e2 100644
--- a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
@@ -74,6 +74,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return retVal;
 		}
 
+		/// <summary>
+		/// Does the handle request.
+		/// </summary>
+		/// <param name="absTime">The abs time.</param>
+		/// <param name="ds">The ds.</param>
+		/// <returns></returns>
+		/// <exception cref="VectoSimulationException">Stopping Time only allowed when target speed is zero!</exception>
 		private IResponse DoHandleRequest(Second absTime, Meter ds)
 		{
 			if (CycleIntervalIterator.LastEntry && PreviousState.Distance.IsEqual(CycleIntervalIterator.RightSample.Distance)) {
diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs
index d5dac98e18..799d859813 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Driver.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Driver.cs
@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
+using System.Security.Cryptography.X509Certificates;
 using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.Exceptions;
 using TUGraz.VectoCore.Models.Connector.Ports;
@@ -32,6 +34,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			//OverSpeed,
 		}
 
+		[DebuggerDisplay("ActionDistance: {ActionDistance}, TriggerDistance: {TriggerDistance}, Action: {Action}")]
 		public class DrivingBehaviorEntry
 		{
 			public DrivingBehavior Action;
@@ -93,32 +96,38 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var currentDistance = DataBus.Distance();
 			var nextDrivingActions = GetNextDrivingActions(currentDistance);
 
+			Log.DebugFormat(", ".Join(nextDrivingActions.Select(x => string.Format("[{0}]: {1}", x.ActionDistance, x.Action))));
+
+
 			if (CurrentState.DrivingAction.Action == DrivingBehavior.Stopped && targetVelocity >= DataBus.VehicleSpeed()) {
 				CurrentState.DrivingAction.Action = DrivingBehavior.Drive;
 			}
 
 			if (nextDrivingActions.Count > 0) {
 				// if we exceeded the previous action (by accident), set the action anyway in case there is no 'next action'...
-				CurrentState.DrivingAction = nextDrivingActions.LastOrDefault(x => x.Key < currentDistance).Value ??
+				CurrentState.DrivingAction = nextDrivingActions.LastOrDefault(x => x.ActionDistance < currentDistance) ??
 											CurrentState.DrivingAction;
 
-				var nextActions = nextDrivingActions.Where(x => x.Key >= currentDistance).ToList();
+				var nextActions = nextDrivingActions.Where(x => x.ActionDistance >= currentDistance).ToList();
 				var nextDrivingAction = nextActions.GetEnumerator();
 				nextDrivingAction.MoveNext();
 				var hasNextEntry = true;
 
 				// if the current position matches the next action - set new action.
-				if (nextDrivingAction.Current.Key.IsEqual(currentDistance,
+				if (nextDrivingAction.Current.ActionDistance.IsEqual(currentDistance,
 					Constants.SimulationSettings.DriverActionDistanceTolerance.Value())) {
-					CurrentState.DrivingAction = nextDrivingAction.Current.Value;
+					CurrentState.DrivingAction = nextDrivingAction.Current;
 					hasNextEntry = nextDrivingAction.MoveNext(); // the current action has already been processed, look at next one...
 				}
 				// check if desired distance exceeds next action point
-				if (hasNextEntry && nextDrivingAction.Current.Key < currentDistance + ds) {
+				if (hasNextEntry && nextDrivingAction.Current.ActionDistance < currentDistance + ds) {
 					Log.DebugFormat(
 						"current Distance: {3} -- Simulation Distance {0} exceeds next DrivingAction at {1}, reducing interval to {2}", ds,
-						nextDrivingAction.Current.Key, nextDrivingAction.Current.Key - currentDistance, currentDistance);
-					return new ResponseDrivingCycleDistanceExceeded { MaxDistance = nextDrivingAction.Current.Key - currentDistance };
+						nextDrivingAction.Current.ActionDistance, nextDrivingAction.Current.ActionDistance - currentDistance,
+						currentDistance);
+					return new ResponseDrivingCycleDistanceExceeded {
+						MaxDistance = nextDrivingAction.Current.ActionDistance - currentDistance
+					};
 				}
 			} else {
 				if (targetVelocity > DataBus.VehicleSpeed()) {
@@ -267,7 +276,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return new ResponseDrivingCycleDistanceExceeded { SimulationInterval = CurrentState.dt };
 		}
 
-		protected SortedList<Meter, DrivingBehaviorEntry> GetNextDrivingActions(Meter minDistance)
+		protected IList<DrivingBehaviorEntry> GetNextDrivingActions(Meter minDistance)
 		{
 			var currentSpeed = DataBus.VehicleSpeed();
 
@@ -278,7 +287,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var lookaheadData = DataBus.LookAhead(1.2 * lookaheadDistance);
 
 			Log.DebugFormat("Lookahead distance: {0} @ current speed {1}", lookaheadDistance, currentSpeed);
-			var nextActions = new SortedList<Meter, DrivingBehaviorEntry>();
+			var nextActions = new List<DrivingBehaviorEntry>();
 			for (var i = 0; i < lookaheadData.Count; i++) {
 				var entry = lookaheadData[i];
 				if (entry.VehicleTargetSpeed < currentSpeed) {
@@ -286,35 +295,35 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					Log.DebugFormat("distance to decelerate from {0} to {1}: {2}", currentSpeed, entry.VehicleTargetSpeed,
 						breakingDistance);
 					Log.DebugFormat("adding 'Braking' starting at distance {0}", entry.Distance - breakingDistance);
-					nextActions[entry.Distance - breakingDistance] =
+					nextActions.Add(
 						new DrivingBehaviorEntry {
 							Action = DrivingBehavior.Breaking,
 							ActionDistance = entry.Distance - breakingDistance,
 							TriggerDistance = entry.Distance,
 							NextTargetSpeed = entry.VehicleTargetSpeed
-						};
+						});
 					var coastingDistance = Formulas.DecelerationDistance(currentSpeed, entry.VehicleTargetSpeed,
 						DeclarationData.Driver.LookAhead.Deceleration);
 					Log.DebugFormat("adding 'Coasting' starting at distance {0}", entry.Distance - coastingDistance);
-					nextActions[entry.Distance - coastingDistance] =
+					nextActions.Add(
 						new DrivingBehaviorEntry {
 							Action = DrivingBehavior.Coasting,
 							ActionDistance = entry.Distance - coastingDistance,
 							TriggerDistance = entry.Distance,
 							NextTargetSpeed = entry.VehicleTargetSpeed
-						};
+						});
 				}
 				if (entry.VehicleTargetSpeed > currentSpeed) {
-					nextActions[entry.Distance] = new DrivingBehaviorEntry {
+					nextActions.Add(new DrivingBehaviorEntry {
 						Action = DrivingBehavior.Accelerating,
 						NextTargetSpeed = entry.VehicleTargetSpeed,
 						TriggerDistance = entry.Distance,
 						ActionDistance = entry.Distance
-					};
+					});
 				}
 			}
 
-			return nextActions;
+			return nextActions.OrderBy(x => x.ActionDistance).ToList();
 		}
 
 		protected internal Meter ComputeDecelerationDistance(MeterPerSecond targetSpeed)
@@ -345,6 +354,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			Log.DebugFormat("Found operating point for coasting. dt: {0}, acceleration: {1}", CurrentState.dt,
 				CurrentState.Acceleration);
 
+			if (CurrentState.Acceleration < DeclarationData.Driver.LookAhead.Deceleration) {
+				Log.DebugFormat("Limiting coasting deceleration from {0} to {1}", CurrentState.Acceleration,
+					DeclarationData.Driver.LookAhead.Deceleration);
+				CurrentState.Acceleration = DeclarationData.Driver.LookAhead.Deceleration;
+				CurrentState.dt = ComputeTimeInterval(CurrentState.Acceleration, ref ds);
+				Log.DebugFormat("Changed dt due to limited coasting deceleration. dt: {0}", CurrentState.dt);
+			}
+
+
 			var retVal = Next.Request(absTime, CurrentState.dt, CurrentState.Acceleration, gradient);
 			CurrentState.Response = retVal;
 
diff --git a/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs
index 0a88778c76..f1757f2403 100644
--- a/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs
+++ b/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using Common.Logging;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.FileIO.Reader;
@@ -34,7 +35,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 		[TestMethod]
 		public void Test_FullPowertrain_SimpleGearbox()
 		{
-			var modalWriter = new ModalDataWriter("Coach_FullPowertrain.vmod");
+			var modalWriter = new ModalDataWriter("Coach_FullPowertrain_SimpleGearbox.vmod");
 			var sumWriter = new TestSumWriter();
 			var container = new VehicleContainer(modalWriter, sumWriter);
 
@@ -80,7 +81,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 
 						ds = container.VehicleSpeed().IsEqual(0)
 							? Constants.SimulationSettings.DriveOffDistance
-							: (Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed()).Cast<Meter>();
+							: Constants.SimulationSettings.TargetTimeInterval * container.VehicleSpeed();
 
 						if (cnt++ % 100 == 0) {
 							modalWriter.Finish();
@@ -122,7 +123,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 			cyclePort.Initialize();
 
 			container.Gear = 0;
-
+			var Log = LogManager.GetLogger<FullPowerTrain>();
 			var absTime = 0.SI<Second>();
 			var ds = Constants.SimulationSettings.DriveOffDistance;
 			var response = cyclePort.Request(absTime, ds);
@@ -133,11 +134,14 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns
 			container.Gear = 1;
 			var cnt = 0;
 			while (!(response is ResponseCycleFinished) && container.Distance().Value() < 17000) {
+				Log.InfoFormat("Test New Request absTime: {0}, ds: {1}", absTime, ds);
 				response = cyclePort.Request(absTime, ds);
+				Log.InfoFormat("Test Got Response: {0},", response);
+
 				response.Switch().
 					Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance).
 					Case<ResponseCycleFinished>(r => { }).
-					Case<ResponseGearShift>(r => { Debug.WriteLine("Gearshift"); }).
+					Case<ResponseGearShift>(r => { Log.Debug("Gearshift"); }).
 					Case<ResponseSuccess>(r => {
 						container.CommitSimulationStep(absTime, r.SimulationInterval);
 						absTime += r.SimulationInterval;
-- 
GitLab