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 e46a625c1a66437aa40f6a04c9317da8d4356e40..5c071725bda812286989a99e8f78444d7291c4de 100644 --- a/VectoCore/Models/Simulation/Impl/DistanceRun.cs +++ b/VectoCore/Models/Simulation/Impl/DistanceRun.cs @@ -14,12 +14,9 @@ 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 { @@ -28,7 +25,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Case<ResponseSuccess>(r => { dt = r.SimulationInterval; }). - Case<ResponseDrivingCycleDistanceExceeded>(r => ds = r.MaxDistance). + Case<ResponseDrivingCycleDistanceExceeded>(r => { + if (r.MaxDistance.Value().IsSmallerOrEqual(0)) { + throw new VectoSimulationException("DistanceExceeded, MaxDistance is invalid: {0}", r.MaxDistance); + } + ds = r.MaxDistance; + }). Case<ResponseCycleFinished>(r => {}). Default(r => { throw new VectoException("DistanceRun got an unexpected response: {0}", r); diff --git a/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/Models/Simulation/Impl/VectoRun.cs index 0ff758681b978463c76ebff22ebfdce03b0c7c38..9769a6775efc451116ecf26af30826e641885ea4 100644 --- a/VectoCore/Models/Simulation/Impl/VectoRun.cs +++ b/VectoCore/Models/Simulation/Impl/VectoRun.cs @@ -20,17 +20,17 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl protected IModalDataWriter DataWriter { get; set; } protected IVehicleContainer Container { get; set; } - public IVehicleContainer GetContainer() - { - return Container; - } - protected VectoRun(IVehicleContainer container) { Container = container; CyclePort = container.GetCycleOutPort(); } + public IVehicleContainer GetContainer() + { + return Container; + } + public void Run() { 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/Clutch.cs b/VectoCore/Models/SimulationComponent/Impl/Clutch.cs index 0a1d8aca7dff8762f6e6bb7920fd2af4223524c7..c507bede2f1507c118b6fc6df71d5605d3b8484c 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Clutch.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Clutch.cs @@ -55,6 +55,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity, bool dryRun = false) { + if (angularVelocity == null) { + var retval = _nextComponent.Request(absTime, dt, torque, null, dryRun); + retval.ClutchPowerRequest = 0.SI<Watt>(); + return retval; + } NewtonMeter torqueIn; PerSecond engineSpeedIn; AddClutchLoss(torque, angularVelocity, out torqueIn, out engineSpeedIn); @@ -87,6 +92,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl torqueIn = torque; engineSpeedIn = angularVelocity; + // @@@quam //if (DataBus.Gear == 0) { // _clutchState = SimulationComponent.ClutchState.ClutchOpened; @@ -113,6 +119,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Log.Debug("to Engine: torque: {0}, angularVelocity: {1}, power {2}", torqueIn, engineSpeedIn, Formulas.TorqueToPower(torqueIn, engineSpeedIn)); } - } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index b8c6a6a16692d4c32af729daa7c163d08cc7493a..9fb5ecf1eca228c52f6a521576e941314a894265 100644 --- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -88,6 +88,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { Watt requestedPower; Watt requestedEnginePower; + + if (engineSpeed == null) { + // TODO: clarify what to do if engine speed is undefined (clutch open) + engineSpeed = _previousState.EngineSpeed; + } ComputeRequestedEnginePower(absTime, dt, torque, engineSpeed, out requestedPower, out requestedEnginePower); ComputeFullLoadPower(engineSpeed, dt); diff --git a/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 7a9f21f55cdf80429d5c39dd9f5b026aa106397b..c2bd91d43a77273763161d042d40f16e36518c97 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/DistanceBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs index 0e3a7d0a050010eaff88f3d9e61dedc05b6d24f6..114986066c3e654bb8af969c12bb513915847251 100644 --- a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs @@ -102,7 +102,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } } - if (PreviousState.Distance + ds > CycleIntervalIterator.RightSample.Distance) { + if ((PreviousState.Distance + ds).IsGreater(CycleIntervalIterator.RightSample.Distance)) { // only drive until next sample point in cycle return new ResponseDrivingCycleDistanceExceeded { MaxDistance = CycleIntervalIterator.RightSample.Distance - PreviousState.Distance diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs index a7b7a80191a63e9dd612b1938b4be4f14478247b..6657405b07b072d08a380dff57c4edaa98267ed9 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); } @@ -158,9 +162,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Log.Debug("DrivingAction Roll"); var retVal = CoastOrRollAction(absTime, ds, maxVelocity, gradient); - retVal.Switch().Case<ResponseGearShift>(() => { - throw new UnexpectedResponseException("DrivingAction Roll: Gearshift during Roll action", retVal); - }); + retVal.Switch(). + //Case<ResponseFailTimeInterval>(r => { + // retVal = new ResponseDrivingCycleDistanceExceeded() { + // Source = r.Source, + // MaxDistance = + // }; + //}). + Case<ResponseGearShift>(() => { + throw new UnexpectedResponseException("DrivingAction Roll: Gearshift during Roll action", retVal); + }); return retVal; } @@ -177,15 +188,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// * ResponseSpeedLimitExceeded: vehicle accelerates during coasting which would lead to exceeding the given maxVelocity (e.g., driving downhill, engine's drag load is not sufficient) /// * ResponseUnderload: engine's operating point is below drag curve (vehicle accelerates more than driver model allows; engine's drag load is not sufficient for limited acceleration /// * ResponseGearShift: gearbox needs to shift gears, vehicle can not accelerate (traction interruption) + /// * ResponseFailTimeInterval: /// </returns> protected IResponse CoastOrRollAction(Second absTime, Meter ds, MeterPerSecond maxVelocity, Radian gradient) { var operatingPoint = ComputeAcceleration(ds, DataBus.VehicleSpeed()); - // todo: @@@ use current velocity instead of maxVelocity? + var response = Next.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, gradient, true); - var response = Next.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, gradient, - dryRun: true); + //if (response is ResponseFailTimeInterval) { + // return response; + //} operatingPoint = SearchOperatingPoint(absTime, operatingPoint.SimulationDistance, gradient, operatingPoint.Acceleration, response, coasting: true); @@ -224,6 +237,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Case<ResponseSuccess>(). Case<ResponseUnderload>(). // driver limits acceleration, operating point may be below engine's drag load Case<ResponseGearShift>(). + Case<ResponseFailTimeInterval>(r => { + retVal = new ResponseDrivingCycleDistanceExceeded() { + Source = this, + MaxDistance = DataBus.VehicleSpeed() * r.DeltaT + CurrentState.Acceleration / 2 * r.DeltaT * r.DeltaT + }; + }). Default(() => { throw new UnexpectedResponseException("CoastOrRoll Action: unhandled response from powertrain", retVal); }); @@ -407,6 +426,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (actionRoll) { initialResponse.Switch(). Case<ResponseDryRun>(r => origDelta = r.GearboxPowerRequest). + Case<ResponseFailTimeInterval>(r => origDelta = r.GearboxPowerRequest). Default(r => { throw new VectoSimulationException("Unknown response type. {0}", r); }); diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs index f3ef31cafdf5a955d8d66fb1ced2452694b34831..028719789135433a94cfbe19f2d0154fec099970 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs @@ -1,4 +1,7 @@ -using System.Diagnostics; +using System; +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; @@ -27,6 +30,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl /// </summary> private Second _shiftTime = double.NegativeInfinity.SI<Second>(); + //private Second _lastShiftTime = double.NegativeInfinity.SI<Second>(); + /// <summary> /// The power loss for the mod data. /// </summary> @@ -91,62 +96,71 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // * 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 (Gear == 0) { - // if no gear is set and dry run: just set GearBoxPowerRequest - if (dryRun) { - return new ResponseDryRun { GearboxPowerRequest = outTorque * outEngineSpeed, Source = this }; - } + if (!dryRun && !Double.IsInfinity(_shiftTime.Value()) && absTime.IsSmaller(_shiftTime) && + (absTime + dt).IsGreater(_shiftTime)) { + return new ResponseFailTimeInterval() { + DeltaT = _shiftTime - absTime, + GearboxPowerRequest = outTorque * outEngineSpeed, + Source = this + }; + } + return absTime < _shiftTime + ? DoHandleRequestNeutralGear(absTime, dt, outTorque, outEngineSpeed, dryRun) + : DoHandleRequestGearEngaged(absTime, dt, outTorque, outEngineSpeed, dryRun); + } - // if shiftTime still not reached (only happens during shifting): apply zero-request - if (_shiftTime > absTime) { - var duringShiftResponse = Next.Request(absTime, dt, 0.SI<NewtonMeter>(), - outEngineSpeed * Data.Gears[LastGear].Ratio); - duringShiftResponse.GearboxPowerRequest = outTorque * outEngineSpeed; - return duringShiftResponse; - } + private IResponse DoHandleRequestNeutralGear(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outEngineSpeed, bool dryRun) + { + if (dryRun) { + return new ResponseDryRun { GearboxPowerRequest = outTorque * outEngineSpeed, Source = this }; + } - // if shiftTime was reached and gear is not set: set correct gear - if (_shiftTime <= absTime) { - Gear = FindGear(outTorque, outEngineSpeed, Data.SkipGears); - } else { - // if clutch is open the gearbox can't provide a torque - // todo: @@@ quam: unreachable code! see if statement above! - if (!outTorque.IsEqual(0)) { - return new ResponseOverload { - Delta = outTorque * outEngineSpeed, - Source = this, - GearboxPowerRequest = outTorque * outEngineSpeed - }; - } - } + if (!outTorque.IsEqual(0, Constants.SimulationSettings.EngineFLDPowerTolerance)) { + return new ResponseOverload { + Delta = outTorque * outEngineSpeed, + Source = this, + GearboxPowerRequest = outTorque * outEngineSpeed + }; } - var inEngineSpeed = outEngineSpeed * Data.Gears[Gear].Ratio; - var inTorque = Data.Gears[Gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque); + var neutralResponse = Next.Request(absTime, dt, 0.SI<NewtonMeter>(), null); + neutralResponse.GearboxPowerRequest = outTorque * outEngineSpeed; - // if dryRun and gear is set: apply dryRun request - if (dryRun) { - var dryRunResponse = Next.Request(absTime, dt, inTorque, inEngineSpeed, true); - dryRunResponse.GearboxPowerRequest = outTorque * outEngineSpeed; - return dryRunResponse; + return neutralResponse; + } + + private IResponse DoHandleRequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, + PerSecond outEngineSpeed, bool dryRun) + { + if (Gear == 0) { + Gear = FindGear(outTorque, outEngineSpeed, Data.SkipGears); + //_lastShiftTime = _shiftTime; + //_shiftTime = double.NegativeInfinity.SI<Second>(); } + var inEngineSpeed = outEngineSpeed * Data.Gears[Gear].Ratio; + var inTorque = Data.Gears[Gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque); + // Check if shift is needed and eventually return ResponseGearShift - if (_shiftTime + Data.ShiftTime < absTime && + if (!dryRun && _shiftTime + Data.ShiftTime < absTime && (ShouldShiftUp(Gear, inEngineSpeed, inTorque) || ShouldShiftDown(Gear, inEngineSpeed, inTorque))) { _shiftTime = absTime + Data.TractionInterruption; - LastGear = Gear; + LastGear = FindGear(outTorque, outEngineSpeed, Data.SkipGears); + //NextGear = FindGear(outTorque, outEngineSpeed, Data.SkipGears) 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 }; + return new ResponseGearShift { + SimulationInterval = Data.TractionInterruption, + Source = this, + GearboxPowerRequest = outTorque * outEngineSpeed + }; } - - // Normal Response _powerLoss = inTorque * inEngineSpeed - outTorque * outEngineSpeed; - var response = Next.Request(absTime, dt, inTorque, inEngineSpeed); + var response = Next.Request(absTime, dt, inTorque, inEngineSpeed, dryRun); response.GearboxPowerRequest = outTorque * outEngineSpeed; return response; } @@ -175,7 +189,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl continue; } break; + // ReSharper disable once LoopVariableIsNeverChangedInsideLoop } while (allowSkipGears); + if (gear == 0) { + throw new VectoSimulationException("Could not find gear!"); + } return gear; } diff --git a/VectoCore/Utils/DoubleExtensionMethods.cs b/VectoCore/Utils/DoubleExtensionMethods.cs index a1a77ecf017461e6177cd9df7e8eb3394c2c2544..54de22d47769cbcbff927d45577311d184cb355e 100644 --- a/VectoCore/Utils/DoubleExtensionMethods.cs +++ b/VectoCore/Utils/DoubleExtensionMethods.cs @@ -17,7 +17,7 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// The tolerancefactor for relative comparisons. /// </summary> - public const double ToleranceFactor = 10e-6; + public const double ToleranceFactor = 1e-6; /// <summary> @@ -41,7 +41,7 @@ namespace TUGraz.VectoCore.Utils /// <returns></returns> public static bool IsSmaller(this double self, double other, double tolerance = Tolerance) { - return self - other < tolerance; + return self < other - tolerance; } /// <summary> @@ -53,7 +53,7 @@ namespace TUGraz.VectoCore.Utils /// <returns></returns> public static bool IsSmallerOrEqual(this double self, double other, double tolerance = Tolerance) { - return self - other <= tolerance; + return self <= other + tolerance; } /// <summary> @@ -65,7 +65,7 @@ namespace TUGraz.VectoCore.Utils /// <returns></returns> public static bool IsGreater(this double self, double other, double tolerance = Tolerance) { - return other.IsSmallerOrEqual(self, tolerance); + return self > other + tolerance; //other.IsSmallerOrEqual(self, tolerance); } /// <summary> @@ -77,7 +77,7 @@ namespace TUGraz.VectoCore.Utils /// <returns></returns> public static bool IsGreaterOrEqual(this double self, double other, double tolerance = Tolerance) { - return other.IsSmaller(self, tolerance); + return self >= other - tolerance; //other.IsSmaller(self, tolerance); } /// <summary> diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs index c18b4d01f8a9adb7f293f2cecd0899256f23defc..7d0fe56396c833d562626103610cea2b667cdfb2 100644 --- a/VectoCore/Utils/SI.cs +++ b/VectoCore/Utils/SI.cs @@ -1638,6 +1638,26 @@ namespace TUGraz.VectoCore.Utils return Val.IsEqual(val, tolerance); } + public bool IsSmaller(SI si, double tolerance = DoubleExtensionMethods.Tolerance) + { + return HasEqualUnit(si) && Val.IsSmaller(si.Val, tolerance); + } + + public bool IsSmallerOrEqual(SI si, double tolerance = DoubleExtensionMethods.Tolerance) + { + return HasEqualUnit(si) && Val.IsSmallerOrEqual(si.Val, tolerance); + } + + public bool IsGreater(SI si, double tolerance = DoubleExtensionMethods.Tolerance) + { + return HasEqualUnit(si) && Val.IsGreater(si.Val, tolerance); + } + + public bool IsGreaterOrEqual(SI si, double tolerance = DoubleExtensionMethods.Tolerance) + { + return HasEqualUnit(si) && Val.IsGreaterOrEqual(si.Val, tolerance); + } + /// <summary> /// Returns a hash code for this instance. /// </summary> diff --git a/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs b/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs index 2dca7fc2b3b428bebf88125c3f3974bf761cc81f..8ae5fd713db1b86b995d1551e1afad4c063521e2 100644 --- a/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs +++ b/VectoCoreTest/Integration/DriverStrategy/DriverStrategyTest.cs @@ -30,13 +30,13 @@ namespace TUGraz.VectoCore.Tests.Integration.DriverStrategy [TestMethod] - public void Accelerate_0_80_level() + public void Accelerate_0_85_level() { var cycle = CreateCycleData(new[] { // <s>,<v>,<grad>,<stop> " 0, 0, 0, 2", - " 0, 80, 0, 0", - "900, 80, 0, 0", + " 0, 85, 0, 0", + "900, 85, 0, 0", }); var run = CreatePowerTrain(cycle, "DriverStrategy_Accelerate_0_80_level.vmod");