From 5300e8cb389d60fd7810a477a7b57ae1ba06d39c Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Thu, 22 Dec 2016 14:18:56 +0100
Subject: [PATCH] refactoring: pwheelcycle: use drivingcycleenumerator

---
 .../SimulationComponent/Impl/PWheelCycle.cs   | 53 +++++++++++++++----
 .../Impl/PowertrainDrivingCycle.cs            | 50 +++++++++--------
 2 files changed, 68 insertions(+), 35 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs
index 1e81e876ab..6805445e14 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs
@@ -44,21 +44,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	/// <summary>
 	/// Driving Cycle for the PWheel driving cycle.
 	/// </summary>
-	public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo
+	public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo, IVehicleInfo
 	{
+		private VehicleData _vehicleData;
+
 		/// <summary>
 		/// Initializes a new instance of the <see cref="PWheelCycle"/> class.
 		/// </summary>
 		/// <param name="container">The container.</param>
 		/// <param name="cycle">The cycle.</param>
 		/// <param name="axleRatio">The axle ratio.</param>
+		/// <param name="vehicleData"></param>
 		/// <param name="gearRatios"></param>
-		public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio,
+		public PWheelCycle(IVehicleContainer container, IDrivingCycleData cycle, double axleRatio, VehicleData vehicleData,
 			IDictionary<uint, double> gearRatios) : base(container, cycle)
 		{
 			// just to ensure that null-gear has ratio 1
 			gearRatios[0] = 1;
-
+			_vehicleData = vehicleData;
 			foreach (var entry in Data.Entries) {
 				entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]);
 				entry.Torque = entry.PWheel / entry.WheelAngularVelocity;
@@ -76,36 +79,68 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public override IResponse Request(Second absTime, Second dt)
 		{
-			if (RightSample.Current == null) {
+			if (CycleIterator.LastEntry && CycleIterator.RightSample.Time == absTime) {
 				return new ResponseCycleFinished { Source = this };
 			}
 
 			// interval exceeded
-			if ((absTime + dt).IsGreater(RightSample.Current.Time)) {
+			if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
 				return new ResponseFailTimeInterval {
 					AbsTime = absTime,
 					Source = this,
-					DeltaT = RightSample.Current.Time - absTime
+					DeltaT = CycleIterator.RightSample.Time - absTime
 				};
 			}
 
-			return DoHandleRequest(absTime, dt, LeftSample.Current.WheelAngularVelocity);
+			return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.WheelAngularVelocity);
 		}
 
 		protected override void DoWriteModalResults(IModalDataContainer container)
 		{
-			container[ModalResultField.P_wheel_in] = LeftSample.Current.PWheel;
+			container[ModalResultField.P_wheel_in] = CycleIterator.LeftSample.PWheel;
 			base.DoWriteModalResults(container);
 		}
 
 		#region IDriverInfo
 
+		public MeterPerSecond VehicleSpeed { get; private set; }
+
 		/// <summary>
 		/// True if the angularVelocity at the wheels is 0.
 		/// </summary>
 		public bool VehicleStopped
 		{
-			get { return false; }
+			get { return CycleIterator.LeftSample.WheelAngularVelocity.IsEqual(0); }
+		}
+
+		public Kilogram VehicleMass
+		{
+			get { return _vehicleData.TotalCurbWeight; }
+		}
+
+		public Kilogram VehicleLoading
+		{
+			get { return _vehicleData.Loading; }
+		}
+
+		public Kilogram TotalMass
+		{
+			get { return _vehicleData.TotalVehicleWeight; }
+		}
+
+		public Newton AirDragResistance(MeterPerSecond previousVelocity, MeterPerSecond nextVelocity)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public Newton RollingResistance(Radian gradient)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public Newton SlopeResistance(Radian gradient)
+		{
+			throw new System.NotImplementedException();
 		}
 
 		/// <summary>
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs
index 7b0cc4c5a2..35f5b42270 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs
@@ -52,8 +52,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		IDrivingCycleInfo, ISimulationOutPort, ITnInProvider, ITnInPort
 	{
 		protected readonly IDrivingCycleData Data;
-		protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; }
-		protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; }
+		protected internal readonly DrivingCycleEnumerator CycleIterator;
 
 		protected Second AbsTime { get; set; }
 
@@ -65,12 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public PowertrainDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container)
 		{
 			Data = cycle;
-			LeftSample = Data.Entries.GetEnumerator();
-			LeftSample.MoveNext();
-
-			RightSample = Data.Entries.GetEnumerator();
-			RightSample.MoveNext();
-			RightSample.MoveNext();
+			CycleIterator = new DrivingCycleEnumerator(Data);
 
 			AbsTime = 0.SI<Second>();
 		}
@@ -94,20 +88,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		public virtual IResponse Request(Second absTime, Second dt)
 		{
 			// cycle finished (no more entries in cycle)
-			if (LeftSample.Current == null) {
+			if (CycleIterator.LastEntry) {
 				return new ResponseCycleFinished { Source = this };
 			}
 
 			// interval exceeded
-			if (RightSample.Current != null && (absTime + dt).IsGreater(RightSample.Current.Time)) {
+			if (CycleIterator.RightSample != null && (absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
 				return new ResponseFailTimeInterval {
 					AbsTime = absTime,
 					Source = this,
-					DeltaT = RightSample.Current.Time - absTime
+					DeltaT = CycleIterator.RightSample.Time - absTime
 				};
 			}
 
-			return DoHandleRequest(absTime, dt, LeftSample.Current.AngularVelocity);
+			return DoHandleRequest(absTime, dt, CycleIterator.LeftSample.AngularVelocity);
 		}
 
 		protected IResponse DoHandleRequest(Second absTime, Second dt, PerSecond angularVelocity)
@@ -117,16 +111,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			IResponse response;
 			var responseCount = 0;
 			do {
-				response = NextComponent.Request(absTime, dt, LeftSample.Current.Torque, angularVelocity);
+				response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity);
 				CurrentState.InAngularVelocity = angularVelocity;
-				CurrentState.InTorque = LeftSample.Current.Torque;
+				CurrentState.InTorque = CycleIterator.LeftSample.Torque;
 				debug.Add(response);
 				response.Switch()
 					.Case<ResponseGearShift>(
-						() => response = NextComponent.Request(absTime, dt, LeftSample.Current.Torque, angularVelocity))
+						() => response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity))
 					.Case<ResponseUnderload>(r => {
 						var torqueInterval = -r.Delta / (angularVelocity.IsEqual(0) ? 10.RPMtoRad() : angularVelocity);
-						var torque = SearchAlgorithm.Search(LeftSample.Current.Torque, r.Delta, torqueInterval,
+						var torque = SearchAlgorithm.Search(CycleIterator.LeftSample.Torque, r.Delta, torqueInterval,
 							getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
 							evaluateFunction: t => NextComponent.Request(absTime, dt, t, angularVelocity, true),
 							criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Value());
@@ -136,9 +130,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					.Case<ResponseOverload>(r => {
 						angularVelocity = SearchAlgorithm.Search(angularVelocity, r.Delta, 50.RPMtoRad(),
 							getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
-							evaluateFunction: n => NextComponent.Request(absTime, dt, LeftSample.Current.Torque, n, true),
+							evaluateFunction: n => NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, n, true),
 							criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value());
-						response = NextComponent.Request(absTime, dt, LeftSample.Current.Torque, angularVelocity);
+						response = NextComponent.Request(absTime, dt, CycleIterator.LeftSample.Torque, angularVelocity);
 						CurrentState.InAngularVelocity = angularVelocity;
 					})
 					.Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; })
@@ -171,10 +165,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		protected override void DoCommitSimulationStep()
 		{
-			if ((RightSample.Current == null) || AbsTime.IsGreaterOrEqual(RightSample.Current.Time)) {
-				RightSample.MoveNext();
-				LeftSample.MoveNext();
-			}
+			CycleIterator.MoveNext();
 		}
 
 		#endregion
@@ -184,10 +175,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			get
 			{
 				return new CycleData {
-					AbsTime = LeftSample.Current.Time,
+					AbsTime = CycleIterator.LeftSample.Time,
 					AbsDistance = null,
-					LeftSample = LeftSample.Current,
-					RightSample = RightSample.Current,
+					LeftSample = CycleIterator.LeftSample,
+					RightSample = CycleIterator.RightSample,
 				};
 			}
 		}
@@ -216,7 +207,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
 		{
-			throw new NotImplementedException();
+			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
+
+			var iterator = CycleIterator.Clone();
+			do {
+				retVal.Add(iterator.RightSample);
+			} while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time);
+
+			return retVal;
 		}
 
 		public void FinishSimulation()
-- 
GitLab