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

Skip to content
Snippets Groups Projects
Commit 5e0f94ae authored by Markus QUARITSCH's avatar Markus QUARITSCH
Browse files

removed inverted lossmap in transmission loss map class (forward calculation)...

removed inverted lossmap in transmission loss map class (forward calculation) as the triangulation may cause errors due to limited numerical accuracy (even with double precision)
parent 881f3509
No related branches found
No related tags found
No related merge requests found
......@@ -209,39 +209,43 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
return null;
}
private static ValidationResult CheckLossMapsEntries(KeyValuePair<uint, GearData> gear, PerSecond angularVelocity,
private static ValidationResult CheckLossMapsEntries(KeyValuePair<uint, GearData> gear, PerSecond engineSpeed,
NewtonMeter inTorque, AngledriveData angledriveData, AxleGearData axleGearData, MeterPerSecond velocity)
{
var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null;
var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive
? angledriveData.Angledrive.Ratio
: 1.0;
NewtonMeter angledriveTorque;
try {
angledriveTorque = gear.Value.LossMap.GetOutTorque(angularVelocity, inTorque);
} catch (VectoException) {
var tqLoss = gear.Value.LossMap.GetTorqueLoss(engineSpeed / gear.Value.Ratio, inTorque * gear.Value.Ratio);
if (tqLoss.Extrapolated) {
return new ValidationResult(
string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key,
inTorque, angularVelocity.ConvertToRoundsPerMinute()));
inTorque, engineSpeed.ConvertToRoundsPerMinute()));
}
var angledriveTorque = (inTorque - tqLoss.Value) / gear.Value.Ratio;
var axlegearTorque = angledriveTorque;
try {
if (hasAngleDrive) {
axlegearTorque = angledriveData.Angledrive.LossMap.GetOutTorque(angularVelocity / gear.Value.Ratio,
angledriveTorque);
if (hasAngleDrive) {
var anglTqLoss = angledriveData.Angledrive.LossMap.GetTorqueLoss(
engineSpeed / gear.Value.Ratio / angledriveRatio,
angledriveTorque * angledriveRatio);
if (anglTqLoss.Extrapolated) {
return new ValidationResult(
string.Format(
"Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}",
angledriveTorque, (engineSpeed / gear.Value.Ratio).ConvertToRoundsPerMinute()));
}
} catch (VectoException) {
return new ValidationResult(
string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}",
angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertToRoundsPerMinute()));
}
if (axleGearData != null) {
var axleAngularVelocity = angularVelocity / gear.Value.Ratio / angledriveRatio;
try {
axleGearData.AxleGear.LossMap.GetOutTorque(axleAngularVelocity, axlegearTorque);
} catch (VectoException) {
return
var axleAngularVelocity = engineSpeed / gear.Value.Ratio / angledriveRatio / axleGearData.AxleGear.Ratio;
var axlTqLoss = axleGearData.AxleGear.LossMap.GetTorqueLoss(axleAngularVelocity, axlegearTorque * axleGearData.AxleGear.Ratio);
if (axlTqLoss.Extrapolated) {
return
new ValidationResult(
string.Format(
"Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})",
......
......@@ -51,11 +51,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
/// </summary>
private readonly DelaunayMap _lossMap;
/// <summary>
/// The inverted loss map for range sanity checks. [X=Input EngineSpeed, Y=Input Torque] => Z=Output Torque
/// </summary>
private readonly DelaunayMap _invertedLossMap;
public string GearName { get; private set; }
public TransmissionLossMap(IReadOnlyList<GearLossMapEntry> entries, double gearRatio, string gearName)
......@@ -64,14 +59,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
_ratio = gearRatio;
_entries = entries;
_lossMap = new DelaunayMap("TransmissionLossMap " + GearName);
_invertedLossMap = new DelaunayMap("TransmissionLossMapInv. " + GearName);
foreach (var entry in _entries) {
_lossMap.AddPoint(entry.InputSpeed.Value(), (entry.InputTorque - entry.TorqueLoss).Value(), entry.TorqueLoss.Value());
_invertedLossMap.AddPoint(entry.InputSpeed.Value(), entry.InputTorque.Value(), entry.TorqueLoss.Value());
}
_lossMap.Triangulate();
_invertedLossMap.Triangulate();
}
/// <summary>
......@@ -104,30 +96,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
public NewtonMeter Value;
}
/// <summary>
/// Computes the OUTPUT torque given by the input engineSpeed and the input torque.
/// </summary>
/// <param name="inAngularVelocity">Angular speed at input side.</param>
/// <param name="inTorque">Torque at input side.</param>
/// <param name="allowExtrapolation"></param>
/// <returns>Torque needed at output side (towards the wheels).</returns>
public NewtonMeter GetOutTorque(PerSecond inAngularVelocity, NewtonMeter inTorque, bool allowExtrapolation = false)
{
var torqueLoss = _invertedLossMap.Interpolate(inAngularVelocity.Value(), inTorque.Value());
if (torqueLoss.HasValue) {
return (inTorque - torqueLoss.Value.SI<NewtonMeter>()) / _ratio;
}
if (allowExtrapolation) {
torqueLoss = _invertedLossMap.Extrapolate(inAngularVelocity.Value(), inTorque.Value());
return (inTorque - torqueLoss.Value.SI<NewtonMeter>()) / _ratio;
}
throw new VectoException("TransmissionLossMap {0}: Interpolation failed. inTorque: {1}, inAngularVelocity: {2}",
GearName, inTorque,
inAngularVelocity.AsRPM);
}
public GearLossMapEntry this[int i]
{
get { return _entries[i]; }
......
......@@ -139,7 +139,7 @@ namespace TUGraz.VectoCore.Utils
// k...points on convex hull (exactly 3 --> supertriangle)
if (triangles.Count != 2 * (pointCount + 3) - 2 - 3) {
throw new VectoException(
"Delaunay-Triangulation invariant violated! Triangle count and point count doesn't fit together.");
"{0} Delaunay-Triangulation invariant violated! Triangle count and point count doesn't fit together.", _mapName);
}
}
......
......@@ -167,49 +167,49 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
AssertHelper.AreRelativeEqual(10, map.GetTorqueLoss(120.RPMtoRad(), 50.SI<NewtonMeter>()).Value);
}
[TestCase]
public void TestLossMap_OUT_10_CONST_Interpolation_Extrapolation()
{
var data = new DataTable();
data.Columns.Add("");
data.Columns.Add("");
data.Columns.Add("");
data.Rows.Add("0", "0", "10"); // (0,100):10 -- (100,100):10
data.Rows.Add("0", "100", "10"); // | \ |
data.Rows.Add("100", "0", "10"); // | \ |
data.Rows.Add("100", "100", "10"); // (0,0):10 ----- (100,10):10
var map = TransmissionLossMapReader.Create(data, 1.0, "1");
// test inside the triangles
AssertHelper.AreRelativeEqual(15, map.GetOutTorque(25.RPMtoRad(), 25.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(40, map.GetOutTorque(75.RPMtoRad(), 50.SI<NewtonMeter>(), true));
// test interpolation on edges
AssertHelper.AreRelativeEqual(-15, map.GetOutTorque(50.RPMtoRad(), -5.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(35, map.GetOutTorque(0.RPMtoRad(), 45.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(30, map.GetOutTorque(50.RPMtoRad(), 40.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(65, map.GetOutTorque(50.RPMtoRad(), 75.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(15, map.GetOutTorque(100.RPMtoRad(), 25.SI<NewtonMeter>(), true));
// test interpolation on corner points
AssertHelper.AreRelativeEqual(-10, map.GetOutTorque(0.RPMtoRad(), 0.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(80, map.GetOutTorque(0.RPMtoRad(), 90.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(-20, map.GetOutTorque(100.RPMtoRad(), -10.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(50, map.GetOutTorque(100.RPMtoRad(), 60.SI<NewtonMeter>(), true));
// test outside the corners
AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(-20.RPMtoRad(), -20.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(110, map.GetOutTorque(-20.RPMtoRad(), 120.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(120.RPMtoRad(), -20.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(110, map.GetOutTorque(120.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// test outside the edges
AssertHelper.AreRelativeEqual(40, map.GetOutTorque(-20.RPMtoRad(), 50.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(110, map.GetOutTorque(50.RPMtoRad(), 120.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(50.RPMtoRad(), -20.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(40, map.GetOutTorque(120.RPMtoRad(), 50.SI<NewtonMeter>(), true));
}
//[TestCase]
//public void TestLossMap_OUT_10_CONST_Interpolation_Extrapolation()
//{
// var data = new DataTable();
// data.Columns.Add("");
// data.Columns.Add("");
// data.Columns.Add("");
// data.Rows.Add("0", "0", "10"); // (0,100):10 -- (100,100):10
// data.Rows.Add("0", "100", "10"); // | \ |
// data.Rows.Add("100", "0", "10"); // | \ |
// data.Rows.Add("100", "100", "10"); // (0,0):10 ----- (100,10):10
// var map = TransmissionLossMapReader.Create(data, 1.0, "1");
// // test inside the triangles
// AssertHelper.AreRelativeEqual(15, map.GetOutTorque(25.RPMtoRad(), 25.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(40, map.GetOutTorque(75.RPMtoRad(), 50.SI<NewtonMeter>(), true));
// // test interpolation on edges
// AssertHelper.AreRelativeEqual(-15, map.GetOutTorque(50.RPMtoRad(), -5.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(35, map.GetOutTorque(0.RPMtoRad(), 45.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(30, map.GetOutTorque(50.RPMtoRad(), 40.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(65, map.GetOutTorque(50.RPMtoRad(), 75.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(15, map.GetOutTorque(100.RPMtoRad(), 25.SI<NewtonMeter>(), true));
// // test interpolation on corner points
// AssertHelper.AreRelativeEqual(-10, map.GetOutTorque(0.RPMtoRad(), 0.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(80, map.GetOutTorque(0.RPMtoRad(), 90.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(-20, map.GetOutTorque(100.RPMtoRad(), -10.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(50, map.GetOutTorque(100.RPMtoRad(), 60.SI<NewtonMeter>(), true));
// // test outside the corners
// AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(-20.RPMtoRad(), -20.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(110, map.GetOutTorque(-20.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(120.RPMtoRad(), -20.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(110, map.GetOutTorque(120.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// // test outside the edges
// AssertHelper.AreRelativeEqual(40, map.GetOutTorque(-20.RPMtoRad(), 50.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(110, map.GetOutTorque(50.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(50.RPMtoRad(), -20.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(40, map.GetOutTorque(120.RPMtoRad(), 50.SI<NewtonMeter>(), true));
//}
[TestCase]
public void TestLossMap_IN_Interpolation_Extrapolation()
......@@ -255,52 +255,52 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
AssertHelper.AreRelativeEqual(25, map.GetTorqueLoss(120.RPMtoRad(), 50.SI<NewtonMeter>()).Value);
}
[TestCase]
public void TestLossMap_OUT_Interpolation_Extrapolation()
{
var data = new DataTable();
data.Columns.Add("");
data.Columns.Add("");
data.Columns.Add("");
data.Rows.Add("0", "0", "0"); // (0,100):10 -- (100,100):40
data.Rows.Add("0", "100", "10"); // | \ |
data.Rows.Add("100", "0", "10"); // | \ |
data.Rows.Add("100", "100", "40"); // (0,0):0 ----- (100,0):10
var map = TransmissionLossMapReader.Create(data, 1.0, "1");
// test inside the triangles
AssertHelper.AreRelativeEqual(20, map.GetOutTorque(25.RPMtoRad(), 25.SI<NewtonMeter>()));
AssertHelper.AreRelativeEqual(32.5, map.GetOutTorque(75.RPMtoRad(), 50.SI<NewtonMeter>()));
// test interpolation on edges
AssertHelper.AreRelativeEqual(-5, map.GetOutTorque(50.RPMtoRad(), 0.SI<NewtonMeter>()));
AssertHelper.AreRelativeEqual(40.5, map.GetOutTorque(0.RPMtoRad(), 45.SI<NewtonMeter>()));
AssertHelper.AreRelativeEqual(31, map.GetOutTorque(50.RPMtoRad(), 40.SI<NewtonMeter>()));
AssertHelper.AreRelativeEqual(57.5, map.GetOutTorque(50.RPMtoRad(), 75.SI<NewtonMeter>()));
AssertHelper.AreRelativeEqual(7.5, map.GetOutTorque(100.RPMtoRad(), 25.SI<NewtonMeter>()));
// test interpolation on corner points
AssertHelper.AreRelativeEqual(0, map.GetTorqueLoss(0.RPMtoRad(), 0.SI<NewtonMeter>()).Value);
AssertHelper.AreRelativeEqual(10, map.GetTorqueLoss(0.RPMtoRad(), 90.SI<NewtonMeter>()).Value);
AssertHelper.AreRelativeEqual(10, map.GetTorqueLoss(100.RPMtoRad(), -10.SI<NewtonMeter>()).Value);
AssertHelper.AreRelativeEqual(40, map.GetTorqueLoss(100.RPMtoRad(), 60.SI<NewtonMeter>()).Value);
// test outside the corners
AssertHelper.AreRelativeEqual(-20, map.GetOutTorque(-20.RPMtoRad(), -20.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(110, map.GetOutTorque(-20.RPMtoRad(), 120.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(120.RPMtoRad(), -20.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(80, map.GetOutTorque(120.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// test outside the edges
AssertHelper.AreRelativeEqual(45, map.GetOutTorque(-20.RPMtoRad(), 50.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(95, map.GetOutTorque(50.RPMtoRad(), 120.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(-25, map.GetOutTorque(50.RPMtoRad(), -20.SI<NewtonMeter>(), true));
AssertHelper.AreRelativeEqual(25, map.GetOutTorque(120.RPMtoRad(), 50.SI<NewtonMeter>(), true));
// test extrapolation not allowed
AssertHelper.Exception<VectoException>(() => { map.GetOutTorque(120.RPMtoRad(), 50.SI<NewtonMeter>()); });
}
//[TestCase]
//public void TestLossMap_OUT_Interpolation_Extrapolation()
//{
// var data = new DataTable();
// data.Columns.Add("");
// data.Columns.Add("");
// data.Columns.Add("");
// data.Rows.Add("0", "0", "0"); // (0,100):10 -- (100,100):40
// data.Rows.Add("0", "100", "10"); // | \ |
// data.Rows.Add("100", "0", "10"); // | \ |
// data.Rows.Add("100", "100", "40"); // (0,0):0 ----- (100,0):10
// var map = TransmissionLossMapReader.Create(data, 1.0, "1");
// // test inside the triangles
// AssertHelper.AreRelativeEqual(20, map.GetOutTorque(25.RPMtoRad(), 25.SI<NewtonMeter>()));
// AssertHelper.AreRelativeEqual(32.5, map.GetOutTorque(75.RPMtoRad(), 50.SI<NewtonMeter>()));
// // test interpolation on edges
// AssertHelper.AreRelativeEqual(-5, map.GetOutTorque(50.RPMtoRad(), 0.SI<NewtonMeter>()));
// AssertHelper.AreRelativeEqual(40.5, map.GetOutTorque(0.RPMtoRad(), 45.SI<NewtonMeter>()));
// AssertHelper.AreRelativeEqual(31, map.GetOutTorque(50.RPMtoRad(), 40.SI<NewtonMeter>()));
// AssertHelper.AreRelativeEqual(57.5, map.GetOutTorque(50.RPMtoRad(), 75.SI<NewtonMeter>()));
// AssertHelper.AreRelativeEqual(7.5, map.GetOutTorque(100.RPMtoRad(), 25.SI<NewtonMeter>()));
// // test interpolation on corner points
// AssertHelper.AreRelativeEqual(0, map.GetTorqueLoss(0.RPMtoRad(), 0.SI<NewtonMeter>()).Value);
// AssertHelper.AreRelativeEqual(10, map.GetTorqueLoss(0.RPMtoRad(), 90.SI<NewtonMeter>()).Value);
// AssertHelper.AreRelativeEqual(10, map.GetTorqueLoss(100.RPMtoRad(), -10.SI<NewtonMeter>()).Value);
// AssertHelper.AreRelativeEqual(40, map.GetTorqueLoss(100.RPMtoRad(), 60.SI<NewtonMeter>()).Value);
// // test outside the corners
// AssertHelper.AreRelativeEqual(-20, map.GetOutTorque(-20.RPMtoRad(), -20.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(110, map.GetOutTorque(-20.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(-30, map.GetOutTorque(120.RPMtoRad(), -20.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(80, map.GetOutTorque(120.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// // test outside the edges
// AssertHelper.AreRelativeEqual(45, map.GetOutTorque(-20.RPMtoRad(), 50.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(95, map.GetOutTorque(50.RPMtoRad(), 120.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(-25, map.GetOutTorque(50.RPMtoRad(), -20.SI<NewtonMeter>(), true));
// AssertHelper.AreRelativeEqual(25, map.GetOutTorque(120.RPMtoRad(), 50.SI<NewtonMeter>(), true));
// // test extrapolation not allowed
// AssertHelper.Exception<VectoException>(() => { map.GetOutTorque(120.RPMtoRad(), 50.SI<NewtonMeter>()); });
//}
[TestCase]
public void TestFullLoadCurveIntersection()
......
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