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

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

adding test for axlegear module

parent 2358368a
No related branches found
No related tags found
No related merge requests found
......@@ -16,9 +16,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
[JsonProperty] private readonly List<GearLossMapEntry> _entries;
private readonly DelauneyMap _lossMap; // Input Speed, Output Torque (to Wheels) => Input Torque (Engine)
private readonly DelauneyMap _reverseLossMap; // Input Speed, Input Torque (Engine) => Output Torque (Wheels)
//private readonly DelauneyMap _reverseLossMap; // Input Speed, Input Torque (Engine) => Output Torque (Wheels)
public static TransmissionLossMap ReadFromFile(string fileName)
public static TransmissionLossMap ReadFromFile(string fileName, double gearRatio)
{
var data = VectoCSVFile.Read(fileName, true);
......@@ -44,7 +44,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
entries = CreateFromColumIndizes(data);
}
return new TransmissionLossMap(entries);
return new TransmissionLossMap(entries, gearRatio);
}
private static bool HeaderIsValid(DataColumnCollection columns)
......@@ -80,45 +80,51 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
}).ToList();
}
private TransmissionLossMap(List<GearLossMapEntry> entries)
private TransmissionLossMap(List<GearLossMapEntry> entries, double gearRatio)
{
_entries = entries;
_lossMap = new DelauneyMap();
_reverseLossMap = new DelauneyMap();
//_reverseLossMap = new DelauneyMap();
foreach (var entry in _entries) {
_lossMap.AddPoint(entry.InputSpeed.Double(), entry.InputTorque.Double() - entry.TorqueLoss.Double(),
_lossMap.AddPoint(entry.InputSpeed.Double(), (entry.InputTorque.Double() - entry.TorqueLoss.Double()) * gearRatio,
entry.InputTorque.Double());
_reverseLossMap.AddPoint(entry.InputSpeed.Double(), entry.InputTorque.Double(),
entry.InputTorque.Double() - entry.TorqueLoss.Double());
// @@@quam: according to Raphael, not needed for now...
//_reverseLossMap.AddPoint(entry.InputSpeed.Double(), entry.InputTorque.Double(),
// entry.InputTorque.Double() - entry.TorqueLoss.Double());
}
_lossMap.Triangulate();
_reverseLossMap.Triangulate();
//_reverseLossMap.Triangulate();
}
/// <summary>
/// Compute the required torque at the input of the gearbox (from engine)
/// Compute the required torque at the input of the gear(box) (from engine)
/// </summary>
/// <param name="angularVelocity">[1/s] angular speed of the shaft</param>
/// <param name="gbxOutTorque">[Nm] torque requested by the previous componend (towards the wheels)</param>
/// <returns>[Nm] torque requested from the next component (towards the engine)</returns>
public NewtonMeter GearboxInTorque(PerSecond angularVelocity, NewtonMeter gbxOutTorque)
{
// TODO: extrapolate!
return _lossMap.Interpolate(angularVelocity.Double(), gbxOutTorque.Double()).SI<NewtonMeter>();
try {
return VectoMath.Max(_lossMap.Interpolate(angularVelocity.Double(), gbxOutTorque.Double()).SI<NewtonMeter>(),
0.SI<NewtonMeter>());
} catch (Exception e) {
throw new VectoSimulationException(
String.Format("Failed to interpolate in TransmissionLossMap. angularVelocity: {0}, torque: {1}", angularVelocity,
gbxOutTorque), e);
}
}
/// <summary>
/// Compute the available torque at the output of the gearbox (towards wheels)
/// Compute the available torque at the output of the gear(box) (towards wheels)
/// </summary>
/// <param name="angularVelocity">[1/s] angular speed of the shaft</param>
/// <param name="gbxInTorque">[Nm] torque provided by the engine at the gearbox' input shaft</param>
/// <returns>[Nm] torque provided to the next component (towards the wheels)</returns>
public NewtonMeter GearboxOutTorque(PerSecond angularVelocity, NewtonMeter gbxInTorque)
{
// TODO extrapolate!
return _reverseLossMap.Interpolate(angularVelocity.Double(), gbxInTorque.Double()).SI<NewtonMeter>();
}
//public NewtonMeter GearboxOutTorque(PerSecond angularVelocity, NewtonMeter gbxInTorque)
//{
// // TODO extrapolate!
// return _reverseLossMap.Interpolate(angularVelocity.Double(), gbxInTorque.Double()).SI<NewtonMeter>();
//}
public GearLossMapEntry this[int i]
{
get { return _entries[i]; }
......
......@@ -84,7 +84,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
public static GearboxData ReadFromJson(string json, string basePath = "")
{
var lossMaps = new Dictionary<string, TransmissionLossMap>();
// var lossMaps = new Dictionary<string, TransmissionLossMap>();
var gearboxData = new GearboxData();
......@@ -98,13 +98,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
for (uint i = 0; i < d.Body.Gears.Count; i++) {
var gearSettings = d.Body.Gears[(int) i];
var lossMapPath = Path.Combine(basePath, gearSettings.LossMap);
TransmissionLossMap lossMap;
if (lossMaps.ContainsKey(lossMapPath)) {
lossMap = lossMaps[lossMapPath];
lossMaps.Add(lossMapPath, lossMap);
} else {
lossMap = TransmissionLossMap.ReadFromFile(lossMapPath);
}
TransmissionLossMap lossMap = TransmissionLossMap.ReadFromFile(lossMapPath, gearSettings.Ratio);
var shiftPolygon = !String.IsNullOrEmpty(gearSettings.ShiftPolygon)
? ShiftPolygon.ReadFromFile(Path.Combine(basePath, gearSettings.ShiftPolygon))
......@@ -135,55 +129,55 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
return gearboxData;
}
public void CalculateAverageEfficiency(CombustionEngineData engineData)
{
var angularVelocityStep = (2.0 / 3.0) * (engineData.GetFullLoadCurve(0).RatedSpeed() - engineData.IdleSpeed) / 10.0;
var axleGearEfficiencySum = 0.0;
var axleGearSumCount = 0;
foreach (var gearEntry in _gearData) {
var gearEfficiencySum = 0.0;
var gearSumCount = 0;
for (var angularVelocity = engineData.IdleSpeed + angularVelocityStep;
angularVelocity < engineData.GetFullLoadCurve(0).RatedSpeed();
angularVelocity += angularVelocityStep) {
var fullLoadStationaryTorque = engineData.GetFullLoadCurve(gearEntry.Key).FullLoadStationaryTorque(angularVelocity);
var torqueStep = (2.0 / 3.0) * fullLoadStationaryTorque / 10.0;
for (var engineOutTorque = (1.0 / 3.0) * fullLoadStationaryTorque;
engineOutTorque < fullLoadStationaryTorque;
engineOutTorque += torqueStep) {
var engineOutPower = Formulas.TorqueToPower(engineOutTorque, angularVelocity);
var gearboxOutPower =
Formulas.TorqueToPower(
gearEntry.Value.LossMap.GearboxOutTorque(angularVelocity, engineOutTorque), angularVelocity);
if (gearboxOutPower > engineOutPower) {
gearboxOutPower = engineOutPower;
}
gearEfficiencySum += ((engineOutPower - gearboxOutPower) / engineOutPower).Double();
gearSumCount += 1;
// axle gear
var angularVelocityAxleGear = angularVelocity / gearEntry.Value.Ratio;
var axlegearOutPower =
Formulas.TorqueToPower(
AxleGearData.LossMap.GearboxOutTorque(angularVelocityAxleGear,
Formulas.PowerToTorque(engineOutPower, angularVelocityAxleGear)),
angularVelocityAxleGear);
if (axlegearOutPower > engineOutPower) {
axlegearOutPower = engineOutPower;
}
axleGearEfficiencySum += (axlegearOutPower / engineOutPower).Double();
axleGearSumCount += 1;
}
}
gearEntry.Value.AverageEfficiency = gearEfficiencySum / gearSumCount;
}
AxleGearData.AverageEfficiency = axleGearEfficiencySum / axleGearSumCount;
}
// @@@quam: according to Raphael no longer required
//public void CalculateAverageEfficiency(CombustionEngineData engineData)
//{
// var angularVelocityStep = (2.0 / 3.0) * (engineData.GetFullLoadCurve(0).RatedSpeed() - engineData.IdleSpeed) / 10.0;
// var axleGearEfficiencySum = 0.0;
// var axleGearSumCount = 0;
// foreach (var gearEntry in _gearData) {
// var gearEfficiencySum = 0.0;
// var gearSumCount = 0;
// for (var angularVelocity = engineData.IdleSpeed + angularVelocityStep;
// angularVelocity < engineData.GetFullLoadCurve(0).RatedSpeed();
// angularVelocity += angularVelocityStep) {
// var fullLoadStationaryTorque = engineData.GetFullLoadCurve(gearEntry.Key).FullLoadStationaryTorque(angularVelocity);
// var torqueStep = (2.0 / 3.0) * fullLoadStationaryTorque / 10.0;
// for (var engineOutTorque = (1.0 / 3.0) * fullLoadStationaryTorque;
// engineOutTorque < fullLoadStationaryTorque;
// engineOutTorque += torqueStep) {
// var engineOutPower = Formulas.TorqueToPower(engineOutTorque, angularVelocity);
// var gearboxOutPower =
// Formulas.TorqueToPower(
// gearEntry.Value.LossMap.GearboxOutTorque(angularVelocity, engineOutTorque), angularVelocity);
// if (gearboxOutPower > engineOutPower) {
// gearboxOutPower = engineOutPower;
// }
// gearEfficiencySum += ((engineOutPower - gearboxOutPower) / engineOutPower).Double();
// gearSumCount += 1;
// // axle gear
// var angularVelocityAxleGear = angularVelocity / gearEntry.Value.Ratio;
// var axlegearOutPower =
// Formulas.TorqueToPower(
// AxleGearData.LossMap.GearboxOutTorque(angularVelocityAxleGear,
// Formulas.PowerToTorque(engineOutPower, angularVelocityAxleGear)),
// angularVelocityAxleGear);
// if (axlegearOutPower > engineOutPower) {
// axlegearOutPower = engineOutPower;
// }
// axleGearEfficiencySum += (axlegearOutPower / engineOutPower).Double();
// axleGearSumCount += 1;
// }
// }
// gearEntry.Value.AverageEfficiency = gearEfficiencySum / gearSumCount;
// }
// AxleGearData.AverageEfficiency = axleGearEfficiencySum / axleGearSumCount;
//}
public int GearsCount()
{
......
......@@ -8,11 +8,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public class AxleGear : IPowerTrainComponent, ITnInPort, ITnOutPort
{
private ITnOutPort _nextComponent;
private GearData _gearDataData;
private readonly GearData _gearData;
public AxleGear(GearData gearDataData)
public AxleGear(GearData gearData)
{
_gearDataData = gearDataData;
_gearData = gearData;
}
public ITnInPort InShaft()
......@@ -32,7 +32,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity)
{
return _nextComponent.Request(absTime, dt, torque, angularVelocity);
return _nextComponent.Request(absTime, dt,
_gearData.LossMap.GearboxInTorque(angularVelocity * _gearData.Ratio, torque),
angularVelocity * _gearData.Ratio);
}
}
}
\ No newline at end of file
using System;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
{
[TestClass]
public class GearboxTest
{
protected string GearboxDataFile = @"TestData\Components\24t Coach.vgbx";
public TestContext TestContext { get; set; }
[TestMethod]
public void AxleGearTest()
{
VehicleContainer vehicle = new VehicleContainer();
var gbxData = GearboxData.ReadFromFile(GearboxDataFile);
//GearData gearData = new GearData();
var axleGear = new AxleGear(gbxData.AxleGearData);
var mockPort = new MockTnOutPort();
axleGear.InShaft().Connect(mockPort);
var absTime = TimeSpan.FromSeconds(0);
var dt = TimeSpan.FromSeconds(1);
var rdyn = 520;
var speed = 20.320;
var angSpeed = SpeedToAngularSpeed(speed, rdyn);
var PvD = 279698.4.SI<Watt>();
// Double.Parse(TestContext.DataRow["PowerGbxOut"].ToString(), CultureInfo.InvariantCulture).SI<Watt>();
var torqueToWheels = Formulas.PowerToTorque(PvD, angSpeed);
//var torqueFromEngine = 0.SI<NewtonMeter>();
axleGear.Request(absTime, dt, torqueToWheels, angSpeed);
var loss = 9401.44062.SI<Watt>();
Assert.AreEqual(Formulas.PowerToTorque(PvD + loss, angSpeed * gbxData.AxleGearData.Ratio), mockPort.Torque,
"Torque Engine Side");
Assert.AreEqual(angSpeed * gbxData.AxleGearData.Ratio, mockPort.AngularVelocity, "Torque Engine Side");
}
protected PerSecond SpeedToAngularSpeed(double v, double r)
{
return ((60 * v) / (2 * r * Math.PI / 1000)).RPMtoRad();
}
}
}
\ No newline at end of file
using System;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Utils;
......@@ -64,6 +65,53 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
TestContext.DataRow["TestName"].ToString());
}
[TestMethod]
public void TestInputOutOfRange()
{
var rdyn = 520.0;
//var speed = double.Parse(TestContext.DataRow["v"].ToString(), CultureInfo.InvariantCulture);
var gbxData = GearboxData.ReadFromFile(GearboxFile);
var angSpeed = 2700.RPMtoRad();
var torqueToWheels = 100.SI<NewtonMeter>();
try {
gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels);
Assert.Fail("angular Speed too high");
} catch (Exception e) {
Assert.IsInstanceOfType(e, typeof (VectoSimulationException));
}
angSpeed = 1000.RPMtoRad();
torqueToWheels = 50000.SI<NewtonMeter>();
try {
gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels);
Assert.Fail("torque too high");
} catch (Exception e) {
Assert.IsInstanceOfType(e, typeof (VectoSimulationException));
}
angSpeed = 1000.RPMtoRad();
torqueToWheels = -5000.SI<NewtonMeter>();
try {
gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels);
Assert.Fail("torque too low");
} catch (Exception e) {
Assert.IsInstanceOfType(e, typeof (VectoSimulationException));
}
angSpeed = -1000.RPMtoRad();
torqueToWheels = 500.SI<NewtonMeter>();
try {
gbxData.AxleGearData.LossMap.GearboxInTorque(angSpeed, torqueToWheels);
Assert.Fail("negative angular speed");
} catch (Exception e) {
Assert.IsInstanceOfType(e, typeof (VectoSimulationException));
}
}
protected PerSecond SpeedToAngularSpeed(double v, double r)
{
return ((60 * v) / (2 * r * Math.PI / 1000)).RPMtoRad();
......
......@@ -75,6 +75,7 @@
<Compile Include="Models\SimulationComponentData\GearboxDataTest.cs" />
<Compile Include="Models\SimulationComponent\ClutchTest.cs" />
<Compile Include="Models\SimulationComponent\CombustionEngineTest.cs" />
<Compile Include="Models\SimulationComponent\GearboxTest.cs" />
<Compile Include="Models\SimulationComponent\RetarderTest.cs" />
<Compile Include="Models\Simulation\DrivingCycleTests.cs" />
<Compile Include="Models\SimulationComponent\MockPorts.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