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

tests for gearbox shift up, shift down, gear 0

parent a10ff27b
No related branches found
No related tags found
No related merge requests found
......@@ -16,6 +16,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
private readonly double _ratio;
private readonly DelauneyMap _lossMap; // Input Speed, Output Torque (to Wheels) => Input Torque (Engine)
private NewtonMeter _minTorque = double.PositiveInfinity.SI<NewtonMeter>();
private NewtonMeter _maxTorque = double.NegativeInfinity.SI<NewtonMeter>();
private PerSecond _maxSpeed = double.NegativeInfinity.SI<PerSecond>();
private PerSecond _minSpeed = double.PositiveInfinity.SI<PerSecond>();
//private readonly DelauneyMap _reverseLossMap; // Input Speed, Input Torque (Engine) => Output Torque (Wheels)
public static TransmissionLossMap ReadFromFile(string fileName, double gearRatio)
......@@ -86,9 +90,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
_entries = entries;
_lossMap = new DelauneyMap();
foreach (var entry in _entries) {
_lossMap.AddPoint(entry.InputSpeed.Value(), ((entry.InputTorque - entry.TorqueLoss) * _ratio).Value(),
entry.InputTorque.Value());
var outTorque = (entry.InputTorque - entry.TorqueLoss) * _ratio;
_minTorque = VectoMath.Min(_minTorque, outTorque);
_maxTorque = VectoMath.Max(_maxTorque, outTorque);
_minSpeed = VectoMath.Min(_minSpeed, entry.InputSpeed);
_maxSpeed = VectoMath.Max(_maxSpeed, entry.InputSpeed);
_lossMap.AddPoint(entry.InputSpeed.Value(), outTorque.Value(), entry.InputTorque.Value());
}
_lossMap.Triangulate();
}
......@@ -101,14 +112,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
public NewtonMeter GearboxInTorque(PerSecond angularVelocity, NewtonMeter gbxOutTorque)
{
try {
var gbxInTorque = _lossMap.Interpolate(angularVelocity.Value(), gbxOutTorque.Value()).SI<NewtonMeter>();
var limitedAngularVelocity = VectoMath.Limit(angularVelocity, _minSpeed, _maxSpeed).Value();
var limitedTorque = VectoMath.Limit(gbxOutTorque, _minTorque, _maxTorque).Value();
var gbxInTorque = _lossMap.Interpolate(limitedAngularVelocity, limitedTorque).SI<NewtonMeter>();
LogManager.GetLogger(GetType()).DebugFormat("GearboxLoss: {0}", gbxInTorque);
// Torque at input of the gearbox must be greater or equal than the value without any losses (just torque/ratio)
return VectoMath.Max(gbxInTorque, gbxOutTorque / _ratio);
} catch (Exception e) {
throw new VectoSimulationException(
string.Format("Failed to interpolate in TransmissionLossMap. angularVelocity: {0}, torque: {1}", angularVelocity,
gbxOutTorque), e);
} catch (VectoException) {
var log = LogManager.GetLogger(GetType());
log.ErrorFormat("Failed to interpolate in TransmissionLossMap. angularVelocity: {0}, torque: {1}", angularVelocity,
gbxOutTorque);
return gbxOutTorque / _ratio;
}
}
......
......@@ -218,7 +218,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// </summary>
protected virtual Watt LimitEnginePower(Watt requestedEnginePower)
{
return VectoMath.Limit(requestedEnginePower, _currentState.DynamicFullLoadPower, _currentState.FullDragPower);
return VectoMath.Limit(requestedEnginePower, _currentState.FullDragPower, _currentState.DynamicFullLoadPower);
}
/// <summary>
......
using System;
using System.Diagnostics;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation;
......@@ -34,6 +36,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
#region ITnOutProvider
[DebuggerHidden]
public ITnOutPort OutPort()
{
return this;
......@@ -48,6 +51,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
get { return _gear; }
set { _gear = value; }
}
#endregion
#region ITnOutPort
......@@ -64,9 +68,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed, bool dryRun)
IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed, bool dryRun)
{
if (Gear == 0) {
if (Gear == 0 || outEngineSpeed.IsEqual(0)) {
return Next.Request(absTime, dt, 0.SI<NewtonMeter>(), 0.SI<PerSecond>());
}
......@@ -74,11 +78,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
PerSecond inEngineSpeed;
NewtonMeter inTorque;
var previousGear = _gear;
do {
gearChanged = false;
// calculate new inEngineSpeed and Torque for the current gear
inEngineSpeed = engineSpeed * CurrentGear.Ratio;
inTorque = CurrentGear.LossMap.GearboxInTorque(inEngineSpeed, torque);
inEngineSpeed = outEngineSpeed * CurrentGear.Ratio;
inTorque = CurrentGear.LossMap.GearboxInTorque(inEngineSpeed, outTorque);
//todo:
// Data.TorqueReserve ... % TorqueReserver for GearSkipping and EarlyUpshift
......@@ -105,7 +111,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}
} while (Data.SkipGears && gearChanged);
if (gearChanged) {
if (previousGear != _gear) {
return new ResponseGearShift { SimulationInterval = Data.TractionInterruption };
}
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using TUGraz.VectoCore.Exceptions;
namespace TUGraz.VectoCore.Utils
{
......@@ -79,8 +81,11 @@ namespace TUGraz.VectoCore.Utils
return c1.CompareTo(c2) >= 0 ? c1 : c2;
}
public static T Limit<T>(T value, T upperBound, T lowerBound) where T : SIBase<T>
public static T Limit<T>(T value, T lowerBound, T upperBound) where T : SIBase<T>
{
if (lowerBound > upperBound)
throw new VectoException("VectoMath.Limit: lowerBound must not be greater than upperBound");
if (value > upperBound) {
return upperBound;
}
......
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NLog.Targets;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.FileIO.Reader.Impl;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
......@@ -72,11 +72,15 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
public void Gearbox_LossMapInterpolationFail()
{
var gearboxData = DeclarationModeSimulationDataReader.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile);
var gearbox = new Gearbox(new VehicleContainer(), gearboxData);
var container = new VehicleContainer();
var gearbox = new Gearbox(container, gearboxData);
container.Gear = 1;
AssertHelper.Exception<VectoException>(
() => gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), 5000.SI<NewtonMeter>(), 10000.SI<PerSecond>()),
"Failed to interpolate in TransmissionLossMap. angularVelocity: 63800.0000 [1/s], torque: 5000.0000 [Nm]");
var response = gearbox.OutPort()
.Request(0.SI<Second>(), 1.SI<Second>(), 5000.SI<NewtonMeter>(), 10000.SI<PerSecond>());
Assert.AreEqual(response.ResponseType, ResponseType.FailOverload);
}
[TestMethod]
......@@ -89,24 +93,38 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
var port = new MockTnOutPort();
gearbox.InPort().Connect(port);
container.Gear = 1;
var ratio = 6.38;
//todo: serach for a overload point in gearbox fullloadcurve
//todo: serach for a overload point in engine fullloadcurve
var expected = new[] {
new { t = 2129, n = 1600, loss = 55.0 }, //todo: calc exact loss
new { t = 2250, n = 1200, loss = 55.0 }, //todo: calc exact loss
new { t = 2500, n = 900 },
new { t = 2500, n = 1700 },
new { t = 2129, n = 1600 }, // to high for gearbox, but ok for engine
};
foreach (var exp in expected) {
var torque = (exp.t.SI<NewtonMeter>() - exp.loss.SI<NewtonMeter>()) * ratio;
var torque = exp.t.SI<NewtonMeter>() * ratio;
var angularVelocity = exp.n.RPMtoRad() / ratio;
var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity);
Assert.IsInstanceOfType(response, typeof(ResponseFailOverload));
}
Assert.Inconclusive("Test if the intersection of two fullloadcurves is correct");
var expectedCorrect = new[] {
new { t = 500, n = 700 },
new { t = 1500, n = 1100 },
new { t = 2000, n = 1500 },
new { t = 2240, n = 1200 } // ok for gearbox but would be to high for engine
};
foreach (var exp in expectedCorrect) {
var torque = exp.t.SI<NewtonMeter>() * ratio;
var angularVelocity = exp.n.RPMtoRad() / ratio;
var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity);
Assert.IsInstanceOfType(response, typeof(ResponseSuccess));
}
}
[TestMethod]
......@@ -123,33 +141,29 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
// the first element 0.0 is just a placeholder for axlegear, not used in this test
var expected = new[] {
new { gear = 1, t = 50, n = 800, loss = 10.108 },
new { gear = 1, t = 2450, n = 800, loss = 58.11 },
new { gear = 1, t = -1000, n = 800, loss = 29.11 },
new { gear = 1, t = 850, n = 800, loss = 26.11 },
new { gear = 1, t = 850, n = 0, loss = 22.06 },
new { gear = 1, t = 850, n = 200, loss = 23.07 },
new { gear = 1, t = 850, n = 2000, loss = 32.18 },
new { gear = 2, t = 50, n = 800, loss = 10.108 },
new { gear = 2, t = 2450, n = 800, loss = 58.11 },
new { gear = 2, t = -1000, n = 800, loss = 29.11 },
new { gear = 2, t = 850, n = 800, loss = 26.11 },
new { gear = 2, t = 850, n = 0, loss = 22.06 },
new { gear = 2, t = 850, n = 200, loss = 23.07 },
new { gear = 2, t = 850, n = 2000, loss = 32.18 },
new { gear = 7, t = -1000, n = 0, loss = 10.06 },
new { gear = 7, t = -1000, n = 1200, loss = 16.132 },
new { gear = 7, t = -1000, n = 2000, loss = 20.18 },
new { gear = 7, t = 850, n = 0, loss = 9.31 },
new { gear = 7, t = 850, n = 1200, loss = 15.382 },
new { gear = 7, t = 850, n = 2000, loss = 19.43 },
new { gear = 7, t = 2450, n = 0, loss = 17.31 },
new { gear = 7, t = 2450, n = 1200, loss = 23.382 },
new { gear = 7, t = 2450, n = 2000, loss = 27.43 },
new { gear = 1, t = 50, n = 800, loss = 10.108, responseType = ResponseType.Success },
new { gear = 1, t = 2450, n = 800, loss = 58.11, responseType = ResponseType.FailOverload },
new { gear = 1, t = -1000, n = 800, loss = 29.11, responseType = ResponseType.Success },
new { gear = 1, t = 850, n = 800, loss = 26.11, responseType = ResponseType.Success },
new { gear = 1, t = 850, n = 0, loss = 22.06, responseType = ResponseType.Success },
new { gear = 1, t = 850, n = 200, loss = 23.07, responseType = ResponseType.FailOverload },
new { gear = 2, t = 50, n = 800, loss = 10.108, responseType = ResponseType.Success },
new { gear = 2, t = 2450, n = 800, loss = 58.11, responseType = ResponseType.GearShift },
new { gear = 2, t = -1000, n = 800, loss = 29.11, responseType = ResponseType.Success },
new { gear = 2, t = 850, n = 800, loss = 26.11, responseType = ResponseType.Success },
new { gear = 2, t = 850, n = 0, loss = 22.06, responseType = ResponseType.Success },
new { gear = 2, t = 850, n = 200, loss = 23.07, responseType = ResponseType.GearShift },
new { gear = 2, t = 850, n = 2000, loss = 32.18, responseType = ResponseType.GearShift },
new { gear = 7, t = -1000, n = 0, loss = 10.06, responseType = ResponseType.Success },
new { gear = 7, t = -1000, n = 1200, loss = 16.132, responseType = ResponseType.Success },
new { gear = 7, t = 850, n = 0, loss = 9.31, responseType = ResponseType.Success },
new { gear = 7, t = 850, n = 1200, loss = 15.382, responseType = ResponseType.Success },
new { gear = 7, t = 850, n = 2000, loss = 19.43, responseType = ResponseType.GearShift },
new { gear = 7, t = 2450, n = 0, loss = 17.31, responseType = ResponseType.Success },
new { gear = 7, t = 2450, n = 1200, loss = 23.382, responseType = ResponseType.FailOverload }
};
for (var i = 0; i < expected.Length; i++) {
var exp = expected[i];
foreach (var exp in expected) {
var expectedT = exp.t.SI<NewtonMeter>();
var expectedN = exp.n.RPMtoRad();
var expectedLoss = exp.loss.SI<NewtonMeter>();
......@@ -157,31 +171,122 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
var torque = (expectedT - expectedLoss) * ratios[exp.gear];
var angularVelocity = expectedN / ratios[exp.gear];
gearbox.Gear = (uint)exp.gear;
gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity);
AssertHelper.AreRelativeEqual(0.SI<Second>(), port.AbsTime, message: i.ToString());
AssertHelper.AreRelativeEqual(1.SI<Second>(), port.Dt, message: i.ToString());
AssertHelper.AreRelativeEqual(expectedN, port.AngularVelocity, message: i.ToString());
AssertHelper.AreRelativeEqual(expectedT, port.Torque, message: i.ToString());
container.Gear = (uint)exp.gear;
var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity);
Assert.AreEqual(exp.responseType, response.ResponseType, exp.ToString());
if (angularVelocity.IsEqual(0)) {
expectedT = 0.SI<NewtonMeter>();
}
if (exp.responseType == ResponseType.Success) {
AssertHelper.AreRelativeEqual(0.SI<Second>(), port.AbsTime, message: exp.ToString());
AssertHelper.AreRelativeEqual(1.SI<Second>(), port.Dt, message: exp.ToString());
AssertHelper.AreRelativeEqual(expectedN, port.AngularVelocity, message: exp.ToString());
AssertHelper.AreRelativeEqual(expectedT, port.Torque, message: exp.ToString());
}
}
}
[TestMethod]
public void Gearbox_ShiftUp()
public void Gearbox_ShiftDown()
{
Assert.Inconclusive();
var container = new VehicleContainer();
var gearboxData = DeclarationModeSimulationDataReader.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile);
var gearbox = new Gearbox(container, gearboxData);
var port = new MockTnOutPort();
gearbox.InPort().Connect(port);
var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
// the first element 0.0 is just a placeholder for axlegear, not used in this test
var expected = new[] {
new { gear = 8, newGear = 7, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 7, newGear = 6, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 6, newGear = 5, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 5, newGear = 4, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 4, newGear = 3, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 3, newGear = 2, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 2, newGear = 1, t = 1500, n = 700, responseType = ResponseType.GearShift },
new { gear = 1, newGear = 1, t = 1200, n = 700, responseType = ResponseType.Success },
new { gear = 8, newGear = 1, t = 10000, n = 120, responseType = ResponseType.GearShift }, // skip gears
};
foreach (var exp in expected) {
var expectedT = exp.t.SI<NewtonMeter>();
var expectedN = exp.n.RPMtoRad();
var torque = expectedT * ratios[exp.gear];
var angularVelocity = expectedN / ratios[exp.gear];
container.Gear = (uint)exp.gear;
var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity);
Assert.AreEqual(response.ResponseType, exp.responseType, exp.ToString());
Assert.AreEqual((uint)exp.newGear, container.Gear, exp.ToString());
}
}
[TestMethod]
public void Gearbox_ShiftDown()
public void Gearbox_ShiftUp()
{
Assert.Inconclusive();
var container = new VehicleContainer();
var gearboxData = DeclarationModeSimulationDataReader.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile);
var gearbox = new Gearbox(container, gearboxData);
var port = new MockTnOutPort();
gearbox.InPort().Connect(port);
var ratios = new[] { 0.0, 6.38, 4.63, 3.44, 2.59, 1.86, 1.35, 1, 0.76 };
// the first element 0.0 is just a placeholder for axlegear, not used in this test
var expected = new[] {
new { gear = 7, newGear = 8, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 6, newGear = 7, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 5, newGear = 6, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 4, newGear = 5, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 3, newGear = 4, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 2, newGear = 3, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 1, newGear = 2, t = 1000, n = 1400, responseType = ResponseType.GearShift },
new { gear = 8, newGear = 8, t = 1000, n = 1400, responseType = ResponseType.Success },
new { gear = 1, newGear = 8, t = 200, n = 9000, responseType = ResponseType.GearShift }, // skip gears
};
foreach (var exp in expected) {
var expectedT = exp.t.SI<NewtonMeter>();
var expectedN = exp.n.RPMtoRad();
var torque = expectedT * ratios[exp.gear];
var angularVelocity = expectedN / ratios[exp.gear];
container.Gear = (uint)exp.gear;
var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity);
Assert.AreEqual(response.ResponseType, exp.responseType, exp.ToString());
Assert.AreEqual((uint)exp.newGear, container.Gear, exp.ToString());
}
}
[TestMethod]
public void Gearbox_Overload()
public void Gearbox_NoGear()
{
var container = new VehicleContainer();
var gearboxData = DeclarationModeSimulationDataReader.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile);
var gearbox = new Gearbox(container, gearboxData);
var port = new MockTnOutPort();
gearbox.InPort().Connect(port);
container.Gear = 0;
var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), 500.SI<NewtonMeter>(), 1000.SI<PerSecond>());
Assert.AreEqual(response.ResponseType, ResponseType.Success);
AssertHelper.AreRelativeEqual(0.SI<Second>(), port.AbsTime);
AssertHelper.AreRelativeEqual(1.SI<Second>(), port.Dt);
AssertHelper.AreRelativeEqual(0.SI<PerSecond>(), port.AngularVelocity);
AssertHelper.AreRelativeEqual(0.SI<NewtonMeter>(), port.Torque);
Assert.Inconclusive();
}
}
......
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