From 57cf6be75e9e6ac00cec6a267b1b5808073f578c Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Mon, 27 Apr 2015 14:03:32 +0200 Subject: [PATCH] adding test for axlegear module --- .../Data/Gearbox/TransmissionLossMap.cs | 44 ++++--- .../SimulationComponent/Data/GearboxData.cs | 108 +++++++++--------- .../SimulationComponent/Impl/AxleGear.cs | 10 +- .../Models/SimulationComponent/GearboxTest.cs | 58 ++++++++++ .../GearboxDataTest.cs | 48 ++++++++ VectoCoreTest/VectoCoreTest.csproj | 1 + 6 files changed, 189 insertions(+), 80 deletions(-) create mode 100644 VectoCoreTest/Models/SimulationComponent/GearboxTest.cs diff --git a/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs b/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs index c0d1f11fc4..8a5b759a3d 100644 --- a/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs +++ b/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs @@ -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]; } diff --git a/VectoCore/Models/SimulationComponent/Data/GearboxData.cs b/VectoCore/Models/SimulationComponent/Data/GearboxData.cs index 91ffee3d21..b88942c957 100644 --- a/VectoCore/Models/SimulationComponent/Data/GearboxData.cs +++ b/VectoCore/Models/SimulationComponent/Data/GearboxData.cs @@ -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() { diff --git a/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs b/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs index f5cd77fcf4..ce738952ff 100644 --- a/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs +++ b/VectoCore/Models/SimulationComponent/Impl/AxleGear.cs @@ -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 diff --git a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs new file mode 100644 index 0000000000..3a044a8d45 --- /dev/null +++ b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -0,0 +1,58 @@ +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 diff --git a/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs b/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs index 49ab38abe7..f233b20357 100644 --- a/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs +++ b/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs @@ -1,6 +1,7 @@ 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(); diff --git a/VectoCoreTest/VectoCoreTest.csproj b/VectoCoreTest/VectoCoreTest.csproj index 34975ef0a7..96f4691238 100644 --- a/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCoreTest/VectoCoreTest.csproj @@ -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" /> -- GitLab