diff --git a/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/Models/Declaration/DeclarationData.cs index 64d8f5f8dd8d3d572f667c7b321a9a0343be83fb..a10817d271505ae7a5d2e273b19226cf23002496 100644 --- a/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/Models/Declaration/DeclarationData.cs @@ -129,7 +129,9 @@ namespace TUGraz.VectoCore.Models.Declaration public static class LookAhead { public const bool Enabled = true; - public static readonly MeterPerSquareSecond Deceleration = -0.5.SI<MeterPerSquareSecond>(); + + public static MeterPerSquareSecond Deceleration = -0.5.SI<MeterPerSquareSecond>(); + public static readonly MeterPerSecond MinimumSpeed = 50.KMPHtoMeterPerSecond(); } diff --git a/VectoCore/Models/Simulation/Impl/DistanceRun.cs b/VectoCore/Models/Simulation/Impl/DistanceRun.cs index 054380aec34d415d7d88fa0b57d31055cb0d6345..c51f33bb38ca46ef5ac6c01da4d3e04785cc2f1d 100644 --- a/VectoCore/Models/Simulation/Impl/DistanceRun.cs +++ b/VectoCore/Models/Simulation/Impl/DistanceRun.cs @@ -14,25 +14,27 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl protected override IResponse DoSimulationStep() { // estimate distance to be traveled within the next TargetTimeInterval - var ds = Container.VehicleSpeed() * Constants.SimulationSettings.TargetTimeInterval; - - if (ds.IsEqual(0)) { - // vehicle stands still, drive a certain distance... - ds = Constants.SimulationSettings.DriveOffDistance; - } + var ds = Container.VehicleSpeed().IsEqual(0) + ? Constants.SimulationSettings.DriveOffDistance + : Constants.SimulationSettings.TargetTimeInterval * Container.VehicleSpeed(); IResponse response; do { response = CyclePort.Request(AbsTime, ds); response.Switch(). Case<ResponseSuccess>(r => { - ds = Container.VehicleSpeed().IsEqual(0) - ? Constants.SimulationSettings.DriveOffDistance - : Constants.SimulationSettings.TargetTimeInterval * Container.VehicleSpeed(); + dt = r.SimulationInterval; + }). + Case<ResponseDrivingCycleDistanceExceeded>(r => { + if (r.MaxDistance <= 0) { + throw new VectoSimulationException("DistanceExceeded, MaxDistance is invalid: {0}", r.MaxDistance); + } + ds = r.MaxDistance; }). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). - Case<ResponseCycleFinished>(r => { }). - Default(r => { throw new VectoException("DistanceRun got an unexpected response: {0}", r); }); + Case<ResponseCycleFinished>(r => {}). + Default(r => { + throw new VectoException("DistanceRun got an unexpected response: {0}", r); + }); } while (!(response is ResponseSuccess || response is ResponseCycleFinished)); return response; diff --git a/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/Models/Simulation/Impl/VectoRun.cs index 8e0550be8dea82fab7f1d947711f4cb2ee9d90b8..2524c659377be257940e6f6aeee3534fabb9a981 100644 --- a/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -42,7 +42,6 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Initialize(); - Container.Gear = 1; do { response = DoSimulationStep(); if (response is ResponseSuccess) { diff --git a/VectoCore/Models/SimulationComponent/IDriverActions.cs b/VectoCore/Models/SimulationComponent/IDriverActions.cs index 42af0aa96ce596da1063bc00d75eaa157066dc0a..236f1f82a2a2eefe597b95c7943fda746bc3d040 100644 --- a/VectoCore/Models/SimulationComponent/IDriverActions.cs +++ b/VectoCore/Models/SimulationComponent/IDriverActions.cs @@ -91,5 +91,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent /// access the vehicle's data bus to get information from other components. /// </summary> IDataBus DataBus { get; } + + MeterPerSquareSecond LookaheadDeceleration { get; } } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 4439a696c94cb343f9540d4198c25b075572847d..90e819da4d8a6968bec1ce09e6a257a7413dea90 100644 --- a/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -51,6 +51,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var nextAction = GetNextDrivingAction(currentDistance); if (nextAction != null && currentDistance.IsEqual(nextAction.ActionDistance)) { CurrentDrivingMode = DrivingMode.DrivingModeBrake; + DrivingModes[CurrentDrivingMode].ResetMode(); BrakeTrigger = nextAction; break; } @@ -63,6 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl case DrivingMode.DrivingModeBrake: if (Driver.DataBus.Distance() >= BrakeTrigger.TriggerDistance) { CurrentDrivingMode = DrivingMode.DrivingModeDrive; + DrivingModes[CurrentDrivingMode].ResetMode(); } break; } @@ -83,7 +85,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // distance until halt var lookaheadDistance = Formulas.DecelerationDistance(currentSpeed, 0.SI<MeterPerSecond>(), - DeclarationData.Driver.LookAhead.Deceleration); + Driver.LookaheadDeceleration); var lookaheadData = Driver.DataBus.LookAhead(1.2 * lookaheadDistance); @@ -104,7 +106,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // NextTargetSpeed = entry.VehicleTargetSpeed // }); var coastingDistance = Formulas.DecelerationDistance(currentSpeed, entry.VehicleTargetSpeed, - DeclarationData.Driver.LookAhead.Deceleration); + Driver.LookaheadDeceleration); Log.Debug("adding 'Coasting' starting at distance {0}", entry.Distance - coastingDistance); nextActions.Add( new DrivingBehaviorEntry { @@ -139,6 +141,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DefaultDriverStrategy DriverStrategy { get; set; } IResponse Request(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient); + + void ResetMode(); } //===================================== @@ -174,6 +178,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } return response; } + + public void ResetMode() {} } //===================================== @@ -220,8 +226,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl MaxDistance = DriverStrategy.BrakeTrigger.TriggerDistance - breakingDistance - currentDistance }; } - if (DriverStrategy.BrakeTrigger.TriggerDistance - breakingDistance > - currentDistance + Constants.SimulationSettings.DriverActionDistanceTolerance) { + if (currentDistance + Constants.SimulationSettings.DriverActionDistanceTolerance > + DriverStrategy.BrakeTrigger.TriggerDistance - breakingDistance) { Phase = BrakingPhase.Brake; } } @@ -234,6 +240,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl response = DriverStrategy.Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient, r); Phase = BrakingPhase.Brake; + }). + Case<ResponseGearShift>(r => { + response = DriverStrategy.Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); }); break; case BrakingPhase.Brake: @@ -241,8 +250,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl gradient); break; } + // todo: @@@quam: add resonse.switch to indicate expected responses? return response; } + + public void ResetMode() + { + Phase = BrakingPhase.Coast; + } } //===================================== diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 640859d4f89312e91668fc9acf657203bf9df5bd..9d60803675d53d0c432634bfb51c7257c5b3b660 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -27,12 +27,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected IDriverStrategy DriverStrategy; + public MeterPerSquareSecond LookaheadDeceleration {get; protected set; } public Driver(VehicleContainer container, DriverData driverData, IDriverStrategy strategy) : base(container) { DriverData = driverData; DriverStrategy = strategy; strategy.Driver = this; + + LookaheadDeceleration = DeclarationData.Driver.LookAhead.Deceleration; } public IDriverDemandInPort InPort() @@ -48,6 +51,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public IResponse Initialize(MeterPerSecond vehicleSpeed, Radian roadGradient) { + LookaheadDeceleration = DriverData.AccelerationCurve.MinDeceleration(); return Next.Initialize(vehicleSpeed, roadGradient); } diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index f3ef31cafdf5a955d8d66fb1ced2452694b34831..d36891f373397b6390d69b102ee832e8c0eb4a93 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -90,7 +90,57 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // * EarlyUpshift (shift before outside of up-shift curve if torque reserve for the next higher gear is fullfilled) // * SkipGears (when already shifting to next gear, check if torque reserve is fullfilled for the overnext gear and eventually shift to it) // * MT, AMT and AT .... different behaviour! - +/* + if (dryRun) { + var gear = Gear; + if (gear == 0 && _shiftTime <= absTime) { + gear = FindGear(outTorque, outEngineSpeed, Data.SkipGears); + } + if (gear == 0) { + return new ResponseDryRun() { GearboxPowerRequest = outTorque * outEngineSpeed, Source = this }; + } else { + var inEngineSpeedDry = outEngineSpeed * Data.Gears[gear].Ratio; + var inTorqueDry = Data.Gears[gear].LossMap.GearboxInTorque(inEngineSpeedDry, outTorque); + var dryRunResponse = Next.Request(absTime, dt, inTorqueDry, inEngineSpeedDry, true); + dryRunResponse.GearboxPowerRequest = outTorque * outEngineSpeed; + return dryRunResponse; + } + } else { + if (Gear == 0) { + if (_shiftTime <= absTime) { + Gear = FindGear(outTorque, outEngineSpeed, Data.SkipGears); + } + if (!outTorque.IsEqual(0)) + { + return new ResponseOverload + { + Delta = outTorque * outEngineSpeed, + Source = this, + GearboxPowerRequest = outTorque * outEngineSpeed + }; + } + } + + // Check if shift is needed and eventually return ResponseGearShift + if (_shiftTime + Data.ShiftTime < absTime && + (ShouldShiftUp(Gear, inEngineSpeed, inTorque) || ShouldShiftDown(Gear, inEngineSpeed, inTorque))) + { + _shiftTime = absTime + Data.TractionInterruption; + LastGear = Gear; + Gear = 0; + + Log.Debug("Gearbox is shifting. absTime: {0}, shiftTime: {1}, outTorque:{2}, outEngineSpeed: {3}", + absTime, _shiftTime, outTorque, outEngineSpeed); + + return new ResponseGearShift + { + SimulationInterval = Data.TractionInterruption, + Source = this, + GearboxPowerRequest = outTorque * outEngineSpeed + }; + } + } +*/ if (Gear == 0) { // if no gear is set and dry run: just set GearBoxPowerRequest if (dryRun) { @@ -141,7 +191,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Log.Debug("Gearbox is shifting. absTime: {0}, shiftTime: {1}, outTorque:{2}, outEngineSpeed: {3}", absTime, _shiftTime, outTorque, outEngineSpeed); - return new ResponseGearShift { SimulationInterval = Data.TractionInterruption, Source = this }; + return new ResponseGearShift { + SimulationInterval = Data.TractionInterruption, + Source = this, + GearboxPowerRequest = outTorque * outEngineSpeed + }; } // Normal Response diff --git a/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs b/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs index 0b37bc351e10be86569e565cdbe7dc10a18943cc..0d20f7630e6b2ddfd4acbade5e29ca453dbbb3d5 100644 --- a/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs +++ b/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs @@ -49,10 +49,10 @@ namespace TUGraz.VectoCore.Tests.Integration.DriverStrategy { var cycle = CreateCycleData(new string[] { " 0,80,0,0", - "900, 0,0,0", + "2500, 0,0,0", }); - var run = CreatePowerTrain(cycle, "DriverStrategy_Accelerate_0_80_level.vmod"); + var run = CreatePowerTrain(cycle, "DriverStrategy_Accelerate_80_0_level.vmod"); run.Run(); }