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

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

started test with variable time (engine only)

parent 8c98a993
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,11 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
public class ResponseFailTimeInterval : IResponse
{
public ResponseFailTimeInterval(TimeSpan dt)
{
DeltaT = dt;
}
public TimeSpan DeltaT { get; set; }
}
}
\ No newline at end of file
......@@ -142,13 +142,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
/// [m] Travelled distance used for distance-based cycles. If "t"
/// is also defined this column will be ignored.
/// </summary>
public double Distance { get; set; }
public Meter Distance { get; set; }
/// <summary>
/// [s] Used for time-based cycles. If neither this nor the distance
/// "s" is defined the data will be interpreted as 1Hz.
/// </summary>
public double Time { get; set; }
public Second Time { get; set; }
/// <summary>
/// [m/s] Required except for Engine Only Mode calculations.
......@@ -164,7 +164,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
/// [s] Required for distance-based cycles. Not used in time based
/// cycles. "stop" defines the time the vehicle spends in stop phases.
/// </summary>
public double StoppingTime { get; set; }
public Second StoppingTime { get; set; }
/// <summary>
/// [W] Supply Power input for each auxiliary defined in the
......@@ -243,7 +243,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
return table.Rows.Cast<DataRow>().Select(row => new DrivingCycleEntry {
Distance = row.ParseDouble(Fields.Distance),
Distance = row.ParseDouble(Fields.Distance).SI<Meter>(),
VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.To<MeterPerSecond>(),
RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.To<Watt>(),
......@@ -297,7 +297,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
var entries = table.Rows.Cast<DataRow>().Select((row, index) => new DrivingCycleEntry {
Time = row.ParseDoubleOrGetDefault(Fields.Time, index),
Time = row.ParseDoubleOrGetDefault(Fields.Time, index).SI<Second>(),
VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.To<MeterPerSecond>(),
RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.To<Watt>(),
......@@ -368,9 +368,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
entry.EngineSpeed);
}
}
entry.Time = absTime.TotalSeconds;
absTime += new TimeSpan(0, 0, 1);
if (row.Table.Columns.Contains(Fields.Time)) {
entry.Time = row.ParseDouble(Fields.Time).SI<Second>();
} else {
entry.Time = absTime.TotalSeconds.SI<Second>();
absTime += new TimeSpan(0, 0, 1);
}
yield return entry;
}
}
......@@ -378,6 +381,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
private static void ValidateHeader(string[] header)
{
var allowedCols = new[] {
Fields.Time,
Fields.EngineTorque,
Fields.EnginePower,
Fields.EngineSpeed,
......
......@@ -35,7 +35,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// </summary>
private EngineState _currentState = new EngineState();
private CombustionEngineData _data = new CombustionEngineData();
private CombustionEngineData _data;
private EngineState _previousState = new EngineState();
public CombustionEngine(IVehicleContainer cockpit, CombustionEngineData data)
......@@ -213,10 +213,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
_currentState.StationaryFullLoadPower = Formulas.TorqueToPower(_currentState.StationaryFullLoadTorque,
angularFrequency);
var pt1 = _data.GetFullLoadCurve(gear).PT1(angularFrequency) / dt.TotalSeconds;
var pt1 = _data.GetFullLoadCurve(gear).PT1(angularFrequency) / dt.TotalSeconds;
var dynFullPowerCalculated = ((1 / (pt1 + 1)) * (_currentState.StationaryFullLoadPower + pt1 * _previousState.EnginePower)).To<Watt>();
((1 / (pt1 + 1)) * (_currentState.StationaryFullLoadPower + pt1 * _previousState.EnginePower)).To<Watt>();
_currentState.DynamicFullLoadPower = dynFullPowerCalculated < _currentState.StationaryFullLoadPower
? dynFullPowerCalculated
: _currentState.StationaryFullLoadPower;
......
using System;
using System.Collections.Generic;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation;
......@@ -17,11 +19,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public EngineOnlyDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) : base(container)
{
Data = cycle;
_nextEntry = cycle.Entries.GetEnumerator();
CurrentEntry = _nextEntry.Current;
_nextEntry.MoveNext();
}
private ITnOutPort OutPort { get; set; }
private int CurrentStep { get; set; }
protected IEnumerator<DrivingCycleData.DrivingCycleEntry> _nextEntry;
protected DrivingCycleData.DrivingCycleEntry NextEntry { get { return _nextEntry.Current; } }
protected DrivingCycleData.DrivingCycleEntry CurrentEntry { get; set; }
#region ITnInPort
public void Connect(ITnOutPort other)
......@@ -42,13 +51,21 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public IResponse Request(TimeSpan absTime, TimeSpan dt)
{
//todo: change to variable time steps
var index = (int) Math.Floor(absTime.TotalSeconds);
if (index >= Data.Entries.Count) {
return new ResponseCycleFinished();
if (absTime.TotalSeconds < CurrentEntry.Time.Double()) {
Log.ErrorFormat(("cannot go back in time! current: {0} requested: {1}", CurrentEntry.Time, absTime.TotalSeconds));
throw new VectoSimulationException(String.Format("cannot go back in time! current: {0} requested: {1}", CurrentEntry.Time, absTime.TotalSeconds));
}
while (NextEntry.Time <= absTime.TotalSeconds) {
CurrentEntry = NextEntry;
if (!_nextEntry.MoveNext()) {
return new ResponseCycleFinished();
}
}
if (dt.TotalSeconds > (NextEntry.Time - CurrentEntry.Time).Double()) {
return new ResponseFailTimeInterval(TimeSpan.FromSeconds((NextEntry.Time - CurrentEntry.Time).Double()));
}
return OutPort.Request(absTime, dt, Data.Entries[index].EngineTorque, Data.Entries[index].EngineSpeed);
return OutPort.Request(absTime, dt, CurrentEntry.EngineTorque, CurrentEntry.EngineSpeed);
}
#endregion
......
......@@ -8,6 +8,11 @@ using TUGraz.VectoCore.Exceptions;
namespace TUGraz.VectoCore.Utils
{
public class Meter : SI
{
public Meter(double val = 0) : base(val, new SI().Meter) { }
}
public class MeterPerSecond : SI
{
public MeterPerSecond(double val = 0) : base(val, new SI().Meter.Per.Second) {}
......@@ -58,6 +63,11 @@ namespace TUGraz.VectoCore.Utils
Exponent = 1;
}
public double Double()
{
return Val;
}
protected SI(double val, IEnumerable<string> numerator, IEnumerable<string> denominator, bool reciproc = false,
bool reverse = false, int exponent = 1)
{
......
......@@ -41,6 +41,65 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
Assert.AreEqual(0.SI<NewtonMeter>(), outPort.Torque);
}
[TestMethod]
public void TestEngineOnlyWithTimestamps()
{
var container = new VehicleContainer();
var cycleData = DrivingCycleData.ReadFromFileEngineOnly(@"TestData\Cycles\Coach Engine Only Paux_var-dt.vdri");
var cycle = new EngineOnlyDrivingCycle(container, cycleData);
var outPort = new MockTnOutPort();
var inPort = cycle.InShaft();
inPort.Connect(outPort);
var absTime = TimeSpan.FromSeconds(10);
var dt = TimeSpan.FromSeconds(1);
var response = cycle.Request(absTime, dt);
Assert.IsInstanceOfType(response, typeof(ResponseFailTimeInterval));
dt = TimeSpan.FromSeconds(0.25);
response = cycle.Request(absTime, dt);
Assert.IsInstanceOfType(response, typeof(ResponseSuccess));
var dataWriter = new TestModalDataWriter();
container.CommitSimulationStep(dataWriter);
Assert.AreEqual(absTime, outPort.AbsTime);
Assert.AreEqual(dt, outPort.Dt);
Assert.AreEqual(743.2361.RPMtoRad(), outPort.AngularFrequency);
Assert.AreEqual(Formulas.PowerToTorque(2779.576.SI<Watt>(), 743.2361.RPMtoRad()), outPort.Torque);
// ========================
dt = TimeSpan.FromSeconds(1);
absTime = TimeSpan.FromSeconds(500);
response = cycle.Request(absTime, dt);
Assert.IsInstanceOfType(response, typeof(ResponseFailTimeInterval));
dt = TimeSpan.FromSeconds(0.25);
for (int i = 0; i < 2; i++) {
response = cycle.Request(absTime, dt);
Assert.IsInstanceOfType(response, typeof (ResponseSuccess));
dataWriter = new TestModalDataWriter();
container.CommitSimulationStep(dataWriter);
Assert.AreEqual(absTime, outPort.AbsTime);
Assert.AreEqual(dt, outPort.Dt);
Assert.AreEqual(1584.731.RPMtoRad(), outPort.AngularFrequency);
Assert.AreEqual(Formulas.PowerToTorque(3380.548.SI<Watt>(), 1584.731.RPMtoRad()), outPort.Torque);
absTime += dt;
}
// todo: test going backward in time, end of cycle
}
[TestMethod]
public void Test_TimeBased_FirstCycle()
{
......
......@@ -116,6 +116,9 @@
<None Include="TestData\Components\FullLoadCurve insufficient entries.vfld">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="TestData\Cycles\Coach Engine Only Paux_var-dt.vdri">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="TestData\Cycles\Coach time based.vdri">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
......
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