Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 0d889322 authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

adding drag torque to response, rename torque converter metods, torque...

adding drag torque to response, rename torque converter metods, torque converter: find operating point when in drag
parent 459718b1
No related branches found
No related tags found
No related merge requests found
Showing with 155 additions and 85 deletions
...@@ -49,6 +49,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl ...@@ -49,6 +49,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
public Watt EnginePowerRequest { get; set; } public Watt EnginePowerRequest { get; set; }
public Watt DynamicFullLoadPower { get; set; } public Watt DynamicFullLoadPower { get; set; }
public Watt DragPower { get; set; }
public Watt AngularGearPowerRequest { get; set; } public Watt AngularGearPowerRequest { get; set; }
public Watt ClutchPowerRequest { get; set; } public Watt ClutchPowerRequest { get; set; }
......
...@@ -55,7 +55,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox ...@@ -55,7 +55,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
TorqueConverterSpeedLimit = maxRpm; 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) public TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter torqueOut, PerSecond angularSpeedOut)
{ {
var solutions = new List<double>(); var solutions = new List<double>();
...@@ -103,28 +110,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox ...@@ -103,28 +110,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
return retVal; 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) /// <summary>
{ /// find an operating point for the torque converter
int index; ///
TorqueConverterEntries.GetSection(x => x.SpeedRatio < speedRatio, out index); /// find the input torque and output torque for the given input and output speeds.
var retVal = VectoMath.Interpolate(TorqueConverterEntries[index].SpeedRatio, /// Computes the speed ratio nu of input and output. Interpolates MP1000 and mu, Computes input torque and output torque
TorqueConverterEntries[index + 1].SpeedRatio, TorqueConverterEntries[index].Torque, /// </summary>
TorqueConverterEntries[index + 1].Torque, speedRatio); /// <param name="inAngularVelocity">speed at the input of the TC</param>
return retVal; /// <param name="outAngularVelocity">speed at the output of the TC</param>
} /// <returns></returns>
public TorqueConverterOperatingPoint FindOperatingPoint(PerSecond inAngularVelocity, PerSecond outAngularVelocity)
public TorqueConverterOperatingPoint GetOutTorque(PerSecond inAngularVelocity, PerSecond outAngularVelocity)
{ {
var retVal = new TorqueConverterOperatingPoint { var retVal = new TorqueConverterOperatingPoint {
InAngularVelocity = inAngularVelocity, InAngularVelocity = inAngularVelocity,
...@@ -147,7 +143,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox ...@@ -147,7 +143,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
inAngularVelocity); 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) PerSecond outAngularSpeedEstimated)
{ {
var referenceTorque = inTorque.Value() / inAngularVelocity.Value() / inAngularVelocity.Value() * var referenceTorque = inTorque.Value() / inAngularVelocity.Value() / inAngularVelocity.Value() *
...@@ -173,10 +179,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox ...@@ -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}", "Failed to find torque converter Operating Point for inputTorque/inputSpeed! n_in: {0}, tq_in: {1}",
inAngularVelocity, inTorque); 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) PerSecond nextOutputSpeed, KilogramSquareMeter inertia, Second dt)
{ {
//var retVal = new TorqueConverterOperatingPoint { //var retVal = new TorqueConverterOperatingPoint {
...@@ -192,7 +198,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox ...@@ -192,7 +198,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
var a = mpEdge.OffsetXY / mpNorm / mpNorm; var a = mpEdge.OffsetXY / mpNorm / mpNorm;
var b = inertia.Value() / 2 / dt.Value() + mpEdge.SlopeXY * nextOutputSpeed.Value() / mpNorm / mpNorm; var b = inertia.Value() / 2 / dt.Value() + mpEdge.SlopeXY * nextOutputSpeed.Value() / mpNorm / mpNorm;
var c = 0; 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 sol = VectoMath.CubicEquationSolver(a, b, c, d);
var selected = sol.Where(x => x > 0 && nextOutputSpeed / x >= mpEdge.P1.X && nextOutputSpeed / x < mpEdge.P2.X); 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 ...@@ -201,12 +207,33 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
if (solutions.Count == 0) { if (solutions.Count == 0) {
throw new VectoException( 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); prevInputSpeed, nextOutputSpeed);
} }
solutions.Sort(); 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;
} }
} }
......
...@@ -23,7 +23,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -23,7 +23,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Second LastShift { get; private set; } 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) : base(container, gearboxModelData)
{ {
Strategy = strategy; Strategy = strategy;
...@@ -139,8 +140,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -139,8 +140,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
if (DataBus.VehicleStopped && outAngularVelocity > 0) { if ((DataBus.VehicleStopped && outAngularVelocity > 0) || (Disengaged && outTorque.IsGreater(0))) {
Gear = Strategy.InitGear(absTime, dt, outTorque, outAngularVelocity); Gear = 1; //Strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
TorqueConverterLocked = false;
LastShift = absTime; LastShift = absTime;
Disengaged = false; Disengaged = false;
} }
...@@ -259,7 +261,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -259,7 +261,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity); TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity);
CurrentState.Gear = 0; CurrentState.Gear = 1;
return retval; return retval;
} }
......
...@@ -63,14 +63,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -63,14 +63,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
NextGear.SetState(absTime, false, 1, false); NextGear.SetState(absTime, false, 1, false);
return true; return true;
} }
if (DataBus.DriverBehavior == DrivingBehavior.Braking && if (DataBus.DriverBehavior == DrivingBehavior.Braking) {
DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed) && if (DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed) &&
outTorque.IsSmaller(0)) { outTorque.IsSmaller(0)) {
// disengage before halting // 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); NextGear.SetState(absTime, true, 1, false);
return true; return true;
} }
if (inAngularVelocity != null) { if (inAngularVelocity != null) {
// emergency shift to not stall the engine ------------------------ // emergency shift to not stall the engine ------------------------
if (_gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>())) { if (_gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>())) {
......
...@@ -208,7 +208,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -208,7 +208,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var gearboxFullLoad = DataBus.GearMaxTorque; var gearboxFullLoad = DataBus.GearMaxTorque;
var deltaFull = ComputeDelta(torqueOut, totalTorqueDemand + (CurrentState.InertiaTorqueLoss < 0 ? CurrentState.InertiaTorqueLoss : 0.SI<NewtonMeter>()), CurrentState.DynamicFullLoadTorque, gearboxFullLoad, true); 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); gearboxFullLoad != null ? -gearboxFullLoad : null, false);
if (dryRun) { if (dryRun) {
...@@ -217,6 +217,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -217,6 +217,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
DeltaDragLoad = deltaDrag * avgEngineSpeed, DeltaDragLoad = deltaDrag * avgEngineSpeed,
EnginePowerRequest = torqueOut * avgEngineSpeed, EnginePowerRequest = torqueOut * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower, DynamicFullLoadPower = dynamicFullLoadPower,
DragPower = CurrentState.FullDragTorque * avgEngineSpeed,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity, EngineSpeed = angularVelocity,
EngineMaxTorqueOut = EngineMaxTorqueOut =
...@@ -254,6 +255,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -254,6 +255,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Delta = deltaFull * avgEngineSpeed, Delta = deltaFull * avgEngineSpeed,
EnginePowerRequest = totalTorqueDemand * avgEngineSpeed, EnginePowerRequest = totalTorqueDemand * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower, DynamicFullLoadPower = dynamicFullLoadPower,
DragPower = CurrentState.FullDragTorque * avgEngineSpeed,
Source = this, Source = this,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity, EngineSpeed = angularVelocity,
...@@ -268,6 +270,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -268,6 +270,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Delta = deltaDrag * avgEngineSpeed, Delta = deltaDrag * avgEngineSpeed,
EnginePowerRequest = totalTorqueDemand * avgEngineSpeed, EnginePowerRequest = totalTorqueDemand * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower, DynamicFullLoadPower = dynamicFullLoadPower,
DragPower = CurrentState.FullDragTorque * avgEngineSpeed,
Source = this, Source = this,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity, EngineSpeed = angularVelocity,
...@@ -279,6 +282,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -279,6 +282,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return new ResponseSuccess { return new ResponseSuccess {
EnginePowerRequest = totalTorqueDemand * avgEngineSpeed, EnginePowerRequest = totalTorqueDemand * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower, DynamicFullLoadPower = dynamicFullLoadPower,
DragPower = CurrentState.FullDragTorque * avgEngineSpeed,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed, AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity, EngineSpeed = angularVelocity,
Source = this Source = this
...@@ -360,7 +364,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -360,7 +364,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var result = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed, var result = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed,
DataBus.ExecutionMode != ExecutionMode.Declaration); DataBus.ExecutionMode != ExecutionMode.Declaration);
if (DataBus.ExecutionMode != ExecutionMode.Declaration && result.Extrapolated) { 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()); avgEngineSpeed.Value(), CurrentState.EngineTorque.Value());
} }
......
...@@ -264,7 +264,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -264,7 +264,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (engineResponse.DeltaFullLoad > 0 || engineResponse.DeltaDragLoad < 0) { if (engineResponse.DeltaFullLoad > 0 || engineResponse.DeltaDragLoad < 0) {
// engine is overloaded with current operating point, reduce torque... // engine is overloaded with current operating point, reduce torque...
dryOperatingPoint = dryOperatingPoint =
TorqueConverter.GetOutTorqueAndSpeed( TorqueConverter.FindOperatingPoint(
outTorque > 0 ? engineResponse.EngineMaxTorqueOut : engineResponse.EngineDragTorque, outTorque > 0 ? engineResponse.EngineMaxTorqueOut : engineResponse.EngineDragTorque,
dryOperatingPoint.InAngularVelocity, null); dryOperatingPoint.InAngularVelocity, null);
} }
...@@ -339,12 +339,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -339,12 +339,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
operatingPoint.InAngularVelocity); operatingPoint.InAngularVelocity);
} }
if (operatingPoint.InAngularVelocity.IsGreater(TorqueConverter.TorqueConverterSpeedLimit)) { if (operatingPoint.InAngularVelocity.IsGreater(TorqueConverter.TorqueConverterSpeedLimit)) {
operatingPoint = TorqueConverter.GetOutTorque(TorqueConverter.TorqueConverterSpeedLimit, outAngularVelocity); operatingPoint = TorqueConverter.FindOperatingPoint(TorqueConverter.TorqueConverterSpeedLimit, outAngularVelocity);
} }
return operatingPoint; return operatingPoint;
} catch (VectoException ve) { } catch (VectoException ve) {
Log.Debug(ve, "failed to find torque converter operating point, fallback: creeping"); 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; return tqOperatingPoint;
} }
} }
......
...@@ -526,11 +526,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -526,11 +526,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
deltaPower = nextResp.GearboxPowerRequest; deltaPower = nextResp.GearboxPowerRequest;
}). }).
Case<ResponseUnderload>(r => 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); }); Default(r => { throw new UnexpectedResponseException("cannot use response for searching braking power!", r); });
try { 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 => { getYValue: result => {
var response = (ResponseDryRun)result; var response = (ResponseDryRun)result;
return DataBus.ClutchClosed(absTime) ? response.DeltaDragLoad : response.GearboxPowerRequest; return DataBus.ClutchClosed(absTime) ? response.DeltaDragLoad : response.GearboxPowerRequest;
...@@ -587,39 +588,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -587,39 +588,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); return actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad);
}, },
evaluateFunction: evaluateFunction:
acc => { acc => {
// calculate new time interval only when vehiclespeed and acceleration are != 0 // calculate new time interval only when vehiclespeed and acceleration are != 0
// else: use same timeinterval as before. // else: use same timeinterval as before.
if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) { if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) {
var tmp = ComputeTimeInterval(acc, ds); var tmp = ComputeTimeInterval(acc, ds);
if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) { 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, throw new VectoSearchAbortedException("next TimeInterval is 0. a: {0}, v: {1}, dt: {2}", acc,
DataBus.VehicleSpeed, tmp.SimulationInterval); DataBus.VehicleSpeed, tmp.SimulationInterval);
}
retVal.Acceleration = tmp.Acceleration;
retVal.SimulationInterval = tmp.SimulationInterval;
retVal.SimulationDistance = tmp.SimulationDistance;
} }
retVal.Acceleration = tmp.Acceleration; IterationStatistics.Increment(this, "SearchOperatingPoint");
retVal.SimulationInterval = tmp.SimulationInterval; DriverAcceleration = acc;
retVal.SimulationDistance = tmp.SimulationDistance; var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true);
} response.OperatingPoint = retVal;
IterationStatistics.Increment(this, "SearchOperatingPoint"); return response;
DriverAcceleration = acc; },
var response = NextComponent.Request(absTime, retVal.SimulationInterval, acc, gradient, true);
response.OperatingPoint = retVal;
return response;
},
criterion: response => { criterion: response => {
var r = (ResponseDryRun)response; var r = (ResponseDryRun)response;
delta = actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad); delta = actionRoll ? r.GearboxPowerRequest : (coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad);
return delta.Value(); return delta.Value();
}, },
abortCriterion: abortCriterion:
(response, cnt) => { (response, cnt) => {
var r = (ResponseDryRun)response; var r = (ResponseDryRun)response;
if (r == null) { if (r == null) {
return false; return false;
} }
return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance);
}); });
} catch (VectoSearchAbortedException) { } catch (VectoSearchAbortedException) {
// search aborted, try to go ahead with the last acceleration // search aborted, try to go ahead with the last acceleration
} catch (Exception) { } catch (Exception) {
......
...@@ -67,16 +67,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -67,16 +67,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
// true); // true);
var deltaEngine = (engineResponse.DeltaFullLoad > 0 ? engineResponse.DeltaFullLoad : 0.SI<Watt>()) + var deltaEngine = (engineResponse.DeltaFullLoad > 0 ? engineResponse.DeltaFullLoad : 0.SI<Watt>()) +
(engineResponse.DeltaDragLoad < 0 ? -engineResponse.DeltaDragLoad : 0.SI<Watt>()); (engineResponse.DeltaDragLoad < 0 ? -engineResponse.DeltaDragLoad : 0.SI<Watt>());
if (deltaTorqueConverter.IsEqual(0) && deltaEngine.IsEqual(0)) { //if (deltaTorqueConverter.IsEqual(0) && deltaEngine.IsEqual(0)) {
return new ResponseDryRun { // return new ResponseDryRun {
Source = this, // Source = this,
DeltaFullLoad = 0.SI<Watt>(), // DeltaFullLoad = 0.SI<Watt>(),
DeltaDragLoad = 0.SI<Watt>(), // DeltaDragLoad = 0.SI<Watt>(),
TorqueConverterOperatingPoint = dryOperatingPoint // 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, engineResponse = (ResponseDryRun)NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque,
dryOperatingPoint.InAngularVelocity, true); dryOperatingPoint.InAngularVelocity, true);
...@@ -99,6 +101,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -99,6 +101,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
}; };
} }
var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity); 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)) { if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) {
// a different operating point was found... // a different operating point was found...
var delta = (outTorque - operatingPoint.OutTorque) * var delta = (outTorque - operatingPoint.OutTorque) *
...@@ -110,7 +117,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -110,7 +117,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint }; 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, if (ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, operatingPoint.InTorque,
operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) { operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) {
return new ResponseGearShift() { Source = this }; return new ResponseGearShift() { Source = this };
...@@ -121,19 +128,41 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -121,19 +128,41 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return retVal; 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, private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
ResponseDryRun engineResponse) ResponseDryRun engineResponse)
{ {
try { try {
var operatingPoint = var operatingPoint =
ModelData.GetMaxPowerOperatingPoint(engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand, ModelData.FindOperatingPointForPowerDemand(engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
DataBus.EngineSpeed, outAngularVelocity, EngineInertia, dt); DataBus.EngineSpeed, outAngularVelocity, EngineInertia, dt);
if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) { if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
operatingPoint = ModelData.GetOutTorque(DataBus.EngineRatedSpeed, outAngularVelocity); operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
} }
return operatingPoint; return operatingPoint;
} catch (VectoException ve) { } 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; throw;
} }
} }
...@@ -148,12 +177,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -148,12 +177,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
operatingPoint.InAngularVelocity); operatingPoint.InAngularVelocity);
} }
if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) { if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
operatingPoint = ModelData.GetOutTorque(DataBus.EngineRatedSpeed, outAngularVelocity); operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineRatedSpeed, outAngularVelocity);
} }
return operatingPoint; return operatingPoint;
} catch (VectoException ve) { } catch (VectoException ve) {
Log.Debug(ve, "failed to find torque converter operating point, fallback: creeping"); 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; return tqOperatingPoint;
} }
} }
......
...@@ -85,7 +85,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData ...@@ -85,7 +85,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
tqInput), 1000.RPMtoRad(), tqLimit.RPMtoRad()); 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.InTorque.Value(), tqIn, 1e-6);
Assert.AreEqual(operatingPoint.InAngularVelocity.Value(), nIn.RPMtoRad().Value(), 1e-6); Assert.AreEqual(operatingPoint.InAngularVelocity.Value(), nIn.RPMtoRad().Value(), 1e-6);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment