From d0c1813ce455159406627c08675f476bdec9740c Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Tue, 18 Oct 2016 14:32:28 +0200
Subject: [PATCH] bugfix: measured speed when halting and gear=0 but vehicle
 still has a remaining velocity.

---
 .../SimulationComponent/Impl/CycleGearbox.cs  | 32 +++++++++----------
 .../Impl/MeasuredSpeedDrivingCycle.cs         |  4 +++
 .../EngineOnlyCycle/EngineOnlyCycleTest.cs    |  2 +-
 .../Models/Simulation/AuxTests.cs             |  2 +-
 .../Models/Simulation/PwheelModeTests.cs      |  4 +--
 .../Models/Simulation/SimulationTests.cs      |  6 ++--
 .../VectoCoreTest/Utils/ResultFileHelper.cs   | 30 ++++++++++++-----
 7 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
index ebab9c2761..742868721b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
@@ -281,7 +281,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		/// <summary>
-		/// Handles Requests when no gear is engaged
+		/// Handles Requests when no gear is disengaged
 		/// </summary>
 		/// <param name="absTime"></param>
 		/// <param name="dt"></param>
@@ -303,8 +303,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				};
 			}
 
-			if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(),
-				Constants.SimulationSettings.LineSearchTolerance)) {
+			if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) &&
+				!outAngularVelocity.IsEqual(0)) {
 				return new ResponseOverload {
 					Source = this,
 					Delta = outTorque * avgOutAngularVelocity,
@@ -312,8 +312,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				};
 			}
 
-			if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(),
-				Constants.SimulationSettings.LineSearchTolerance)) {
+			if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
 				return new ResponseUnderload {
 					Source = this,
 					Delta = outTorque * avgOutAngularVelocity,
@@ -321,13 +320,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				};
 			}
 
-			CurrentState.SetState(0.SI<NewtonMeter>(), 0.RPMtoRad(), outTorque, outAngularVelocity);
+			CurrentState.SetState(0.SI<NewtonMeter>(), 0.SI<PerSecond>(), outTorque, outAngularVelocity);
 			CurrentState.Gear = Gear;
 
 			var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
 			disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
 			return disengagedResponse;
-			//todo mk-2016-08-17: minus inTorqueLoss?? Why not plus?
 		}
 
 		private TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
@@ -354,12 +352,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			}
 
 			var filtered = operatingPointList.Where(x =>
-				(x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity),
-					Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) &&
-				(x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity),
-					Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())
-				).ToArray();
-			if (filtered.Count() == 1) {
+					(x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity),
+						Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) &&
+					(x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity),
+						Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())
+			).ToArray();
+			if (filtered.Length == 1) {
 				return filtered.First();
 			}
 			return operatingPointList[0];
@@ -448,12 +446,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				container[ModalResultField.TC_angularSpeedOut] = CurrentState.TorqueConverterOperatingPoint.OutAngularVelocity;
 
 				var avgOutVelocity = ((PreviousState.TorqueConverterOperatingPoint != null
-					? PreviousState.TorqueConverterOperatingPoint.OutAngularVelocity
-					: PreviousState.InAngularVelocity) +
+										? PreviousState.TorqueConverterOperatingPoint.OutAngularVelocity
+										: PreviousState.InAngularVelocity) +
 									CurrentState.TorqueConverterOperatingPoint.OutAngularVelocity) / 2.0;
 				var avgInVelocity = ((PreviousState.TorqueConverterOperatingPoint != null
-					? PreviousState.TorqueConverterOperatingPoint.InAngularVelocity
-					: PreviousState.InAngularVelocity) +
+										? PreviousState.TorqueConverterOperatingPoint.InAngularVelocity
+										: PreviousState.InAngularVelocity) +
 									CurrentState.TorqueConverterOperatingPoint.InAngularVelocity) / 2.0;
 				container[ModalResultField.P_TC_out] = CurrentState.OutTorque * avgOutVelocity;
 				container[ModalResultField.P_TC_loss] = CurrentState.InTorque * avgInVelocity -
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs
index a900c1b2d2..a716c914fa 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs
@@ -196,6 +196,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			debug.Add(response);
 
 			CurrentState.SimulationDistance = acceleration / 2 * dt * dt + DataBus.VehicleSpeed * dt;
+			if (CurrentState.SimulationDistance.IsSmaller(0))
+				throw new VectoSimulationException(
+					"MeasuredSpeed: Simulation Distance must not be negative. Driving Backward is not allowed.");
+
 			CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance;
 			CurrentState.Acceleration = acceleration;
 
diff --git a/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs b/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs
index c0302b2db8..16b80d77c4 100644
--- a/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs
@@ -104,7 +104,7 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle
 			}
 			modData.Finish(VectoRun.Status.Success);
 
-			ResultFileHelper.TestModFile(modalResultFile, modFile + Constants.FileExtensions.ModDataFile, testVelocity: false);
+			ResultFileHelper.TestModFile(modalResultFile, modFile + Constants.FileExtensions.ModDataFile);
 		}
 
 		[TestCase]
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs
index d06e55cc5c..9f87714bc7 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs
@@ -109,7 +109,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 			var testColumns = new[] { "P_aux_FAN", "P_aux_STP", "P_aux_AC", "P_aux_ES", "P_aux_PS", "P_aux" };
 
 			ResultFileHelper.TestModFile(@"TestData\Results\EngineOnlyCycles\AuxWriteModFileSumFile.vmod",
-				@"AuxWriteModFileSumFile.vmod", testColumns, testVelocity: false);
+				@"AuxWriteModFileSumFile.vmod", testColumns);
 			ResultFileHelper.TestSumFile(@"TestData\Results\EngineOnlyCycles\AuxWriteModFileSumFile.vsum",
 				@"AuxWriteModFileSumFile.vsum");
 		}
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs
index 2cbb495822..d3f9f0b7ed 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs
@@ -166,7 +166,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 			ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel.vsum", @"TestData\Pwheel\Pwheel.vsum");
 
 			ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_Gear2_pt1_rep1_actual.vmod",
-				@"TestData\Pwheel\Pwheel_Gear2_pt1_rep1_actual.vmod", testVelocity: false);
+				@"TestData\Pwheel\Pwheel_Gear2_pt1_rep1_actual.vmod");
 		}
 
 		/// <summary>
@@ -194,7 +194,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 			ResultFileHelper.TestSumFile(@"TestData\Pwheel\Results\Pwheel_ultimate.vsum", @"TestData\Pwheel\Pwheel_ultimate.vsum");
 
 			ResultFileHelper.TestModFile(@"TestData\Pwheel\Results\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod",
-				@"TestData\Pwheel\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod", testVelocity: false);
+				@"TestData\Pwheel\Pwheel_ultimate_RD_#1_Pwheel_AuxStd.vmod");
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs
index 9a6632f0de..98e683de89 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs
@@ -69,7 +69,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 
 			Assert.IsTrue(job.FinishedWithoutErrors);
 
-			ResultFileHelper.TestModFile(expected, actual, testVelocity: false);
+			ResultFileHelper.TestModFile(expected, actual);
 		}
 
 		[TestMethod]
@@ -89,7 +89,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 				Assert.IsTrue(r.Run.FinishedWithoutErrors, string.Format("{0}", r.ExecException));
 			}
 
-			ResultFileHelper.TestModFile(expected, actual, testVelocity: false);
+			ResultFileHelper.TestModFile(expected, actual);
 		}
 
 		public IVectoRun CreateRun(string resultFileName)
@@ -136,7 +136,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 					@"TestData\Jobs\24t Coach EngineOnly_Engine Only1.vmod",
 					@"TestData\Jobs\24t Coach EngineOnly_Engine Only2.vmod",
 					@"TestData\Jobs\24t Coach EngineOnly_Engine Only3.vmod"
-				}, testVelocity: false)
+				})
 				;
 		}
 	}
diff --git a/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs b/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs
index 4b9c1bdfc4..d747cfc73d 100644
--- a/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs
+++ b/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs
@@ -43,13 +43,13 @@ namespace TUGraz.VectoCore.Tests.Utils
 	public static class ResultFileHelper
 	{
 		public static void TestModFile(string expectedFile, string actualFile, string[] testColumns = null,
-			bool testRowCount = true, bool testVelocity = true)
+			bool testRowCount = true)
 		{
-			TestModFiles(new[] { expectedFile }, new[] { actualFile }, testColumns, testRowCount, testVelocity);
+			TestModFiles(new[] { expectedFile }, new[] { actualFile }, testColumns, testRowCount);
 		}
 
 		public static void TestModFiles(IEnumerable<string> expectedFiles, IEnumerable<string> actualFiles,
-			string[] testColumns = null, bool testRowcount = true, bool testVelocity = true)
+			string[] testColumns = null, bool testRowcount = true)
 		{
 			var resultFiles = expectedFiles.ZipAll(actualFiles, (expectedFile, actualFile) => new { expectedFile, actualFile });
 			foreach (var result in resultFiles) {
@@ -59,17 +59,31 @@ namespace TUGraz.VectoCore.Tests.Utils
 				var expected = VectoCSVFile.Read(result.expectedFile);
 				var actual = VectoCSVFile.Read(result.actualFile);
 
-				if (testVelocity) {
-					Assert.IsTrue(
-						actual.Rows.Cast<DataRow>()
+				if (actual.Columns.Contains(ModalResultField.v_act.GetShortCaption()) &&
+					!double.IsNaN(actual.Rows[0].Field<string>(ModalResultField.v_act.GetShortCaption()).ToDouble(double.NaN))) {
+					// test v_act >= 0
+					Assert.IsTrue(actual.Rows.Cast<DataRow>()
 							.All(r => r.ParseDouble(ModalResultField.v_act.GetShortCaption()).IsGreaterOrEqual(0)),
 						"v_act must not be negative.");
-					Assert.IsTrue(
-						actual.Rows.Cast<DataRow>()
+
+					// test v_targ >= 0
+					Assert.IsTrue(actual.Rows.Cast<DataRow>()
 							.All(r => r.ParseDouble(ModalResultField.v_targ.GetShortCaption()).IsGreaterOrEqual(0)),
 						"v_targ must not be negative.");
 				}
 
+				if (actual.Columns.Contains(ModalResultField.dist.GetShortCaption()) &&
+					!double.IsNaN(actual.Rows[0].Field<string>(ModalResultField.dist.GetShortCaption()).ToDouble(double.NaN))) {
+					// test distance monotonous increasing
+
+					var distPrev = actual.Rows[0].ParseDouble(ModalResultField.dist.GetShortCaption());
+					for (var i = 1; i < actual.Rows.Count; i++) {
+						var dist = actual.Rows[i].ParseDouble(ModalResultField.dist.GetShortCaption());
+						Assert.IsTrue(distPrev.IsSmallerOrEqual(dist), "distance must not decrease.");
+						distPrev = dist;
+					}
+				}
+
 				if (testRowcount) {
 					Assert.AreEqual(expected.Rows.Count, actual.Rows.Count,
 						string.Format("Moddata: Row count differs.\nExpected {0} Rows in {1}\nGot {2} Rows in {3}", expected.Rows.Count,
-- 
GitLab