diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs index 5302d1abd708509975bb264e892819f16be2deba..323fb37a05af41bd615957e4e33164a151f6b0ae 100644 --- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs +++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs @@ -49,6 +49,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl public Watt EnginePowerRequest { get; set; } public Watt DynamicFullLoadPower { get; set; } + public Watt DragPower { get; set; } public Watt AngularGearPowerRequest { get; set; } public Watt ClutchPowerRequest { get; set; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs index 0626475a0286bb9f51e8ef38b810fd23c0c03f02..8127ff2a2a0311c48afac4719eea97ef44cc84d3 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TorqueConverterData.cs @@ -55,7 +55,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox TorqueConverterSpeedLimit = maxRpm; } - + /// <summary> + /// find an operating point for the torque converter + /// + /// find the input speed and input torque for the given output torque and output speed. + /// </summary> + /// <param name="torqueOut">torque provided at the TC output</param> + /// <param name="angularSpeedOut">angular speed at the TC output</param> + /// <returns></returns> public TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter torqueOut, PerSecond angularSpeedOut) { var solutions = new List<double>(); @@ -103,28 +110,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox return retVal; } - private double MuLookup(double speedRatio) - { - int index; - TorqueConverterEntries.GetSection(x => x.SpeedRatio < speedRatio, out index); - var retVal = VectoMath.Interpolate(TorqueConverterEntries[index].SpeedRatio, - TorqueConverterEntries[index + 1].SpeedRatio, TorqueConverterEntries[index].TorqueRatio, - TorqueConverterEntries[index + 1].TorqueRatio, speedRatio); - return retVal; - } - - private NewtonMeter ReferenceTorqueLookup(double speedRatio) - { - int index; - TorqueConverterEntries.GetSection(x => x.SpeedRatio < speedRatio, out index); - var retVal = VectoMath.Interpolate(TorqueConverterEntries[index].SpeedRatio, - TorqueConverterEntries[index + 1].SpeedRatio, TorqueConverterEntries[index].Torque, - TorqueConverterEntries[index + 1].Torque, speedRatio); - return retVal; - } - - public TorqueConverterOperatingPoint GetOutTorque(PerSecond inAngularVelocity, PerSecond outAngularVelocity) + /// <summary> + /// find an operating point for the torque converter + /// + /// find the input torque and output torque for the given input and output speeds. + /// Computes the speed ratio nu of input and output. Interpolates MP1000 and mu, Computes input torque and output torque + /// </summary> + /// <param name="inAngularVelocity">speed at the input of the TC</param> + /// <param name="outAngularVelocity">speed at the output of the TC</param> + /// <returns></returns> + public TorqueConverterOperatingPoint FindOperatingPoint(PerSecond inAngularVelocity, PerSecond outAngularVelocity) { var retVal = new TorqueConverterOperatingPoint { InAngularVelocity = inAngularVelocity, @@ -147,7 +143,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox inAngularVelocity); } - public TorqueConverterOperatingPoint GetOutTorqueAndSpeed(NewtonMeter inTorque, PerSecond inAngularVelocity, + + /// <summary> + /// find an operating point for the torque converter + /// + /// find the output torque and output speed for the given input torque and input speed + /// </summary> + /// <param name="inTorque"></param> + /// <param name="inAngularVelocity"></param> + /// <param name="outAngularSpeedEstimated"></param> + /// <returns></returns> + public TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter inTorque, PerSecond inAngularVelocity, PerSecond outAngularSpeedEstimated) { var referenceTorque = inTorque.Value() / inAngularVelocity.Value() / inAngularVelocity.Value() * @@ -173,10 +179,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox "Failed to find torque converter Operating Point for inputTorque/inputSpeed! n_in: {0}, tq_in: {1}", inAngularVelocity, inTorque); } - return GetOutTorque(inAngularVelocity, solutions.Max().SI<PerSecond>()); + return FindOperatingPoint(inAngularVelocity, solutions.Max().SI<PerSecond>()); } - public TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Watt maxPower, PerSecond prevInputSpeed, + public TorqueConverterOperatingPoint FindOperatingPointForPowerDemand(Watt power, PerSecond prevInputSpeed, PerSecond nextOutputSpeed, KilogramSquareMeter inertia, Second dt) { //var retVal = new TorqueConverterOperatingPoint { @@ -192,7 +198,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox var a = mpEdge.OffsetXY / mpNorm / mpNorm; var b = inertia.Value() / 2 / dt.Value() + mpEdge.SlopeXY * nextOutputSpeed.Value() / mpNorm / mpNorm; var c = 0; - var d = -inertia.Value() / 2 / dt.Value() * prevInputSpeed.Value() * prevInputSpeed.Value() - maxPower.Value(); + var d = -inertia.Value() / 2 / dt.Value() * prevInputSpeed.Value() * prevInputSpeed.Value() - power.Value(); var sol = VectoMath.CubicEquationSolver(a, b, c, d); var selected = sol.Where(x => x > 0 && nextOutputSpeed / x >= mpEdge.P1.X && nextOutputSpeed / x < mpEdge.P2.X); @@ -201,12 +207,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox if (solutions.Count == 0) { throw new VectoException( - "Failed to find operating point for maxPower {0}, prevInputSpeed {1}, nextOutputSpeed {2}", maxPower, + "Failed to find operating point for power {0}, prevInputSpeed {1}, nextOutputSpeed {2}", power, prevInputSpeed, nextOutputSpeed); } solutions.Sort(); - return GetOutTorque(solutions.First().SI<PerSecond>(), nextOutputSpeed); + return FindOperatingPoint(solutions.First().SI<PerSecond>(), nextOutputSpeed); + } + + private double MuLookup(double speedRatio) + { + int index; + TorqueConverterEntries.GetSection(x => x.SpeedRatio < speedRatio, out index); + var retVal = VectoMath.Interpolate(TorqueConverterEntries[index].SpeedRatio, + TorqueConverterEntries[index + 1].SpeedRatio, TorqueConverterEntries[index].TorqueRatio, + TorqueConverterEntries[index + 1].TorqueRatio, speedRatio); + return retVal; + } + + + private NewtonMeter ReferenceTorqueLookup(double speedRatio) + { + int index; + TorqueConverterEntries.GetSection(x => x.SpeedRatio < speedRatio, out index); + var retVal = VectoMath.Interpolate(TorqueConverterEntries[index].SpeedRatio, + TorqueConverterEntries[index + 1].SpeedRatio, TorqueConverterEntries[index].Torque, + TorqueConverterEntries[index + 1].Torque, speedRatio); + return retVal; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs index 5de45f6723818cbb51519bd21bcd5fc10f530c26..ece53469170f064b71b0e857f6486e76dfaec314 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs @@ -23,7 +23,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public Second LastShift { get; private set; } - public ATGearbox(IVehicleContainer container, GearboxData gearboxModelData, IShiftStrategy strategy, KilogramSquareMeter engineInertia) + public ATGearbox(IVehicleContainer container, GearboxData gearboxModelData, IShiftStrategy strategy, + KilogramSquareMeter engineInertia) : base(container, gearboxModelData) { Strategy = strategy; @@ -139,8 +140,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); - if (DataBus.VehicleStopped && outAngularVelocity > 0) { - Gear = Strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); + if ((DataBus.VehicleStopped && outAngularVelocity > 0) || (Disengaged && outTorque.IsGreater(0))) { + Gear = 1; //Strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); + TorqueConverterLocked = false; LastShift = absTime; Disengaged = false; } @@ -259,7 +261,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity); - CurrentState.Gear = 0; + CurrentState.Gear = 1; return retval; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index da54ae418eed713017dafd70ff7ae83639ccad43..9bca7f2623ed23b9f14a1331bd9bcf4968d16eb5 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -63,14 +63,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl NextGear.SetState(absTime, false, 1, false); return true; } - if (DataBus.DriverBehavior == DrivingBehavior.Braking && - DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed) && - outTorque.IsSmaller(0)) { - // disengage before halting + if (DataBus.DriverBehavior == DrivingBehavior.Braking) { + if (DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed) && + outTorque.IsSmaller(0)) { + // disengage before halting + NextGear.SetState(absTime, true, 1, false); + return true; + } + + } + if (gear == 1 && !_gearbox.TorqueConverterLocked && outTorque.IsSmaller(0) && inTorque.IsGreater(0)) + { NextGear.SetState(absTime, true, 1, false); return true; } - if (inAngularVelocity != null) { // emergency shift to not stall the engine ------------------------ if (_gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>())) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 423492afe37f167aa9d8c40e6cca3c2f936b4b22..5145b3c88a59ba749c8eb517180b0564f3354e8a 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -208,7 +208,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var gearboxFullLoad = DataBus.GearMaxTorque; var deltaFull = ComputeDelta(torqueOut, totalTorqueDemand + (CurrentState.InertiaTorqueLoss < 0 ? CurrentState.InertiaTorqueLoss : 0.SI<NewtonMeter>()), CurrentState.DynamicFullLoadTorque, gearboxFullLoad, true); - var deltaDrag = ComputeDelta(torqueOut, totalTorqueDemand, CurrentState.FullDragTorque, + var deltaDrag = ComputeDelta(torqueOut, totalTorqueDemand - (CurrentState.InertiaTorqueLoss < 0 ? CurrentState.InertiaTorqueLoss : 0.SI<NewtonMeter>()), CurrentState.FullDragTorque, gearboxFullLoad != null ? -gearboxFullLoad : null, false); if (dryRun) { @@ -217,6 +217,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl DeltaDragLoad = deltaDrag * avgEngineSpeed, EnginePowerRequest = torqueOut * avgEngineSpeed, DynamicFullLoadPower = dynamicFullLoadPower, + DragPower = CurrentState.FullDragTorque * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, EngineSpeed = angularVelocity, EngineMaxTorqueOut = @@ -254,6 +255,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Delta = deltaFull * avgEngineSpeed, EnginePowerRequest = totalTorqueDemand * avgEngineSpeed, DynamicFullLoadPower = dynamicFullLoadPower, + DragPower = CurrentState.FullDragTorque * avgEngineSpeed, Source = this, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, EngineSpeed = angularVelocity, @@ -268,6 +270,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Delta = deltaDrag * avgEngineSpeed, EnginePowerRequest = totalTorqueDemand * avgEngineSpeed, DynamicFullLoadPower = dynamicFullLoadPower, + DragPower = CurrentState.FullDragTorque * avgEngineSpeed, Source = this, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, EngineSpeed = angularVelocity, @@ -279,6 +282,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseSuccess { EnginePowerRequest = totalTorqueDemand * avgEngineSpeed, DynamicFullLoadPower = dynamicFullLoadPower, + DragPower = CurrentState.FullDragTorque * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, EngineSpeed = angularVelocity, Source = this @@ -360,7 +364,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var result = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed, DataBus.ExecutionMode != ExecutionMode.Declaration); if (DataBus.ExecutionMode != ExecutionMode.Declaration && result.Extrapolated) { - Log.Warn("FuelConsumptionMap was extrapolated: range for FC-Map is not sufficient: n: {0}, torque: {2}", + Log.Warn("FuelConsumptionMap was extrapolated: range for FC-Map is not sufficient: n: {0}, torque: {1}", avgEngineSpeed.Value(), CurrentState.EngineTorque.Value()); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs index c81f999804d4380d301ceebdc9eac963d0740ad6..8b8b15cb5149c3b8cb190dd3d4c3618e7fb44f6f 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs @@ -264,7 +264,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl if (engineResponse.DeltaFullLoad > 0 || engineResponse.DeltaDragLoad < 0) { // engine is overloaded with current operating point, reduce torque... dryOperatingPoint = - TorqueConverter.GetOutTorqueAndSpeed( + TorqueConverter.FindOperatingPoint( outTorque > 0 ? engineResponse.EngineMaxTorqueOut : engineResponse.EngineDragTorque, dryOperatingPoint.InAngularVelocity, null); } @@ -339,12 +339,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl operatingPoint.InAngularVelocity); } if (operatingPoint.InAngularVelocity.IsGreater(TorqueConverter.TorqueConverterSpeedLimit)) { - operatingPoint = TorqueConverter.GetOutTorque(TorqueConverter.TorqueConverterSpeedLimit, outAngularVelocity); + operatingPoint = TorqueConverter.FindOperatingPoint(TorqueConverter.TorqueConverterSpeedLimit, outAngularVelocity); } return operatingPoint; } catch (VectoException ve) { Log.Debug(ve, "failed to find torque converter operating point, fallback: creeping"); - var tqOperatingPoint = TorqueConverter.GetOutTorque(DataBus.EngineIdleSpeed, outAngularVelocity); + var tqOperatingPoint = TorqueConverter.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); return tqOperatingPoint; } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 4f6e12dbf501f6d282ab3082f613ef0553019dbe..1e4a862f9e0cb251ba5f10a8d068365841cddd02 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -526,11 +526,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl deltaPower = nextResp.GearboxPowerRequest; }). Case<ResponseUnderload>(r => - deltaPower = DataBus.ClutchClosed(absTime) ? r.Delta : r.GearboxPowerRequest). + deltaPower = DataBus.ClutchClosed(absTime) ? r.Delta : r.GearboxPowerRequest). Default(r => { throw new UnexpectedResponseException("cannot use response for searching braking power!", r); }); try { - DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, deltaPower, deltaPower.Abs(), + DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, deltaPower, + deltaPower.Abs() * (DataBus.GearboxType.AutomaticTransmission() ? 0.5 : 1), getYValue: result => { var response = (ResponseDryRun)result; return DataBus.ClutchClosed(absTime) ? response.DeltaDragLoad : response.GearboxPowerRequest; @@ -587,39 +588,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); }, evaluateFunction: - acc => { - // calculate new time interval only when vehiclespeed and acceleration are != 0 - // else: use same timeinterval as before. - if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) { - var tmp = ComputeTimeInterval(acc, ds); - if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) { - throw new VectoSearchAbortedException("next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc, - DataBus.VehicleSpeed, tmp.SimulationInterval); + acc => { + // calculate new time interval only when vehiclespeed and acceleration are != 0 + // else: use same timeinterval as before. + if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) { + var tmp = ComputeTimeInterval(acc, ds); + if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) { + throw new VectoSearchAbortedException("next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc, + DataBus.VehicleSpeed, tmp.SimulationInterval); + } + retVal.Acceleration = tmp.Acceleration; + retVal.SimulationInterval = tmp.SimulationInterval; + retVal.SimulationDistance = tmp.SimulationDistance; } - retVal.Acceleration = tmp.Acceleration; - retVal.SimulationInterval = tmp.SimulationInterval; - retVal.SimulationDistance = tmp.SimulationDistance; - } - IterationStatistics.Increment(this, "SearchOperatingPoint"); - DriverAcceleration = acc; - var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true); - response.OperatingPoint = retVal; - return response; - }, + IterationStatistics.Increment(this, "SearchOperatingPoint"); + DriverAcceleration = acc; + var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true); + response.OperatingPoint = retVal; + return response; + }, criterion: response => { var r = (ResponseDryRun)response; delta = actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); return delta.Value(); }, abortCriterion: - (response, cnt) => { - var r = (ResponseDryRun)response; - if (r == null) { - return false; - } + (response, cnt) => { + var r = (ResponseDryRun)response; + if (r == null) { + return false; + } - return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); - }); + return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); + }); } catch (VectoSearchAbortedException) { // search aborted, try to go ahead with the last acceleration } catch (Exception) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs index 83c481351b1fd3a16e4872024a10bd4e499793f0..e2e86577474746df296ec6ca8ccc88aff99a12fe 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs @@ -67,16 +67,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl // true); var deltaEngine = (engineResponse.DeltaFullLoad > 0 ? engineResponse.DeltaFullLoad : 0.SI<Watt>()) + (engineResponse.DeltaDragLoad < 0 ? -engineResponse.DeltaDragLoad : 0.SI<Watt>()); - if (deltaTorqueConverter.IsEqual(0) && deltaEngine.IsEqual(0)) { - return new ResponseDryRun { - Source = this, - DeltaFullLoad = 0.SI<Watt>(), - DeltaDragLoad = 0.SI<Watt>(), - TorqueConverterOperatingPoint = dryOperatingPoint - }; - } + //if (deltaTorqueConverter.IsEqual(0) && deltaEngine.IsEqual(0)) { + // return new ResponseDryRun { + // Source = this, + // DeltaFullLoad = 0.SI<Watt>(), + // DeltaDragLoad = 0.SI<Watt>(), + // TorqueConverterOperatingPoint = dryOperatingPoint + // }; + //} - dryOperatingPoint = GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse); + dryOperatingPoint = outTorque.IsGreater(0) && DataBus.BrakePower.IsEqual(0) + ? GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse) + : GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse); engineResponse = (ResponseDryRun)NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque, dryOperatingPoint.InAngularVelocity, true); @@ -99,6 +101,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl }; } var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity); + var ratio = Gearbox.ModelData.Gears[Gearbox.Gear].TorqueConverterRatio; + if (ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, operatingPoint.InTorque, + operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) { + return new ResponseGearShift() { Source = this }; + } if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) { // a different operating point was found... var delta = (outTorque - operatingPoint.OutTorque) * @@ -110,7 +117,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint }; } } - var ratio = Gearbox.ModelData.Gears[Gearbox.Gear].TorqueConverterRatio; + if (ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, operatingPoint.InTorque, operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) { return new ResponseGearShift() { Source = this }; @@ -121,19 +128,41 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return retVal; } + private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity, + ResponseDryRun engineResponse) + { + try { + var operatingPoint = + ModelData.FindOperatingPointForPowerDemand(engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand, + DataBus.EngineSpeed, outAngularVelocity, EngineInertia, dt); + if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) { + operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity); + } + if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); + } + return operatingPoint; + } catch (VectoException ve) { + Log.Error(ve, "failed to find torque converter operating point for DragPower {0}", engineResponse.DragPower); + //throw; + return ModelData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity); + } + } + private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity, ResponseDryRun engineResponse) { try { var operatingPoint = - ModelData.GetMaxPowerOperatingPoint(engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand, + ModelData.FindOperatingPointForPowerDemand(engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand, DataBus.EngineSpeed, outAngularVelocity, EngineInertia, dt); if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) { - operatingPoint = ModelData.GetOutTorque(DataBus.EngineRatedSpeed, outAngularVelocity); + operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity); } return operatingPoint; } catch (VectoException ve) { - Log.Error(ve, "failed to find torque converter operating point for MaxPower"); + Log.Error(ve, "failed to find torque converter operating point for MaxPower {0}", + engineResponse.DynamicFullLoadPower); throw; } } @@ -148,12 +177,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl operatingPoint.InAngularVelocity); } if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) { - operatingPoint = ModelData.GetOutTorque(DataBus.EngineRatedSpeed, outAngularVelocity); + operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity); } return operatingPoint; } catch (VectoException ve) { Log.Debug(ve, "failed to find torque converter operating point, fallback: creeping"); - var tqOperatingPoint = ModelData.GetOutTorque(DataBus.EngineIdleSpeed, outAngularVelocity); + var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity); return tqOperatingPoint; } } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs index 96190a875f4ee2b95a9f8b9e38f2a1a54d9f06f2..a395445c598cc95831ce57b059085ad263e9aa8d 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs @@ -85,7 +85,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData tqInput), 1000.RPMtoRad(), tqLimit.RPMtoRad()); - var operatingPoint = tqData.GetOutTorqueAndSpeed(tqIn.SI<NewtonMeter>(), nIn.RPMtoRad(), null); + var operatingPoint = tqData.FindOperatingPoint(tqIn.SI<NewtonMeter>(), nIn.RPMtoRad(), null); Assert.AreEqual(operatingPoint.InTorque.Value(), tqIn, 1e-6); Assert.AreEqual(operatingPoint.InAngularVelocity.Value(), nIn.RPMtoRad().Value(), 1e-6);