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

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

TorqueConverter: compute max. available torque at TC-out depending on the...

TorqueConverter: compute max. available torque at TC-out depending on the engine's (dyn) full-load power and inertia. used to improve search operating point when accelerating
parent d0fed5f5
No related branches found
No related tags found
No related merge requests found
......@@ -48,6 +48,8 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
public PerSecond EngineSpeed { get; set; }
public Watt EnginePowerRequest { get; set; }
public Watt DynamicFullLoadPower { get; set; }
public Watt AngularGearPowerRequest { get; set; }
public Watt ClutchPowerRequest { get; set; }
public Watt GearboxPowerRequest { get; set; }
......@@ -75,7 +77,8 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
/// <summary>
/// Response when a request was successful.
/// </summary>
public class ResponseSuccess : AbstractResponse {}
public class ResponseSuccess : AbstractResponse {
}
/// <summary>
/// Response when the request resulted in an engine or gearbox overload.
......
......@@ -33,6 +33,7 @@ using System;
using System.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.SimulationComponent;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
......@@ -138,7 +139,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
.AddComponent(new Brakes(container))
.AddComponent(new AxleGear(container, data.AxleGearData))
.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTO, container);
.AddComponent(GetGearbox(container, data.GearboxData, data.EngineData.Inertia), data.Retarder, data.PTO, container);
if (data.GearboxData.Type.ManualTransmission()) {
powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData));
}
......@@ -169,7 +170,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
.AddComponent(new Brakes(container))
.AddComponent(new AxleGear(container, data.AxleGearData))
.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTO, container);
.AddComponent(GetGearbox(container, data.GearboxData, data.EngineData.Inertia), data.Retarder, data.PTO, container);
if (data.GearboxData.Type.ManualTransmission()) {
powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData));
}
......@@ -196,7 +197,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
.AddComponent(new Brakes(container))
.AddComponent(new AxleGear(container, data.AxleGearData))
.AddComponent(data.AngularGearData != null ? new AngularGear(container, data.AngularGearData) : null)
.AddComponent(GetGearbox(container, data.GearboxData), data.Retarder, data.PTO, container);
.AddComponent(GetGearbox(container, data.GearboxData, data.EngineData.Inertia), data.Retarder, data.PTO, container);
if (data.GearboxData.Type.ManualTransmission()) {
powertrain = powertrain.AddComponent(new Clutch(container, data.EngineData));
}
......@@ -256,7 +257,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
return aux;
}
private static IGearbox GetGearbox(IVehicleContainer container, GearboxData data)
private static IGearbox GetGearbox(IVehicleContainer container, GearboxData data, KilogramSquareMeter engineInertia)
{
IShiftStrategy strategy;
switch (data.Type) {
......@@ -269,7 +270,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
case GearboxType.ATPowerSplit:
case GearboxType.ATSerial:
strategy = new ATShiftStrategy(data, container);
return new ATGearbox(container, data, strategy);
return new ATGearbox(container, data, strategy, engineInertia);
default:
throw new VectoSimulationException("Unknown Gearbox Type: {0}", data.Type);
}
......
......@@ -175,6 +175,39 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
}
return GetOutTorque(inAngularVelocity, solutions.Max().SI<PerSecond>());
}
public TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Watt maxPower, PerSecond prevInputSpeed,
PerSecond nextOutputSpeed, KilogramSquareMeter inertia, Second dt)
{
//var retVal = new TorqueConverterOperatingPoint {
// OutAngularVelocity = nextOutputSpeed
//};
var solutions = new List<double>();
var mpNorm = ReferenceSpeed.Value();
foreach (var segment in TorqueConverterEntries.Pairwise(Tuple.Create)) {
var mpEdge = Edge.Create(new Point(segment.Item1.SpeedRatio, segment.Item1.Torque.Value()),
new Point(segment.Item2.SpeedRatio, segment.Item2.Torque.Value()));
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 sol = VectoMath.CubicEquationSolver(a, b, c, d);
var selected = sol.Where(x => x > 0 && nextOutputSpeed / x >= mpEdge.P1.X && nextOutputSpeed / x < mpEdge.P2.X);
solutions.AddRange(selected);
}
if (solutions.Count == 0) {
throw new VectoException(
"Failed to find operating point for maxPower {0}, prevInputSpeed {1}, nextOutputSpeed {2}", maxPower,
prevInputSpeed, nextOutputSpeed);
}
solutions.Sort();
return GetOutTorque(solutions.First().SI<PerSecond>(), nextOutputSpeed);
}
}
public class TorqueConverterOperatingPoint
......
......@@ -23,13 +23,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public Second LastShift { get; private set; }
public ATGearbox(IVehicleContainer container, GearboxData gearboxModelData, IShiftStrategy strategy)
public ATGearbox(IVehicleContainer container, GearboxData gearboxModelData, IShiftStrategy strategy, KilogramSquareMeter engineInertia)
: base(container, gearboxModelData)
{
Strategy = strategy;
Strategy.Gearbox = this;
LastShift = -double.MaxValue.SI<Second>();
TorqueConverter = new TorqueConverter(this, Strategy, container, gearboxModelData.TorqueConverterData);
TorqueConverter = new TorqueConverter(this, Strategy, container, gearboxModelData.TorqueConverterData, engineInertia);
}
private IIdleController _idleController;
......
......@@ -216,6 +216,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
DeltaFullLoad = deltaFull * avgEngineSpeed,
DeltaDragLoad = deltaDrag * avgEngineSpeed,
EnginePowerRequest = torqueOut * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity,
EngineMaxTorqueOut =
......@@ -252,6 +253,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
AbsTime = absTime,
Delta = deltaFull * avgEngineSpeed,
EnginePowerRequest = totalTorqueDemand * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower,
Source = this,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity,
......@@ -265,6 +267,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
AbsTime = absTime,
Delta = deltaDrag * avgEngineSpeed,
EnginePowerRequest = totalTorqueDemand * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower,
Source = this,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity,
......@@ -275,6 +278,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return new ResponseSuccess {
EnginePowerRequest = totalTorqueDemand * avgEngineSpeed,
DynamicFullLoadPower = dynamicFullLoadPower,
AuxiliariesPowerDemand = auxTorqueDemand * avgEngineSpeed,
EngineSpeed = angularVelocity,
Source = this
......
......@@ -14,22 +14,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>,
ITnInPort, ITnOutPort
{
protected ATGearbox Gearbox;
protected readonly ATGearbox Gearbox;
protected IShiftStrategy ShiftStrategy;
protected readonly IShiftStrategy ShiftStrategy;
protected TorqueConverterData ModelData;
private KilogramSquareMeter EngineInertia;
//protected bool SearchingTcOperatingPoint;
public ITnOutPort NextComponent { protected internal get; set; }
public TorqueConverter(ATGearbox gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container,
TorqueConverterData tcData) : base(container)
TorqueConverterData tcData, KilogramSquareMeter engineInertia) : base(container)
{
Gearbox = gearbox;
ShiftStrategy = shiftStrategy;
ModelData = tcData;
EngineInertia = engineInertia;
}
public void Connect(ITnOutPort other)
......@@ -52,12 +54,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
if (dryRun) {
var dryOperatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
var deltaTorqueConverter = (outTorque - dryOperatingPoint.OutTorque) *
(PreviousState.OutAngularVelocity + dryOperatingPoint.OutAngularVelocity) / 2.0;
// operatingPoint.inAngularVelocity is for sure between engine idle speed and max TC speed
var engineResponse =
(ResponseDryRun)NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque, dryOperatingPoint.InAngularVelocity,
true);
//var dryOperatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
var deltaTorqueConverter = (outTorque - dryOperatingPoint.OutTorque) *
(PreviousState.OutAngularVelocity + dryOperatingPoint.OutAngularVelocity) / 2.0;
//// operatingPoint.inAngularVelocity is for sure between engine idle speed and max TC speed
//var engineResponse =
// (ResponseDryRun)NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque, dryOperatingPoint.InAngularVelocity,
// 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)) {
......@@ -68,15 +75,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
TorqueConverterOperatingPoint = dryOperatingPoint
};
}
if (engineResponse.DeltaFullLoad > 0 || engineResponse.DeltaDragLoad < 0) {
// engine is overloaded with current operating point, reduce torque...
dryOperatingPoint =
ModelData.GetOutTorqueAndSpeed(
outTorque > 0 ? engineResponse.EngineMaxTorqueOut : engineResponse.EngineDragTorque,
dryOperatingPoint.InAngularVelocity, null);
}
dryOperatingPoint = GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse);
engineResponse = (ResponseDryRun)NextComponent.Request(absTime, dt, dryOperatingPoint.InTorque,
dryOperatingPoint.InAngularVelocity, true);
//if (engineResponse.DeltaFullLoad > 0 || engineResponse.DeltaDragLoad < 0)
//{
// // engine is overloaded with current operating point, reduce torque...
// dryOperatingPoint =
// ModelData.GetOutTorqueAndSpeed(
// outTorque > 0 ? engineResponse.EngineMaxTorqueOut : engineResponse.EngineDragTorque,
// dryOperatingPoint.InAngularVelocity, null);
//}
var delta = (outTorque - dryOperatingPoint.OutTorque) *
(PreviousState.OutAngularVelocity + dryOperatingPoint.OutAngularVelocity) / 2.0;
//deltaTorqueConverter.Value() * (deltaEngine.IsEqual(0) ? 1 : deltaEngine.Value());
......@@ -110,6 +121,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return retVal;
}
private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
ResponseDryRun engineResponse)
{
try {
var operatingPoint =
ModelData.GetMaxPowerOperatingPoint(engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
DataBus.EngineSpeed, outAngularVelocity, EngineInertia, dt);
if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
operatingPoint = ModelData.GetOutTorque(DataBus.EngineRatedSpeed, outAngularVelocity);
}
return operatingPoint;
} catch (VectoException ve) {
Log.Error(ve, "failed to find torque converter operating point for MaxPower");
throw;
}
}
protected internal TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
PerSecond outAngularVelocity)
{
......@@ -120,7 +148,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
operatingPoint.InAngularVelocity);
}
if (operatingPoint.InAngularVelocity.IsGreater(DataBus.EngineRatedSpeed)) {
//ModelData.TorqueConverterSpeedLimit)) {
operatingPoint = ModelData.GetOutTorque(DataBus.EngineRatedSpeed, outAngularVelocity);
}
return operatingPoint;
......
......@@ -70,7 +70,7 @@ namespace TUGraz.VectoCore.Tests.Integration
.AddComponent(new Brakes(container))
.AddComponent(new AxleGear(container, axleGearData))
.AddComponent(new DummyRetarder(container))
.AddComponent(new ATGearbox(container, gearboxData, new ATShiftStrategy(gearboxData, container)))
.AddComponent(new ATGearbox(container, gearboxData, new ATShiftStrategy(gearboxData, container), engineData.Inertia))
.AddComponent(engine);
var aux = new EngineAuxiliary(container);
......
......@@ -38,10 +38,10 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
public void TestATGearInitialize(double vehicleSpeed, double torque, int expectedGear)
{
var vehicleContainer = new MockVehicleContainer(); //(ExecutionMode.Engineering);
vehicleContainer.Engine = new CombustionEngine(vehicleContainer,
MockSimulationDataFactory.CreateEngineDataFromFile(EngineDataFile));
var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineDataFile);
vehicleContainer.Engine = new CombustionEngine(vehicleContainer,engineData);
var gearboxData = MockSimulationDataFactory.CreateGearboxDataFromFile(GearboxDataFile, EngineDataFile, false);
var gearbox = new ATGearbox(vehicleContainer, gearboxData, new ATShiftStrategy(gearboxData, vehicleContainer));
var gearbox = new ATGearbox(vehicleContainer, gearboxData, new ATShiftStrategy(gearboxData, vehicleContainer), engineData.Inertia);
vehicleContainer.VehicleSpeed = vehicleSpeed.KMPHtoMeterPerSecond();
......
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