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 dd79fc66 authored by Michael KRISPER's avatar Michael KRISPER
Browse files

PTOIdleLossMap and Reader added; also added a fast GetSection method for arrays

parent 3bc2f834
No related branches found
No related tags found
No related merge requests found
......@@ -137,6 +137,26 @@ namespace TUGraz.VectoCommon.Utils
return Tuple.Create(list[index], list[index + 1]);
}
/// <summary>
/// Get the first two adjacent items where the predicate changes from true to false.
/// If the predicate is always false, the first 2 elements are returned.
/// If the predicate is always true, the last 2 elements are returned.
/// </summary>
public static Tuple<T, T> GetSection<T>(this T[] self, Func<T, bool> predicate)
{
var i = 0;
for (; i < self.Length; i++) {
if (!predicate(self[i]))
break;
}
if (i == 0) {
i = 1;
} else if (i == self.Length) {
i--;
}
return Tuple.Create(self[i - 1], self[i]);
}
/// <summary>
/// Get the first two adjacent items where the predicate changes from true to false.
/// If the predicate never gets true, the last 2 elements are returned.
......
using System;
using System.Data;
using System.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.InputData.Reader.ComponentData
{
public static class PTOIdleLossMapReader
{
/// <summary>
/// Read the retarder loss map from a file.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static PTOIdleLossMap ReadFromFile(string fileName)
{
try {
return Create(VectoCSVFile.Read(fileName));
} catch (Exception ex) {
throw new VectoException("ERROR while loading PTO Idle LossMap: " + ex.Message);
}
}
/// <summary>
/// Create the pto idle loss map from an appropriate datatable. (2 columns: Engine Speed, PTO Torque)
/// </summary>
public static PTOIdleLossMap Create(DataTable data)
{
if (data.Columns.Count != 2) {
throw new VectoException("PTO Idle LossMap Data File must consist of 2 columns: {0}, {1}", Fields.EngineSpeed,
Fields.PTOTorque);
}
if (data.Rows.Count < 2) {
throw new VectoException("PTO Idle LossMap must contain at least 2 entries.");
}
if (!data.Columns.Contains(Fields.EngineSpeed) || !data.Columns.Contains(Fields.PTOTorque)) {
data.Columns[0].ColumnName = Fields.EngineSpeed;
data.Columns[1].ColumnName = Fields.PTOTorque;
LoggingObject.Logger<RetarderLossMap>().Warn(
"PTO Idle LossMap: Header Line is not valid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
Fields.EngineSpeed, Fields.PTOTorque, ", ".Join(data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
}
return new PTOIdleLossMap(data.Rows.Cast<DataRow>()
.Select(row => new PTOIdleLossMap.Entry {
EngineSpeed = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(),
PTOTorque = row.ParseDouble(Fields.PTOTorque).SI<NewtonMeter>()
}).OrderBy(e => e.EngineSpeed).ToArray());
}
private static class Fields
{
/// <summary>
/// [rpm]
/// </summary>
public const string EngineSpeed = "Engine Speed";
/// <summary>
/// [Nm]
/// </summary>
public const string PTOTorque = "PTO Torque";
}
}
}
\ No newline at end of file
using System.ComponentModel.DataAnnotations;
using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data
{
/// <summary>
/// LossMap for PTO Idle losses.
/// </summary>
public class PTOIdleLossMap : SimulationComponentData
{
[ValidateObject] private readonly Entry[] _entries;
protected internal PTOIdleLossMap(Entry[] entries)
{
_entries = entries;
}
/// <summary>
/// Calculates the pto torque loss.
/// </summary>
/// <param name="angularVelocity"></param>
/// <returns></returns>
public NewtonMeter PTOTorqueLoss(PerSecond angularVelocity)
{
var s = _entries.GetSection(e => e.EngineSpeed < angularVelocity);
return VectoMath.Interpolate(s.Item1.EngineSpeed, s.Item2.EngineSpeed, s.Item1.PTOTorque, s.Item2.PTOTorque,
angularVelocity);
}
public class Entry
{
[Required, SIRange(0, double.MaxValue)] public PerSecond EngineSpeed;
[Required, SIRange(0, 1000)] public NewtonMeter PTOTorque;
}
}
}
\ No newline at end of file
......@@ -117,6 +117,7 @@
<Compile Include="InputData\FileIO\JSON\JSONInputDataFactory.cs" />
<Compile Include="InputData\FileIO\JSON\JSONVehicleData.cs" />
<Compile Include="InputData\IVectoRunDataFactory.cs" />
<Compile Include="InputData\Reader\ComponentData\PTOIdleLossMapReader.cs" />
<Compile Include="InputData\Reader\DataObjectAdapter\AbstractSimulationDataAdapter.cs" />
<Compile Include="InputData\Reader\DataObjectAdapter\DeclarationDataAdapter.cs" />
<Compile Include="InputData\Reader\DataObjectAdapter\EngineeringDataAdapter.cs" />
......@@ -140,6 +141,7 @@
<Compile Include="InputData\Reader\ComponentData\TorqueConverterDataReader.cs" />
<Compile Include="InputData\Reader\ComponentData\AuxiliaryDataReader.cs" />
<Compile Include="Models\SimulationComponent\Data\Engine\FuelConsumptionMapReader.cs" />
<Compile Include="Models\SimulationComponent\Data\PTOIdleLossMap.cs" />
<Compile Include="Utils\ProviderExtensions.cs" />
<Compile Include="Models\Declaration\AirDrag.cs" />
<Compile Include="Models\Declaration\Fan.cs" />
......
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