Code development platform for open source projects from the European Union institutions

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

implemented engine model, accessing full load curve (incl. interpolation).

Testcases: green
parent 655a5be8
No related branches found
No related tags found
No related merge requests found
......@@ -55,28 +55,28 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
return fullLoadCurve;
}
public double FullLoadStaticTorque(double rpm)
public double FullLoadStationaryTorque(double rpm)
{
var idx = FindIndexForRpm(rpm);
return VectoMath.Interpolate(entries[idx - 1].EngineSpeed, entries[idx].EngineSpeed,
entries[idx - 1].TorqueFullLoad, entries[idx].TorqueFullLoad, rpm);
}
public double FullLoadStaticPower(double rpm)
public double FullLoadStationaryPower(double rpm)
{
return VectoMath.ConvertRpmToPower(rpm, FullLoadStaticTorque(rpm));
return VectoMath.ConvertRpmToPower(rpm, FullLoadStationaryTorque(rpm));
}
public double DragLoadStaticTorque(double rpm)
public double DragLoadStationaryTorque(double rpm)
{
var idx = FindIndexForRpm(rpm);
return VectoMath.Interpolate(entries[idx - 1].EngineSpeed, entries[idx].EngineSpeed,
entries[idx - 1].TorqueDrag, entries[idx].TorqueDrag, rpm);
}
public double DragLoadStaticPower(double rpm)
public double DragLoadStationaryPower(double rpm)
{
return VectoMath.ConvertRpmToPower(rpm, DragLoadStaticTorque(rpm));
return VectoMath.ConvertRpmToPower(rpm, DragLoadStationaryTorque(rpm));
}
public double PT1(double rpm)
......@@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
{
int idx;
if (rpm < entries[0].EngineSpeed) {
Logger.ErrorFormat("requested rpm below minimum rpm in FLD curve - extrapolating. n: {0}, rpm_min: {1}", rpm,
Log.ErrorFormat("requested rpm below minimum rpm in FLD curve - extrapolating. n: {0}, rpm_min: {1}", rpm,
entries[0].EngineSpeed);
idx = 1;
} else {
......@@ -99,6 +99,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
if (idx <= 0) {
idx = 1;
}
return idx;
}
}
}
using System;
using System.Collections.Generic;
using NLog;
using NLog.Layouts;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
......@@ -14,6 +11,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public class CombustionEngine : VectoSimulationComponent, ICombustionEngine, ITnOutPort
{
private const int EngineIdleSpeedStopThreshold = 100;
private const double MaxPowerExceededThreshold = 1.05;
private const double ZeroThreshold = 0.0001;
private const double FullLoadMargin = 0.01;
public enum EngineOperationMode
{
......@@ -63,47 +63,73 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (engineSpeed < _data.IdleSpeed - EngineIdleSpeedStopThreshold) {
_currentState.OperationMode = EngineOperationMode.Stopped;
_currentState.EnginePowerLoss = enginePowerLoss
}
_currentState.EnginePowerLoss = enginePowerLoss;
}
uint currentGear = 0; // TODO: get current Gear from Vehicle!
var minEnginePower = _data.GetFullLoadCurve(currentGear).DragLoadStaticPower(engineSpeed);
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)));
throw new VectoSimulationException(String.Format("t: {0} P_engine_full < 0! n: {1} [1/min] ", absTime, engineSpeed));
}
if (requestedPower > maxEnginePower) {
if (requestedEnginePower/maxEnginePower > 1.05) {
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 > 1.05 && requestedEnginePower > -99999) {
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);
}
}
//throw new NotImplementedException();
if (requestedEnginePower < -ZeroThreshold) {
_currentState.OperationMode = IsFullLoad(requestedEnginePower, maxEnginePower)
? EngineOperationMode.FullLoad
: EngineOperationMode.Load;
}
else if (requestedPower > ZeroThreshold) {
_currentState.OperationMode = IsFullLoad(requestedEnginePower, maxEnginePower)
? EngineOperationMode.FullDrag
: EngineOperationMode.Drag;
}
else {
// -ZeroThreshold <= requestedEnginePower <= ZeroThreshold
_currentState.OperationMode = EngineOperationMode.Idle;
}
}
public IList<string> Warnings()
{
IList<string> retVal = new List<string>();
retVal.Add(string.Format("Engine power corrected (>5%) in {0} time steps ", _enginePowerCorrections.Count));
return retVal;
}
protected double FullLoadPowerDyamic(uint gear, double rpm)
{
var staticFullLoadPower = _data.GetFullLoadCurve(gear).FullLoadStaticPower(rpm);
var staticFullLoadPower = _data.GetFullLoadCurve(gear).FullLoadStationaryPower(rpm);
var pt1 = _data.GetFullLoadCurve(gear).PT1(rpm);
return Math.Min( (1 / (pt1 + 1)) * (staticFullLoadPower + pt1 * _previousState.EnginePower),
staticFullLoadPower);
}
protected bool IsFullLoad(double requestedPower, double maxPower)
{
return Math.Abs(requestedPower / maxPower - 1.0) < FullLoadMargin;
}
protected double InertiaPowerLoss(double torque, double engineSpeed)
{
......
......@@ -27,7 +27,7 @@ namespace TUGraz.VectoCore.Utils
/// <returns>the power equivalent to the given rpm and torque [W]</returns>
public static double ConvertRpmToPower(double rpm, double torque)
{
return (2.0 * Math.PI / 60.0) * torque * rpm
return (2.0 * Math.PI / 60.0) * torque * rpm;
}
}
}
\ No newline at end of file
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
{
[TestClass]
public class FullLoadCurveTest
{
private static string CoachEngineFLD = "TestData\\EngineOnly\\EngineMaps\\24t Coach.vfld";
private static double tolerance = 0.0001;
[TestMethod]
public void TestFullLoadStaticTorque()
{
FullLoadCurve fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD);
Assert.AreEqual(1180, fldCurve.FullLoadStationaryTorque(560.0), tolerance);
Assert.AreEqual(1352, fldCurve.FullLoadStationaryTorque(2000), tolerance);
Assert.AreEqual(1231, fldCurve.FullLoadStationaryTorque(580), tolerance);
}
[TestMethod]
public void TestFullLoadStaticPower()
{
FullLoadCurve fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD);
Assert.AreEqual( 69198.814183, fldCurve.FullLoadStationaryPower(560.0), tolerance);
Assert.AreEqual(283162.218372, fldCurve.FullLoadStationaryPower(2000), tolerance);
Assert.AreEqual( 74767.810760, fldCurve.FullLoadStationaryPower(580), tolerance);
}
[TestMethod]
public void TestDragLoadStaticTorque()
{
FullLoadCurve fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD);
Assert.AreEqual(-149, fldCurve.DragLoadStationaryTorque(560.0), tolerance);
Assert.AreEqual(-301, fldCurve.DragLoadStationaryTorque(2000), tolerance);
Assert.AreEqual(-148.5, fldCurve.DragLoadStationaryTorque(580), tolerance);
}
[TestMethod]
public void TestDragLoadStaticPower()
{
FullLoadCurve fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD);
Assert.AreEqual( -8737.81636, fldCurve.DragLoadStationaryPower(560.0), tolerance);
Assert.AreEqual(-63041.29254, fldCurve.DragLoadStationaryPower(2000), tolerance);
Assert.AreEqual(-9019.51251, fldCurve.DragLoadStationaryPower(580), tolerance);
}
[TestMethod]
public void TestPT1()
{
FullLoadCurve fldCurve = FullLoadCurve.ReadFromFile(CoachEngineFLD);
Assert.AreEqual(0.6, fldCurve.PT1(560.0), tolerance);
Assert.AreEqual(0.25, fldCurve.PT1(2000), tolerance);
Assert.AreEqual(0.37, fldCurve.PT1(1700), tolerance);
}
}
}
......@@ -67,6 +67,7 @@
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="Models\SimulationComponentData\FullLoadCurveTest.cs" />
<Compile Include="Models\SimulationComponent\CombustionEngineTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
......@@ -111,9 +112,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="TestData\EngineOnly\ResultFiles\" />
</ItemGroup>
<ItemGroup />
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
......
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