diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs index 9bc9aa5d2c3ff7e6139d677b55e11fc05fafa1f7..7811d57c540ecc4c54fdddf6839fec2bdce374c7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs @@ -156,7 +156,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return response; } - public override bool TCLocked { get { return PreviousState.TorqueConverterLocked; } } + public override bool TCLocked { get { return CurrentState.TorqueConverterLocked; } } internal ResponseDryRun Initialize(uint gear, bool torqueConverterLocked, NewtonMeter outTorque, PerSecond outAngularVelocity) diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs index 4ca611871051c3f26d46030911e3a9c430c0ef5f..09c9ba2e97e72ff144db6df86516f33db8169173 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs @@ -402,7 +402,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl velocity += DriverData.OverSpeedEcoRoll.OverSpeed; } if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { - return HandleRequestEngaged(absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocity, debug); + for (var i = 0; i < 3; i++) { + var retVal = HandleRequestEngaged(absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocity, debug); + if (retVal != null) { + return retVal; + } + } + throw new VectoException("HandleRequestEngaged found no operating point."); } else { return HandleRequestDisengaged(absTime, ds, gradient, velocity, debug); } @@ -459,6 +465,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl second = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r); }); + if (second == null) { + return null; + } var third = second; second.Switch(). @@ -585,7 +594,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl bool prohibitOverspeed = false) { if (DataBus.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed) { - return HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); + var retVal = HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); + for (var i = 0; i < 3 && retVal == null; i++) { + retVal = HandleTargetspeedReached(absTime, ds, targetVelocity, gradient); + } + + if (retVal == null) { + throw new VectoException("Failed to find operating point!"); + } } var currentDistance = DataBus.Distance; @@ -628,6 +644,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Driver.DriverBehavior = DrivingBehavior.Braking; response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient, targetDistance: targetDistance); + + if (DataBus.GearboxType.AutomaticTransmission() && response == null) { + for (var i = 0; i < 3 && response == null; i++) { + response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, targetDistance: targetDistance); + } + + if (response == null) { + throw new VectoException("No valid operating point found"); + } + } response.Switch(). Case<ResponseOverload>(r => { Log.Info( @@ -780,30 +807,34 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // gradient, r); response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval, gradient, r); - response.Switch(). - Case<ResponseGearShift>(() => { - DataBus.BrakePower = 0.SI<Watt>(); - response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, - gradient, r); - }). - Case<ResponseOverload>(() => { - DataBus.BrakePower = 0.SI<Watt>(); - if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { - if (DataBus.VehicleSpeed.IsGreater(0)) { - response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } else { - if (RetryDistanceExceeded) { - response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + if (response != null) { + response.Switch().Case<ResponseGearShift>( + () => { + DataBus.BrakePower = 0.SI<Watt>(); + response = Driver.DrivingActionBrake( + absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, + gradient, r); + }).Case<ResponseOverload>( + () => { + DataBus.BrakePower = 0.SI<Watt>(); + if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) { + if (DataBus.VehicleSpeed.IsGreater(0)) { + response = Driver.DrivingActionAccelerate( + absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); } else { - RetryDistanceExceeded = true; - response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; + if (RetryDistanceExceeded) { + response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient); + } else { + RetryDistanceExceeded = true; + response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 }; + } } + } else { + response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); } - } else { - response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient); - } - }); - }); + }); + } + }); //} while (!(response is ResponseSuccess) && i++ < 3); return response; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 00da33cc0eb1968777d7d46d1df04acde1728ef4..34bfd9b2a0b0fd7f05b59f4b23d6c63927da96b3 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -560,9 +560,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } DriverAcceleration = operatingPoint.Acceleration; + var gear = DataBus.Gear; + var tcLocked = DataBus.TCLocked; retVal = NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, gradient); - + var gearChanged = !(DataBus.Gear == gear && DataBus.TCLocked == tcLocked); + if (DataBus.GearboxType.AutomaticTransmission() && gearChanged && retVal is ResponseOverload) { + Log.Debug("Gear changed after a valid operating point was found - braking is no longer applicable due to overload"); + return null; + } retVal.Switch(). Case<ResponseSuccess>(). Case<ResponseGearShift>(). @@ -587,8 +593,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var i = 5; while (i-- > 0 && !(retVal is ResponseSuccess)) { DataBus.BrakePower = 0.SI<Watt>(); + + retVal = NextComponent.Request( + absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, + gradient); + if (retVal is ResponseSuccess) { + break; + } + operatingPoint = SearchBrakingPower(absTime, operatingPoint.SimulationDistance, gradient, - operatingPoint.Acceleration, response); + operatingPoint.Acceleration, retVal); DriverAcceleration = operatingPoint.Acceleration; if (DataBus.BrakePower.IsSmaller(0)) { DataBus.BrakePower = 0.SI<Watt>(); @@ -608,6 +622,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl throw new UnexpectedResponseException( "DrivingAction Brake: request failed after braking power was found.", r); }); + CurrentState.Acceleration = operatingPoint.Acceleration; CurrentState.dt = operatingPoint.SimulationInterval; CurrentState.Response = retVal; @@ -615,7 +630,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl retVal.SimulationInterval = operatingPoint.SimulationInterval; retVal.SimulationDistance = ds; retVal.OperatingPoint = operatingPoint; - + return retVal; } @@ -858,6 +873,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (actionRoll) { initialResponse.Switch(). Case<ResponseDryRun>(r => origDelta = r.GearboxPowerRequest). + Case<ResponseOverload>(r => origDelta = r.Delta). Case<ResponseFailTimeInterval>(r => origDelta = r.GearboxPowerRequest). Default(r => { throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); diff --git a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs index 1336ab4f911072183ce0cbc5504d0af1f67a691f..8487f426b3eaf4d6601e59115e30015c3e900aa7 100644 --- a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs +++ b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs @@ -527,14 +527,14 @@ namespace TUGraz.VectoCore.Tests.Reports foreach (var modalResults in modData) { AssertModDataIntegrityAT(modalResults.Item1, auxKeys, modalResults.Item2, - FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).JobInputData.Vehicle.EngineInputData.FuelConsumptionMap)); + FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).JobInputData.Vehicle.EngineInputData.FuelConsumptionMap), true); } AssertSumDataIntegrity(sumData, ExecutionMode.Engineering, true); } private static void AssertModDataIntegrityAT(ModalResults modData, Dictionary<string, DataColumn> auxKeys, - Meter totalDistance, FuelConsumptionMap consumptionMap) + Meter totalDistance, FuelConsumptionMap consumptionMap, bool atGbx) { Assert.IsTrue(modData.Rows.Count > 0); @@ -623,7 +623,7 @@ namespace TUGraz.VectoCore.Tests.Reports "time: {0} distance: {1}", time, distance); // P_eng_fcmap = P_eng_out + P_AUX + P_eng_inertia ( + P_PTO_Transm + P_PTO_Consumer ) - Assert.AreEqual(pEngFcmap.Value(), (pEngOut + pAux + pEngInertia + pPTOtransm + pPTOconsumer).Value(), 1E-3, + Assert.AreEqual(pEngFcmap.Value(), (pEngOut + pAux + pEngInertia + pPTOtransm + pPTOconsumer).Value(), atGbx ? 1E-1 : 1e-3, "time: {0} distance: {1}", time, distance); @@ -631,7 +631,7 @@ namespace TUGraz.VectoCore.Tests.Reports var pLossTot = pTcLoss + pLossGbx + pLossRet + pGbxInertia + pLossAngle + pLossAxle + pBrakeLoss + pWheelInertia + pAir + pRoll + pGrad + pVehInertia + pPTOconsumer + pPTOtransm; - Assert.AreEqual(pEngFcmap.Value(), (pLossTot + pEngInertia + pAux).Value(), 1E-3, "time: {0} distance: {1}", time, + Assert.AreEqual(pEngFcmap.Value(), (pLossTot + pEngInertia + pAux).Value(), atGbx ? 1E-1 : 1e-3, "time: {0} distance: {1}", time, distance); Assert.IsTrue(pLossGbx.IsGreaterOrEqual(pShiftLoss + pGbxInertia, 0.5.SI<Watt>()), "time: {0} distance: {1}", time,