Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit 14205221 authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

more work on engine model, implementing first testcases

parent 092bf9b0
No related branches found
No related tags found
No related merge requests found
......@@ -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
......@@ -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());
......
......@@ -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;
}
......
......@@ -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; }
}
}
......
......@@ -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
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)]
......
......@@ -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]
......
......@@ -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; }
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment