Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

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

read effshift parameters for tc->L shift from .vtcu file; add standard values...

read effshift parameters for tc->L shift from .vtcu file; add standard values to declaration data folder
parent d7d805cf
No related branches found
No related tags found
No related merge requests found
Showing
with 242 additions and 128 deletions
...@@ -619,6 +619,12 @@ Public Class Gearbox ...@@ -619,6 +619,12 @@ Public Class Gearbox
End Get End Get
End Property End Property
Public ReadOnly Property ShiftSpeedsTCToLocked As Double()() Implements IGearshiftEngineeringInputData.ShiftSpeedsTCToLocked
get
return Nothing
End Get
End Property
Public Overridable ReadOnly Property LoadStageShiftLines As TableData Implements IGearshiftEngineeringInputData.LoadStageShiftLines Public Overridable ReadOnly Property LoadStageShiftLines As TableData Implements IGearshiftEngineeringInputData.LoadStageShiftLines
Get Get
Return Nothing Return Nothing
......
...@@ -288,6 +288,7 @@ namespace TUGraz.VectoCommon.InputData ...@@ -288,6 +288,7 @@ namespace TUGraz.VectoCommon.InputData
PerSecond MinEngineSpeedPostUpshift { get; } PerSecond MinEngineSpeedPostUpshift { get; }
Second ATLookAheadTime { get; } Second ATLookAheadTime { get; }
double[][] ShiftSpeedsTCToLocked { get; }
} }
public interface ITorqueConverterEngineeringShiftParameterInputData public interface ITorqueConverterEngineeringShiftParameterInputData
......
...@@ -407,6 +407,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON ...@@ -407,6 +407,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
public PerSecond MinEngineSpeedPostUpshift { get { return null; } } public PerSecond MinEngineSpeedPostUpshift { get { return null; } }
public Second ATLookAheadTime { get { return null; } } public Second ATLookAheadTime { get { return null; } }
public double[][] ShiftSpeedsTCToLocked { get { return null; } }
public double? VeloictyDropFactor public double? VeloictyDropFactor
{ {
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Utils; using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Declaration;
...@@ -312,6 +313,26 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON ...@@ -312,6 +313,26 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
} }
} }
public double[][] ShiftSpeedsTCToLocked
{
get {
if (Body["ShiftSpeedsTCLockup"] == null) {
return null;
}
var retVal = new List<double[]>();
foreach (var entry in Body["ShiftSpeedsTCLockup"]) {
if (!(entry is JArray)) {
throw new VectoException("Array expected");
}
retVal.Add(entry.Select(shiftSpeed => shiftSpeed.Value<double>()).ToArray());
}
return retVal.ToArray();
}
}
public TableData LoadStageShiftLines public TableData LoadStageShiftLines
{ {
get { get {
...@@ -325,13 +346,15 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON ...@@ -325,13 +346,15 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
public IList<double> LoadStageThresoldsUp public IList<double> LoadStageThresoldsUp
{ {
get { return (Body["LoadStageThresoldsUp"]?.ToString() ?? "").Split(';').Select(x => x.ToDouble(0)).ToList(); } get {
return (Body["LoadStageThresoldsUp"]?.ToString())?.Split(';').Select(x => x.ToDouble(0)).ToList();
}
} }
public IList<double> LoadStageThresoldsDown public IList<double> LoadStageThresoldsDown
{ {
get { get {
return (Body["LoadStageThresoldsDown"]?.ToString() ?? "").Split(';').Select(x => x.ToDouble(0)).ToList(); return (Body["LoadStageThresoldsDown"]?.ToString())?.Split(';').Select(x => x.ToDouble(0)).ToList();
} }
} }
......
...@@ -120,6 +120,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering.DataProvider ...@@ -120,6 +120,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering.DataProvider
public PerSecond MinEngineSpeedPostUpshift { get { return null; } } public PerSecond MinEngineSpeedPostUpshift { get { return null; } }
public Second ATLookAheadTime { get { return null; } } public Second ATLookAheadTime { get { return null; } }
public double[][] ShiftSpeedsTCToLocked { get { return null; } }
public double? AccelerationFactor public double? AccelerationFactor
{ {
......
...@@ -602,7 +602,11 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter ...@@ -602,7 +602,11 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
VelocityDropFactor = DeclarationData.GearboxTCU.VelocityDropFactor, VelocityDropFactor = DeclarationData.GearboxTCU.VelocityDropFactor,
AccelerationFactor = DeclarationData.GearboxTCU.AccelerationFactor, AccelerationFactor = DeclarationData.GearboxTCU.AccelerationFactor,
MinEngineSpeedPostUpshift = 0.RPMtoRad(), MinEngineSpeedPostUpshift = 0.RPMtoRad(),
ATLookAheadTime = DeclarationData.Gearbox.PowershiftShiftTime ATLookAheadTime = DeclarationData.Gearbox.PowershiftShiftTime,
LoadStageThresoldsUp = DeclarationData.GearboxTCU.LoadStageThresholdsUp,
LoadStageThresoldsDown = DeclarationData.GearboxTCU.LoadStageThresoldsDown,
ShiftSpeedsTCToLocked = DeclarationData.GearboxTCU.ShiftSpeedsTCToLocked,
}; };
return retVal; return retVal;
......
...@@ -463,6 +463,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter ...@@ -463,6 +463,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
MinEngineSpeedPostUpshift = gsInputData.MinEngineSpeedPostUpshift ?? 0.RPMtoRad(), MinEngineSpeedPostUpshift = gsInputData.MinEngineSpeedPostUpshift ?? 0.RPMtoRad(),
ATLookAheadTime = gsInputData.ATLookAheadTime ?? DeclarationData.Gearbox.PowershiftShiftTime, ATLookAheadTime = gsInputData.ATLookAheadTime ?? DeclarationData.Gearbox.PowershiftShiftTime,
LoadStageThresoldsDown = gsInputData.LoadStageThresoldsDown?.ToArray() ?? DeclarationData.GearboxTCU.LoadStageThresoldsDown,
LoadStageThresoldsUp = gsInputData.LoadStageThresoldsUp?.ToArray() ?? DeclarationData.GearboxTCU.LoadStageThresholdsUp,
ShiftSpeedsTCToLocked = gsInputData.ShiftSpeedsTCToLocked ?? DeclarationData.GearboxTCU.ShiftSpeedsTCToLocked,
// voith gs parameters // voith gs parameters
GearshiftLines = gsInputData.LoadStageShiftLines, GearshiftLines = gsInputData.LoadStageShiftLines,
......
...@@ -97,6 +97,7 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -97,6 +97,7 @@ namespace TUGraz.VectoCore.Models.Declaration
if (equationName.ToLower().StartsWith("pc75")) { if (equationName.ToLower().StartsWith("pc75")) {
return Payloads.Lookup75Percent(grossVehicleWeight); return Payloads.Lookup75Percent(grossVehicleWeight);
} }
return Payloads.Lookup50Percent(grossVehicleWeight); return Payloads.Lookup50Percent(grossVehicleWeight);
} }
...@@ -107,7 +108,8 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -107,7 +108,8 @@ namespace TUGraz.VectoCore.Models.Declaration
{ {
return return
(Math.Round( (Math.Round(
(Payloads.LookupTrailer(grossVehicleWeight, curbWeight) / (lowLoading ? 7.5 : 1)).LimitTo(0.SI<Kilogram>(), (Payloads.LookupTrailer(grossVehicleWeight, curbWeight) / (lowLoading ? 7.5 : 1)).LimitTo(
0.SI<Kilogram>(),
grossVehicleWeight - curbWeight).Value() / 100, 0) * 100).SI<Kilogram>(); grossVehicleWeight - curbWeight).Value() / 100, 0) * 100).SI<Kilogram>();
} }
...@@ -154,6 +156,7 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -154,6 +156,7 @@ namespace TUGraz.VectoCore.Models.Declaration
public const double TyreTestLoad = 37500; public const double TyreTestLoad = 37500;
public const bool TwinTyres = false; public const bool TwinTyres = false;
//public const string WheelsType = "385/65 R 22.5"; //public const string WheelsType = "385/65 R 22.5";
} }
...@@ -198,18 +201,33 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -198,18 +201,33 @@ namespace TUGraz.VectoCore.Models.Declaration
public const double TargetSpeedDeviationFactor = 0.1; public const double TargetSpeedDeviationFactor = 0.1;
public const double RatingFactorCurrentGear = 0.99; public const double RatingFactorCurrentGear = 0.97;
public const double RatingFactorCurrentGearAT = 0.95; public const double RatingFactorCurrentGearAT = 0.97;
public static readonly MeterPerSquareSecond DriverAccelerationThresholdLow = 0.1.SI<MeterPerSquareSecond>(); public static readonly MeterPerSquareSecond DriverAccelerationThresholdLow = 0.1.SI<MeterPerSquareSecond>();
public static double VelocityDropFactor = 0.0; public static double VelocityDropFactor = 1.0;
public static double AccelerationFactor = 1.0; public static double AccelerationFactor = 0.5;
public const double RatioEarlyUpshiftFC = 24; public const double RatioEarlyUpshiftFC = 24;
public const double RatioEarlyDownshiftFC = 24; public const double RatioEarlyDownshiftFC = 24;
public const int AllowedGearRangeFCAMT = 2; public const int AllowedGearRangeFCAMT = 2;
public const int AllowedGearRangeFCAT = 1; public const int AllowedGearRangeFCAT = 1;
public static readonly double[] LoadStageThresholdsUp = new[] { 19.7, 36.34, 53.01, 69.68, 86.35 };
public static readonly double[] LoadStageThresoldsDown = new[] { 13.7, 30.34, 47.01, 63.68, 80.35 };
public static readonly double[][] ShiftSpeedsTCToLocked = new[] {
new[] { 650.0, 680, 725, 650, 680, 725 },
new[] { 650.0, 680, 725, 650, 680, 725 },
new[] { 650.0, 680, 725, 650, 680, 725 },
new[] { 650.0, 680, 725, 670, 700, 745 },
new[] { 660.0, 690, 735, 680, 710, 755 },
new[] { 670.0, 700, 745, 690, 720, 755 },
};
public const double DownhillSlope = -5;
public const double UphillSlope = 5;
} }
public static class Gearbox public static class Gearbox
...@@ -245,14 +263,17 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -245,14 +263,17 @@ namespace TUGraz.VectoCore.Models.Declaration
/// <param name="axlegearRatio"></param> /// <param name="axlegearRatio"></param>
/// <param name="dynamicTyreRadius"></param> /// <param name="dynamicTyreRadius"></param>
/// <returns></returns> /// <returns></returns>
public static ShiftPolygon ComputeShiftPolygon(GearboxType type, int gearIdx, EngineFullLoadCurve fullLoadCurve, public static ShiftPolygon ComputeShiftPolygon(
GearboxType type, int gearIdx, EngineFullLoadCurve fullLoadCurve,
IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius) IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius)
{ {
switch (type) { switch (type) {
case GearboxType.AMT: case GearboxType.AMT:
//return ComputeEfficiencyShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius); //return ComputeEfficiencyShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius);
case GearboxType.MT: case GearboxType.MT:
return ComputeManualTransmissionShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius); return ComputeManualTransmissionShiftPolygon(
gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius);
case GearboxType.ATSerial: case GearboxType.ATSerial:
case GearboxType.ATPowerSplit: case GearboxType.ATPowerSplit:
return TorqueConverter.ComputeShiftPolygon(fullLoadCurve, gearIdx == 0, gearIdx >= gears.Count - 1); return TorqueConverter.ComputeShiftPolygon(fullLoadCurve, gearIdx == 0, gearIdx >= gears.Count - 1);
...@@ -262,11 +283,14 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -262,11 +283,14 @@ namespace TUGraz.VectoCore.Models.Declaration
return type.AutomaticTransmission() return type.AutomaticTransmission()
? TorqueConverter.ComputeShiftPolygon(fullLoadCurve, gearIdx == 0, gearIdx >= gears.Count - 1) ? TorqueConverter.ComputeShiftPolygon(fullLoadCurve, gearIdx == 0, gearIdx >= gears.Count - 1)
// That's the same for all gears, so call the same method... // That's the same for all gears, so call the same method...
: ComputeManualTransmissionShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius); : ComputeManualTransmissionShiftPolygon(gearIdx, fullLoadCurve, gears, engine, axlegearRatio, dynamicTyreRadius);
} }
public static ShiftPolygon ComputeEfficiencyShiftPolygon(int gearIdx, EngineFullLoadCurve fullLoadCurve, IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius) public static ShiftPolygon ComputeEfficiencyShiftPolygon(
int gearIdx, EngineFullLoadCurve fullLoadCurve, IList<ITransmissionInputData> gears, CombustionEngineData engine,
double axlegearRatio, Meter dynamicTyreRadius)
{ {
if (gears.Count < 2) { if (gears.Count < 2) {
throw new VectoException("ComputeShiftPolygon needs at least 2 gears. {0} gears given.", gears.Count); throw new VectoException("ComputeShiftPolygon needs at least 2 gears. {0} gears given.", gears.Count);
...@@ -292,7 +316,9 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -292,7 +316,9 @@ namespace TUGraz.VectoCore.Models.Declaration
fullLoadCurve.FullLoadStationaryTorque(p2.X.SI<PerSecond>()) * ShiftPolygonEngineFldMargin, fullLoadCurve.FullLoadStationaryTorque(p2.X.SI<PerSecond>()) * ShiftPolygonEngineFldMargin,
p2.X.SI<PerSecond>())); p2.X.SI<PerSecond>()));
} }
downShift.AddRange(downShiftPoints.Select(x => new ShiftPolygon.ShiftPolygonEntry(x.Y.SI<NewtonMeter>() * 0.98, x.X.SI<PerSecond>()))); downShift.AddRange(
downShiftPoints.Select(
x => new ShiftPolygon.ShiftPolygonEntry(x.Y.SI<NewtonMeter>() * 0.98, x.X.SI<PerSecond>())));
if (downShiftPoints.Max(x => x.X) < p3.X) { if (downShiftPoints.Max(x => x.X) < p3.X) {
downShift.Add( downShift.Add(
new ShiftPolygon.ShiftPolygonEntry( new ShiftPolygon.ShiftPolygonEntry(
...@@ -306,13 +332,15 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -306,13 +332,15 @@ namespace TUGraz.VectoCore.Models.Declaration
if (gearIdx >= gears.Count - 1) { if (gearIdx >= gears.Count - 1) {
return new ShiftPolygon(downShift, upShift); return new ShiftPolygon(downShift, upShift);
} }
upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDragTorque * 1.1, p5.X.SI<PerSecond>())); upShift.Add(new ShiftPolygon.ShiftPolygonEntry(fullLoadCurve.MaxDragTorque * 1.1, p5.X.SI<PerSecond>()));
upShift.Add(new ShiftPolygon.ShiftPolygonEntry(p5.Y.SI<NewtonMeter>(), p5.X.SI<PerSecond>())); upShift.Add(new ShiftPolygon.ShiftPolygonEntry(p5.Y.SI<NewtonMeter>(), p5.X.SI<PerSecond>()));
return new ShiftPolygon(downShift, upShift); return new ShiftPolygon(downShift, upShift);
} }
public static ShiftPolygon ComputeManualTransmissionShiftPolygon(int gearIdx, EngineFullLoadCurve fullLoadCurve, public static ShiftPolygon ComputeManualTransmissionShiftPolygon(
int gearIdx, EngineFullLoadCurve fullLoadCurve,
IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius) IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius)
{ {
if (gears.Count < 2) { if (gears.Count < 2) {
...@@ -330,7 +358,8 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -330,7 +358,8 @@ namespace TUGraz.VectoCore.Models.Declaration
var p1 = new Point(engine.IdleSpeed.Value() / 2, 0); var p1 = new Point(engine.IdleSpeed.Value() / 2, 0);
var p2 = new Point(engine.IdleSpeed.Value() * 1.1, 0); var p2 = new Point(engine.IdleSpeed.Value() * 1.1, 0);
var p3 = new Point(nVHigh.Value() * 0.9, var p3 = new Point(
nVHigh.Value() * 0.9,
fullLoadCurve.FullLoadStationaryTorque(nVHigh * 0.9).Value()); fullLoadCurve.FullLoadStationaryTorque(nVHigh * 0.9).Value());
var p4 = new Point((nVHigh * (1 + diffRatio / 3)).Value(), 0); var p4 = new Point((nVHigh * (1 + diffRatio / 3)).Value(), 0);
...@@ -346,7 +375,8 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -346,7 +375,8 @@ namespace TUGraz.VectoCore.Models.Declaration
if (gearIdx > 0) { if (gearIdx > 0) {
downShift = downShift =
new[] { p2, downshiftCorr.P1, downshiftCorr.P2 }.Select( new[] { p2, downshiftCorr.P1, downshiftCorr.P2 }.Select(
point => new ShiftPolygon.ShiftPolygonEntry(point.Y.SI<NewtonMeter>(), point.X.SI<PerSecond>())).ToList(); point => new ShiftPolygon.ShiftPolygonEntry(point.Y.SI<NewtonMeter>(), point.X.SI<PerSecond>()))
.ToList();
downShift[0].Torque = maxDragTorque; downShift[0].Torque = maxDragTorque;
} }
...@@ -364,12 +394,14 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -364,12 +394,14 @@ namespace TUGraz.VectoCore.Models.Declaration
var p6p = new Point(p6.X * gearRatio * rpmMarginFactor, p6.Y / gearRatio); var p6p = new Point(p6.X * gearRatio * rpmMarginFactor, p6.Y / gearRatio);
var edgeP6pP3p = new Edge(p6p, p3p); var edgeP6pP3p = new Edge(p6p, p3p);
var p3pExt = new Point((1.1 * p5.Y - edgeP6pP3p.OffsetXY) / edgeP6pP3p.SlopeXY, 1.1 * p5.Y); var p3pExt = new Point((1.1 * p5.Y - edgeP6pP3p.OffsetXY) / edgeP6pP3p.SlopeXY, 1.1 * p5.Y);
// ReSharper restore InconsistentNaming // ReSharper restore InconsistentNaming
var upShiftPts = IntersectTakeHigherShiftLine(new[] { p4, p7, p5 }, new[] { p2p, p6p, p3pExt }); var upShiftPts = IntersectTakeHigherShiftLine(new[] { p4, p7, p5 }, new[] { p2p, p6p, p3pExt });
if (gears[gearIdx].MaxInputSpeed != null) { if (gears[gearIdx].MaxInputSpeed != null) {
var maxSpeed = gears[gearIdx].MaxInputSpeed.Value(); var maxSpeed = gears[gearIdx].MaxInputSpeed.Value();
upShiftPts = IntersectTakeLowerShiftLine(upShiftPts, upShiftPts = IntersectTakeLowerShiftLine(
upShiftPts,
new[] { new Point(maxSpeed, 0), new Point(maxSpeed, upShiftPts.Max(pt => pt.Y)) }); new[] { new Point(maxSpeed, 0), new Point(maxSpeed, upShiftPts.Max(pt => pt.Y)) });
} }
upShift = upShift =
...@@ -403,17 +435,20 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -403,17 +435,20 @@ namespace TUGraz.VectoCore.Models.Declaration
/// <param name="fullLoadCurve"></param> /// <param name="fullLoadCurve"></param>
/// <param name="rpmLimit"></param> /// <param name="rpmLimit"></param>
/// <returns></returns> /// <returns></returns>
internal static IEnumerable<Point> ShiftPolygonFldMargin(List<EngineFullLoadCurve.FullLoadCurveEntry> fullLoadCurve, internal static IEnumerable<Point> ShiftPolygonFldMargin(
List<EngineFullLoadCurve.FullLoadCurveEntry> fullLoadCurve,
PerSecond rpmLimit) PerSecond rpmLimit)
{ {
return fullLoadCurve.TakeWhile(fldEntry => fldEntry.EngineSpeed < rpmLimit) return fullLoadCurve.TakeWhile(fldEntry => fldEntry.EngineSpeed < rpmLimit)
.Select(fldEntry => .Select(
fldEntry =>
new Point(fldEntry.EngineSpeed.Value(), fldEntry.TorqueFullLoad.Value() * ShiftPolygonEngineFldMargin)) new Point(fldEntry.EngineSpeed.Value(), fldEntry.TorqueFullLoad.Value() * ShiftPolygonEngineFldMargin))
.ToList(); .ToList();
} }
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
private static PerSecond ComputeEngineSpeed85kmh(ITransmissionInputData gear, double axleRatio, private static PerSecond ComputeEngineSpeed85kmh(
ITransmissionInputData gear, double axleRatio,
Meter dynamicTyreRadius) Meter dynamicTyreRadius)
{ {
var engineSpeed = TruckMaxAllowedSpeed / dynamicTyreRadius * axleRatio * gear.Ratio; var engineSpeed = TruckMaxAllowedSpeed / dynamicTyreRadius * axleRatio * gear.Ratio;
...@@ -441,6 +476,7 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -441,6 +476,7 @@ namespace TUGraz.VectoCore.Models.Declaration
if (!tmp.Any()) { if (!tmp.Any()) {
continue; continue;
} }
shiftPolygon.Add(tmp.First()); shiftPolygon.Add(tmp.First());
break; break;
} }
...@@ -467,6 +503,7 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -467,6 +503,7 @@ namespace TUGraz.VectoCore.Models.Declaration
if (!intersections.Any()) { if (!intersections.Any()) {
return upShiftPts[0].X < upperLimit[0].X ? upShiftPts : upperLimit; return upShiftPts[0].X < upperLimit[0].X ? upShiftPts : upperLimit;
} }
var pointSet = new List<Point>(upShiftPts); var pointSet = new List<Point>(upShiftPts);
pointSet.AddRange(upperLimit); pointSet.AddRange(upperLimit);
pointSet.AddRange(intersections); pointSet.AddRange(intersections);
...@@ -498,6 +535,7 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -498,6 +535,7 @@ namespace TUGraz.VectoCore.Models.Declaration
private static Point[] Intersect(Point[] orig, Point[] transformedDownshift) private static Point[] Intersect(Point[] orig, Point[] transformedDownshift)
{ {
var intersections = new List<Point>(); var intersections = new List<Point>();
// compute all intersection points between both line segments // compute all intersection points between both line segments
// ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once LoopCanBeConvertedToQuery
foreach (var origLine in orig.Pairwise(Edge.Create)) { foreach (var origLine in orig.Pairwise(Edge.Create)) {
...@@ -509,10 +547,12 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -509,10 +547,12 @@ namespace TUGraz.VectoCore.Models.Declaration
} }
} }
} }
return intersections.ToArray(); return intersections.ToArray();
} }
private static IEnumerable<Point> ProjectPointsToLineSegments(IEnumerable<Point> lineSegments, Point[] points, private static IEnumerable<Point> ProjectPointsToLineSegments(
IEnumerable<Point> lineSegments, Point[] points,
bool projectToVertical = false) bool projectToVertical = false)
{ {
var pointSet = new List<Point>(); var pointSet = new List<Point>();
...@@ -520,14 +560,17 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -520,14 +560,17 @@ namespace TUGraz.VectoCore.Models.Declaration
if (segment.P1.X.IsEqual(segment.P2.X)) { if (segment.P1.X.IsEqual(segment.P2.X)) {
if (projectToVertical) { if (projectToVertical) {
pointSet.AddRange( pointSet.AddRange(
points.Select(point => new Point(segment.P1.X, point.Y)).Where(pt => pt.Y.IsBetween(segment.P1.Y, segment.P2.Y))); points.Select(point => new Point(segment.P1.X, point.Y))
.Where(pt => pt.Y.IsBetween(segment.P1.Y, segment.P2.Y)));
} }
continue; continue;
} }
var k = segment.SlopeXY; var k = segment.SlopeXY;
var d = segment.P1.Y - segment.P1.X * k; var d = segment.P1.Y - segment.P1.X * k;
pointSet.AddRange(points.Select(point => new Point(point.X, point.X * k + d))); pointSet.AddRange(points.Select(point => new Point(point.X, point.X * k + d)));
} }
return pointSet; return pointSet;
} }
} }
...@@ -543,7 +586,8 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -543,7 +586,8 @@ namespace TUGraz.VectoCore.Models.Declaration
private static readonly PerSecond UpshiftLowRPM = 900.RPMtoRad(); private static readonly PerSecond UpshiftLowRPM = 900.RPMtoRad();
private static readonly PerSecond UpshiftHighRPM = 1150.RPMtoRad(); private static readonly PerSecond UpshiftHighRPM = 1150.RPMtoRad();
public static ShiftPolygon ComputeShiftPolygon(EngineFullLoadCurve fullLoadCurve, bool first = false, public static ShiftPolygon ComputeShiftPolygon(
EngineFullLoadCurve fullLoadCurve, bool first = false,
bool last = false) bool last = false)
{ {
var maxDragTorque = fullLoadCurve.MaxDragTorque * 1.1; var maxDragTorque = fullLoadCurve.MaxDragTorque * 1.1;
...@@ -561,7 +605,8 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -561,7 +605,8 @@ namespace TUGraz.VectoCore.Models.Declaration
var upshift = new[] { p0, p1, p2corr }.Select( var upshift = new[] { p0, p1, p2corr }.Select(
pt => new ShiftPolygon.ShiftPolygonEntry(pt.Y.SI<NewtonMeter>(), pt.X.SI<PerSecond>())); pt => new ShiftPolygon.ShiftPolygonEntry(pt.Y.SI<NewtonMeter>(), pt.X.SI<PerSecond>()));
return new ShiftPolygon(first ? new List<ShiftPolygon.ShiftPolygonEntry>() : downshift.ToList(), return new ShiftPolygon(
first ? new List<ShiftPolygon.ShiftPolygonEntry>() : downshift.ToList(),
last ? new List<ShiftPolygon.ShiftPolygonEntry>() : upshift.ToList()); last ? new List<ShiftPolygon.ShiftPolygonEntry>() : upshift.ToList());
} }
...@@ -580,6 +625,7 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -580,6 +625,7 @@ namespace TUGraz.VectoCore.Models.Declaration
torqueConverterEntry.SpeedRatio = torqueConverterEntry.SpeedRatio * ratio; torqueConverterEntry.SpeedRatio = torqueConverterEntry.SpeedRatio * ratio;
torqueConverterEntry.TorqueRatio = torqueConverterEntry.TorqueRatio / ratio; torqueConverterEntry.TorqueRatio = torqueConverterEntry.TorqueRatio / ratio;
} }
return characteristicTorque.Where(x => x.SpeedRatio >= ratio).ToArray(); return characteristicTorque.Where(x => x.SpeedRatio >= ratio).ToArray();
} }
} }
...@@ -618,13 +664,19 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -618,13 +664,19 @@ namespace TUGraz.VectoCore.Models.Declaration
public static readonly Second SamplingInterval = 0.5.SI<Second>(); public static readonly Second SamplingInterval = 0.5.SI<Second>();
public static readonly WattSecond MinPosWorkAtWheelsForFC = 1.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>(); public static readonly WattSecond MinPosWorkAtWheelsForFC = 1.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>();
public static readonly SpecificFuelConsumption LowerFCThreshold = 180.SI(Unit.SI.Gramm.Per.Kilo.Watt.Hour).Cast<SpecificFuelConsumption>();
public static readonly SpecificFuelConsumption UpperFCThreshold = 600.SI(Unit.SI.Gramm.Per.Kilo.Watt.Hour).Cast<SpecificFuelConsumption>(); public static readonly SpecificFuelConsumption LowerFCThreshold =
180.SI(Unit.SI.Gramm.Per.Kilo.Watt.Hour).Cast<SpecificFuelConsumption>();
public static readonly SpecificFuelConsumption UpperFCThreshold =
600.SI(Unit.SI.Gramm.Per.Kilo.Watt.Hour).Cast<SpecificFuelConsumption>();
public static readonly Second FCAccumulationWindow = 10.SI(Unit.SI.Minute).Cast<Second>(); public static readonly Second FCAccumulationWindow = 10.SI(Unit.SI.Minute).Cast<Second>();
public static readonly double[] FanParameters = { 7.320, 1200.0, 810 }; public static readonly double[] FanParameters = { 7.320, 1200.0, 810 };
} }
public static class Vehicle { public static class Vehicle
{
public const bool DualFuelVehicleDefault = false; public const bool DualFuelVehicleDefault = false;
public const bool HybridElectricHDVDefault = false; public const bool HybridElectricHDVDefault = false;
public const bool ZeroEmissionVehicleDefault = false; public const bool ZeroEmissionVehicleDefault = false;
...@@ -632,7 +684,8 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -632,7 +684,8 @@ namespace TUGraz.VectoCore.Models.Declaration
public const bool SleeperCabDefault = true; public const bool SleeperCabDefault = true;
public const bool VocationalVehicleDefault = false; public const bool VocationalVehicleDefault = false;
public static class ADAS { public static class ADAS
{
public const PredictiveCruiseControlType PredictiveCruiseControlDefault = PredictiveCruiseControlType.None; public const PredictiveCruiseControlType PredictiveCruiseControlDefault = PredictiveCruiseControlType.None;
public const EcoRollType EcoRoll = EcoRollType.None; public const EcoRollType EcoRoll = EcoRollType.None;
public const bool EngineStopStartDefault = false; public const bool EngineStopStartDefault = false;
......
...@@ -67,5 +67,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data { ...@@ -67,5 +67,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data {
public PerSecond MinEngineSpeedPostUpshift { get; set; } public PerSecond MinEngineSpeedPostUpshift { get; set; }
public Second ATLookAheadTime { get; set; } public Second ATLookAheadTime { get; set; }
public double[] LoadStageThresoldsUp { get; set; }
public double[] LoadStageThresoldsDown { get; set; }
public double[][] ShiftSpeedsTCToLocked { get; set; }
} }
} }
\ No newline at end of file
...@@ -21,8 +21,6 @@ using TUGraz.VectoCore.Utils; ...@@ -21,8 +21,6 @@ using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{ {
public class ATShiftStrategyOptimized : ATShiftStrategy public class ATShiftStrategyOptimized : ATShiftStrategy
{ {
private FuelConsumptionMap fcMap; private FuelConsumptionMap fcMap;
...@@ -31,7 +29,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -31,7 +29,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private SimplePowertrainContainer TestContainer; private SimplePowertrainContainer TestContainer;
private ATGearbox TestContainerGbx; private ATGearbox TestContainerGbx;
protected readonly List<GearshiftPosition> GearList; protected List<GearshiftPosition> GearList;
private Kilogram vehicleMass; private Kilogram vehicleMass;
private Kilogram MinMass; private Kilogram MinMass;
...@@ -40,9 +38,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -40,9 +38,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private List<SchmittTrigger> LoadStageSteps = new List<SchmittTrigger>(); private List<SchmittTrigger> LoadStageSteps = new List<SchmittTrigger>();
private ShiftLineSet UpshiftLineTCLocked = new ShiftLineSet(); private ShiftLineSet UpshiftLineTCLocked = new ShiftLineSet();
public const double DownhillSlope = -5;
public const double UphillSlope = 5;
public new static string Name public new static string Name
{ {
get { return "AT - EffShift"; } get { return "AT - EffShift"; }
...@@ -53,6 +48,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -53,6 +48,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (runData.EngineData == null) { if (runData.EngineData == null) {
return; return;
} }
fcMap = runData.EngineData.ConsumptionMap; fcMap = runData.EngineData.ConsumptionMap;
fld = runData.EngineData.FullLoadCurves; fld = runData.EngineData.FullLoadCurves;
vehicleMass = runData.VehicleData.TotalVehicleMass; vehicleMass = runData.VehicleData.TotalVehicleMass;
...@@ -61,58 +57,61 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -61,58 +57,61 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
MinMass = runData.VehicleData.MinimumVehicleMass; MinMass = runData.VehicleData.MinimumVehicleMass;
MaxMass = runData.VehicleData.MaximumVehicleMass; MaxMass = runData.VehicleData.MaximumVehicleMass;
var LoadStageThresoldsUp = "19.7;36.34;53.01;69.68;86.35"; if (shiftStrategyParameters == null) {
var LoadStageThresoldsDown = "13.7;30.34;47.01;63.68;80.35"; throw new VectoException("Parameters for shift strategy missing!");
foreach (var entry in LoadStageThresoldsUp.Split(';').Select(x => x.ToDouble()).Zip(LoadStageThresoldsDown.Split(';').Select(x => x.ToDouble()), Tuple.Create)) { }
InitializeShiftlinesTCToLocked();
InitializeTestContainer(runData);
InitializeGearList(runData);
}
private void InitializeShiftlinesTCToLocked()
{
if (shiftStrategyParameters.LoadStageThresoldsUp.Length != shiftStrategyParameters.LoadStageThresoldsDown.Length) {
throw new VectoException("Thresholds for loadstage definition Up/Down need to be of same length!");
}
foreach (var entry in shiftStrategyParameters.LoadStageThresoldsUp.Zip(
shiftStrategyParameters.LoadStageThresoldsDown, Tuple.Create)) {
LoadStageSteps.Add(new SchmittTrigger(entry)); LoadStageSteps.Add(new SchmittTrigger(entry));
} }
var slopeDh = VectoMath.InclinationToAngle(DownhillSlope / 100.0); var slopes = new[] {
var slopeLevel = VectoMath.InclinationToAngle(0); VectoMath.InclinationToAngle(DeclarationData.GearboxTCU.DownhillSlope / 100.0),
var slopeUh = VectoMath.InclinationToAngle(UphillSlope / 100.0); VectoMath.InclinationToAngle(0),
VectoMath.InclinationToAngle(DeclarationData.GearboxTCU.UphillSlope / 100.0)
var sl1 = new ShiftLines(); };
sl1.entriesAMin.Add(Tuple.Create(slopeDh, 650.RPMtoRad()));
sl1.entriesAMin.Add(Tuple.Create(slopeLevel, 680.RPMtoRad()));
sl1.entriesAMin.Add(Tuple.Create(slopeUh, 725.RPMtoRad()));
sl1.entriesAMax.Add(Tuple.Create(slopeDh, 650.RPMtoRad()));
sl1.entriesAMax.Add(Tuple.Create(slopeLevel, 680.RPMtoRad()));
sl1.entriesAMax.Add(Tuple.Create(slopeUh, 725.RPMtoRad()));
UpshiftLineTCLocked.LoadStages[1] = sl1;
UpshiftLineTCLocked.LoadStages[2] = sl1;
UpshiftLineTCLocked.LoadStages[3] = sl1;
var sl4 = new ShiftLines();
sl4.entriesAMin.Add(Tuple.Create(slopeDh, 650.RPMtoRad()));
sl4.entriesAMin.Add(Tuple.Create(slopeLevel, 680.RPMtoRad()));
sl4.entriesAMin.Add(Tuple.Create(slopeUh, 725.RPMtoRad()));
sl4.entriesAMax.Add(Tuple.Create(slopeDh, 670.RPMtoRad()));
sl4.entriesAMax.Add(Tuple.Create(slopeLevel, 700.RPMtoRad()));
sl4.entriesAMax.Add(Tuple.Create(slopeUh, 745.RPMtoRad()));
UpshiftLineTCLocked.LoadStages[4] = sl4;
var sl5 = new ShiftLines();
sl5.entriesAMin.Add(Tuple.Create(slopeDh, 660.RPMtoRad()));
sl5.entriesAMin.Add(Tuple.Create(slopeLevel, 690.RPMtoRad()));
sl5.entriesAMin.Add(Tuple.Create(slopeUh, 735.RPMtoRad()));
sl5.entriesAMax.Add(Tuple.Create(slopeDh, 680.RPMtoRad()));
sl5.entriesAMax.Add(Tuple.Create(slopeLevel, 710.RPMtoRad()));
sl5.entriesAMax.Add(Tuple.Create(slopeUh, 755.RPMtoRad()));
UpshiftLineTCLocked.LoadStages[5] = sl5;
var sl6 = new ShiftLines();
sl6.entriesAMin.Add(Tuple.Create(slopeDh, 670.RPMtoRad()));
sl6.entriesAMin.Add(Tuple.Create(slopeLevel, 700.RPMtoRad()));
sl6.entriesAMin.Add(Tuple.Create(slopeUh, 745.RPMtoRad()));
sl6.entriesAMax.Add(Tuple.Create(slopeDh, 690.RPMtoRad()));
sl6.entriesAMax.Add(Tuple.Create(slopeLevel, 720.RPMtoRad()));
sl6.entriesAMax.Add(Tuple.Create(slopeUh, 765.RPMtoRad()));
UpshiftLineTCLocked.LoadStages[6] = sl6;
if (shiftStrategyParameters == null) { if (shiftStrategyParameters.ShiftSpeedsTCToLocked.Length < shiftStrategyParameters.LoadStageThresoldsUp.Length + 1) {
throw new VectoException("Parameters for shift strategy missing!"); throw new VectoException(
"Shift speeds TC -> L need to be defined for all {0} load stages",
shiftStrategyParameters.LoadStageThresoldsUp.Length + 1);
}
for (var loadStage = 1; loadStage <= 6; loadStage++) {
if (shiftStrategyParameters.ShiftSpeedsTCToLocked[loadStage - 1].Length != 6) {
throw new VectoException("Exactly 6 shift speeds need to be provided! (downhill/level/uphill)*(a_max/a_min)");
}
var shiftLines = new ShiftLines();
for (var i = 0; i < 6; i++) {
var t = Tuple.Create(slopes[i % 3], shiftStrategyParameters.ShiftSpeedsTCToLocked[loadStage - 1][i].RPMtoRad());
if (i < 3) {
shiftLines.entriesAMax.Add(t);
} else {
shiftLines.entriesAMin.Add(t);
}
} }
UpshiftLineTCLocked.LoadStages[loadStage] = shiftLines;
}
}
private void InitializeTestContainer(VectoRunData runData)
{
var modData = new ModalDataContainer(runData, null, null, false); var modData = new ModalDataContainer(runData, null, null, false);
var builder = new PowertrainBuilder(modData); var builder = new PowertrainBuilder(modData);
TestContainer = new SimplePowertrainContainer(runData); TestContainer = new SimplePowertrainContainer(runData);
...@@ -122,6 +121,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -122,6 +121,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (TestContainerGbx == null) { if (TestContainerGbx == null) {
throw new VectoException("Unknown gearboxtype: {0}", TestContainer.GearboxCtl.GetType().FullName); throw new VectoException("Unknown gearboxtype: {0}", TestContainer.GearboxCtl.GetType().FullName);
} }
// initialize vehicle so that vehicleStopped of the testcontainer is false (required for test-runs) // initialize vehicle so that vehicleStopped of the testcontainer is false (required for test-runs)
TestContainer.VehiclePort.Initialize(10.KMPHtoMeterPerSecond(), 0.SI<Radian>()); TestContainer.VehiclePort.Initialize(10.KMPHtoMeterPerSecond(), 0.SI<Radian>());
...@@ -136,8 +136,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -136,8 +136,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Log.Warn("Gear-range for FC-based gearshift must be either 1 or 2!"); Log.Warn("Gear-range for FC-based gearshift must be either 1 or 2!");
shiftStrategyParameters.AllowedGearRangeFC = shiftStrategyParameters.AllowedGearRangeFC.LimitTo(1, 2); shiftStrategyParameters.AllowedGearRangeFC = shiftStrategyParameters.AllowedGearRangeFC.LimitTo(1, 2);
} }
}
private void InitializeGearList(VectoRunData runData)
{
GearList = new List<GearshiftPosition>(); GearList = new List<GearshiftPosition>();
foreach (var gear in runData.GearboxData.Gears) { foreach (var gear in runData.GearboxData.Gears) {
if (runData.GearboxData.Type.AutomaticTransmission()) { if (runData.GearboxData.Type.AutomaticTransmission()) {
...@@ -155,21 +157,28 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -155,21 +157,28 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
#region Overrides of ATShiftStrategy #region Overrides of ATShiftStrategy
protected override bool? CheckEarlyUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque, PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response) protected override bool? CheckEarlyUpshift(
Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque,
PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response)
{ {
var current = new GearshiftPosition(currentGear, _gearbox.TorqueConverterLocked); var current = new GearshiftPosition(currentGear, _gearbox.TorqueConverterLocked);
var currentIdx = GearList.IndexOf(current); var currentIdx = GearList.IndexOf(current);
var next = GearList[currentIdx + 1]; var next = GearList[currentIdx + 1];
if (current.Gear == next.Gear && current.TorqueConverterLocked != next.TorqueConverterLocked) { if (current.Gear == next.Gear && current.TorqueConverterLocked != next.TorqueConverterLocked) {
return CheckUpshiftFromTC(absTime, dt, outTorque, outAngularVelocity, origInTorque, origInAngularVelocity, currentGear, lastShiftTime, response); return CheckUpshiftFromTC(
absTime, dt, outTorque, outAngularVelocity, origInTorque, origInAngularVelocity, currentGear, lastShiftTime,
response);
} }
return CheckEarlyUpshiftFromLocked( return CheckEarlyUpshiftFromLocked(
absTime, dt, outTorque, outAngularVelocity, origInTorque, origInAngularVelocity, currentGear, lastShiftTime, response); absTime, dt, outTorque, outAngularVelocity, origInTorque, origInAngularVelocity, currentGear, lastShiftTime,
response);
} }
private bool? CheckUpshiftFromTC(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response) private bool? CheckUpshiftFromTC(
Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response)
{ {
var accPower = EstimateAccelerrationPower(outAngularVelocity, outTorque); var accPower = EstimateAccelerrationPower(outAngularVelocity, outTorque);
...@@ -217,7 +226,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -217,7 +226,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return sum; return sum;
} }
protected bool? CheckEarlyUpshiftFromLocked(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque, PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response1) protected bool? CheckEarlyUpshiftFromLocked(
Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque,
PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response1)
{ {
if (outAngularVelocity.IsEqual(0)) { if (outAngularVelocity.IsEqual(0)) {
return null; return null;
...@@ -231,13 +242,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -231,13 +242,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var currentIdx = GearList.IndexOf(current); var currentIdx = GearList.IndexOf(current);
var vDrop = DataBus.DriverAcceleration * shiftStrategyParameters.ATLookAheadTime; var vDrop = DataBus.DriverAcceleration * shiftStrategyParameters.ATLookAheadTime;
var vehicleSpeedPostShift = (DataBus.VehicleSpeed + vDrop * shiftStrategyParameters.VelocityDropFactor).LimitTo(0.KMPHtoMeterPerSecond(), DataBus.CycleData.LeftSample.VehicleTargetSpeed); var vehicleSpeedPostShift = (DataBus.VehicleSpeed + vDrop * shiftStrategyParameters.VelocityDropFactor).LimitTo(
0.KMPHtoMeterPerSecond(), DataBus.CycleData.LeftSample.VehicleTargetSpeed);
var outAngularVelocityEst = (outAngularVelocity * vehicleSpeedPostShift / (DataBus.VehicleSpeed + DataBus.DriverAcceleration * dt)).Cast<PerSecond>(); var outAngularVelocityEst =
(outAngularVelocity * vehicleSpeedPostShift / (DataBus.VehicleSpeed + DataBus.DriverAcceleration * dt))
.Cast<PerSecond>();
var outTorqueEst = outTorque * outAngularVelocity / outAngularVelocityEst; var outTorqueEst = outTorque * outAngularVelocity / outAngularVelocityEst;
for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) { for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) {
if (currentIdx + i >= GearList.Count) { if (currentIdx + i >= GearList.Count) {
// no further gear // no further gear
continue; continue;
...@@ -263,6 +276,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -263,6 +276,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var pNextGearMax = DataBus.EngineStationaryFullPower(estimatedEngineSpeed); var pNextGearMax = DataBus.EngineStationaryFullPower(estimatedEngineSpeed);
var response = RequestDryRunWithGear(absTime, dt, outTorqueEst, outAngularVelocityEst, next); var response = RequestDryRunWithGear(absTime, dt, outTorqueEst, outAngularVelocityEst, next);
//var response = RequestDryRunWithGear(absTime, dt, vehicleSpeedPostShift, DataBus.DriverAcceleration, next); //var response = RequestDryRunWithGear(absTime, dt, vehicleSpeedPostShift, DataBus.DriverAcceleration, next);
if (!response.EnginePowerRequest.IsSmaller(pNextGearMax)) { if (!response.EnginePowerRequest.IsSmaller(pNextGearMax)) {
...@@ -271,8 +285,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -271,8 +285,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var inTorque = response.EnginePowerRequest / inAngularVelocity; var inTorque = response.EnginePowerRequest / inAngularVelocity;
// if next gear supplied enough power reserve: take it // if next gear supplied enough power reserve: take it
// otherwise take // otherwise take
if (ModelData.Gears[next.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inAngularVelocity)) { if (ModelData.Gears[next.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inAngularVelocity)) {
...@@ -291,10 +303,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -291,10 +303,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (accelerationFactor.IsEqual(1, 1e-9)) { if (accelerationFactor.IsEqual(1, 1e-9)) {
continue; continue;
} }
var accelerationTorque = vehicleMass * DataBus.DriverAcceleration * DataBus.VehicleSpeed / outAngularVelocity; var accelerationTorque = vehicleMass * DataBus.DriverAcceleration * DataBus.VehicleSpeed / outAngularVelocity;
var reducedTorque = outTorque - accelerationTorque * (1 - accelerationFactor); var reducedTorque = outTorque - accelerationTorque * (1 - accelerationFactor);
response = RequestDryRunWithGear(absTime, dt, reducedTorque, outAngularVelocity, next); response = RequestDryRunWithGear(absTime, dt, reducedTorque, outAngularVelocity, next);
//response = RequestDryRunWithGear(absTime, dt, vehicleSpeedPostShift, DataBus.DriverAcceleration * accelerationFactor, next); //response = RequestDryRunWithGear(absTime, dt, vehicleSpeedPostShift, DataBus.DriverAcceleration * accelerationFactor, next);
fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad; fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
reserve = 1 - response.EnginePowerRequest / fullLoadPower; reserve = 1 - response.EnginePowerRequest / fullLoadPower;
...@@ -313,7 +327,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -313,7 +327,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
fld[currentGear].FullLoadStationaryTorque(responseCurrent.EngineSpeed)); fld[currentGear].FullLoadStationaryTorque(responseCurrent.EngineSpeed));
var fcCurrentRes = fcMap.GetFuelConsumption(tqCurrent, responseCurrent.EngineSpeed, true); var fcCurrentRes = fcMap.GetFuelConsumption(tqCurrent, responseCurrent.EngineSpeed, true);
if (fcCurrentRes.Extrapolated) { if (fcCurrentRes.Extrapolated) {
Log.Warn("EffShift Strategy: Extrapolation of fuel consumption for current gear!n: {1}, Tq: {2}", responseCurrent.EngineSpeed, tqCurrent); Log.Warn(
"EffShift Strategy: Extrapolation of fuel consumption for current gear!n: {1}, Tq: {2}",
responseCurrent.EngineSpeed, tqCurrent);
} }
fcCurrent = fcCurrentRes.Value; fcCurrent = fcCurrentRes.Value;
} }
...@@ -322,7 +338,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -322,7 +338,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
fld[next.Gear].FullLoadStationaryTorque(response.EngineSpeed)); fld[next.Gear].FullLoadStationaryTorque(response.EngineSpeed));
var fcNextRes = fcMap.GetFuelConsumption(tqNext, response.EngineSpeed, true); var fcNextRes = fcMap.GetFuelConsumption(tqNext, response.EngineSpeed, true);
if (fcNextRes.Extrapolated) { if (fcNextRes.Extrapolated) {
Log.Warn("EffShift Strategy: Extrapolation of fuel consumption for gear {0}! n: {1}, Tq: {2}", next, response.EngineSpeed, tqNext); Log.Warn(
"EffShift Strategy: Extrapolation of fuel consumption for gear {0}! n: {1}, Tq: {2}", next, response.EngineSpeed,
tqNext);
} }
var fcNext = fcNextRes.Value; var fcNext = fcNextRes.Value;
...@@ -344,8 +362,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -344,8 +362,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
} }
protected override bool? CheckEarlyDownshift(
protected override bool? CheckEarlyDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque, PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response1) Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter origInTorque,
PerSecond origInAngularVelocity, uint currentGear, Second lastShiftTime, IResponse response1)
{ {
var minFcGear = new GearshiftPosition(currentGear, _gearbox.TorqueConverterLocked); var minFcGear = new GearshiftPosition(currentGear, _gearbox.TorqueConverterLocked);
var minFc = double.MaxValue; var minFc = double.MaxValue;
...@@ -355,7 +374,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -355,7 +374,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var currentIdx = GearList.IndexOf(current); var currentIdx = GearList.IndexOf(current);
for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) { for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) {
if (currentIdx - i < 0) { if (currentIdx - i < 0) {
// no further gear // no further gear
continue; continue;
...@@ -380,7 +398,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -380,7 +398,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var inTorque = response.EnginePowerRequest / inAngularVelocity; var inTorque = response.EnginePowerRequest / inAngularVelocity;
if (!IsAboveUpShiftCurve(next.Gear, inTorque, inAngularVelocity, next.TorqueConverterLocked.Value)) { if (!IsAboveUpShiftCurve(next.Gear, inTorque, inAngularVelocity, next.TorqueConverterLocked.Value)) {
if (fcCurrent == null) { if (fcCurrent == null) {
var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, current); var responseCurrent = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, current);
fcCurrent = fcMap.GetFuelConsumption( fcCurrent = fcMap.GetFuelConsumption(
...@@ -397,7 +414,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -397,7 +414,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
if (fcNext.IsSmaller(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear) && fcNext.IsSmaller(minFc)) { if (fcNext.IsSmaller(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear) && fcNext.IsSmaller(minFc)) {
minFcGear = next; minFcGear = next;
minFc = fcNext.Value(); minFc = fcNext.Value();
} }
} }
} }
...@@ -413,14 +429,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -413,14 +429,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected virtual void ShiftGear(Second absTime, GearshiftPosition currentGear, GearshiftPosition nextGear) protected virtual void ShiftGear(Second absTime, GearshiftPosition currentGear, GearshiftPosition nextGear)
{ {
if (currentGear.TorqueConverterLocked != nextGear.TorqueConverterLocked && currentGear.Gear != nextGear.Gear) { if (currentGear.TorqueConverterLocked != nextGear.TorqueConverterLocked && currentGear.Gear != nextGear.Gear) {
throw new VectoException("skipping gear from converter to locked not allowed! {0} -> {1}", currentGear.Name, nextGear.Name); throw new VectoException(
"skipping gear from converter to locked not allowed! {0} -> {1}", currentGear.Name, nextGear.Name);
} }
_nextGear.SetState(absTime, disengaged: false, gear: nextGear.Gear, tcLocked: nextGear.TorqueConverterLocked.Value); _nextGear.SetState(absTime, disengaged: false, gear: nextGear.Gear, tcLocked: nextGear.TorqueConverterLocked.Value);
} }
#endregion #endregion
protected ResponseDryRun RequestDryRunWithGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition gear) protected ResponseDryRun RequestDryRunWithGear(
Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition gear)
{ {
TestContainerGbx.Disengaged = false; TestContainerGbx.Disengaged = false;
TestContainerGbx.Gear = gear.Gear; TestContainerGbx.Gear = gear.Gear;
...@@ -432,7 +451,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -432,7 +451,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return response; return response;
} }
protected ResponseDryRun RequestDryRunWithGear(Second absTime, Second dt, MeterPerSecond vehicleSpeed, MeterPerSquareSecond acceleration, GearshiftPosition gear) protected ResponseDryRun RequestDryRunWithGear(
Second absTime, Second dt, MeterPerSecond vehicleSpeed, MeterPerSquareSecond acceleration, GearshiftPosition gear)
{ {
TestContainerGbx.Disengaged = false; TestContainerGbx.Disengaged = false;
TestContainerGbx.Gear = gear.Gear; TestContainerGbx.Gear = gear.Gear;
...@@ -447,7 +467,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -447,7 +467,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
#region Overrides of ATShiftStrategy #region Overrides of ATShiftStrategy
public override ShiftPolygon ComputeDeclarationShiftPolygon( public override ShiftPolygon ComputeDeclarationShiftPolygon(
GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears, GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
IList<ITransmissionInputData> gearboxGears,
CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius) CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius)
{ {
var shiftLine = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon( var shiftLine = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon(
...@@ -456,13 +477,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -456,13 +477,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var upshift = new List<ShiftPolygon.ShiftPolygonEntry>(); var upshift = new List<ShiftPolygon.ShiftPolygonEntry>();
if (i < gearboxGears.Count - 1) { if (i < gearboxGears.Count - 1) {
var maxDragTorque = engineDataFullLoadCurve.MaxDragTorque * 1.1; var maxDragTorque = engineDataFullLoadCurve.MaxDragTorque * 1.1;
var maxTorque = engineDataFullLoadCurve.MaxTorque * 1.1; var maxTorque = engineDataFullLoadCurve.MaxTorque * 1.1;
var speed = engineData.FullLoadCurves[0].NP98hSpeed / gearboxGears[i].Ratio * gearboxGears[i + 1].Ratio; var speed = engineData.FullLoadCurves[0].NP98hSpeed / gearboxGears[i].Ratio * gearboxGears[i + 1].Ratio;
upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, speed)); upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, speed));
upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxTorque, speed)); upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxTorque, speed));
} }
...@@ -506,6 +525,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -506,6 +525,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{ {
return Name.GetHashCode(); return Name.GetHashCode();
} }
} }
} }
...@@ -13,6 +13,6 @@ ...@@ -13,6 +13,6 @@
"StartAcc": 0.6, "StartAcc": 0.6,
"LoadStageShiftLines": "GearshiftLinesVoith.vgsv", "LoadStageShiftLines": "GearshiftLinesVoith.vgsv",
"LoadStageThresoldsUp": "19.7;36.34;53.01;69.68;86.35", "LoadStageThresoldsUp": "19.7;36.34;53.01;69.68;86.35",
"LoadStageThresoldsDown": "13.7;30.34;47.01;63.68;80.35", "LoadStageThresoldsDown": "13.7;30.34;47.01;63.68;80.35"
} }
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment