diff --git a/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/Models/Connector/Ports/Impl/Response.cs index f825c45db986fc5a66182b9a924c45e50e96ebf3..6955c4cd811543eaa3ff3757591698210b968557 100644 --- a/VectoCore/Models/Connector/Ports/Impl/Response.cs +++ b/VectoCore/Models/Connector/Ports/Impl/Response.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using TUGraz.VectoCore.Models.SimulationComponent; using TUGraz.VectoCore.Utils; @@ -24,7 +25,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl public Watt BrakePower { get; set; } - public VectoSimulationComponent Source { get; set; } + public object Source { get; set; } public override string ToString() { diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index b9edeed54d218e6f02ad55f87fa66d7ccb990092..c5807e98a4c9f77b38c65320143658f10fb50925 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -121,9 +121,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// </returns> public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed, bool dryRun) { - var retVal = ClutchClosed(absTime) - ? RequestGearEngaged(absTime, dt, outTorque, outEngineSpeed, dryRun) - : RequestGearDisengaged(absTime, dt, outTorque, outEngineSpeed, dryRun); + IResponse retVal; + if (ClutchClosed(absTime)) { + retVal = RequestGearEngaged(absTime, dt, outTorque, outEngineSpeed, dryRun); + } else { + retVal = RequestGearDisengaged(absTime, dt, outTorque, outEngineSpeed, dryRun); + } return retVal; } @@ -200,28 +203,35 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl bool dryRun) { // Set a Gear if no gear was set - if (_disengaged) { + if (_disengaged && !outEngineSpeed.IsEqual(0)) { _disengaged = false; - Gear = DataBus.VehicleSpeed.IsEqual(0) - ? _strategy.InitGear(absTime, dt, outTorque, outEngineSpeed) // initGear if speed was 0 - : _strategy.Engage(absTime, dt, outTorque, outEngineSpeed); + if (DataBus.VehicleSpeed.IsEqual(0)) { + Gear = _strategy.InitGear(absTime, dt, outTorque, outEngineSpeed); + } else { + Gear = _strategy.Engage(absTime, dt, outTorque, outEngineSpeed); + } Log.Debug("Gearbox engaged gear {0}", Gear); } - var inEngineSpeed = outEngineSpeed * Data.Gears[Gear].Ratio; - var inTorque = Data.Gears[Gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque); + var inEngineSpeed = outEngineSpeed; + var inTorque = outTorque; + + if (!outEngineSpeed.IsEqual(0)) { + inEngineSpeed = outEngineSpeed * Data.Gears[Gear].Ratio; + inTorque = Data.Gears[Gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque); - _powerLoss = inTorque * inEngineSpeed - outTorque * outEngineSpeed; - var torqueLossInertia = !inEngineSpeed.IsEqual(0) - ? Formulas.InertiaPower(inEngineSpeed, _previousInEnginespeed, Data.Inertia, dt) / inEngineSpeed - : 0.SI<NewtonMeter>(); + _powerLoss = inTorque * inEngineSpeed - outTorque * outEngineSpeed; + var torqueLossInertia = !inEngineSpeed.IsEqual(0) + ? Formulas.InertiaPower(inEngineSpeed, _previousInEnginespeed, Data.Inertia, dt) / inEngineSpeed + : 0.SI<NewtonMeter>(); - _previousInEnginespeed = inEngineSpeed; + _previousInEnginespeed = inEngineSpeed; - inTorque += torqueLossInertia; + inTorque += torqueLossInertia; - _powerLossInertia = torqueLossInertia * inEngineSpeed; + _powerLossInertia = torqueLossInertia * inEngineSpeed; + } if (dryRun) { var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed, true); @@ -229,22 +239,25 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return dryRunResponse; } - var isShiftAllowed = (_shiftTime + Data.ShiftTime).IsSmaller(absTime); - if (isShiftAllowed && _strategy.ShiftRequired(Gear, inTorque, inEngineSpeed)) { - _shiftTime = absTime + Data.TractionInterruption; - - Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, shiftTime: {2}, out: ({3}, {4}), in: ({5}, {6})", absTime, dt, - _shiftTime, outTorque, outEngineSpeed, inTorque, inEngineSpeed); - - _disengaged = true; - _strategy.Disengage(absTime, dt, outTorque, outEngineSpeed); - Log.Info("Gearbox disengaged"); - - return new ResponseGearShift { - Source = this, - SimulationInterval = Data.TractionInterruption, - GearboxPowerRequest = outTorque * outEngineSpeed - }; + if (!outEngineSpeed.IsEqual(0)) { + var isShiftAllowed = (_shiftTime + Data.ShiftTime).IsSmaller(absTime); + if (isShiftAllowed && _strategy.ShiftRequired(Gear, inTorque, inEngineSpeed)) { + _shiftTime = absTime + Data.TractionInterruption; + + Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, shiftTime: {2}, out: ({3}, {4}), in: ({5}, {6})", absTime, + dt, + _shiftTime, outTorque, outEngineSpeed, inTorque, inEngineSpeed); + + _disengaged = true; + _strategy.Disengage(absTime, dt, outTorque, outEngineSpeed); + Log.Info("Gearbox disengaged"); + + return new ResponseGearShift { + Source = this, + SimulationInterval = Data.TractionInterruption, + GearboxPowerRequest = outTorque * outEngineSpeed + }; + } } var response = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed); diff --git a/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs index 7239eb8c0850b2beab29ec40d6e665f409e5a198..69fd61542240dd88d9989b0b4046fafbe2049a72 100644 --- a/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs +++ b/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs @@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio; var inTorque = currentPower / inAngularSpeed; - if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && reserve >= torqueReserve) { + if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && reserve >= torqueReserve / 100) { return gear; } } @@ -113,7 +113,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed) { - PreviousGear = GetGear(absTime, dt, outTorque, outEngineSpeed, Data.SkipGears, Data.TorqueReserve); + PreviousGear = Gearbox.Gear; } public override bool ShiftRequired(uint gear, NewtonMeter torque, PerSecond angularSpeed) diff --git a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs index 58923dbb2ddea0be22587394d44728c3f3701b55..425a5e65f3445efd74f265ca095a7b00075c86a2 100644 --- a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -4,7 +4,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using NLog; 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.Data; @@ -278,6 +277,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent gearbox.OutPort().Initialize(0.SI<NewtonMeter>(), 0.SI<PerSecond>()); + var first = gearbox.OutPort().Request(absTime, dt, 1000.SI<NewtonMeter>(), 100.SI<PerSecond>()); + + absTime += dt; + foreach (var exp in expected) { var expectedT = exp.t.SI<NewtonMeter>(); var expectedN = exp.n.RPMtoRad(); @@ -286,12 +289,12 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var angularVelocity = expectedN / ratios[exp.gear]; gearbox.Gear = (uint)exp.gear; - var response = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); - Assert.IsInstanceOfType(response, exp.responseType, exp.ToString()); + var gearShiftResponse = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); + Assert.IsInstanceOfType(gearShiftResponse, exp.responseType, exp.ToString()); absTime += dt; - response = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); - Assert.IsInstanceOfType(response, typeof(ResponseSuccess), exp.ToString()); + var successResponse = gearbox.OutPort().Request(absTime, dt, torque, angularVelocity); + Assert.IsInstanceOfType(successResponse, typeof(ResponseSuccess), exp.ToString()); Assert.AreEqual((uint)exp.newGear, container.Gear, exp.ToString()); absTime += dt; } @@ -325,8 +328,9 @@ 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>()); - + gearbox.OutPort().Initialize(1000.SI<NewtonMeter>(), 100.SI<PerSecond>()); + var first = gearbox.OutPort().Request(absTime, dt, 1000.SI<NewtonMeter>(), 100.SI<PerSecond>()); + absTime += dt; foreach (var exp in expected) { var expectedT = exp.t.SI<NewtonMeter>(); var expectedN = exp.n.RPMtoRad(); @@ -358,23 +362,28 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent 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); + var absTime = 0.SI<Second>(); + var dt = 1.SI<Second>(); - response = gearbox.OutPort().Request(2.SI<Second>(), 1.SI<Second>(), 500.SI<NewtonMeter>(), 10000.SI<PerSecond>()); + var response = gearbox.OutPort().Request(absTime, dt, 50.SI<NewtonMeter>(), 10000.SI<PerSecond>()); Assert.IsInstanceOfType(response, typeof(ResponseSuccess)); - - AssertHelper.AreRelativeEqual(2.SI<Second>(), port.AbsTime); - AssertHelper.AreRelativeEqual(1.SI<Second>(), port.Dt); + AssertHelper.AreRelativeEqual(absTime, port.AbsTime); + AssertHelper.AreRelativeEqual(dt, port.Dt); Assert.IsNotNull(port.AngularVelocity); Assert.IsNotNull(port.Torque); - Assert.IsTrue(port.AngularVelocity.IsGreater(0)); Assert.IsTrue(port.Torque.IsGreater(0)); + + port.DoCommitSimulationStep(); + + absTime += dt; + + response = gearbox.OutPort().Request(absTime, dt, 5000.SI<NewtonMeter>(), 100.SI<PerSecond>()); + Assert.IsInstanceOfType(response, typeof(ResponseGearShift)); + Assert.IsNull(port.AbsTime); + Assert.IsNull(port.Dt); + Assert.IsNull(port.AngularVelocity); + Assert.IsNull(port.Torque); } } } \ No newline at end of file diff --git a/VectoCoreTest/Utils/MockPorts.cs b/VectoCoreTest/Utils/MockPorts.cs index 67ee79231f1a776c0b16734a0fd3b745f6a91416..769dc3d286afc443bce80a473f8b617993cb76d7 100644 --- a/VectoCoreTest/Utils/MockPorts.cs +++ b/VectoCoreTest/Utils/MockPorts.cs @@ -11,10 +11,10 @@ namespace TUGraz.VectoCore.Tests.Utils { protected static readonly Logger Log = LogManager.GetCurrentClassLogger(); - public Second AbsTime { get; set; } - public Second Dt { get; set; } - public NewtonMeter Torque { get; set; } - public PerSecond AngularVelocity { get; set; } + public Second AbsTime; + public Second Dt; + public NewtonMeter Torque; + public PerSecond AngularVelocity; public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity, bool dryRun = false) { @@ -23,23 +23,45 @@ namespace TUGraz.VectoCore.Tests.Utils Torque = torque; AngularVelocity = angularVelocity; Log.Debug("Request: absTime: {0}, dt: {1}, torque: {3}, engineSpeed: {4}", absTime, dt, torque, angularVelocity); - return new ResponseSuccess(); + + if (dryRun) { + return new ResponseDryRun { + Source = this, + GearboxPowerRequest = torque * angularVelocity, + EnginePowerRequest = torque * angularVelocity, + DeltaFullLoad = -100000.SI<Watt>(), + DeltaDragLoad = -500.SI<Watt>() + }; + } + + return new ResponseSuccess { + Source = this, + GearboxPowerRequest = torque * angularVelocity, + EnginePowerRequest = torque * angularVelocity, + }; } public IResponse Initialize(NewtonMeter torque, PerSecond angularVelocity) { return new ResponseSuccess(); } + + public void DoCommitSimulationStep() + { + AbsTime = null; + Dt = null; + Torque = null; + AngularVelocity = null; + } } public class MockDrivingCycleOutPort : LoggingObject, IDrivingCycleOutPort { - public Second AbsTime { get; set; } - public Meter Ds { get; set; } - - public Second Dt { get; set; } - public MeterPerSecond Velocity { get; set; } - public Radian Gradient { get; set; } + public Second AbsTime; + public Meter Ds; + public Second Dt; + public MeterPerSecond Velocity; + public Radian Gradient; public IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient) {