From aafe09c12a8e888179aeca2d3c1136705cbb2ef3 Mon Sep 17 00:00:00 2001 From: Michael Krisper <michael.krisper@tugraz.at> Date: Tue, 23 Feb 2016 14:44:40 +0100 Subject: [PATCH] measured speed gear --- .../Simulation/Impl/PowertrainBuilder.cs | 2 +- .../Impl/CombustionEngine.cs | 1 + .../SimulationComponent/Impl/CycleGearbox.cs | 288 ++++++++++++++++++ .../SimulationComponent/Impl/Gearbox.cs | 267 ---------------- .../Impl/PowertrainDrivingCycle.cs | 227 +------------- VectoCore/VectoCore.csproj | 1 + .../Simulation/MeasuredSpeedModeTest.cs | 21 +- .../MeasuredSpeed/MeasuredSpeedGear.vecto | 10 +- VectoCoreTest/Utils/ResultFileHelper.cs | 13 +- 9 files changed, 314 insertions(+), 516 deletions(-) create mode 100644 VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs diff --git a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 9beee35306..d0609afbec 100644 --- a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -180,7 +180,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Debug.Assert(data.Cycle.CycleType == CycleType.MeasuredSpeedGear); var container = new VehicleContainer(_modData, _sumWriter, ExecutionMode.Engineering) { RunData = data }; - var cycle = new MeasuredSpeedGearDrivingCycle(container, data.Cycle); + var cycle = new MeasuredSpeedDrivingCycle(container, data.Cycle); var vehicle = AddComponent(cycle, new Vehicle(container, data.VehicleData)); var wheels = AddComponent(vehicle, new Wheels(container, data.VehicleData.DynamicTyreRadius, data.VehicleData.WheelsInertia)); diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 22f76e3e63..d512a473a3 100644 --- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -414,6 +414,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl //public Second AbsTime { get; set; } + // ReSharper disable once InconsistentNaming public Second dt { get; set; } public PerSecond EngineSpeed { get; set; } diff --git a/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs new file mode 100644 index 0000000000..23df337fa8 --- /dev/null +++ b/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs @@ -0,0 +1,288 @@ +using System.Diagnostics; +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; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.DataBus; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class CycleGearbox : StatefulVectoSimulationComponent<Gearbox.GearboxState>, IGearbox, ITnOutPort, ITnInPort, + IClutchInfo + { + /// <summary> + /// The next port. + /// </summary> + protected ITnOutPort NextComponent; + + /// <summary> + /// The data and settings for the gearbox. + /// </summary> + internal readonly GearboxData ModelData; + + public bool ClutchClosed(Second absTime) + { + return DataBus.CycleData.LeftSample.Gear != 0; + } + + public CycleGearbox(IVehicleContainer container, GearboxData gearboxModelData) + : base(container) + { + ModelData = gearboxModelData; + } + + #region ITnInProvider + + public ITnInPort InPort() + { + return this; + } + + #endregion + + #region ITnOutProvider + + [DebuggerHidden] + public ITnOutPort OutPort() + { + return this; + } + + #endregion + + #region IGearboxCockpit + + /// <summary> + /// The current gear. + /// </summary> + public uint Gear { get; private set; } + + [DebuggerHidden] + public MeterPerSecond StartSpeed + { + get { return ModelData.StartSpeed; } + } + + [DebuggerHidden] + public MeterPerSquareSecond StartAcceleration + { + get { return ModelData.StartAcceleration; } + } + + public FullLoadCurve GearFullLoadCurve + { + get { return Gear == 0 ? null : ModelData.Gears[Gear].FullLoadCurve; } + } + + #endregion + + #region ITnInPort + + void ITnInPort.Connect(ITnOutPort other) + { + NextComponent = other; + } + + #endregion + + #region ITnOutPort + + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var dt = Constants.SimulationSettings.TargetTimeInterval; + + Gear = DataBus.CycleData.LeftSample.Gear; + + PerSecond inAngularVelocity; + NewtonMeter inTorque; + + if (Gear != 0) { + inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; + inTorque = ModelData.Gears[Gear].LossMap.GetInTorque(inAngularVelocity, outTorque); + + var torqueLossInertia = outAngularVelocity.IsEqual(0) + ? 0.SI<NewtonMeter>() + : Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / + inAngularVelocity; + + inTorque += torqueLossInertia; + } else { + inTorque = 0.SI<NewtonMeter>(); + inAngularVelocity = 0.RPMtoRad(); + } + PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); + PreviousState.Gear = Gear; + + var response = NextComponent.Initialize(inTorque, inAngularVelocity); + response.GearboxPowerRequest = inTorque * inAngularVelocity; + return response; + } + + internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity) + { + var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; + var inTorque = ModelData.Gears[gear].LossMap.GetInTorque(inAngularVelocity, outTorque); + + if (!inAngularVelocity.IsEqual(0)) { + var alpha = (ModelData.Inertia.IsEqual(0)) + ? 0.SI<PerSquareSecond>() + : outTorque / ModelData.Inertia; + + var inertiaPowerLoss = Formulas.InertiaPower(inAngularVelocity, alpha, ModelData.Inertia, + Constants.SimulationSettings.TargetTimeInterval); + inTorque += inertiaPowerLoss / inAngularVelocity; + } + + var response = NextComponent.Initialize(inTorque, inAngularVelocity); + response.Switch(). + Case<ResponseSuccess>(). + Case<ResponseOverload>(). + Case<ResponseUnderload>(). + Default(r => { throw new UnexpectedResponseException("Gearbox.Initialize", r); }); + + var fullLoadGearbox = ModelData.Gears[gear].FullLoadCurve.FullLoadStationaryTorque(inAngularVelocity) * + inAngularVelocity; + var fullLoadEngine = DataBus.EngineStationaryFullPower(inAngularVelocity); + + var fullLoad = VectoMath.Min(fullLoadGearbox, fullLoadEngine); + + return new ResponseDryRun { + Source = this, + EnginePowerRequest = response.EnginePowerRequest, + ClutchPowerRequest = response.ClutchPowerRequest, + GearboxPowerRequest = outTorque * outAngularVelocity, + DeltaFullLoad = response.EnginePowerRequest - fullLoad + }; + } + + /// <summary> + /// Requests the Gearbox to deliver torque and angularVelocity + /// </summary> + /// <returns> + /// <list type="bullet"> + /// <item><description>ResponseDryRun</description></item> + /// <item><description>ResponseOverload</description></item> + /// <item><description>ResponseGearshift</description></item> + /// </list> + /// </returns> + public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) + { + Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); + Gear = DataBus.CycleData.LeftSample.Gear; + + var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; + + if (Gear == 0) { + //disengaged + if (dryRun) { + // if gearbox is disengaged the 0-line is the limit for drag and full load + return new ResponseDryRun { + Source = this, + GearboxPowerRequest = outTorque * avgOutAngularVelocity, + DeltaDragLoad = outTorque * avgOutAngularVelocity, + DeltaFullLoad = outTorque * avgOutAngularVelocity, + }; + } + + if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), + Constants.SimulationSettings.EnginePowerSearchTolerance)) { + return new ResponseOverload { + Source = this, + Delta = outTorque * avgOutAngularVelocity, + GearboxPowerRequest = outTorque * avgOutAngularVelocity + }; + } + + if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), + Constants.SimulationSettings.EnginePowerSearchTolerance)) { + return new ResponseUnderload { + Source = this, + Delta = outTorque * avgOutAngularVelocity, + GearboxPowerRequest = outTorque * avgOutAngularVelocity + }; + } + + CurrentState.SetState(0.SI<NewtonMeter>(), 0.RPMtoRad(), outTorque, outAngularVelocity); + CurrentState.Gear = Gear; + + var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null); + disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return disengagedResponse; + } else { + //engaged + var inTorque = ModelData.Gears[Gear].LossMap.GetInTorque(avgOutAngularVelocity * ModelData.Gears[Gear].Ratio, + outTorque); + var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; + + if (dryRun) { + var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true); + dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return dryRunResponse; + } + + // this code has to be _after_ the check for a potential gear-shift! + // (the above block issues dry-run requests and thus may update the CurrentState!) + CurrentState.TransmissionTorqueLoss = inTorque - (outTorque / ModelData.Gears[Gear].Ratio); + if (!inAngularVelocity.IsEqual(0)) { + // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side + CurrentState.InertiaTorqueLossOut = + Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / + avgOutAngularVelocity; + inTorque += CurrentState.InertiaTorqueLossOut / ModelData.Gears[Gear].Ratio; + } else { + CurrentState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); + } + CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); + CurrentState.Gear = Gear; + // end critical section + + var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); + response.GearboxPowerRequest = outTorque * avgOutAngularVelocity; + return response; + } + } + + #endregion + + #region VectoSimulationComponent + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.Gear] = Gear; + + var avgInAngularSpeed = Gear != 0 + ? (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0 * ModelData.Gears[Gear].Ratio + : 0.RPMtoRad(); + + container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgInAngularSpeed; + container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgInAngularSpeed; + container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; + } + + protected override void DoCommitSimulationStep() + { + if (Gear != 0) { + if (ModelData.Gears[Gear].LossMap.Extrapolated) { + Log.Warn("Gear {0} LossMap data was extrapolated: range for loss map is not sufficient.", Gear); + + if (DataBus.ExecutionMode == ExecutionMode.Declaration) { + // todo (MK, 2016-02-22): add operating point and loss values for easier debugging + throw new VectoException( + "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient.", Gear); + } + } + } + + AdvanceState(); + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index 8a963ebc26..c9a2111e12 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -421,271 +421,4 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public uint Gear; } } - - - public class CycleGearbox : StatefulVectoSimulationComponent<Gearbox.GearboxState>, IGearbox, ITnOutPort, ITnInPort, - IClutchInfo - { - /// <summary> - /// The next port. - /// </summary> - protected ITnOutPort NextComponent; - - /// <summary> - /// The data and settings for the gearbox. - /// </summary> - internal readonly GearboxData ModelData; - - public bool ClutchClosed(Second absTime) - { - return DataBus.CycleData.LeftSample.Gear != 0; - } - - public CycleGearbox(IVehicleContainer container, GearboxData gearboxModelData) - : base(container) - { - ModelData = gearboxModelData; - } - - #region ITnInProvider - - public ITnInPort InPort() - { - return this; - } - - #endregion - - #region ITnOutProvider - - [DebuggerHidden] - public ITnOutPort OutPort() - { - return this; - } - - #endregion - - #region IGearboxCockpit - - /// <summary> - /// The current gear. - /// </summary> - public uint Gear { get; private set; } - - [DebuggerHidden] - public MeterPerSecond StartSpeed - { - get { return ModelData.StartSpeed; } - } - - [DebuggerHidden] - public MeterPerSquareSecond StartAcceleration - { - get { return ModelData.StartAcceleration; } - } - - public FullLoadCurve GearFullLoadCurve - { - get { return Gear == 0 ? null : ModelData.Gears[Gear].FullLoadCurve; } - } - - #endregion - - #region ITnOutPort - - public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var dt = Constants.SimulationSettings.TargetTimeInterval; - - Gear = DataBus.CycleData.LeftSample.Gear; - - var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; - var inTorque = ModelData.Gears[Gear].LossMap.GetInTorque(inAngularVelocity, outTorque); - - var torqueLossInertia = outAngularVelocity.IsEqual(0) - ? 0.SI<NewtonMeter>() - : Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) / - inAngularVelocity; - - inTorque += torqueLossInertia; - - PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - PreviousState.Gear = Gear; - - var response = NextComponent.Initialize(inTorque, inAngularVelocity); - response.GearboxPowerRequest = inTorque * inAngularVelocity; - return response; - } - - internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity) - { - var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio; - var inTorque = ModelData.Gears[gear].LossMap.GetInTorque(inAngularVelocity, outTorque); - - if (!inAngularVelocity.IsEqual(0)) { - var alpha = (ModelData.Inertia.IsEqual(0)) - ? 0.SI<PerSquareSecond>() - : outTorque / ModelData.Inertia; - - var inertiaPowerLoss = Formulas.InertiaPower(inAngularVelocity, alpha, ModelData.Inertia, - Constants.SimulationSettings.TargetTimeInterval); - inTorque += inertiaPowerLoss / inAngularVelocity; - } - - var response = NextComponent.Initialize(inTorque, inAngularVelocity); - response.Switch(). - Case<ResponseSuccess>(). - Case<ResponseOverload>(). - Case<ResponseUnderload>(). - Default(r => { throw new UnexpectedResponseException("Gearbox.Initialize", r); }); - - var fullLoadGearbox = ModelData.Gears[gear].FullLoadCurve.FullLoadStationaryTorque(inAngularVelocity) * - inAngularVelocity; - var fullLoadEngine = DataBus.EngineStationaryFullPower(inAngularVelocity); - - var fullLoad = VectoMath.Min(fullLoadGearbox, fullLoadEngine); - - return new ResponseDryRun { - Source = this, - EnginePowerRequest = response.EnginePowerRequest, - ClutchPowerRequest = response.ClutchPowerRequest, - GearboxPowerRequest = outTorque * outAngularVelocity, - DeltaFullLoad = response.EnginePowerRequest - fullLoad - }; - } - - /// <summary> - /// Requests the Gearbox to deliver torque and angularVelocity - /// </summary> - /// <returns> - /// <list type="bullet"> - /// <item><description>ResponseDryRun</description></item> - /// <item><description>ResponseOverload</description></item> - /// <item><description>ResponseGearshift</description></item> - /// </list> - /// </returns> - public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun) - { - Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); - Gear = DataBus.CycleData.LeftSample.Gear; - - var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - - if (Gear == 0) { - //disengaged - if (dryRun) { - // if gearbox is disengaged the 0-line is the limit for drag and full load - return new ResponseDryRun { - Source = this, - GearboxPowerRequest = outTorque * avgOutAngularVelocity, - DeltaDragLoad = outTorque * avgOutAngularVelocity, - DeltaFullLoad = outTorque * avgOutAngularVelocity, - }; - } - - if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), - Constants.SimulationSettings.EnginePowerSearchTolerance)) { - return new ResponseOverload { - Source = this, - Delta = outTorque * avgOutAngularVelocity, - GearboxPowerRequest = outTorque * avgOutAngularVelocity - }; - } - - if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), - Constants.SimulationSettings.EnginePowerSearchTolerance)) { - return new ResponseUnderload { - Source = this, - Delta = outTorque * avgOutAngularVelocity, - GearboxPowerRequest = outTorque * avgOutAngularVelocity - }; - } - - CurrentState.SetState(0.SI<NewtonMeter>(), outAngularVelocity * ModelData.Gears[PreviousState.Gear].Ratio, outTorque, - outAngularVelocity); - CurrentState.Gear = Gear; - - var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null); - disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity; - return disengagedResponse; - } else { - //engaged - var inTorque = ModelData.Gears[Gear].LossMap.GetInTorque(avgOutAngularVelocity * ModelData.Gears[Gear].Ratio, - outTorque); - var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio; - - if (dryRun) { - var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true); - dryRunResponse.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0; - return dryRunResponse; - } - - // this code has to be _after_ the check for a potential gear-shift! - // (the above block issues dry-run requests and thus may update the CurrentState!) - CurrentState.TransmissionTorqueLoss = inTorque - (outTorque / ModelData.Gears[Gear].Ratio); - if (!inAngularVelocity.IsEqual(0)) { - // MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side - CurrentState.InertiaTorqueLossOut = - Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) / - avgOutAngularVelocity; - inTorque += CurrentState.InertiaTorqueLossOut / ModelData.Gears[Gear].Ratio; - } else { - CurrentState.InertiaTorqueLossOut = 0.SI<NewtonMeter>(); - } - CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity); - CurrentState.Gear = Gear; - // end critical section - - var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity); - response.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / - 2.0; - return response; - } - } - - #endregion - - #region ITnInPort - - void ITnInPort.Connect(ITnOutPort other) - { - NextComponent = other; - } - - #endregion - - #region VectoSimulationComponent - - protected override void DoWriteModalResults(IModalDataContainer container) - { - var avgInAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0 * - ModelData.Gears[Gear].Ratio; - - container[ModalResultField.Gear] = Gear; - container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgInAngularSpeed; - container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgInAngularSpeed; - container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed; - } - - protected override void DoCommitSimulationStep() - { - if (Gear != 0) { - if (ModelData.Gears[Gear].LossMap.Extrapolated) { - Log.Warn("Gear {0} LossMap data was extrapolated: range for loss map is not sufficient.", Gear); - - if (DataBus.ExecutionMode == ExecutionMode.Declaration) { - // todo (MK, 2016-02-22): add operating point and loss values for easier debugging - throw new VectoException( - "Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient.", Gear); - } - } - } - - AdvanceState(); - } - - #endregion - } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs index c89317fc39..b86c492511 100644 --- a/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs @@ -16,11 +16,8 @@ * limitations under the Licence. */ -using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Runtime.CompilerServices; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; @@ -250,204 +247,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - - /// <summary> - /// Driving Cycle for the Measured Speed Gear driving cycle. - /// </summary> - public class MeasuredSpeedGearDrivingCycle : VectoSimulationComponent, IDriverInfo, IDrivingCycleInfo, - IDriverDemandInProvider, - IDriverDemandInPort, ISimulationOutProvider, ISimulationOutPort, IClutchInfo - { - protected DrivingCycleData Data; - protected IDriverDemandOutPort NextComponent; - protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; } - protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; } - private bool initialize; - - protected Second AbsTime { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - public MeasuredSpeedGearDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) - : base(container) - { - Data = cycle; - LeftSample = Data.Entries.GetEnumerator(); - LeftSample.MoveNext(); - - RightSample = Data.Entries.GetEnumerator(); - RightSample.MoveNext(); - RightSample.MoveNext(); - } - - #region IDriverDemandInProvider - - public IDriverDemandInPort InPort() - { - return this; - } - - #endregion - - #region ISimulationOutProvider - - public ISimulationOutPort OutPort() - { - return this; - } - - #endregion - - #region ISimulationOutPort - - public IResponse Request(Second absTime, Meter ds) - { - throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request."); - } - - public virtual IResponse Request(Second absTime, Second dt) - { - // cycle finished (no more entries in cycle) - if (RightSample.Current == null || LeftSample.Current == null) { - return new ResponseCycleFinished { AbsTime = absTime, Source = this }; - } - - // interval exceeded - if (RightSample.Current != null && (absTime + dt).IsGreater(RightSample.Current.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = RightSample.Current.Time - absTime - }; - } - - var delta_v = RightSample.Current.VehicleTargetSpeed - DataBus.VehicleSpeed; - var delta_t = RightSample.Current.Time - LeftSample.Current.Time; - var acceleration = delta_v / delta_t; - var gradient = LeftSample.Current.RoadGradient; - - var response = NextComponent.Request(absTime, dt, acceleration, gradient); - var firstResponse = response; - - response.Switch() - .Case<ResponseUnderload>(r => { - DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, -r.Delta, -r.Delta, - getYValue: result => ((ResponseDryRun)result).DeltaDragLoad, - evaluateFunction: x => { - DataBus.BrakePower = x; - return NextComponent.Request(absTime, dt, acceleration, gradient, true); - }, - criterion: y => ((ResponseDryRun)y).DeltaDragLoad.Abs() < Constants.SimulationSettings.EnginePowerSearchTolerance); - response = NextComponent.Request(absTime, dt, acceleration, gradient); - }) - .Case<ResponseOverload>(r => { - acceleration = SearchAlgorithm.Search(acceleration, r.Delta, -0.5.SI<MeterPerSquareSecond>(), - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), - criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Abs() < Constants.SimulationSettings.EnginePowerSearchTolerance); - response = NextComponent.Request(absTime, dt, acceleration, gradient); - }) - .Case<ResponseSuccess>(() => { }) - .Default( - r => { throw new UnexpectedResponseException("PowertrainDrivingCycle received an unexpected response.", r); }); - - if (!(response is ResponseSuccess)) { - throw new UnexpectedResponseException("PowertrainDrivingCycle received an unexpected response.", response); - } - - AbsTime = absTime + dt; - return response; - } - - public IResponse Initialize() - { - var first = Data.Entries.First(); - - AbsTime = first.Time; - - initialize = true; - - if (first.VehicleTargetSpeed.IsEqual(0)) { - var retVal = NextComponent.Initialize(DataBus.StartSpeed, first.RoadGradient, DataBus.StartAcceleration); - if (!(retVal is ResponseSuccess)) { - throw new UnexpectedResponseException("Couldn't find start gear.", retVal); - } - } - - var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient); - response.AbsTime = AbsTime; - - initialize = false; - return response; - } - - public string CycleName - { - get { return Data.Name; } - } - - public double Progress - { - get { return AbsTime.Value() / Data.Entries.Last().Time.Value(); } - } - - #endregion - - #region IDriverDemandInPort - - void IDriverDemandInPort.Connect(IDriverDemandOutPort other) - { - NextComponent = other; - } - - #endregion - - #region VectoSimulationComponent - - protected override void DoCommitSimulationStep() - { - if ((RightSample.Current == null) || AbsTime.IsGreaterOrEqual(RightSample.Current.Time)) { - RightSample.MoveNext(); - LeftSample.MoveNext(); - } - } - - #endregion - - public CycleData CycleData - { - get - { - return new CycleData { - AbsTime = LeftSample.Current.Time, - AbsDistance = null, - LeftSample = LeftSample.Current, - RightSample = RightSample.Current, - }; - } - } - - protected override void DoWriteModalResults(IModalDataContainer container) {} - - public bool VehicleStopped - { - get { return !initialize && LeftSample.Current.VehicleTargetSpeed.IsEqual(0); } - } - - public DrivingBehavior DrivingBehavior - { - get { return DrivingBehavior.Driving; } - } - - public virtual bool ClutchClosed(Second absTime) - { - return (RightSample.Current != null ? RightSample.Current.Gear : LeftSample.Current.Gear) != 0; - } - } - /// <summary> /// Driving Cycle for the Measured Speed Gear driving cycle. /// </summary> @@ -456,7 +255,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { protected DrivingCycleData Data; protected IDriverDemandOutPort NextComponent; - private bool isInitializing = false; + private bool _isInitializing; protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; } protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; } @@ -522,9 +321,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } // calc acceleration from speed diff vehicle to cycle - var delta_v = RightSample.Current.VehicleTargetSpeed - DataBus.VehicleSpeed; - var delta_t = RightSample.Current.Time - LeftSample.Current.Time; - var acceleration = delta_v / delta_t; + var deltaV = RightSample.Current.VehicleTargetSpeed - DataBus.VehicleSpeed; + var deltaT = RightSample.Current.Time - LeftSample.Current.Time; + var acceleration = deltaV / deltaT; var gradient = LeftSample.Current.RoadGradient; var response = NextComponent.Request(absTime, dt, acceleration, gradient); @@ -532,13 +331,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl response = NextComponent.Request(absTime, dt, acceleration, gradient); } - - // todo mk-2016-02-19: remove after finished working on measured speed cycle - var debugFirstResponse = response; - - - //var delta = DataBus.ClutchClosed(absTime) ? response.DeltaDragLoad : response.GearboxPowerRequest - response.Switch() .Case<ResponseUnderload>(r => { DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, @@ -547,9 +339,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DataBus.BrakePower = x; return NextComponent.Request(absTime, dt, acceleration, gradient, true); }, - criterion: - y => - ((ResponseDryRun)y).DeltaDragLoad.IsEqual(0.SI<Watt>(), Constants.SimulationSettings.EnginePowerSearchTolerance)); + criterion: y => + ((ResponseDryRun)y).DeltaDragLoad.IsEqual(0.SI<Watt>(), Constants.SimulationSettings.EnginePowerSearchTolerance)); response = NextComponent.Request(absTime, dt, acceleration, gradient); }) .Case<ResponseOverload>(r => { @@ -578,7 +369,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl AbsTime = first.Time; - isInitializing = true; + _isInitializing = true; IResponse response; response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient); @@ -586,7 +377,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl throw new UnexpectedResponseException("Couldn't find start gear.", response); } - isInitializing = false; + _isInitializing = false; response.AbsTime = AbsTime; return response; @@ -642,7 +433,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public bool VehicleStopped { - get { return !isInitializing && LeftSample.Current.VehicleTargetSpeed.IsEqual(0); } + get { return !_isInitializing && LeftSample.Current.VehicleTargetSpeed.IsEqual(0); } } public DrivingBehavior DrivingBehavior diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index 0dbe72cdea..1439699f1a 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -170,6 +170,7 @@ <Compile Include="Models\SimulationComponent\IDrivingCycleInfo.cs" /> <Compile Include="Models\SimulationComponent\IEngineAuxPort.cs" /> <Compile Include="Models\SimulationComponent\Impl\Brakes.cs" /> + <Compile Include="Models\SimulationComponent\Impl\CycleGearbox.cs" /> <Compile Include="Models\SimulationComponent\Impl\DefaultDriverStrategy.cs" /> <Compile Include="Models\SimulationComponent\Impl\DummyRetarder.cs" /> <Compile Include="Models\SimulationComponent\Impl\EngineAuxiliary.cs" /> diff --git a/VectoCoreTest/Models/Simulation/MeasuredSpeedModeTest.cs b/VectoCoreTest/Models/Simulation/MeasuredSpeedModeTest.cs index 3ababa20cb..51b7035944 100644 --- a/VectoCoreTest/Models/Simulation/MeasuredSpeedModeTest.cs +++ b/VectoCoreTest/Models/Simulation/MeasuredSpeedModeTest.cs @@ -155,19 +155,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var drivingCycle = DrivingCycleDataReader.ReadFromStream(inputData.GetStream(), cycleType); Assert.AreEqual(cycleType, drivingCycle.CycleType); - if (cycleType == CycleType.MeasuredSpeed) { - var cycle = new MeasuredSpeedDrivingCycle(container, drivingCycle); - } else { - var gearbox = new CycleGearbox(container, - new GearboxData { - Gears = new Dictionary<uint, GearData> { - { 1, new GearData { Ratio = 6.696 } }, - { 2, new GearData { Ratio = 3.806 } }, - { 3, new GearData { Ratio = 2.289 } } - } - }); - var cycle = new MeasuredSpeedGearDrivingCycle(container, drivingCycle); - } + var cycle = new MeasuredSpeedDrivingCycle(container, drivingCycle); } @@ -327,10 +315,9 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); - Assert.IsTrue(File.Exists(@"TestData\Jobs\MeasuredSpeed_Gear.vsum")); - Assert.IsTrue(File.Exists(@"TestData\Jobs\Measuredspeed_Gear.vmod")); - - Assert.Fail("Implement this test!"); + Assert.IsTrue(File.Exists(@"TestData\MeasuredSpeed\MeasuredSpeedGear.vsum"), "SUM file missing."); + Assert.IsTrue(File.Exists(@"TestData\MeasuredSpeed\MeasuredSpeedGear_MeasuredSpeed_Gear_Rural.vmod"), + "MOD File missing."); } } } \ No newline at end of file diff --git a/VectoCoreTest/TestData/MeasuredSpeed/MeasuredSpeedGear.vecto b/VectoCoreTest/TestData/MeasuredSpeed/MeasuredSpeedGear.vecto index eb5f261d46..a5fe755fb7 100644 --- a/VectoCoreTest/TestData/MeasuredSpeed/MeasuredSpeedGear.vecto +++ b/VectoCoreTest/TestData/MeasuredSpeed/MeasuredSpeedGear.vecto @@ -12,15 +12,7 @@ "EngineFile": "Engine.veng", "GearboxFile": "Gearbox.vgbx", "Cycles": [ - "MeasuredSpeed_Gear_Motorway.vdri" - ], - "Aux": [ - { - "ID": "Alt", - "Type": "Alternator", - "Path": "Alternator.vaux", - "Technology": "" - } + "MeasuredSpeed_Gear_Rural.vdri" ], "VACC": "Driver.vacc", "StartStop": { diff --git a/VectoCoreTest/Utils/ResultFileHelper.cs b/VectoCoreTest/Utils/ResultFileHelper.cs index 1371c1a59f..936a77dc44 100644 --- a/VectoCoreTest/Utils/ResultFileHelper.cs +++ b/VectoCoreTest/Utils/ResultFileHelper.cs @@ -66,8 +66,10 @@ namespace TUGraz.VectoCore.Tests.Utils } Assert.IsTrue(expectedCols.SequenceEqual(actualCols), - string.Format("Moddata: Columns differ:\nExpected: {0}\nActual: {1}", ", ".Join(expectedCols), - ", ".Join(actualCols))); + string.Format("Moddata {3}: Columns differ:\nExpected: {0}\nMissing:{1},\nToo Much:{2}", + ", ".Join(expectedCols), + ", ".Join(expectedCols.Except(actualCols)), + ", ".Join(actualCols.Except(expectedCols)), result.actualFile)); for (var i = 0; testRowcount && i < expected.Rows.Count; i++) { var expectedRow = expected.Rows[i]; @@ -96,8 +98,11 @@ namespace TUGraz.VectoCore.Tests.Utils var expectedCols = expected.Columns.Cast<DataColumn>().Select(x => x.ColumnName).OrderBy(x => x).ToList(); Assert.IsTrue(expectedCols.SequenceEqual(actualCols), - string.Format("SUM FILE: Columns differ:\nExpected: {0}\nActual: {1}", ", ".Join(expectedCols), - ", ".Join(actualCols))); + string.Format("SUM FILE {3}: Columns differ:\nExpected: {0}\nMissing:{1},\nToo Much:{2}", + ", ".Join(expectedCols), + ", ".Join(expectedCols.Except(actualCols)), + ", ".Join(actualCols.Except(expectedCols)), + actualFile)); for (var i = 0; i < expected.Rows.Count; i++) { var expectedRow = expected.Rows[i]; -- GitLab