From b941003c8abb34bbb5279453fb3897b74fcb4f23 Mon Sep 17 00:00:00 2001 From: Michael Krisper <michael.krisper@tugraz.at> Date: Wed, 20 Jan 2016 16:16:12 +0100 Subject: [PATCH] changed Gearbox to be derivable into a manual gearbox --- .../Simulation/Impl/PowertrainBuilder.cs | 97 ++++++++++---- .../Simulation/Impl/SimulatorFactory.cs | 3 +- ...ivingCycle.cs => IPowertrainSimulation.cs} | 4 +- .../Impl/EngineOnlyGearbox.cs | 111 ---------------- .../SimulationComponent/Impl/Gearbox.cs | 109 ++++++++-------- .../SimulationComponent/Impl/ManualGearbox.cs | 122 ++++++++++++++++++ .../Impl/PowertrainDrivingCycle.cs | 2 +- VectoCore/VectoCore.csproj | 4 +- .../EngineOnlyCycle/EngineOnlyCycleTest.cs | 6 +- .../Simulation/PowerTrainBuilderTest.cs | 2 +- .../CombustionEngineTest.cs | 22 ++-- 11 files changed, 272 insertions(+), 210 deletions(-) rename VectoCore/Models/SimulationComponent/{IEngineOnlyDrivingCycle.cs => IPowertrainSimulation.cs} (80%) delete mode 100644 VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs create mode 100644 VectoCore/Models/SimulationComponent/Impl/ManualGearbox.cs diff --git a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 3a1d30058d..28a27ad6b1 100644 --- a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -14,6 +14,7 @@ * limitations under the Licence. */ +using System; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Simulation.Data; @@ -29,28 +30,33 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl /// </summary> public class PowertrainBuilder { - private readonly bool _engineOnly; private readonly VehicleContainer _container; private readonly IModalDataContainer _modData; - public PowertrainBuilder(IModalDataContainer modData, bool engineOnly, WriteSumData sumWriter = null) + public PowertrainBuilder(IModalDataContainer modData, WriteSumData sumWriter = null) { - _engineOnly = engineOnly; _modData = modData; _container = new VehicleContainer(modData, sumWriter); } public VehicleContainer Build(VectoRunData data) { - return _engineOnly ? BuildEngineOnly(data) : BuildFullPowertrain(data); + if (data.IsEngineOnly) { + return BuildEngineOnly(data); + } + if (data.Cycle.CycleType == CycleType.PWheel) { + return BuildPWheel(data); + } + + return BuildFullPowertrain(data); } private VehicleContainer BuildEngineOnly(VectoRunData data) { - var cycle = new EngineOnlyDrivingCycle(_container, data.Cycle); + var cycle = new PowertrainDrivingCycle(_container, data.Cycle); - var gearbox = new EngineOnlyGearbox(_container); + var gearbox = new ManualGearbox(_container); cycle.InPort().Connect(gearbox.OutPort()); var directAux = new Auxiliary(_container); @@ -63,6 +69,65 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return _container; } + private VehicleContainer BuildPWheel(VectoRunData data) + { + var cycle = new PowertrainDrivingCycle(_container, data.Cycle); + + var tmp = AddComponent(cycle, new AxleGear(_container, data.AxleGearData)); + + switch (data.Retarder.Type) { + case RetarderData.RetarderType.Primary: + tmp = AddComponent(tmp, new Retarder(_container, data.Retarder.LossMap)); + tmp = AddComponent(tmp, GetGearbox(_container, data.GearboxData)); + break; + case RetarderData.RetarderType.Secondary: + tmp = AddComponent(tmp, GetGearbox(_container, data.GearboxData)); + tmp = AddComponent(tmp, new Retarder(_container, data.Retarder.LossMap)); + break; + case RetarderData.RetarderType.None: + tmp = AddComponent(tmp, GetGearbox(_container, data.GearboxData)); + break; + case RetarderData.RetarderType.LossesIncludedInTransmission: + tmp = AddComponent(tmp, GetGearbox(_container, data.GearboxData)); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + var engine = new CombustionEngine(_container, data.EngineData); + var clutch = new Clutch(_container, data.EngineData, engine.IdleController); + + // gearbox --> clutch + tmp = AddComponent(tmp, clutch); + + // clutch --> direct aux --> ... --> aux_XXX --> directAux + if (data.Aux != null) { + var aux = new Auxiliary(_container); + foreach (var auxData in data.Aux) { + switch (auxData.DemandType) { + case AuxiliaryDemandType.Constant: + aux.AddConstant(auxData.ID, auxData.PowerDemand); + break; + case AuxiliaryDemandType.Direct: + aux.AddDirect(cycle); + break; + case AuxiliaryDemandType.Mapping: + aux.AddMapping(auxData.ID, cycle, auxData.Data); + break; + } + _modData.AddAuxiliary(auxData.ID); + } + tmp = AddComponent(tmp, aux); + } + // connect aux --> engine + AddComponent(tmp, engine); + + engine.IdleController.RequestPort = clutch.IdleControlPort; + + return _container; + } + + private VehicleContainer BuildFullPowertrain(VectoRunData data) { _container.RunData = data; @@ -74,29 +139,15 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl case CycleType.TimeBased: cycle = new TimeBasedDrivingCycle(_container, data.Cycle); break; - case CycleType.PWheel: - cycle = new PWheelDrivingCycle(_container, data.Cycle); - break; - //case CycleType.MeasuredSpeed: - // cycle = new MeasuredSpeedDrivingCycle(_container, data.Cycle); - // break; default: throw new VectoSimulationException("Unhandled Cycle Type"); } // cycle --> driver --> vehicle --> wheels --> axleGear --> retarder --> gearBox var driver = AddComponent(cycle, new Driver(_container, data.DriverData, new DefaultDriverStrategy())); var vehicle = AddComponent(driver, new Vehicle(_container, data.VehicleData)); - var wheels = AddComponent(vehicle, new Wheels(_container, data.VehicleData.DynamicTyreRadius)); var brakes = AddComponent(wheels, new Brakes(_container)); - - IPowerTrainComponent tmp; - if (data.Cycle.CycleType == CycleType.PWheel) { - tmp = new AxleGear(_container, data.AxleGearData); - //((PWheelDrivingCycle)cycle).InPort().Connect(tmp.OutPort()); - } else { - tmp = AddComponent(brakes, new AxleGear(_container, data.AxleGearData)); - } + var tmp = AddComponent(brakes, new AxleGear(_container, data.AxleGearData)); switch (data.Retarder.Type) { case RetarderData.RetarderType.Primary: @@ -113,6 +164,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl case RetarderData.RetarderType.LossesIncludedInTransmission: tmp = AddComponent(tmp, GetGearbox(_container, data.GearboxData)); break; + default: + throw new ArgumentOutOfRangeException(); } var engine = new CombustionEngine(_container, data.EngineData); @@ -149,7 +202,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return _container; } - private IGearbox GetGearbox(VehicleContainer container, GearboxData data) + private static IGearbox GetGearbox(IVehicleContainer container, GearboxData data) { IShiftStrategy strategy; switch (data.Type) { diff --git a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 174fa4fd90..d0fe36fbed 100644 --- a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -100,8 +100,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl }, _mode); modContainer.WriteModalResults = WriteModalResults; var current = i++; - var builder = new PowertrainBuilder(modContainer, - data.IsEngineOnly, (writer, mass, loading) => + var builder = new PowertrainBuilder(modContainer, (writer, mass, loading) => SumData.Write(d.IsEngineOnly, modContainer, d.JobName, string.Format("{0}-{1}", JobNumber, current), d.Cycle.Name + Constants.FileExtensions.CycleFile, mass, loading)); diff --git a/VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs b/VectoCore/Models/SimulationComponent/IPowertrainSimulation.cs similarity index 80% rename from VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs rename to VectoCore/Models/SimulationComponent/IPowertrainSimulation.cs index 3b23170c09..edbba48e37 100644 --- a/VectoCore/Models/SimulationComponent/IEngineOnlyDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/IPowertrainSimulation.cs @@ -19,7 +19,7 @@ using TUGraz.VectoCore.Models.Connector.Ports; namespace TUGraz.VectoCore.Models.SimulationComponent { /// <summary> - /// Defines interfaces for a engine only driving cycle. + /// Defines interfaces for a powertrain only driving cycle. /// </summary> - public interface IEngineOnlySimulation : ISimulationOutProvider, ITnInProvider {} + public interface IPowertrainSimulation : IDrivingCycleInfo, ISimulationOutProvider, ITnInProvider {} } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs deleted file mode 100644 index 9f4ea23f91..0000000000 --- a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs +++ /dev/null @@ -1,111 +0,0 @@ -/* -* Copyright 2015 European Union -* -* Licensed under the EUPL (the "Licence"); -* You may not use this work except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* http://ec.europa.eu/idabc/eupl5 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -*/ - -using System; -using TUGraz.VectoCore.Exceptions; -using TUGraz.VectoCore.Models.Connector.Ports; -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.OutputData; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.SimulationComponent.Impl -{ - public class EngineOnlyGearbox : VectoSimulationComponent, IGearbox, ITnInPort, ITnOutPort - { - protected ITnOutPort NextComponent; - public EngineOnlyGearbox(IVehicleContainer cockpit) : base(cockpit) {} - - #region ITnInProvider - - public ITnInPort InPort() - { - return this; - } - - #endregion ITnOutProvider - - #region ITnOutProvider - - public ITnOutPort OutPort() - { - return this; - } - - #endregion - - #region IGearboxCockpit - - uint IGearboxInfo.Gear - { - get { return 0; } - } - - public MeterPerSecond StartSpeed - { - get { throw new VectoSimulationException("Not Implemented: EngineOnlyGearbox has no StartSpeed value."); } - } - - public MeterPerSquareSecond StartAcceleration - { - get { throw new VectoSimulationException("Not Implemented: EngineOnlyGearbox has no StartAcceleration value."); } - } - - public FullLoadCurve GearFullLoadCurve - { - get { return null; } - } - - #endregion - - #region ITnInPort - - void ITnInPort.Connect(ITnOutPort other) - { - NextComponent = other; - } - - #endregion - - #region ITnOutPort - - IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity, bool dryRun) - { - if (NextComponent == null) { - Log.Error("Ccannot handle incoming request - no outport available. absTime: {0}, dt: {1}", absTime, dt); - throw new VectoSimulationException("Cannot handle incoming request - no outport available."); - } - return NextComponent.Request(absTime, dt, torque, angularVelocity, dryRun); - } - - public IResponse Initialize(NewtonMeter torque, PerSecond angularSpeed) - { - return NextComponent.Initialize(torque, angularSpeed); - } - - #endregion - - #region VectoSimulationComponent - - protected override void DoWriteModalResults(IModalDataContainer container) {} - - protected override void DoCommitSimulationStep() {} - - #endregion - } -} \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 857280a377..762c4e21bc 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -44,43 +44,48 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <summary> /// The shift strategy. /// </summary> - private readonly IShiftStrategy _strategy; + protected readonly IShiftStrategy Strategy; /// <summary> /// Time when a gearbox shift engages a new gear (shift is finished). Is set when shifting is needed. /// </summary> - private Second _shiftTime = 0.SI<Second>(); + protected Second ShiftTime = 0.SI<Second>(); /// <summary> /// True if gearbox is disengaged (no gear is set). /// </summary> - private bool _disengaged = true; + protected bool Disengaged = true; /// <summary> /// The power loss for the mod data. /// </summary> - private Watt _powerLoss; + protected Watt PowerLoss; /// <summary> /// The inertia power loss for the mod data. /// </summary> - private Watt _powerLossInertia; + protected Watt PowerLossInertia; /// <summary> /// The previous enginespeed for inertia calculation /// </summary> - private PerSecond _previousInAngularSpeed = 0.SI<PerSecond>(); + protected PerSecond PreviousInAngularSpeed = 0.SI<PerSecond>(); public bool ClutchClosed(Second absTime) { - return _shiftTime.IsSmallerOrEqual(absTime); + return ShiftTime.IsSmallerOrEqual(absTime); } public Gearbox(IVehicleContainer container, GearboxData gearboxData, IShiftStrategy strategy) : base(container) { Data = gearboxData; - _strategy = strategy; - _strategy.Gearbox = this; + Strategy = strategy; + Strategy.Gearbox = this; + } + + protected Gearbox(IVehicleContainer container, GearboxData gearboxData) : base(container) + { + Data = gearboxData; } #region ITnInProvider @@ -102,20 +107,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #endregion - #region IGearboxCockpit + #region IGearboxInfo /// <summary> /// The current gear. /// </summary> public uint Gear { get; set; } - [DebuggerHidden] public MeterPerSecond StartSpeed { get { return Data.StartSpeed; } } - [DebuggerHidden] public MeterPerSquareSecond StartAcceleration { get { return Data.StartAcceleration; } @@ -130,15 +133,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #region ITnOutPort - public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + public virtual IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) { var absTime = 0.SI<Second>(); var dt = Constants.SimulationSettings.TargetTimeInterval; - _shiftTime = double.NegativeInfinity.SI<Second>(); - _powerLoss = null; + ShiftTime = double.NegativeInfinity.SI<Second>(); + PowerLoss = null; - if (_disengaged) { - Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); + if (Disengaged) { + Gear = Strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); } var inAngularVelocity = outAngularVelocity * Data.Gears[Gear].Ratio; @@ -146,14 +149,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var torqueLossInertia = outAngularVelocity.IsEqual(0) ? 0.SI<NewtonMeter>() - : Formulas.InertiaPower(inAngularVelocity, _previousInAngularSpeed, Data.Inertia, dt) / inAngularVelocity; + : Formulas.InertiaPower(inAngularVelocity, PreviousInAngularSpeed, Data.Inertia, dt) / inAngularVelocity; inTorque += torqueLossInertia; var response = NextComponent.Initialize(inTorque, inAngularVelocity); if (response is ResponseSuccess) { - _previousInAngularSpeed = inAngularVelocity; - _disengaged = false; + PreviousInAngularSpeed = inAngularVelocity; + Disengaged = false; } return response; @@ -165,7 +168,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var inTorque = Data.Gears[gear].LossMap.GetInTorque(inAngularVelocity, outTorque); if (!inAngularVelocity.IsEqual(0)) { - var alpha = (Data.Inertia.IsEqual(0)) + var alpha = Data.Inertia.IsEqual(0) ? 0.SI<PerSquareSecond>() : outTorque / Data.Inertia; @@ -211,7 +214,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", torque, angularVelocity); if (DataBus.VehicleStopped) { - _shiftTime = absTime; + ShiftTime = absTime; } IResponse retVal; if (ClutchClosed(absTime)) { @@ -235,7 +238,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <item><term>else</term><description>Response from NextComponent</description></item> /// </list> /// </returns> - private IResponse RequestGearDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + protected virtual IResponse RequestGearDisengaged(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, bool dryRun) { Log.Debug("Current Gear: Neutral"); @@ -247,12 +251,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }; } - var shiftTimeExceeded = absTime.IsSmaller(_shiftTime) && - _shiftTime.IsSmaller(absTime + dt, Data.TractionInterruption / 20.0); + var shiftTimeExceeded = absTime.IsSmaller(ShiftTime) && + ShiftTime.IsSmaller(absTime + dt, Data.TractionInterruption / 20.0); if (shiftTimeExceeded) { return new ResponseFailTimeInterval { Source = this, - DeltaT = _shiftTime - absTime, + DeltaT = ShiftTime - absTime, GearboxPowerRequest = outTorque * outAngularVelocity }; } @@ -288,42 +292,43 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <item><term>else</term><description>Response from NextComponent.</description></item> /// </list> /// </returns> - private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + protected virtual IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, bool dryRun) { // Set a Gear if no gear was set and engineSpeed is not zero - if (_disengaged && !outAngularVelocity.IsEqual(0)) { - _disengaged = false; + if (Disengaged && !outAngularVelocity.IsEqual(0)) { + Disengaged = false; if (DataBus.VehicleStopped) { - Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); + Gear = Strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); } else { - Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity); + Gear = Strategy.Engage(absTime, dt, outTorque, outAngularVelocity); } Log.Debug("Gearbox engaged gear {0}", Gear); } var inEngineSpeed = outAngularVelocity * Data.Gears[Gear].Ratio; - var inTorque = (outAngularVelocity.IsEqual(0)) + var inTorque = outAngularVelocity.IsEqual(0) ? outTorque / Data.Gears[Gear].Ratio : Data.Gears[Gear].LossMap.GetInTorque(inEngineSpeed, outTorque); - _powerLoss = inTorque * inEngineSpeed - outTorque * outAngularVelocity; + PowerLoss = inTorque * inEngineSpeed - outTorque * outAngularVelocity; if (!inEngineSpeed.IsEqual(0)) { - _powerLossInertia = Formulas.InertiaPower(inEngineSpeed, _previousInAngularSpeed, Data.Inertia, dt); - inTorque += _powerLossInertia / inEngineSpeed; + PowerLossInertia = Formulas.InertiaPower(inEngineSpeed, PreviousInAngularSpeed, Data.Inertia, dt); + inTorque += PowerLossInertia / inEngineSpeed; } else { - _powerLossInertia = 0.SI<Watt>(); + PowerLossInertia = 0.SI<Watt>(); } if (dryRun) { if ((DataBus.DrivingBehavior == DrivingBehavior.Braking || DataBus.DrivingBehavior == DrivingBehavior.Coasting) && inEngineSpeed < DataBus.EngineIdleSpeed && DataBus.VehicleSpeed < Constants.SimulationSettings.VehicleStopClutchDisengageSpeed) { - _disengaged = true; - _shiftTime = absTime + dt; - _strategy.Disengage(absTime, dt, outTorque, outAngularVelocity); + Disengaged = true; + ShiftTime = absTime + dt; + Strategy.Disengage(absTime, dt, outTorque, outAngularVelocity); Log.Debug("EngineSpeed is below IdleSpeed, Gearbox disengage!"); return new ResponseEngineSpeedTooLow() { Source = this, GearboxPowerRequest = outTorque * outAngularVelocity }; } @@ -335,17 +340,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var shiftAllowed = !inEngineSpeed.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0); if (shiftAllowed) { - var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inEngineSpeed, - Gear, _shiftTime + Data.TractionInterruption); + var shiftRequired = Strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inEngineSpeed, + Gear, ShiftTime + Data.TractionInterruption); if (shiftRequired) { - _shiftTime = absTime + Data.TractionInterruption; + 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, outAngularVelocity, inTorque, inEngineSpeed); + dt, ShiftTime, outTorque, outAngularVelocity, inTorque, inEngineSpeed); - _disengaged = true; - _strategy.Disengage(absTime, dt, outTorque, outAngularVelocity); + Disengaged = true; + Strategy.Disengage(absTime, dt, outTorque, outAngularVelocity); Log.Info("Gearbox disengaged"); return new ResponseGearShift { @@ -359,7 +364,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var response = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed); response.GearboxPowerRequest = outTorque * outAngularVelocity; - _previousInAngularSpeed = inEngineSpeed; + PreviousInAngularSpeed = inEngineSpeed; return response; } @@ -378,14 +383,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected override void DoWriteModalResults(IModalDataContainer container) { - container[ModalResultField.Gear] = _disengaged || DataBus.VehicleStopped ? 0 : Gear; - container[ModalResultField.PlossGB] = _powerLoss; - container[ModalResultField.PaGB] = _powerLossInertia; + container[ModalResultField.Gear] = Disengaged || DataBus.VehicleStopped ? 0 : Gear; + container[ModalResultField.PlossGB] = PowerLoss; + container[ModalResultField.PaGB] = PowerLossInertia; } protected override void DoCommitSimulationStep() { - if (!_disengaged) { + if (!Disengaged) { if (Data.Gears[Gear].LossMap.Extrapolated) { // todo (MK, 2015-12-14): should we throw an interpolation error in EngineOnly Mode also? Log.Warn("Gear {0} LossMap data was extrapolated: range for loss map is not sufficient.", Gear); @@ -397,8 +402,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - _powerLoss = null; - _powerLossInertia = null; + PowerLoss = null; + PowerLossInertia = null; } #endregion diff --git a/VectoCore/Models/SimulationComponent/Impl/ManualGearbox.cs b/VectoCore/Models/SimulationComponent/Impl/ManualGearbox.cs new file mode 100644 index 0000000000..8e91a5c4f5 --- /dev/null +++ b/VectoCore/Models/SimulationComponent/Impl/ManualGearbox.cs @@ -0,0 +1,122 @@ +/* +* Copyright 2015 European Union +* +* Licensed under the EUPL (the "Licence"); +* You may not use this work except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* http://ec.europa.eu/idabc/eupl5 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +*/ + +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class ManualGearbox : Gearbox + { + public ManualGearbox(IVehicleContainer container, GearboxData gearboxData = null) : base(container, gearboxData) {} + + #region ITnOutPort + + public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var dt = Constants.SimulationSettings.TargetTimeInterval; + ShiftTime = double.NegativeInfinity.SI<Second>(); + PowerLoss = null; + + if (Disengaged) { + Gear = DataBus.Gear; + } + + var inAngularVelocity = outAngularVelocity * Data.Gears[Gear].Ratio; + var inTorque = Data.Gears[Gear].LossMap.GetInTorque(inAngularVelocity, outTorque); + + var torqueLossInertia = outAngularVelocity.IsEqual(0) + ? 0.SI<NewtonMeter>() + : Formulas.InertiaPower(inAngularVelocity, PreviousInAngularSpeed, Data.Inertia, dt) / inAngularVelocity; + + inTorque += torqueLossInertia; + + var response = NextComponent.Initialize(inTorque, inAngularVelocity); + if (response is ResponseSuccess) { + PreviousInAngularSpeed = inAngularVelocity; + Disengaged = false; + } + + return response; + } + + + /// <summary> + /// Requests the gearbox in engaged mode. Sets the gear if no gear was set previously. + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><term>ResponseGearShift</term><description>if a shift is needed.</description></item> + /// <item><term>else</term><description>Response from NextComponent.</description></item> + /// </list> + /// </returns> + protected override IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outAngularVelocity, + bool dryRun) + { + // Set a Gear if no gear was set and engineSpeed is not zero + if (Disengaged && !outAngularVelocity.IsEqual(0)) { + Disengaged = false; + Gear = DataBus.Gear; + Log.Debug("Gearbox engaged gear {0}", Gear); + } + + var inEngineSpeed = outAngularVelocity * Data.Gears[Gear].Ratio; + var inTorque = outAngularVelocity.IsEqual(0) + ? outTorque / Data.Gears[Gear].Ratio + : Data.Gears[Gear].LossMap.GetInTorque(inEngineSpeed, outTorque); + + PowerLoss = inTorque * inEngineSpeed - outTorque * outAngularVelocity; + + if (!inEngineSpeed.IsEqual(0)) { + PowerLossInertia = Formulas.InertiaPower(inEngineSpeed, PreviousInAngularSpeed, Data.Inertia, dt); + inTorque += PowerLossInertia / inEngineSpeed; + } else { + PowerLossInertia = 0.SI<Watt>(); + } + + var shiftRequired = Gear != DataBus.Gear; + + if (shiftRequired) { + 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, outAngularVelocity, inTorque, inEngineSpeed); + + Disengaged = true; + Log.Info("Gearbox disengaged"); + + return new ResponseGearShift { + Source = this, + SimulationInterval = Data.TractionInterruption, + GearboxPowerRequest = outTorque * outAngularVelocity + }; + } + + var response = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed); + response.GearboxPowerRequest = outTorque * outAngularVelocity; + + PreviousInAngularSpeed = inEngineSpeed; + return response; + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs index 8c6c373472..e1dfeff2de 100644 --- a/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs @@ -30,7 +30,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// <summary> /// Represents a driving cycle which directly is connected to the powertrain (e.g. engine, or axle gear). /// </summary> - public class PowertrainDrivingCycle : VectoSimulationComponent, IDrivingCycleInfo, IEngineOnlySimulation, ITnInPort, + public class PowertrainDrivingCycle : VectoSimulationComponent, IPowertrainSimulation, ITnInPort, ISimulationOutPort { protected DrivingCycleData Data; diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index 81706a3d75..d070f09a54 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -246,12 +246,12 @@ <Compile Include="Models\SimulationComponent\Impl\Auxiliary.cs" /> <Compile Include="Models\SimulationComponent\Impl\TimeBasedDrivingCycle.cs" /> <Compile Include="Models\SimulationComponent\Impl\CombustionEngine.cs" /> - <Compile Include="Models\SimulationComponent\Impl\EngineOnlyGearbox.cs" /> + <Compile Include="Models\SimulationComponent\Impl\ManualGearbox.cs" /> <Compile Include="Models\SimulationComponent\Impl\Gearbox.cs" /> <Compile Include="Models\SimulationComponent\Impl\Wheels.cs" /> <Compile Include="Models\SimulationComponent\IWheels.cs" /> <Compile Include="Models\SimulationComponent\VectoSimulationComponent.cs" /> - <Compile Include="Models\SimulationComponent\Impl\EngineOnlyDrivingCycle.cs" /> + <Compile Include="Models\SimulationComponent\Impl\PowertrainDrivingCycle.cs" /> <Compile Include="Models\Simulation\Data\ModalResult.cs"> <SubType>Component</SubType> </Compile> diff --git a/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs b/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs index ac7acf2d6f..adf7298e70 100644 --- a/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs +++ b/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs @@ -14,9 +14,7 @@ * limitations under the Licence. */ -using System.Data; using System.IO; -using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.InputData.Reader; @@ -52,7 +50,7 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle var aux = new Auxiliary(vehicle); aux.AddDirect(cycle); - var gearbox = new EngineOnlyGearbox(vehicle); + var gearbox = new ManualGearbox(vehicle); var engine = new EngineOnlyCombustionEngine(vehicle, engineData); @@ -91,7 +89,7 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle var vehicleContainer = new VehicleContainer(); - var gearbox = new EngineOnlyGearbox(vehicleContainer); + var gearbox = new ManualGearbox(vehicleContainer); var engine = new CombustionEngine(vehicleContainer, MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile)); diff --git a/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs b/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs index 40c569194b..aaca466c8f 100644 --- a/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs +++ b/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs @@ -39,7 +39,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var runData = reader.NextRun().First(); var writer = new MockModalDataContainer(); - var builder = new PowertrainBuilder(writer, false); + var builder = new PowertrainBuilder(writer); var powerTrain = builder.Build(runData); diff --git a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index 48a4a7cd6c..fdc15a653a 100644 --- a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -22,12 +22,10 @@ using System.Linq; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.Tests.Utils; using TUGraz.VectoCore.Utils; @@ -87,7 +85,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine); var engine = new CombustionEngine(vehicle, engineData); - new EngineOnlyGearbox(vehicle); + new ManualGearbox(vehicle); var port = engine.OutPort(); @@ -105,7 +103,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var vehicle = new VehicleContainer(); var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine); var engine = new CombustionEngine(vehicle, engineData); - var gearbox = new EngineOnlyGearbox(vehicle); + var gearbox = new ManualGearbox(vehicle); var port = engine.OutPort(); var absTime = 0.SI<Second>(); @@ -134,7 +132,6 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent absTime += dt; var power = new[] { 569.3641, 4264.177 }; - ; for (var i = 0; i < 2; i++) { port.Request(absTime, dt, Formulas.PowerToTorque(power[i].SI<Watt>(), engineSpeed), engineSpeed); engine.CommitSimulationStep(dataWriter); @@ -157,7 +154,6 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent Assert.AreEqual(-7108.32, ((SI)dataWriter[ModalResultField.PaEng]).Value(), 0.001); dataWriter.CommitSimulationStep(absTime, dt); - absTime += dt; dataWriter.Data.WriteToFile(@"test1.csv"); } @@ -169,7 +165,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent public void TestEngineFullLoadJump() { var vehicleContainer = new VehicleContainer(); - var gearbox = new EngineOnlyGearbox(vehicleContainer); + var gearbox = new ManualGearbox(vehicleContainer); var engineData = MockSimulationDataFactory.CreateEngineDataFromFile( TestContext.DataRow["EngineFile"].ToString()); @@ -311,10 +307,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent container.CommitSimulationStep(absTime, dt); absTime += dt; - var engineSpeed = new PerSecond[] { 800.RPMtoRad(), 800.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; - var enginePower = new Watt[] { 5000.SI<Watt>(), 5000.SI<Watt>(), -8601.6308.SI<Watt>(), 5000.SI<Watt>() }; + var engineSpeed = new[] { 800.RPMtoRad(), 800.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; + var enginePower = new[] { 5000.SI<Watt>(), 5000.SI<Watt>(), -8601.6308.SI<Watt>(), 5000.SI<Watt>() }; - for (var i = 0; i < engineSpeed.Count(); i++) { + for (var i = 0; i < engineSpeed.Length; i++) { torque = 0.SI<NewtonMeter>(); response = requestPort.Request(absTime, dt, torque, null); @@ -371,13 +367,13 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent container.CommitSimulationStep(absTime, dt); absTime += dt; - var engineSpeed = new PerSecond[] { + var engineSpeed = new[] { 1680.RPMtoRad(), 1680.RPMtoRad(), 1467.014.RPMtoRad(), 1272.8658.RPMtoRad(), 1090.989.RPMtoRad(), 915.3533.RPMtoRad(), 738.599.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad(), 560.RPMtoRad() }; - var enginePower = new Watt[] { + var enginePower = new[] { 5000.SI<Watt>(), 5000.SI<Watt>(), -32832.8834.SI<Watt>(), -25025.1308.SI<Watt>(), -19267.0360.SI<Watt>(), -14890.1962.SI<Watt>(), -11500.7991.SI<Watt>(), -8091.0577.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), 5000.SI<Watt>(), @@ -385,7 +381,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent }; var engSpeedResults = new List<dynamic>(); - for (var i = 0; i < engineSpeed.Count(); i++) { + for (var i = 0; i < engineSpeed.Length; i++) { torque = 0.SI<NewtonMeter>(); response = requestPort.Request(absTime, dt, torque, null); -- GitLab