Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit cfc67ff8 authored by Michael KRISPER's avatar Michael KRISPER
Browse files

implemented ManualGearbox and PWheelCycle, renamed EngineTorque, EngineSpeed...

implemented ManualGearbox and PWheelCycle, renamed EngineTorque, EngineSpeed to Torque, AngularVelocity in Cycle
parent f8d32247
No related branches found
No related tags found
No related merge requests found
......@@ -289,8 +289,8 @@ namespace TUGraz.VectoCore.InputData.Reader
RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
StoppingTime = row.ParseDouble(Fields.StoppingTime).SI<Second>(),
AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
EngineSpeed = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
Gear = (uint)row.ParseDoubleOrGetDefault(Fields.Gear),
AirSpeedRelativeToVehicle = row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle).KMPHtoMeterPerSecond(),
WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
......@@ -359,8 +359,8 @@ namespace TUGraz.VectoCore.InputData.Reader
RoadGradientPercent = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
EngineSpeed = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
Gear = (uint)row.ParseDoubleOrGetDefault(Fields.Gear),
AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
AirSpeedRelativeToVehicle = row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle).KMPHtoMeterPerSecond(),
WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
......@@ -426,7 +426,7 @@ namespace TUGraz.VectoCore.InputData.Reader
var absTime = 0.SI<Second>();
foreach (DataRow row in table.Rows) {
var entry = new DrivingCycleData.DrivingCycleEntry {
EngineSpeed = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
AdditionalAuxPowerDemand =
row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
......@@ -436,13 +436,13 @@ namespace TUGraz.VectoCore.InputData.Reader
if (row.Field<string>(Fields.EngineTorque).Equals("<DRAG>")) {
entry.Drag = true;
} else {
entry.EngineTorque = row.ParseDouble(Fields.EngineTorque).SI<NewtonMeter>();
entry.Torque = row.ParseDouble(Fields.EngineTorque).SI<NewtonMeter>();
}
} else {
if (row.Field<string>(Fields.EnginePower).Equals("<DRAG>")) {
entry.Drag = true;
} else {
entry.EngineTorque = row.ParseDouble(Fields.EnginePower).SI().Kilo.Watt.Cast<Watt>() / entry.EngineSpeed;
entry.Torque = row.ParseDouble(Fields.EnginePower).SI().Kilo.Watt.Cast<Watt>() / entry.AngularVelocity;
}
}
entry.Time = absTime;
......@@ -506,8 +506,8 @@ namespace TUGraz.VectoCore.InputData.Reader
var entries = table.Rows.Cast<DataRow>().Select(row => new DrivingCycleData.DrivingCycleEntry {
Time = row.ParseDouble(Fields.Time).SI<Second>(),
PWheel = row.ParseDouble(Fields.PWheel).SI().Kilo.Watt.Cast<Watt>(),
Gear = row.ParseDouble(Fields.Gear),
EngineSpeed = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(),
Gear = (uint)row.ParseDouble(Fields.Gear),
AngularVelocity = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(),
AdditionalAuxPowerDemand = row.ParseDouble(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
}).ToArray();
......@@ -553,7 +553,7 @@ namespace TUGraz.VectoCore.InputData.Reader
Time = row.ParseDouble(Fields.Time).SI<Second>(),
VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(),
RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
Gear = row.ParseDouble(Fields.Gear),
Gear = (uint)row.ParseDouble(Fields.Gear),
AdditionalAuxPowerDemand = row.ParseDouble(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
}).ToArray();
......
......@@ -101,8 +101,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
modContainer.WriteModalResults = WriteModalResults;
var current = i++;
var builder = new PowertrainBuilder(modContainer, (writer, mass, loading) =>
SumData.Write(d.IsEngineOnly, modContainer, d.JobName, string.Format("{0}-{1}", JobNumber, current),
d.Cycle.Name + Constants.FileExtensions.CycleFile, mass, loading));
SumData.Write(d.IsEngineOnly, modContainer, d.JobName, string.Format("{0}-{1}", JobNumber, current),
d.Cycle.Name + Constants.FileExtensions.CycleFile, mass, loading));
VectoRun run;
......
......@@ -50,12 +50,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
RoadGradient = entry.RoadGradient;
Altitude = entry.Altitude;
StoppingTime = entry.StoppingTime;
EngineSpeed = entry.EngineSpeed;
AngularVelocity = entry.AngularVelocity;
Gear = entry.Gear;
AdditionalAuxPowerDemand = entry.AdditionalAuxPowerDemand;
AirSpeedRelativeToVehicle = entry.AirSpeedRelativeToVehicle;
WindYawAngle = entry.WindYawAngle;
EngineTorque = entry.EngineTorque;
Torque = entry.Torque;
Drag = entry.Drag;
AuxiliarySupplyPower = new Dictionary<string, Watt>(entry.AuxiliarySupplyPower);
}
......@@ -104,12 +104,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
/// <summary>
/// If "n" is defined VECTO uses that instead of the calculated engine speed value.
/// </summary>
public PerSecond EngineSpeed { get; set; }
public PerSecond AngularVelocity { get; set; }
/// <summary>
/// [-] Gear input. Overwrites the gear shift model.
/// </summary>
public double Gear { get; set; }
public uint Gear { get; set; }
/// <summary>
/// This power input will be directly added to the engine power in addition to possible other auxiliaries. Also used in Engine Only Mode.
......@@ -129,7 +129,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
/// <summary>
/// Effective engine torque at clutch. Only required in Engine Only Mode. Alternatively power "Pe" can be defined. Use "DRAG" to define motoring operation.
/// </summary>
public NewtonMeter EngineTorque { get; set; }
public NewtonMeter Torque { get; set; }
public bool Drag { get; set; }
......
......@@ -14,57 +14,80 @@
* limitations under the Licence.
*/
using System;
using System.Diagnostics;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation;
using TUGraz.VectoCore.Models.Simulation.Data;
using TUGraz.VectoCore.Models.Simulation.DataBus;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.OutputData;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{
public class ManualGearbox : Gearbox
public class ManualGearbox : VectoSimulationComponent, IGearbox, ITnOutPort, ITnInPort, IClutchInfo
{
public ManualGearbox(IVehicleContainer container, GearboxData gearboxData = null) : base(container, gearboxData) {}
private readonly GearboxData _data;
private ITnOutPort NextComponent { get; set; }
private PerSecond PreviousInAngularSpeed { get; set; }
private Watt PowerLossInertia { get; set; }
private Watt PowerLoss { get; set; }
#region ITnOutPort
private Func<uint> GetGear { get; set; }
public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
public uint Gear
{
get { return GetGear(); }
}
public MeterPerSecond StartSpeed
{
get { return _data.StartSpeed; }
}
public MeterPerSquareSecond StartAcceleration
{
get { return _data.StartAcceleration; }
}
public FullLoadCurve GearFullLoadCurve
{
get { return Gear == 0 ? null : _data.Gears[Gear].FullLoadCurve; }
}
public ManualGearbox(IVehicleContainer container, GearboxData gearboxData, Func<uint> getGear)
: base(container)
{
_data = gearboxData;
GetGear = getGear;
}
public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
{
var dt = Constants.SimulationSettings.TargetTimeInterval;
ShiftTime = double.NegativeInfinity.SI<Second>();
PowerLoss = null;
if (Disengaged) {
Gear = DataBus.Gear;
}
if (Data == null || Data.Gears == null) {
if (_data == null || _data.Gears == null) {
var r = NextComponent.Initialize(outTorque, outAngularVelocity);
if (r is ResponseSuccess) {
PreviousInAngularSpeed = outAngularVelocity;
Disengaged = false;
}
return r;
}
var inAngularVelocity = outAngularVelocity * Data.Gears[Gear].Ratio;
var inTorque = Data.Gears[Gear].LossMap.GetInTorque(inAngularVelocity, outTorque);
var inAngularVelocity = outAngularVelocity * _data.Gears[Gear].Ratio;
var inTorque = _data.Gears[Gear].LossMap.GetInTorque(inAngularVelocity, outTorque);
var torqueLossInertia = outAngularVelocity.IsEqual(0)
? 0.SI<NewtonMeter>()
: Formulas.InertiaPower(inAngularVelocity, PreviousInAngularSpeed, Data.Inertia, dt) / inAngularVelocity;
: Formulas.InertiaPower(inAngularVelocity, PreviousInAngularSpeed, _data.Inertia, dt) / inAngularVelocity;
inTorque += torqueLossInertia;
var response = NextComponent.Initialize(inTorque, inAngularVelocity);
if (response is ResponseSuccess) {
PreviousInAngularSpeed = inAngularVelocity;
Disengaged = false;
}
return response;
}
......@@ -78,80 +101,30 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
/// <item><description>ResponseGearshift</description></item>
/// </list>
/// </returns>
public override IResponse Request(Second absTime, Second dt, NewtonMeter torque, PerSecond angularVelocity,
public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
bool dryRun)
{
Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", torque, angularVelocity);
IResponse retVal;
if (ClutchClosed(absTime)) {
retVal = RequestGearEngaged(absTime, dt, torque, angularVelocity, dryRun);
} else {
retVal = RequestGearDisengaged(absTime, dt, torque, angularVelocity, dryRun);
}
return retVal;
}
Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
/// <summary>
/// Requests the gearbox in engaged mode. Sets the gear if no gear was set previously.
/// </summary>
/// <returns>
/// <list type="bullet">
/// <item><term>ResponseGearShift</term><description>if a shift is needed.</description></item>
/// <item><term>else</term><description>Response from NextComponent.</description></item>
/// </list>
/// </returns>
protected override IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque,
PerSecond outAngularVelocity,
bool dryRun)
{
// Set a Gear if no gear was set and engineSpeed is not zero
if (Disengaged && !outAngularVelocity.IsEqual(0)) {
Disengaged = false;
Gear = DataBus.Gear;
Log.Debug("Gearbox engaged gear {0}", Gear);
if (Gear == 0) {
var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
disengagedResponse.GearboxPowerRequest = outTorque * outAngularVelocity;
PreviousInAngularSpeed = DataBus.EngineIdleSpeed;
return disengagedResponse;
}
if (Data == null || Data.Gears == null) {
var r = NextComponent.Request(absTime, dt, outTorque, outAngularVelocity);
r.GearboxPowerRequest = outTorque * outAngularVelocity;
PreviousInAngularSpeed = outAngularVelocity;
return r;
}
var inEngineSpeed = outAngularVelocity * Data.Gears[Gear].Ratio;
var inTorque = outAngularVelocity.IsEqual(0)
? outTorque / Data.Gears[Gear].Ratio
: Data.Gears[Gear].LossMap.GetInTorque(inEngineSpeed, outTorque);
var inEngineSpeed = outAngularVelocity * _data.Gears[Gear].Ratio;
var inTorque = _data.Gears[Gear].LossMap.GetInTorque(inEngineSpeed, outTorque);
PowerLoss = inTorque * inEngineSpeed - outTorque * outAngularVelocity;
if (!inEngineSpeed.IsEqual(0)) {
PowerLossInertia = Formulas.InertiaPower(inEngineSpeed, PreviousInAngularSpeed, Data.Inertia, dt);
PowerLossInertia = Formulas.InertiaPower(inEngineSpeed, PreviousInAngularSpeed, _data.Inertia, dt);
inTorque += PowerLossInertia / inEngineSpeed;
} else {
PowerLossInertia = 0.SI<Watt>();
}
var shiftRequired = Gear != DataBus.Gear;
if (shiftRequired) {
ShiftTime = absTime + Data.TractionInterruption;
Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, shiftTime: {2}, out: ({3}, {4}), in: ({5}, {6})", absTime, dt,
ShiftTime, outTorque, outAngularVelocity, inTorque, inEngineSpeed);
Disengaged = true;
Log.Info("Gearbox disengaged");
return new ResponseGearShift {
Source = this,
SimulationInterval = Data.TractionInterruption,
GearboxPowerRequest = outTorque * outAngularVelocity
};
}
var response = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed);
response.GearboxPowerRequest = outTorque * outAngularVelocity;
......@@ -159,8 +132,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return response;
}
#endregion
protected override void DoWriteModalResults(IModalDataContainer container)
{
container[ModalResultField.Gear] = Gear;
......@@ -168,11 +139,37 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
container[ModalResultField.PaGB] = PowerLossInertia;
}
protected override void DoCommitSimulationStep()
{
if (Data != null && Data.Gears != null) {
base.DoCommitSimulationStep();
if (_data.Gears[Gear].LossMap.Extrapolated) {
Log.Warn("Gear {0} LossMap data was extrapolated: range for loss map is not sufficient.", Gear);
}
PowerLoss = null;
PowerLossInertia = null;
}
[DebuggerHidden]
public ITnInPort InPort()
{
return this;
}
[DebuggerHidden]
public ITnOutPort OutPort()
{
return this;
}
void ITnInPort.Connect(ITnOutPort other)
{
NextComponent = other;
}
public bool ClutchClosed(Second absTime)
{
return true;
}
}
}
\ No newline at end of file
......@@ -21,7 +21,9 @@ using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
using TUGraz.VectoCore.Models.Simulation;
using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.Models.SimulationComponent.Data;
using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
using TUGraz.VectoCore.OutputData;
using TUGraz.VectoCore.Utils;
......@@ -84,13 +86,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return new ResponseCycleFinished();
}
AbsTime = absTime;
return NextComponent.Request(absTime, dt, Data.Entries[index].EngineTorque, Data.Entries[index].EngineSpeed);
return NextComponent.Request(absTime, dt, Data.Entries[index].Torque, Data.Entries[index].AngularVelocity);
}
public IResponse Initialize()
{
var index = 0;
return NextComponent.Initialize(Data.Entries[index].EngineTorque, Data.Entries[index].EngineSpeed);
return NextComponent.Initialize(Data.Entries[index].Torque, Data.Entries[index].AngularVelocity);
}
public string CycleName
......@@ -142,4 +144,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
};
}
}
public class PWheelCycle : PowertrainDrivingCycle
{
public PWheelCycle(IVehicleContainer container, DrivingCycleData cycle, double axleRatio,
IDictionary<uint, double> gears) : base(container, cycle)
{
gears[0] = 1;
foreach (var entry in Data.Entries) {
entry.AngularVelocity *= axleRatio * gears[entry.Gear];
entry.Torque = entry.PWheel / entry.AngularVelocity;
}
}
}
}
\ No newline at end of file
......@@ -64,7 +64,7 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle
var modData = new ModalDataContainer(modFile, fileWriter, ExecutionMode.EngineOnly);
foreach (var cycleEntry in data.Entries) {
var response = port.Request(absTime, dt, cycleEntry.EngineTorque, cycleEntry.EngineSpeed);
var response = port.Request(absTime, dt, cycleEntry.Torque, cycleEntry.AngularVelocity);
Assert.IsInstanceOfType(response, typeof(ResponseSuccess));
foreach (var sc in vehicle.SimulationComponents()) {
modData[ModalResultField.time] = absTime + dt / 2;
......
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