diff --git a/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs b/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs index bd7a4507c16afe73db701c8faa849ba3b511cae6..008f598063955e566d6653b089db081507a4567b 100644 --- a/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs +++ b/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; +using System.Diagnostics; using System.Linq; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Utils; @@ -99,6 +100,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox public const string AngularSpeedDown = "downshift rpm"; } + [DebuggerDisplay("{Torque}, {AngularSpeed}")] public class ShiftPolygonEntry { /// <summary> diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 8e1bb6ac27ad01ff5fa3dadafbffdd7143778f83..3839fa9a41da59be5d9e1c0142767ebcd5c96801 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -1,10 +1,8 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Utils; @@ -26,7 +24,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <summary> /// Time when a gearbox shift is finished. Is set when shifting is needed. /// </summary> - private Second _shiftTime = double.PositiveInfinity.SI<Second>(); + private Second _shiftTime = double.NegativeInfinity.SI<Second>(); /// <summary> /// The power loss for the mod data. @@ -68,6 +66,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort + /// <summary> + /// Requests the specified abs time. + /// </summary> + /// <param name="absTime">The abs time.</param> + /// <param name="dt">The dt.</param> + /// <param name="outTorque">The out torque.</param> + /// <param name="outEngineSpeed">The out engine speed.</param> + /// <param name="dryRun">if set to <c>true</c> [dry run].</param> + /// <returns> + /// Special Cases: + /// * ResponseDryRun + /// * ResponseOverload + /// * ResponseGearshift + /// </returns> public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed, bool dryRun) { // TODO: @@ -78,17 +90,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (Gear == 0) { // if no gear is set and dry run: just set GearBoxPowerRequest if (dryRun) { - return new ResponseDryRun { GearboxPowerRequest = outTorque * outEngineSpeed }; + return new ResponseDryRun { GearboxPowerRequest = outTorque * outEngineSpeed, Source = this }; } - if (!outTorque.IsEqual(0)) { - // if clutch is open the gearbox can't provide a torque - return new ResponseOverload { - Delta = outTorque * outEngineSpeed, - Source = this, - GearboxPowerRequest = outTorque * outEngineSpeed - }; - } // if shiftTime still not reached (only happens during shifting): apply zero-request if (_shiftTime > absTime) { var duringShiftResponse = Next.Request(absTime, dt, 0.SI<NewtonMeter>(), 0.SI<PerSecond>()); @@ -99,6 +103,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // if shiftTime was reached and gear is not set: set correct gear if (_shiftTime <= absTime) { Gear = FindGear(outTorque, outEngineSpeed); + } else { + // if clutch is open the gearbox can't provide a torque + if (!outTorque.IsEqual(0)) { + return new ResponseOverload { + Delta = outTorque * outEngineSpeed, + Source = this, + GearboxPowerRequest = outTorque * outEngineSpeed + }; + } } } @@ -121,7 +134,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Log.Debug("Gearbox is shifting. absTime: {0}, shiftTime: {1}, outTorque:{2}, outEngineSpeed: {3}", absTime, _shiftTime, outTorque, outEngineSpeed); - return new ResponseGearShift { SimulationInterval = Data.TractionInterruption }; + return new ResponseGearShift { SimulationInterval = Data.TractionInterruption, Source = this }; } // Normal Response @@ -141,10 +154,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { var gear = (Gear != 0) ? Gear : 1; - var inEngineSpeed = outEngineSpeed * Data.Gears[gear].Ratio; - var inTorque = Data.Gears[gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque); - do { + var inEngineSpeed = outEngineSpeed * Data.Gears[gear].Ratio; + var inTorque = Data.Gears[gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque); if (ShouldShiftUp(gear, inEngineSpeed, inTorque)) { gear++; continue; @@ -211,6 +223,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public IResponse Initialize(NewtonMeter torque, PerSecond engineSpeed) { + _shiftTime = double.NegativeInfinity.SI<Second>(); Gear = FindGear(torque, engineSpeed); return Next.Initialize(torque, engineSpeed); diff --git a/VectoCore/Utils/DelauneyMap.cs b/VectoCore/Utils/DelauneyMap.cs index b471e6136108dcaca11c0ecaa493fe4bee5a1ae9..79878e2b0697e15f164bcb39b67f9e9c5733b9c5 100644 --- a/VectoCore/Utils/DelauneyMap.cs +++ b/VectoCore/Utils/DelauneyMap.cs @@ -68,7 +68,7 @@ namespace TUGraz.VectoCore.Utils Log.Info("Exact search found no fitting triangle. Approximation will be used."); tr = _triangles.Find(triangle => triangle.IsInside(x, y, exact: false)); if (tr == null) { - throw new VectoException(string.Format("Interpolation failed. x: {0}, y: {1}", x, y)); + throw new VectoException("Interpolation failed. x: {0}, y: {1}", x, y); } } diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs index eb5cc3b41b7ad7e0df444e36c86db1a1eeb8c584..c18b4d01f8a9adb7f293f2cecd0899256f23defc 100644 --- a/VectoCore/Utils/SI.cs +++ b/VectoCore/Utils/SI.cs @@ -190,6 +190,7 @@ namespace TUGraz.VectoCore.Utils /// </summary> public class Second : SIBase<Second> { + [DebuggerHidden] static Second() { Register(val => new Second(val)); @@ -344,6 +345,7 @@ namespace TUGraz.VectoCore.Utils [DebuggerDisplay("rad/s: {this} | rpm: {ConvertTo().Rounds.Per.Minute}")] public class PerSecond : SIBase<PerSecond> { + [DebuggerHidden] static PerSecond() { Register(val => new PerSecond(val)); @@ -444,6 +446,7 @@ namespace TUGraz.VectoCore.Utils /// </summary> public class NewtonMeter : SIBase<NewtonMeter> { + [DebuggerHidden] static NewtonMeter() { Register(val => new NewtonMeter(val)); diff --git a/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs index 3d6a844022f582d2ff21b66f33c0a197c1983d12..35fe1c8548f32527af15e756dadaab97989be2f5 100644 --- a/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs +++ b/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs @@ -95,7 +95,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns Assert.IsInstanceOfType(response, typeof(ResponseCycleFinished)); } - [TestMethod] + [TestMethod, Ignore] public void Test_FullPowertrain() { var modalWriter = new ModalDataWriter("Coach_FullPowertrain.vmod"); @@ -274,7 +274,8 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns ShiftPolygon = ShiftPolygon.ReadFromFile(GearboxShiftPolygonFile) })) .ToDictionary(k => k.Item1 + 1, v => v.Item2), - ShiftTime = 2.SI<Second>() + ShiftTime = 2.SI<Second>(), + TractionInterruption = 1.SI<Second>(), }; } diff --git a/VectoCoreTest/Models/SimulationComponent/DriverTest.cs b/VectoCoreTest/Models/SimulationComponent/DriverTest.cs index c3df444d8ce178a4be58b27dcfd7db1d3c0a75ed..049805ccae4b2f61d9034eb91d64b5b1983f85fe 100644 --- a/VectoCoreTest/Models/SimulationComponent/DriverTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/DriverTest.cs @@ -152,12 +152,15 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicleData = CreateVehicleData(33000.SI<Kilogram>()); + var driverData = CreateDriverData(); var modalWriter = new ModalDataWriter("Coach_MinimalPowertrain.vmod", SimulatorFactory.FactoryMode.EngineeringMode); var sumWriter = new TestSumWriter(); var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var cycle = new MockDrivingCycle(vehicleContainer, null); + var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); dynamic tmp = AddComponent(driver, new Vehicle(vehicleContainer, vehicleData)); diff --git a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs index cb429490c1c039112c8efaced6c5b971ebf31ae7..8b23b0c6917cd2ef52faf5cd04572d10172a3d9e 100644 --- a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -86,7 +86,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var t = 2600.SI<NewtonMeter>(); var n = 1600.RPMtoRad(); var response = gearbox.OutPort().Request(absTime, dt, t * ratio, n / ratio); - Assert.IsInstanceOfType(response, typeof(ResponseOverload)); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); absTime += dt; t = -1300.SI<NewtonMeter>(); @@ -125,7 +125,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var angularVelocity = exp.n.RPMtoRad() / ratio; var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), torque, angularVelocity); - Assert.IsInstanceOfType(response, typeof(ResponseOverload)); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); } var expectedCorrect = new[] { @@ -159,11 +159,11 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var expected = new[] { new { gear = 1, t = 50, n = 800, loss = 10.108, responseType = typeof(ResponseSuccess) }, - new { gear = 1, t = 2450, n = 800, loss = 58.11, responseType = typeof(ResponseOverload) }, + new { gear = 1, t = 2450, n = 800, loss = 58.11, responseType = typeof(ResponseSuccess) }, new { gear = 1, t = -1000, n = 800, loss = 29.11, responseType = typeof(ResponseSuccess) }, new { gear = 1, t = 850, n = 800, loss = 26.11, responseType = typeof(ResponseSuccess) }, new { gear = 1, t = 850, n = 0, loss = 22.06, responseType = typeof(ResponseSuccess) }, - new { gear = 1, t = 850, n = 200, loss = 23.07, responseType = typeof(ResponseOverload) }, + new { gear = 1, t = 850, n = 200, loss = 23.07, responseType = typeof(ResponseSuccess) }, new { gear = 2, t = 50, n = 800, loss = 10.108, responseType = typeof(ResponseSuccess) }, new { gear = 2, t = 2450, n = 800, loss = 58.11, responseType = typeof(ResponseGearShift) }, new { gear = 2, t = -1000, n = 800, loss = 29.11, responseType = typeof(ResponseSuccess) }, @@ -177,13 +177,16 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent new { gear = 7, t = 850, n = 1200, loss = 15.382, responseType = typeof(ResponseSuccess) }, new { gear = 7, t = 850, n = 2000, loss = 19.43, responseType = typeof(ResponseGearShift) }, new { gear = 7, t = 2450, n = 0, loss = 17.31, responseType = typeof(ResponseGearShift) }, - new { gear = 7, t = 2450, n = 1200, loss = 23.382, responseType = typeof(ResponseOverload) } + new { gear = 7, t = 2450, n = 1200, loss = 23.382, responseType = typeof(ResponseSuccess) } }; var absTime = 0.SI<Second>(); var dt = 2.SI<Second>(); foreach (var exp in expected) { + gearbox.OutPort().Initialize(0.SI<NewtonMeter>(), 0.SI<PerSecond>()); + + var expectedT = exp.t.SI<NewtonMeter>(); var expectedN = exp.n.RPMtoRad(); var expectedLoss = exp.loss.SI<NewtonMeter>(); @@ -201,7 +204,6 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent AssertHelper.AreRelativeEqual(expectedN, port.AngularVelocity, message: exp.ToString()); AssertHelper.AreRelativeEqual(expectedT, port.Torque, message: exp.ToString()); } - absTime += dt; } } @@ -220,13 +222,13 @@ 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 = 8, newGear = 7, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, - new { gear = 7, newGear = 6, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, - new { gear = 6, newGear = 5, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, - new { gear = 5, newGear = 4, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, - new { gear = 4, newGear = 3, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, - new { gear = 3, newGear = 2, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, - new { gear = 2, newGear = 1, t = 1500, n = 700, responseType = typeof(ResponseGearShift) }, + new { gear = 8, newGear = 7, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, + new { gear = 7, newGear = 6, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, + new { gear = 6, newGear = 5, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, + new { gear = 5, newGear = 4, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, + new { gear = 4, newGear = 3, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, + new { gear = 3, newGear = 2, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, + new { gear = 2, newGear = 1, t = 1500, n = 750, responseType = typeof(ResponseGearShift) }, new { gear = 1, newGear = 1, t = 1200, n = 700, responseType = typeof(ResponseSuccess) }, new { gear = 8, newGear = 1, t = 10000, n = 120, responseType = typeof(ResponseGearShift) } }; @@ -234,6 +236,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var absTime = 0.SI<Second>(); var dt = 2.SI<Second>(); + gearbox.OutPort().Initialize(0.SI<NewtonMeter>(), 0.SI<PerSecond>()); + foreach (var exp in expected) { var expectedT = exp.t.SI<NewtonMeter>(); var expectedN = exp.n.RPMtoRad(); @@ -244,6 +248,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent container.Gear = (uint)exp.gear; var response = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); Assert.IsInstanceOfType(response, exp.responseType, exp.ToString()); + + absTime += dt; + response = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess), exp.ToString()); Assert.AreEqual((uint)exp.newGear, container.Gear, exp.ToString()); absTime += dt; } @@ -277,6 +285,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var absTime = 0.SI<Second>(); var dt = 2.SI<Second>(); + gearbox.OutPort().Initialize(0.SI<NewtonMeter>(), 0.SI<PerSecond>()); + foreach (var exp in expected) { var expectedT = exp.t.SI<NewtonMeter>(); var expectedN = exp.n.RPMtoRad(); @@ -287,6 +297,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent container.Gear = (uint)exp.gear; var response = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); Assert.IsInstanceOfType(response, exp.responseType, exp.ToString()); + + absTime += dt; + response = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); + Assert.IsInstanceOfType(response, typeof(ResponseSuccess), exp.ToString()); Assert.AreEqual((uint)exp.newGear, container.Gear, exp.ToString()); absTime += dt; } @@ -302,9 +316,16 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var port = new MockTnOutPort(); gearbox.InPort().Connect(port); - container.Gear = 0; - var response = gearbox.OutPort() - .Request(0.SI<Second>(), 1.SI<Second>(), 50000000.SI<NewtonMeter>(), 1000000.SI<PerSecond>()); + gearbox.Initialize(0.SI<NewtonMeter>(), 0.SI<PerSecond>()); + + var response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), 50.SI<NewtonMeter>(), 10000.SI<PerSecond>()); + Assert.IsInstanceOfType(response, typeof(ResponseGearShift)); + Assert.IsNull(port.AbsTime); + Assert.IsNull(port.Dt); + Assert.IsNull(port.AngularVelocity); + Assert.IsNull(port.Torque); + + response = gearbox.OutPort().Request(0.SI<Second>(), 1.SI<Second>(), 500.SI<NewtonMeter>(), 10000.SI<PerSecond>()); Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); AssertHelper.AreRelativeEqual(0.SI<Second>(), port.AbsTime); diff --git a/VectoCoreTest/Utils/MockPorts.cs b/VectoCoreTest/Utils/MockPorts.cs index 0467404d896de71f686d4461c39f55c7890e4395..67ee79231f1a776c0b16734a0fd3b745f6a91416 100644 --- a/VectoCoreTest/Utils/MockPorts.cs +++ b/VectoCoreTest/Utils/MockPorts.cs @@ -28,7 +28,7 @@ namespace TUGraz.VectoCore.Tests.Utils public IResponse Initialize(NewtonMeter torque, PerSecond angularVelocity) { - throw new NotImplementedException(); + return new ResponseSuccess(); } }