diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IPowertrainSimulation.cs b/VectoCore/VectoCore/Models/SimulationComponent/IPowertrainSimulation.cs deleted file mode 100644 index 913d3dadca00b8bc25ee94b0be0e22c5ad2105c9..0000000000000000000000000000000000000000 --- a/VectoCore/VectoCore/Models/SimulationComponent/IPowertrainSimulation.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2016 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* 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. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using TUGraz.VectoCore.Models.Connector.Ports; - -namespace TUGraz.VectoCore.Models.SimulationComponent -{ - /// <summary> - /// Defines interfaces for a powertrain only driving cycle. - /// </summary> - public interface IPowertrainSimulation : IDrivingCycleInfo, ISimulationOutProvider, ITnInProvider {} -} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs new file mode 100644 index 0000000000000000000000000000000000000000..b127496f976ebebd9e034aa544cf56dac01ecb3a --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs @@ -0,0 +1,269 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +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.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 +{ + /// <summary> + /// Driving Cycle for the Measured Speed Gear driving cycle. + /// </summary> + public class MeasuredSpeedDrivingCycle : + StatefulProviderComponent + <MeasuredSpeedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDriverDemandInPort, IDriverDemandOutPort>, + IDriverInfo, IDrivingCycleInfo, IMileageCounter, IDriverDemandInProvider, IDriverDemandInPort, ISimulationOutProvider, + ISimulationOutPort + { + public class DrivingCycleState + { + public DrivingCycleState Clone() + { + return new DrivingCycleState { + Distance = Distance, + VehicleSpeed = VehicleSpeed, + }; + } + + public Meter Distance; + public MeterPerSecond VehicleSpeed; + public Meter SimulationDistance; + public MeterPerSquareSecond Acceleration; + } + + protected DrivingCycleData Data; + private bool _isInitializing; + protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; } + protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; } + + 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 MeasuredSpeedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) + : base(container) + { + Data = cycle; + LeftSample = Data.Entries.GetEnumerator(); + LeftSample.MoveNext(); + + RightSample = Data.Entries.GetEnumerator(); + RightSample.MoveNext(); + RightSample.MoveNext(); + + var first = LeftSample.Current; + PreviousState = new DrivingCycleState { + Distance = 0.SI<Meter>(), + VehicleSpeed = first.VehicleTargetSpeed, + }; + CurrentState = PreviousState.Clone(); + } + + public IResponse Initialize() + { + var first = Data.Entries.First(); + + AbsTime = first.Time; + + _isInitializing = true; + + var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient); + if (!(response is ResponseSuccess)) { + throw new UnexpectedResponseException("Couldn't find start gear.", response); + } + + _isInitializing = false; + + response.AbsTime = AbsTime; + return response; + } + + public IResponse Request(Second absTime, Meter ds) + { + Log.Fatal("MeasuredSpeed Cycle can not handle distance request."); + throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request."); + } + + public virtual IResponse Request(Second absTime, Second dt) + { + var debug = new DebugData(); + + // cycle finished + 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 + }; + } + + // calc acceleration from speed diff vehicle to cycle + var deltaV = RightSample.Current.VehicleTargetSpeed - DataBus.VehicleSpeed; + var deltaT = RightSample.Current.Time - LeftSample.Current.Time; + var acceleration = deltaV / deltaT; + var gradient = LeftSample.Current.RoadGradient; + DriverAcceleration = acceleration; + DriverBehavior = acceleration < 0 + ? DriverBehavior = DrivingBehavior.Braking + : DriverBehavior = DrivingBehavior.Driving; + + IResponse response; + var responseCount = 0; + do { + response = NextComponent.Request(absTime, dt, acceleration, gradient); + debug.Add(response); + response.Switch() + .Case<ResponseGearShift>(() => response = NextComponent.Request(absTime, dt, acceleration, gradient)) + .Case<ResponseUnderload>(r => { + DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, + getYValue: result => RightSample.Current.Gear == 0 + ? ((ResponseDryRun)result).GearboxPowerRequest + : ((ResponseDryRun)result).DeltaDragLoad, + evaluateFunction: x => { + DataBus.BrakePower = x; + return NextComponent.Request(absTime, dt, acceleration, gradient, true); + }, + criterion: y => RightSample.Current.Gear == 0 + ? ((ResponseDryRun)y).GearboxPowerRequest.Value() + : ((ResponseDryRun)y).DeltaDragLoad.Value()); + Log.Info( + "Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}", + absTime, dt, acceleration, gradient, DataBus.BrakePower); + response = NextComponent.Request(absTime, dt, acceleration, gradient); + }) + .Case<ResponseOverload>(r => { + acceleration = SearchAlgorithm.Search(acceleration, r.Delta, + Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, + getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, + evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), + criterion: + y => ((ResponseDryRun)y).DeltaFullLoad.Value()); + Log.Info( + "Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", + absTime, + dt, acceleration, gradient); + response = NextComponent.Request(absTime, dt, acceleration, gradient); + }) + .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) + .Case<ResponseSuccess>() + .Default( + r => { throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle received an unexpected response.", r); }); + } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); + + AbsTime = absTime + dt; + + response.SimulationInterval = dt; + response.Acceleration = acceleration; + debug.Add(response); + + CurrentState.SimulationDistance = acceleration / 2 * dt * dt + PreviousState.VehicleSpeed * dt; + CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance; + CurrentState.VehicleSpeed = acceleration * dt + PreviousState.VehicleSpeed; + CurrentState.Acceleration = acceleration; + + return response; + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.dist] = CurrentState.Distance; + container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance; + container[ModalResultField.v_targ] = LeftSample.Current.VehicleTargetSpeed; + container[ModalResultField.grad] = LeftSample.Current.RoadGradientPercent; + container[ModalResultField.altitude] = LeftSample.Current.Altitude; + container[ModalResultField.acc] = CurrentState.Acceleration; + } + + protected override void DoCommitSimulationStep() + { + if ((RightSample.Current == null) || AbsTime.IsGreaterOrEqual(RightSample.Current.Time)) { + RightSample.MoveNext(); + LeftSample.MoveNext(); + } + + PreviousState = CurrentState; + CurrentState = CurrentState.Clone(); + } + + public string CycleName + { + get { return Data.Name; } + } + + public double Progress + { + get { return AbsTime == null ? 0 : AbsTime.Value() / Data.Entries.Last().Time.Value(); } + } + + public CycleData CycleData + { + get + { + return new CycleData { + AbsTime = LeftSample.Current.Time, + AbsDistance = null, + LeftSample = LeftSample.Current, + RightSample = RightSample.Current, + }; + } + } + + public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) + { + return new DrivingCycleData.DrivingCycleEntry(RightSample.Current); + //throw new System.NotImplementedException(); + } + + public Meter Altitude + { + get { return LeftSample.Current.Altitude; } + } + + public Meter CycleStartDistance + { + get { return 0.SI<Meter>(); } + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) + { + throw new NotImplementedException(); + } + + public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) + { + throw new NotImplementedException(); + } + + public bool VehicleStopped + { + get { return !_isInitializing && LeftSample.Current.VehicleTargetSpeed.IsEqual(0); } + } + + public DrivingBehavior DriverBehavior { get; internal set; } + + public MeterPerSquareSecond DriverAcceleration { get; protected set; } + + public Meter Distance + { + get { return CurrentState.Distance; } + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOEngineCycleController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOEngineCycleController.cs new file mode 100644 index 0000000000000000000000000000000000000000..ef003b4f9bbbbc3261072bd4b4aae8df7f36cabb --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PTOEngineCycleController.cs @@ -0,0 +1,51 @@ +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Simulation; +using TUGraz.VectoCore.Models.SimulationComponent.Data; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class PTOEngineCycleController : PowertrainDrivingCycle, ICombustionEngineIdleController + { + public ITnOutPort RequestPort { get; set; } + protected Second IdleStart; + + public PTOEngineCycleController(IVehicleContainer container, DrivingCycleData cycle) + : base(container, cycle) {} + + public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, + bool dryRun = false) + { + if (outAngularVelocity != null) { + throw new VectoException("{0} can only handle idle requests: AngularVelocity has to be null!", GetType().ToString()); + } + if (!outTorque.IsEqual(0)) { + throw new VectoException("{0} can only handle idle requests: Torque has to be 0!", GetType().ToString()); + } + if (IdleStart == null) { + IdleStart = absTime; + } + return base.Request(absTime, dt); + } + + public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) + { + return new ResponseSuccess { Source = this }; + } + + public void Reset() + { + LeftSample = Data.Entries.GetEnumerator(); + LeftSample.MoveNext(); + + RightSample = Data.Entries.GetEnumerator(); + RightSample.MoveNext(); + RightSample.MoveNext(); + + IdleStart = null; + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs new file mode 100644 index 0000000000000000000000000000000000000000..6127390842f3f5285dc759f27588a19df5fb037e --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PWheelCycle.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +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.OutputData; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + /// <summary> + /// Driving Cycle for the PWheel driving cycle. + /// </summary> + public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo + { + /// <summary> + /// Initializes a new instance of the <see cref="PWheelCycle"/> class. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="cycle">The cycle.</param> + /// <param name="axleRatio">The axle ratio.</param> + /// <param name="gearRatios"></param> + public PWheelCycle(IVehicleContainer container, DrivingCycleData cycle, double axleRatio, + IDictionary<uint, double> gearRatios) : base(container, cycle) + { + // just to ensure that null-gear has ratio 1 + gearRatios[0] = 1; + + foreach (var entry in Data.Entries) { + entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]); + entry.Torque = entry.PWheel / entry.WheelAngularVelocity; + } + } + + public override IResponse Request(Second absTime, Second dt) + { + if (RightSample.Current == null) { + return new ResponseCycleFinished { Source = this }; + } + + // interval exceeded + if ((absTime + dt).IsGreater(RightSample.Current.Time)) { + return new ResponseFailTimeInterval { + AbsTime = absTime, + Source = this, + DeltaT = RightSample.Current.Time - absTime + }; + } + + return DoHandleRequest(absTime, dt, LeftSample.Current.WheelAngularVelocity); + } + + protected override void DoWriteModalResults(IModalDataContainer container) + { + container[ModalResultField.P_wheel_in] = LeftSample.Current.PWheel; + base.DoWriteModalResults(container); + } + + #region IDriverInfo + + /// <summary> + /// True if the angularVelocity at the wheels is 0. + /// </summary> + public bool VehicleStopped + { + get { return false; } + } + + /// <summary> + /// Always Driving. + /// </summary> + public DrivingBehavior DriverBehavior + { + get { return DrivingBehavior.Driving; } + } + + public MeterPerSquareSecond DriverAcceleration + { + get { return 0.SI<MeterPerSquareSecond>(); } + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs index 1c22fff8ad2fd6e334009189992532f262f19059..60dd67a49fb885c2654ed684b760e36154039097 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PowertrainDrivingCycle.cs @@ -35,12 +35,9 @@ using System.Linq; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; -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.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.Utils; @@ -50,11 +47,13 @@ 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, IPowertrainSimulation, ITnInPort, - ISimulationOutPort + public class PowertrainDrivingCycle : + StatefulProviderComponent<PowertrainDrivingCycle.DummyState, ISimulationOutPort, ITnInPort, ITnOutPort>, + IDrivingCycleInfo, ISimulationOutPort, ITnInProvider { - protected DrivingCycleData Data; - protected ITnOutPort NextComponent; + public class DummyState {} + + protected readonly DrivingCycleData Data; protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; } protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; } @@ -78,24 +77,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl AbsTime = 0.SI<Second>(); } - #region ITnInProvider - - public ITnInPort InPort() - { - return this; - } - - #endregion - - #region ISimulationOutProvider - - public ISimulationOutPort OutPort() - { - return this; - } - - #endregion - #region ISimulationOutPort public IResponse Request(Second absTime, Meter ds) @@ -183,15 +164,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl #endregion - #region ITnInPort - - public void Connect(ITnOutPort other) - { - NextComponent = other; - } - - #endregion - #region VectoSimulationComponent protected override void DoWriteModalResults(IModalDataContainer container) {} @@ -246,329 +218,4 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl throw new NotImplementedException(); } } - - /// <summary> - /// Driving Cycle for the PWheel driving cycle. - /// </summary> - public class PWheelCycle : PowertrainDrivingCycle, IDriverInfo - { - /// <summary> - /// Initializes a new instance of the <see cref="PWheelCycle"/> class. - /// </summary> - /// <param name="container">The container.</param> - /// <param name="cycle">The cycle.</param> - /// <param name="axleRatio">The axle ratio.</param> - /// <param name="gearRatios"></param> - public PWheelCycle(IVehicleContainer container, DrivingCycleData cycle, double axleRatio, - IDictionary<uint, double> gearRatios) : base(container, cycle) - { - // just to ensure that null-gear has ratio 1 - gearRatios[0] = 1; - - foreach (var entry in Data.Entries) { - entry.WheelAngularVelocity = entry.AngularVelocity / (axleRatio * gearRatios[entry.Gear]); - entry.Torque = entry.PWheel / entry.WheelAngularVelocity; - } - } - - public override IResponse Request(Second absTime, Second dt) - { - if (RightSample.Current == null) { - return new ResponseCycleFinished { Source = this }; - } - - // interval exceeded - if ((absTime + dt).IsGreater(RightSample.Current.Time)) { - return new ResponseFailTimeInterval { - AbsTime = absTime, - Source = this, - DeltaT = RightSample.Current.Time - absTime - }; - } - - return DoHandleRequest(absTime, dt, LeftSample.Current.WheelAngularVelocity); - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - container[ModalResultField.P_wheel_in] = LeftSample.Current.PWheel; - base.DoWriteModalResults(container); - } - - #region IDriverInfo - - /// <summary> - /// True if the angularVelocity at the wheels is 0. - /// </summary> - public bool VehicleStopped - { - get { return false; } - } - - /// <summary> - /// Always Driving. - /// </summary> - public DrivingBehavior DriverBehavior - { - get { return DrivingBehavior.Driving; } - } - - public MeterPerSquareSecond DriverAcceleration - { - get { return 0.SI<MeterPerSquareSecond>(); } - } - - #endregion - } - - /// <summary> - /// Driving Cycle for the Measured Speed Gear driving cycle. - /// </summary> - public class MeasuredSpeedDrivingCycle : - StatefulProviderComponent - <MeasuredSpeedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDriverDemandInPort, IDriverDemandOutPort>, - IDriverInfo, IDrivingCycleInfo, IMileageCounter, IDriverDemandInProvider, IDriverDemandInPort, ISimulationOutProvider, - ISimulationOutPort - { - public class DrivingCycleState - { - public DrivingCycleState Clone() - { - return new DrivingCycleState { - Distance = Distance, - VehicleSpeed = VehicleSpeed, - }; - } - - public Meter Distance; - public MeterPerSecond VehicleSpeed; - public Meter SimulationDistance; - public MeterPerSquareSecond Acceleration; - } - - protected DrivingCycleData Data; - private bool _isInitializing; - protected IEnumerator<DrivingCycleData.DrivingCycleEntry> RightSample { get; set; } - protected IEnumerator<DrivingCycleData.DrivingCycleEntry> LeftSample { get; set; } - - 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 MeasuredSpeedDrivingCycle(IVehicleContainer container, DrivingCycleData cycle) - : base(container) - { - Data = cycle; - LeftSample = Data.Entries.GetEnumerator(); - LeftSample.MoveNext(); - - RightSample = Data.Entries.GetEnumerator(); - RightSample.MoveNext(); - RightSample.MoveNext(); - - var first = LeftSample.Current; - PreviousState = new DrivingCycleState { - Distance = 0.SI<Meter>(), - VehicleSpeed = first.VehicleTargetSpeed, - }; - CurrentState = PreviousState.Clone(); - } - - public IResponse Initialize() - { - var first = Data.Entries.First(); - - AbsTime = first.Time; - - _isInitializing = true; - - var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient); - if (!(response is ResponseSuccess)) { - throw new UnexpectedResponseException("Couldn't find start gear.", response); - } - - _isInitializing = false; - - response.AbsTime = AbsTime; - return response; - } - - public IResponse Request(Second absTime, Meter ds) - { - Log.Fatal("MeasuredSpeed Cycle can not handle distance request."); - throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request."); - } - - public virtual IResponse Request(Second absTime, Second dt) - { - var debug = new DebugData(); - - // cycle finished - 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 - }; - } - - // calc acceleration from speed diff vehicle to cycle - var deltaV = RightSample.Current.VehicleTargetSpeed - DataBus.VehicleSpeed; - var deltaT = RightSample.Current.Time - LeftSample.Current.Time; - var acceleration = deltaV / deltaT; - var gradient = LeftSample.Current.RoadGradient; - DriverAcceleration = acceleration; - DriverBehavior = acceleration < 0 - ? DriverBehavior = DrivingBehavior.Braking - : DriverBehavior = DrivingBehavior.Driving; - - IResponse response; - var responseCount = 0; - do { - response = NextComponent.Request(absTime, dt, acceleration, gradient); - debug.Add(response); - response.Switch() - .Case<ResponseGearShift>(() => response = NextComponent.Request(absTime, dt, acceleration, gradient)) - .Case<ResponseUnderload>(r => { - DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta, - getYValue: result => RightSample.Current.Gear == 0 - ? ((ResponseDryRun)result).GearboxPowerRequest - : ((ResponseDryRun)result).DeltaDragLoad, - evaluateFunction: x => { - DataBus.BrakePower = x; - return NextComponent.Request(absTime, dt, acceleration, gradient, true); - }, - criterion: y => RightSample.Current.Gear == 0 - ? ((ResponseDryRun)y).GearboxPowerRequest.Value() - : ((ResponseDryRun)y).DeltaDragLoad.Value()); - Log.Info( - "Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}", - absTime, dt, acceleration, gradient, DataBus.BrakePower); - response = NextComponent.Request(absTime, dt, acceleration, gradient); - }) - .Case<ResponseOverload>(r => { - acceleration = SearchAlgorithm.Search(acceleration, r.Delta, - Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating, - getYValue: result => ((ResponseDryRun)result).DeltaFullLoad, - evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true), - criterion: - y => ((ResponseDryRun)y).DeltaFullLoad.Value()); - Log.Info( - "Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}", - absTime, - dt, acceleration, gradient); - response = NextComponent.Request(absTime, dt, acceleration, gradient); - }) - .Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; }) - .Case<ResponseSuccess>() - .Default( - r => { throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle received an unexpected response.", r); }); - } while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10)); - - AbsTime = absTime + dt; - - response.SimulationInterval = dt; - response.Acceleration = acceleration; - debug.Add(response); - - CurrentState.SimulationDistance = acceleration / 2 * dt * dt + PreviousState.VehicleSpeed * dt; - CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance; - CurrentState.VehicleSpeed = acceleration * dt + PreviousState.VehicleSpeed; - CurrentState.Acceleration = acceleration; - - return response; - } - - protected override void DoWriteModalResults(IModalDataContainer container) - { - container[ModalResultField.dist] = CurrentState.Distance; - container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance; - container[ModalResultField.v_targ] = LeftSample.Current.VehicleTargetSpeed; - container[ModalResultField.grad] = LeftSample.Current.RoadGradientPercent; - container[ModalResultField.altitude] = LeftSample.Current.Altitude; - container[ModalResultField.acc] = CurrentState.Acceleration; - } - - protected override void DoCommitSimulationStep() - { - if ((RightSample.Current == null) || AbsTime.IsGreaterOrEqual(RightSample.Current.Time)) { - RightSample.MoveNext(); - LeftSample.MoveNext(); - } - - PreviousState = CurrentState; - CurrentState = CurrentState.Clone(); - } - - public string CycleName - { - get { return Data.Name; } - } - - public double Progress - { - get { return AbsTime == null ? 0 : AbsTime.Value() / Data.Entries.Last().Time.Value(); } - } - - public CycleData CycleData - { - get - { - return new CycleData { - AbsTime = LeftSample.Current.Time, - AbsDistance = null, - LeftSample = LeftSample.Current, - RightSample = RightSample.Current, - }; - } - } - - public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance) - { - return new DrivingCycleData.DrivingCycleEntry(RightSample.Current); - //throw new System.NotImplementedException(); - } - - public Meter Altitude - { - get { return LeftSample.Current.Altitude; } - } - - public Meter CycleStartDistance - { - get { return 0.SI<Meter>(); } - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance) - { - throw new NotImplementedException(); - } - - public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time) - { - throw new NotImplementedException(); - } - - public bool VehicleStopped - { - get { return !_isInitializing && LeftSample.Current.VehicleTargetSpeed.IsEqual(0); } - } - - public DrivingBehavior DriverBehavior { get; internal set; } - - public MeterPerSquareSecond DriverAcceleration { get; protected set; } - - public Meter Distance - { - get { return CurrentState.Distance; } - } - } } \ No newline at end of file diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index ea67bf8d1e1b0de354bb3b58e3802aa1369e7b16..1b71ff4030c21deaaa98bba374642a7063ae9650 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -149,6 +149,9 @@ <Compile Include="Models\SimulationComponent\Impl\AbstractGearbox.cs" /> <Compile Include="Models\SimulationComponent\Impl\ATGearbox.cs" /> <Compile Include="Models\SimulationComponent\Impl\ATShiftStrategy.cs" /> + <Compile Include="Models\SimulationComponent\Impl\MeasuredSpeedDrivingCycle.cs" /> + <Compile Include="Models\SimulationComponent\Impl\PTOEngineCycleController.cs" /> + <Compile Include="Models\SimulationComponent\Impl\PWheelCycle.cs" /> <Compile Include="Models\SimulationComponent\Impl\TorqueConverter.cs" /> <Compile Include="Utils\ProviderExtensions.cs" /> <Compile Include="Models\Declaration\AirDrag.cs" /> @@ -249,7 +252,6 @@ <Compile Include="Models\SimulationComponent\Data\RetarderLossMap.cs" /> <Compile Include="Models\SimulationComponent\Data\VehicleData.cs" /> <Compile Include="Models\SimulationComponent\IClutch.cs" /> - <Compile Include="Models\SimulationComponent\IPowertrainSimulation.cs" /> <Compile Include="Models\SimulationComponent\IDrivingCycle.cs" /> <Compile Include="Models\SimulationComponent\IDriver.cs" /> <Compile Include="Models\SimulationComponent\Impl\Vehicle.cs" />