From 142052212074451bd99ac3bafa74ee2d05d3f398 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Thu, 12 Mar 2015 17:01:09 +0100 Subject: [PATCH] more work on engine model, implementing first testcases --- .gitignore | 3 +- .../Data/CombustionEngineData.cs | 1 + .../Data/Engine/FullLoadCurve.cs | 2 +- .../Impl/CombustionEngine.cs | 91 +++++++++++++------ VectoCore/Utils/VectoMath.cs | 5 + .../CombustionEngineTest.cs | 32 ++++--- .../FullLoadCurveTest.cs | 9 +- VectoCoreTest/Utils/TestModalDataWriter.cs | 4 +- 8 files changed, 101 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index 5464d948ea..eb85b28f04 100644 --- a/.gitignore +++ b/.gitignore @@ -187,4 +187,5 @@ UpgradeLog*.htm *.bim_*.settings # Microsoft Fakes -FakesAssemblies/ \ No newline at end of file +FakesAssemblies/ +VectoCoreTest/TestData/EngineOnly/Test1/Test1_results.vmod.csv diff --git a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs index 2ba69b556e..148cebdd74 100644 --- a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs +++ b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs @@ -203,6 +203,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public FullLoadCurve GetFullLoadCurve(uint gear) { + // TODO: @@@quam refactor foreach (var gearRange in _fullLoadCurves.Keys) { var low = uint.Parse(gearRange.Split('-').First().Trim()); diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs index 9ed51dfa2d..af54d8af7f 100644 --- a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs +++ b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs @@ -97,7 +97,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine idx = entries.FindIndex(x => x.EngineSpeed > rpm); } if (idx <= 0) { - idx = 1; + idx = rpm > entries[0].EngineSpeed ? entries.Count - 1 : 1; } return idx; } diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 813055b317..21d625f555 100644 --- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -50,13 +50,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public override void CommitSimulationStep(IModalDataWriter writer) { - writer[ModalResultField.FC] = 1; - writer[ModalResultField.FCAUXc] = 2; - writer[ModalResultField.FCWHTCc] = 3; + writer[ModalResultField.PaEng] = _currentState.EnginePowerLoss; + _previousState = _currentState; + _currentState = new EngineState(); } public void Request(TimeSpan absTime, TimeSpan dt, double torque, double engineSpeed) { + _currentState.EngineSpeed = engineSpeed; + _currentState.AbsTime = absTime; + var requestedPower = VectoMath.ConvertRpmToPower(engineSpeed, torque); var enginePowerLoss = InertiaPowerLoss(torque, engineSpeed); var requestedEnginePower = requestedPower + enginePowerLoss; @@ -71,43 +74,69 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var minEnginePower = _data.GetFullLoadCurve(currentGear).DragLoadStationaryPower(engineSpeed); var maxEnginePower = FullLoadPowerDyamic(currentGear, engineSpeed); - if (minEnginePower >= 0 && requestedPower < 0) { - throw new VectoSimulationException(String.Format("t: {0} P_engine_drag > 0! n: {1} [1/min] ", absTime, engineSpeed)); - } - if (maxEnginePower <= 0 && requestedPower > 0) { - throw new VectoSimulationException(String.Format("t: {0} P_engine_full < 0! n: {1} [1/min] ", absTime, engineSpeed)); - } + ValidatePowerDemand(requestedEnginePower, maxEnginePower, minEnginePower); + + requestedEnginePower = LimitEnginePower(requestedEnginePower, maxEnginePower, minEnginePower); + + UpdateEngineState(requestedEnginePower, maxEnginePower, minEnginePower); + } + + protected void ValidatePowerDemand(double requestedEnginePower, double maxEnginePower, double minEnginePower) + { + if (minEnginePower >= 0 && requestedEnginePower < 0) + { + throw new VectoSimulationException(String.Format("t: {0} P_engine_drag > 0! n: {1} [1/min] ", _currentState.AbsTime, _currentState.EngineSpeed)); + } + if (maxEnginePower <= 0 && requestedEnginePower > 0) + { + throw new VectoSimulationException(String.Format("t: {0} P_engine_full < 0! n: {1} [1/min] ", _currentState.AbsTime, _currentState.EngineSpeed)); + } + } - if (requestedPower > maxEnginePower) { + protected double LimitEnginePower(double requestedEnginePower, double maxEnginePower, double minEnginePower) + { + if (requestedEnginePower > maxEnginePower) + { if (requestedEnginePower / maxEnginePower > MaxPowerExceededThreshold) { - requestedEnginePower = maxEnginePower; - _enginePowerCorrections.Add(absTime); - Log.WarnFormat("t: {0} requested power > P_engine_full * 1.05 - corrected. P_request: {1} P_engine_full: {2}", absTime, requestedEnginePower, maxEnginePower); - } - } else if (requestedPower < minEnginePower) { - if (requestedEnginePower/minEnginePower > MaxPowerExceededThreshold && requestedEnginePower > -99999) { - requestedEnginePower = minEnginePower; - _enginePowerCorrections.Add(absTime); - Log.WarnFormat("t: {0} requested power < P_engine_drag * 1.05 - corrected. P_request: {1} P_engine_drag: {2}", absTime, requestedEnginePower, minEnginePower); - } - } - - if (requestedEnginePower < -ZeroThreshold) { - _currentState.OperationMode = IsFullLoad(requestedEnginePower, maxEnginePower) - ? EngineOperationMode.FullLoad - : EngineOperationMode.Load; - } - else if (requestedPower > ZeroThreshold) { + _enginePowerCorrections.Add(_currentState.AbsTime); + Log.WarnFormat("t: {0} requested power > P_engine_full * 1.05 - corrected. P_request: {1} P_engine_full: {2}", _currentState.AbsTime, requestedEnginePower, maxEnginePower); + return maxEnginePower; + } + } + else if (requestedEnginePower < minEnginePower) + { + if (requestedEnginePower / minEnginePower > MaxPowerExceededThreshold && requestedEnginePower > -99999) + { + _enginePowerCorrections.Add(_currentState.AbsTime); + Log.WarnFormat("t: {0} requested power < P_engine_drag * 1.05 - corrected. P_request: {1} P_engine_drag: {2}", _currentState.AbsTime, requestedEnginePower, minEnginePower); + return minEnginePower; + } + } + return requestedEnginePower; + + } + + protected void UpdateEngineState(double requestedEnginePower, double maxEnginePower, double minEnginePower) + { + if (requestedEnginePower < -ZeroThreshold) + { _currentState.OperationMode = IsFullLoad(requestedEnginePower, maxEnginePower) + ? EngineOperationMode.FullLoad + : EngineOperationMode.Load; + } + else if (requestedEnginePower > ZeroThreshold) + { + _currentState.OperationMode = IsFullLoad(requestedEnginePower, minEnginePower) ? EngineOperationMode.FullDrag : EngineOperationMode.Drag; } - else { + else + { // -ZeroThreshold <= requestedEnginePower <= ZeroThreshold _currentState.OperationMode = EngineOperationMode.Idle; } - } + } public IList<string> Warnings() { @@ -147,6 +176,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public double EnginePower { get; set; } public double EngineSpeed { get; set; } public double EnginePowerLoss { get; set; } + + public TimeSpan AbsTime { get; set; } } } diff --git a/VectoCore/Utils/VectoMath.cs b/VectoCore/Utils/VectoMath.cs index 6a13ab40ed..1475c14e9f 100644 --- a/VectoCore/Utils/VectoMath.cs +++ b/VectoCore/Utils/VectoMath.cs @@ -29,5 +29,10 @@ namespace TUGraz.VectoCore.Utils { return (2.0 * Math.PI / 60.0) * torque * rpm; } + + public static double ConvertPowerToTorque(double power, double rpm) + { + return power / ((2.0 * Math.PI / 60.0) * rpm); + } } } \ No newline at end of file diff --git a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index cecf1cd2f7..f58efb4494 100644 --- a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -1,12 +1,14 @@ using System; using System.Data; using System.IO; +using System.Net.Security; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.Tests.Utils; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Tests.Models.SimulationComponent { @@ -14,6 +16,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent [TestClass] public class CombustionEngineTest { + private const string CoachEngine = "TestData\\EngineOnly\\EngineMaps\\24t Coach.veng"; + public TestContext TestContext { get; set; } [ClassInitialize] @@ -26,7 +30,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent [TestMethod] public void TestEngineHasOutPort() { - var engineData = CombustionEngineData.ReadFromFile("TestData\\EngineOnly\\EngineMaps\\24t Coach.veng"); + var engineData = CombustionEngineData.ReadFromFile(CoachEngine); var engine = new CombustionEngine(engineData); var port = engine.OutShaft(); @@ -36,7 +40,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent [TestMethod] public void TestOutPortRequestNotFailing() { - var engineData = CombustionEngineData.ReadFromFile("TestData\\EngineOnly\\EngineMaps\\24t Coach.veng"); + var engineData = CombustionEngineData.ReadFromFile(CoachEngine); var engine = new CombustionEngine(engineData); var port = engine.OutShaft(); @@ -52,7 +56,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent [TestMethod] public void TestSimpleModalData() { - var engineData = CombustionEngineData.ReadFromFile("TestData\\EngineOnly\\EngineMaps\\24t Coach.veng"); + var engineData = CombustionEngineData.ReadFromFile(CoachEngine); var engine = new CombustionEngine(engineData); var port = engine.OutShaft(); @@ -60,18 +64,24 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0); //todo: set correct input values to test - var torque = 400.0; - var engineSpeed = 1500.0; - port.Request(absTime, dt, torque, engineSpeed); + var torque = 0.0; + var engineSpeed = 600.0; + var dataWriter = new TestModalDataWriter(); + for (var i = 0; i < 10; i++) { + port.Request(absTime, dt, torque, engineSpeed); + engine.CommitSimulationStep(dataWriter); + absTime += dt; + } - var dataWriter = new TestModalDataWriter(); - engine.CommitSimulationStep(dataWriter); + port.Request(absTime, dt, VectoMath.ConvertPowerToTorque(2329.973, 644.4445), 644.4445); + engine.CommitSimulationStep(dataWriter); //todo: test with correct output values, add other fields to test - Assert.AreEqual(dataWriter[ModalResultField.FC], 13000); - Assert.AreEqual(dataWriter[ModalResultField.FCAUXc], 14000); - Assert.AreEqual(dataWriter[ModalResultField.FCWHTCc], 15000); + //Assert.AreEqual(dataWriter[ModalResultField.FC], 13000); + //Assert.AreEqual(dataWriter[ModalResultField.FCAUXc], 14000); + //Assert.AreEqual(dataWriter[ModalResultField.FCWHTCc], 15000); + Assert.AreEqual(2.906175, dataWriter[ModalResultField.PaEng]); } [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\TestData\\EngineTests.csv", "EngineTests#csv", DataAccessMethod.Sequential)] diff --git a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs index 9f56e2640f..a64cace5f5 100644 --- a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs +++ b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs @@ -19,6 +19,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000), tolerance); Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580), tolerance); + + } [TestMethod] @@ -42,7 +44,12 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData Assert.AreEqual(-301, fldCurve.DragLoadStationaryTorque(2000), tolerance); Assert.AreEqual(-148.5, fldCurve.DragLoadStationaryTorque(580), tolerance); - + + Assert.AreEqual(-150, fldCurve.DragLoadStationaryTorque(520.0), tolerance); + + Assert.AreEqual(-339, fldCurve.DragLoadStationaryTorque(2200.0), tolerance); + + } [TestMethod] diff --git a/VectoCoreTest/Utils/TestModalDataWriter.cs b/VectoCoreTest/Utils/TestModalDataWriter.cs index 53a0ffaf56..05548027a0 100644 --- a/VectoCoreTest/Utils/TestModalDataWriter.cs +++ b/VectoCoreTest/Utils/TestModalDataWriter.cs @@ -27,8 +27,8 @@ namespace TUGraz.VectoCore.Tests.Utils public object this[ModalResultField key] { - get { return CurrentRow[key.ToString()]; } - set { CurrentRow[key.ToString()] = value; } + get { return CurrentRow[key.GetName()]; } + set { CurrentRow[key.GetName()] = value; } } } } -- GitLab