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 c73b4e0e authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

more work on new shift strategy

parent 93addc8c
Branches
Tags
No related merge requests found
...@@ -398,7 +398,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter ...@@ -398,7 +398,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight) string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight)
{ {
const int startSpeed = 60; const int startSpeed = 60;
const int maxSpeed = 130; const int maxSpeed = 200;
const int speedStep = 5; const int speedStep = 5;
const int maxAlpha = 180; const int maxAlpha = 180;
......
...@@ -199,9 +199,9 @@ namespace TUGraz.VectoCore.Models.Declaration ...@@ -199,9 +199,9 @@ namespace TUGraz.VectoCore.Models.Declaration
public const double ShiftPolygonRPMMargin = 7; // % public const double ShiftPolygonRPMMargin = 7; // %
private const double ShiftPolygonEngineFldMargin = 0.98; private const double ShiftPolygonEngineFldMargin = 0.98;
public static readonly Second MinTimeBetweenGearshifts = 1.5.SI<Second>(); public static readonly Second MinTimeBetweenGearshifts = 2.SI<Second>();
public static readonly Second DownshiftAfterUpshiftDelay = 10.SI<Second>(); public static readonly Second DownshiftAfterUpshiftDelay = 6.SI<Second>();
public static readonly Second UpshiftAfterDownshiftDelay = 10.SI<Second>(); public static readonly Second UpshiftAfterDownshiftDelay = 6.SI<Second>();
public static readonly MeterPerSquareSecond UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>(); public static readonly MeterPerSquareSecond UpshiftMinAcceleration = 0.1.SI<MeterPerSquareSecond>();
......
...@@ -32,6 +32,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -32,6 +32,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
protected MaxCardanTorqueLookup MaxCardanTorqueLookup; protected MaxCardanTorqueLookup MaxCardanTorqueLookup;
protected DebugData DebugData = new DebugData(); protected DebugData DebugData = new DebugData();
private Dictionary<uint, GearRating> GearRatings = new Dictionary<uint, GearRating>();
private MeterPerSquareSecond accRsv;
public struct HistoryEntry public struct HistoryEntry
{ {
...@@ -63,12 +65,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -63,12 +65,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
dataBus.AddPreprocessor(new EngineSpeedDriveOffPreprocessor(EngineSpeedAtDriveOff, data, TestContainer)); dataBus.AddPreprocessor(new EngineSpeedDriveOffPreprocessor(EngineSpeedAtDriveOff, data, TestContainer));
AverageAccelerationTorqueLookup = new AverageAccelerationTorqueLookup(); AverageAccelerationTorqueLookup = new AverageAccelerationTorqueLookup();
dataBus.AddPreprocessor(new AverageAccelerationTorquePreprocessor(AverageAccelerationTorqueLookup, data, GetEngineSpeedLimitHighMin())); dataBus.AddPreprocessor(
new AverageAccelerationTorquePreprocessor(AverageAccelerationTorqueLookup, data, GetEngineSpeedLimitHighMin()));
MaxCardanTorqueLookup = new MaxCardanTorqueLookup(); MaxCardanTorqueLookup = new MaxCardanTorqueLookup();
dataBus.AddPreprocessor(new MaxCardanTorquePreprocessor(MaxCardanTorqueLookup, data, TestContainer)); dataBus.AddPreprocessor(new MaxCardanTorquePreprocessor(MaxCardanTorqueLookup, data, TestContainer));
} }
private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
{
return (outAngularSpeed * ModelData.Gears[gear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
}
private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed)
{
return
(outAngularSpeed * ModelData.Gears[gear].Ratio).IsGreaterOrEqual(
VectoMath.Min(
ModelData.Gears[gear].MaxSpeed,
DataBus.EngineN95hSpeed));
}
#region Overrides of BaseShiftStrategy #region Overrides of BaseShiftStrategy
public override bool ShiftRequired( public override bool ShiftRequired(
...@@ -82,7 +99,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -82,7 +99,29 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
UpdateHistoryBuffer(absTime, dt, currentCardanPower, velocity); UpdateHistoryBuffer(absTime, dt, currentCardanPower, velocity);
// normal shift when all requirements are fullfilled ------------------ // no shift when vehicle stands
if (DataBus.VehicleStopped) {
return false;
}
// emergency shift to not stall the engine ------------------------
if (gear == 1 && SpeedTooLowForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) {
return true;
}
_nextGear = gear;
while (_nextGear > 1 && SpeedTooLowForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) {
_nextGear--;
}
while (_nextGear < ModelData.Gears.Count &&
SpeedTooHighForEngine(_nextGear, inAngularVelocity / ModelData.Gears[gear].Ratio)) {
_nextGear++;
}
if (_nextGear != gear) {
return true;
}
var minimumShiftTimePassed = (lastShiftTime + ModelData.ShiftTime).IsSmallerOrEqual(absTime); var minimumShiftTimePassed = (lastShiftTime + ModelData.ShiftTime).IsSmallerOrEqual(absTime);
if (!minimumShiftTimePassed) { if (!minimumShiftTimePassed) {
return false; return false;
...@@ -117,33 +156,46 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -117,33 +156,46 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
PerSecond inAngularVelocity, uint gear, Second lastShiftTime) PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
{ {
var lookAheadDistance = DataBus.VehicleSpeed * ShiftStrategyParameters.GearResidenceTime; var lookAheadDistance = DataBus.VehicleSpeed * ModelData.TractionInterruption;//ShiftStrategyParameters.GearResidenceTime;
var roadGradient = DataBus.CycleLookAhead(lookAheadDistance).RoadGradient; var roadGradient = DataBus.CycleLookAhead(lookAheadDistance).RoadGradient;
var minRating = new GearRating(GearRatingCase.D, double.MaxValue, 0.RPMtoRad()); var minRating = new GearRating(GearRatingCase.E, double.MaxValue, 0.RPMtoRad());
var selectedGear = gear; var selectedGear = gear;
var debugData = new DebugData(); var debugData = new DebugData();
for (var i = Math.Max(0, gear - ShiftStrategyParameters.AllowedGearRangeDown);
var currentVelocity = DataBus.VehicleSpeed;
var gradient = CalcGradientDuringGearshift(false, dt, currentVelocity);
var estimatedVelocityPostShift = VelocityDropData.Interpolate(currentVelocity, gradient);
var predictionVelocity = CalcPredictionVelocity(currentVelocity, estimatedVelocityPostShift);
accRsv = CalcAccelerationReserve(currentVelocity);
GearRatings.Clear();
for (var i = Math.Max(1, gear - ShiftStrategyParameters.AllowedGearRangeDown);
i <= Math.Min(ModelData.Gears.Count, gear + ShiftStrategyParameters.AllowedGearRangeUp); i <= Math.Min(ModelData.Gears.Count, gear + ShiftStrategyParameters.AllowedGearRangeUp);
i++) { i++) {
var nextGear = (uint)i; var nextGear = (uint)i;
var gradientBelowMaxGrad = roadGradient < MaxGradability.GradabilityLimitedTorque(nextGear); var gradientBelowMaxGrad = roadGradient < MaxGradability.GradabilityLimitedTorque(nextGear);
var engineSpeedAboveMin = outAngularVelocity * ModelData.Gears[nextGear].Ratio > GetEngineSpeedLimitLow(false); var engineSpeedAboveMin =
outAngularVelocity * ModelData.Gears[nextGear].Ratio > PowertrainConfig.EngineData.IdleSpeed;
var engineSpeedBelowMax = outAngularVelocity * ModelData.Gears[nextGear].Ratio < var engineSpeedBelowMax = outAngularVelocity * ModelData.Gears[nextGear].Ratio <
PowertrainConfig.EngineData.FullLoadCurves[0].N95hSpeed; PowertrainConfig.EngineData.FullLoadCurves[0].N95hSpeed;
if (nextGear > gear && !(gradientBelowMaxGrad && engineSpeedAboveMin && engineSpeedBelowMax)) {
if (!(gradientBelowMaxGrad && engineSpeedAboveMin && engineSpeedBelowMax)) {
debugData.Add( debugData.Add(
string.Format( string.Format(
"{0} - gear {1} exceeds speed limits / gradability {2}", absTime, nextGear, "{0} - gear {1} exceeds speed limits / gradability {2}", absTime, nextGear,
outAngularVelocity * ModelData.Gears[nextGear].Ratio)); outAngularVelocity * ModelData.Gears[nextGear].Ratio));
GearRatings[nextGear] = new GearRating(GearRatingCase.E, 0, null);
continue; continue;
} }
var rating = RatingGear(false, nextGear, dt); var rating = RatingGear(false, nextGear, gear, gradient, predictionVelocity, estimatedVelocityPostShift, accRsv);
if (nextGear == gear) { if (nextGear == gear) {
if (rating.RatingCase == GearRatingCase.A) { if (rating.RatingCase == GearRatingCase.A) {
rating = new GearRating(GearRatingCase.A, rating.Rating * ShiftStrategyParameters.RatingFactorCurrentGear, rating.MaxEngineSpeed); rating = new GearRating(
GearRatingCase.A, rating.Rating * ShiftStrategyParameters.RatingFactorCurrentGear, rating.MaxEngineSpeed);
} }
} }
debugData.Add(string.Format("{0} - gear {1}: rating {2}", absTime, nextGear, rating)); debugData.Add(string.Format("{0} - gear {1}: rating {2}", absTime, nextGear, rating));
...@@ -151,7 +203,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -151,7 +203,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
minRating = rating; minRating = rating;
selectedGear = nextGear; selectedGear = nextGear;
} }
GearRatings[nextGear] = rating;
} }
debugData.Add(string.Format("selected gear: {0} - {1}", selectedGear, minRating)); debugData.Add(string.Format("selected gear: {0} - {1}", selectedGear, minRating));
if (selectedGear < gear && (DownshiftAllowed(absTime) || inAngularVelocity < GetEngineSpeedLimitLow(false))) { if (selectedGear < gear && (DownshiftAllowed(absTime) || inAngularVelocity < GetEngineSpeedLimitLow(false))) {
...@@ -167,27 +221,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -167,27 +221,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
private bool UpshiftAllowed(Second absTime) private bool UpshiftAllowed(Second absTime)
{ {
return (absTime - _gearbox.LastDownshift).IsSmaller(_gearbox.ModelData.UpshiftAfterDownshiftDelay); return (absTime - _gearbox.LastDownshift).IsGreaterOrEqual(_gearbox.ModelData.UpshiftAfterDownshiftDelay);
} }
private bool DownshiftAllowed(Second absTime) private bool DownshiftAllowed(Second absTime)
{ {
return (absTime - _gearbox.LastUpshift).IsSmaller(_gearbox.ModelData.DownshiftAfterUpshiftDelay); return (absTime - _gearbox.LastUpshift).IsGreaterOrEqual(_gearbox.ModelData.DownshiftAfterUpshiftDelay);
} }
private GearRating RatingGear(bool driveOff, uint gear, Second dt) private GearRating RatingGear(
bool driveOff, uint gear, uint currentGear, Radian gradient, MeterPerSecond predictionVelocity,
MeterPerSecond velocityAfterGearshift, MeterPerSquareSecond accRsv)
{ {
var currentVelocity = DataBus.VehicleSpeed;
var gradient = CalcGradientDuringGearshift(driveOff, dt, currentVelocity);
var predictionVelocity = ShiftStrategyParameters.StartVelocity;
var accRsv = ShiftStrategyParameters.StartAcceleration;
if (!driveOff) {
predictionVelocity = CalcPredictionVelocity(currentVelocity, gradient);
accRsv = CalcAccelerationReserve(currentVelocity);
}
TestContainer.GearboxCtl.Gear = gear; TestContainer.GearboxCtl.Gear = gear;
TestContainer.VehiclePort.Initialize(predictionVelocity, gradient); TestContainer.VehiclePort.Initialize(predictionVelocity, gradient);
var respAccRsv = (ResponseDryRun)TestContainer.VehiclePort.Request( var respAccRsv = (ResponseDryRun)TestContainer.VehiclePort.Request(
...@@ -196,38 +241,55 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -196,38 +241,55 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var respConstVel = (ResponseDryRun)TestContainer.VehiclePort.Request( var respConstVel = (ResponseDryRun)TestContainer.VehiclePort.Request(
0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, 0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval,
0.SI<MeterPerSquareSecond>(), gradient, true); 0.SI<MeterPerSquareSecond>(), gradient, true);
var respDriverDemand = (ResponseDryRun)TestContainer.VehiclePort.Request(
0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, DataBus.DriverAcceleration, gradient,
true);
if (respAccRsv.EngineSpeed < PowertrainConfig.EngineData.IdleSpeed || if (respAccRsv.EngineSpeed < PowertrainConfig.EngineData.IdleSpeed ||
respAccRsv.EngineSpeed > PowertrainConfig.EngineData.FullLoadCurves[0].N95hSpeed) { respAccRsv.EngineSpeed > PowertrainConfig.EngineData.FullLoadCurves[0].N95hSpeed) {
return new GearRating(GearRatingCase.E, 0, 0.RPMtoRad()); return new GearRating(GearRatingCase.E, 0, 0.RPMtoRad());
} }
GearRating? retVal; GearRating? retVal;
var engineSpeedLowThreshold = GetEngineSpeedLimitLow(driveOff); var engineSpeedLowThreshold = GetEngineSpeedLimitLow(driveOff);
var engineSpeedHighThreshold = GetEngineSpeedLimitHigh(driveOff, gear, respAccRsv.EngineSpeed, respConstVel.CardanTorque); var engineSpeedHighThreshold = GetEngineSpeedLimitHigh(
driveOff, gear, respAccRsv.EngineSpeed, respConstVel.CardanTorque);
if (respAccRsv.EngineSpeed < engineSpeedLowThreshold) { if (respAccRsv.EngineSpeed < engineSpeedLowThreshold) {
return new GearRating(GearRatingCase.D, (engineSpeedLowThreshold - respAccRsv.EngineSpeed).Value(), engineSpeedHighThreshold); return new GearRating(
GearRatingCase.D, (engineSpeedLowThreshold - respAccRsv.EngineSpeed).Value(), engineSpeedHighThreshold);
} }
if (respAccRsv.EngineSpeed > engineSpeedHighThreshold) { if (respAccRsv.EngineSpeed > engineSpeedHighThreshold) {
return new GearRating(GearRatingCase.D, (respAccRsv.EngineSpeed - engineSpeedHighThreshold).Value(), engineSpeedHighThreshold); return new GearRating(
GearRatingCase.D, (respAccRsv.EngineSpeed - engineSpeedHighThreshold).Value(), engineSpeedHighThreshold);
} }
if (respAccRsv.EngineTorqueDemandTotal <= respAccRsv.EngineDynamicFullLoadTorque) { if (respAccRsv.EngineTorqueDemandTotal <= respAccRsv.EngineDynamicFullLoadTorque) {
var fc = PowertrainConfig.EngineData.ConsumptionMap.GetFuelConsumption( var fc = PowertrainConfig.EngineData.ConsumptionMap.GetFuelConsumption(
VectoMath.Max(respAccRsv.EngineTorqueDemandTotal, PowertrainConfig.EngineData.FullLoadCurves[0].DragLoadStationaryTorque(respAccRsv.EngineSpeed)), respAccRsv.EngineSpeed); VectoMath.Max(
retVal = new GearRating(GearRatingCase.A, (fc.Value / respAccRsv.AxlegearPowerRequest).Value(), engineSpeedHighThreshold); respAccRsv.EngineTorqueDemandTotal,
PowertrainConfig.EngineData.FullLoadCurves[0].DragLoadStationaryTorque(respAccRsv.EngineSpeed)),
respAccRsv.EngineSpeed);
retVal = new GearRating(
GearRatingCase.A,
(fc.Value.ConvertToGrammPerHour().Value / VectoMath.Max(respAccRsv.AxlegearPowerRequest, 1.SI<Watt>())).Value(),
engineSpeedHighThreshold);
} else { } else {
retVal = new GearRating(GearRatingCase.B, (respAccRsv.EnginePowerRequest - respAccRsv.DynamicFullLoadPower).Value(), engineSpeedHighThreshold); retVal = new GearRating(
GearRatingCase.B, (respAccRsv.EnginePowerRequest - respAccRsv.DynamicFullLoadPower).Value(),
engineSpeedHighThreshold);
} }
var estimatedResidenceTime = EstimateResidenceTimeInGear(gear, respAccRsv, engineSpeedHighThreshold, gradient); if (gear > currentGear) {
if (estimatedResidenceTime < ShiftStrategyParameters.GearResidenceTime) { var estimatedResidenceTime =
EstimateResidenceTimeInGear(
gear, respDriverDemand, engineSpeedHighThreshold, velocityAfterGearshift, gradient, engineSpeedLowThreshold);
if (estimatedResidenceTime != null && estimatedResidenceTime < ShiftStrategyParameters.GearResidenceTime) {
retVal = new GearRating( retVal = new GearRating(
GearRatingCase.C, (ShiftStrategyParameters.GearResidenceTime - estimatedResidenceTime).Value(), engineSpeedHighThreshold); GearRatingCase.C, (ShiftStrategyParameters.GearResidenceTime - estimatedResidenceTime).Value(),
engineSpeedHighThreshold);
}
} }
return retVal.Value; return retVal.Value;
} }
...@@ -258,9 +320,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -258,9 +320,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return accRsv; return accRsv;
} }
private MeterPerSecond CalcPredictionVelocity(MeterPerSecond currentVelocity, Radian gradient) private MeterPerSecond CalcPredictionVelocity(
MeterPerSecond currentVelocity, MeterPerSecond estimatedVelocityPostShift)
{ {
var estimatedVelocityPostShift = VelocityDropData.Interpolate(currentVelocity, gradient);
var ratioSpeedDrop = estimatedVelocityPostShift / VectoMath.Max(currentVelocity, 0.1.SI<MeterPerSecond>()); var ratioSpeedDrop = estimatedVelocityPostShift / VectoMath.Max(currentVelocity, 0.1.SI<MeterPerSecond>());
var predictionIntervalRatio = ShiftStrategyParameters.PredictionDurationLookup.Lookup(ratioSpeedDrop.Value()); var predictionIntervalRatio = ShiftStrategyParameters.PredictionDurationLookup.Lookup(ratioSpeedDrop.Value());
var speedChange = estimatedVelocityPostShift - currentVelocity; var speedChange = estimatedVelocityPostShift - currentVelocity;
...@@ -288,13 +350,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -288,13 +350,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{ {
var upperEngineSpeedLimit = (PowertrainConfig.EngineData.FullLoadCurves[0].NTq99lSpeed + var upperEngineSpeedLimit = (PowertrainConfig.EngineData.FullLoadCurves[0].NTq99lSpeed +
PowertrainConfig.EngineData.FullLoadCurves[0].NTq99hSpeed) / 2.0; PowertrainConfig.EngineData.FullLoadCurves[0].NTq99hSpeed) / 2.0;
var currentVelocity = DataBus.VehicleSpeed;
var gradient = CalcGradientDuringGearshift(false, dt, currentVelocity);
var estimatedVelocityPostShift = VelocityDropData.Interpolate(currentVelocity, gradient);
var predictedVelocity = DataBus.DriverBehavior == DrivingBehavior.Braking
? currentVelocity + PowertrainConfig.DriverData.AccelerationCurve.Lookup(currentVelocity).Deceleration *
ModelData.TractionInterruption
: CalcPredictionVelocity(currentVelocity, estimatedVelocityPostShift);
if (inAngularVelocity < GetEngineSpeedLimitLow(false)) { if (inAngularVelocity < GetEngineSpeedLimitLow(false)) {
for (var i = Math.Max(0, gear - ShiftStrategyParameters.AllowedGearRangeDown); for (var i = Math.Max(0, gear - ShiftStrategyParameters.AllowedGearRangeDown);
i <= Math.Min(ModelData.Gears.Count, gear + ShiftStrategyParameters.AllowedGearRangeUp); i <= Math.Min(ModelData.Gears.Count, gear + ShiftStrategyParameters.AllowedGearRangeUp);
i++) { i++) {
var nextGear = (uint)i; var nextGear = (uint)i;
if (outAngularVelocity * ModelData.Gears[nextGear].Ratio > GetEngineSpeedLimitLow(false) && TestContainer.GearboxCtl.Gear = nextGear;
outAngularVelocity * ModelData.Gears[nextGear].Ratio < upperEngineSpeedLimit) { var init = TestContainer.VehiclePort.Initialize(predictedVelocity, gradient);
if (init.EngineSpeed > GetEngineSpeedLimitLow(false) &&
init.EngineSpeed < upperEngineSpeedLimit) {
_nextGear = nextGear; _nextGear = nextGear;
return true; return true;
} }
...@@ -306,8 +379,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -306,8 +379,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
i >= Math.Max(0, gear + ShiftStrategyParameters.AllowedGearRangeDown); i >= Math.Max(0, gear + ShiftStrategyParameters.AllowedGearRangeDown);
i--) { i--) {
var nextGear = (uint)i; var nextGear = (uint)i;
if (outAngularVelocity * ModelData.Gears[nextGear].Ratio > GetEngineSpeedLimitLow(false) && TestContainer.GearboxCtl.Gear = nextGear;
outAngularVelocity * ModelData.Gears[nextGear].Ratio < upperEngineSpeedLimit) { var init = TestContainer.VehiclePort.Initialize(predictedVelocity, gradient);
if (init.EngineSpeed > GetEngineSpeedLimitLow(false) &&
init.EngineSpeed < upperEngineSpeedLimit) {
_nextGear = nextGear; _nextGear = nextGear;
return true; return true;
} }
...@@ -352,9 +427,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -352,9 +427,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
{ {
var maxStartGear = (int)Math.Round(ModelData.Gears.Count / 2.0, MidpointRounding.AwayFromZero); var maxStartGear = (int)Math.Round(ModelData.Gears.Count / 2.0, MidpointRounding.AwayFromZero);
var currentVelocity = DataBus.VehicleSpeed;
var gradient = CalcGradientDuringGearshift(true, null, null);
var estimatedVelocityPostShift = VelocityDropData.Interpolate(currentVelocity, gradient);
var predictionVelocity = ShiftStrategyParameters.StartVelocity;
accRsv = ShiftStrategyParameters.StartAcceleration;
var startGear = 1u; var startGear = 1u;
var minRating = new GearRating(GearRatingCase.D, double.MaxValue, 0.RPMtoRad()); var minRating = new GearRating(GearRatingCase.E, double.MaxValue, 0.RPMtoRad());
var roadGradient = DataBus.CycleData.LeftSample.RoadGradient; //CycleLookAhead(0.SI<Meter>()).RoadGradient; var roadGradient = DataBus.CycleData.LeftSample.RoadGradient; //CycleLookAhead(0.SI<Meter>()).RoadGradient;
GearRatings.Clear();
for (uint i = (uint)maxStartGear; i > 0; i--) { for (uint i = (uint)maxStartGear; i > 0; i--) {
var gradientBelowMaxGrad = roadGradient < MaxGradability.GradabilityLimitedTorque(i); var gradientBelowMaxGrad = roadGradient < MaxGradability.GradabilityLimitedTorque(i);
var engineSpeedLimitLow = GetEngineSpeedLimitLow(true); var engineSpeedLimitLow = GetEngineSpeedLimitLow(true);
...@@ -362,7 +444,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -362,7 +444,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
var engineSpeedAboveMin = engineSpeed > engineSpeedLimitLow; var engineSpeedAboveMin = engineSpeed > engineSpeedLimitLow;
var engineSpeedBelowN95h = engineSpeed < PowertrainConfig.EngineData.FullLoadCurves[0].N95hSpeed; var engineSpeedBelowN95h = engineSpeed < PowertrainConfig.EngineData.FullLoadCurves[0].N95hSpeed;
if (gradientBelowMaxGrad && engineSpeedAboveMin && engineSpeedBelowN95h) { if (gradientBelowMaxGrad && engineSpeedAboveMin && engineSpeedBelowN95h) {
var rating = RatingGear(true, i, null); var rating = RatingGear(true, i, 0, roadGradient, predictionVelocity, estimatedVelocityPostShift, accRsv);
GearRatings[i] = rating;
if (rating < minRating) { if (rating < minRating) {
minRating = rating; minRating = rating;
startGear = i; startGear = i;
...@@ -389,30 +472,34 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -389,30 +472,34 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
} }
private Second EstimateResidenceTimeInGear(uint gear, ResponseDryRun responseDriverDemand, PerSecond engineSpeedHighThreshold, Radian estimatedGradient) private Second EstimateResidenceTimeInGear(
uint gear, ResponseDryRun responseDriverDemand, PerSecond engineSpeedHighThreshold,
MeterPerSecond velocityAfterGearshift, Radian estimatedGradient, PerSecond engineSpeedLowThreshold)
{ {
// get total 'transmission ratio' of powertrain // get total 'transmission ratio' of powertrain
var engineSpeed = responseDriverDemand.EngineSpeed; var engineSpeed = responseDriverDemand.EngineSpeed;
var vehicleSpeed = responseDriverDemand.VehicleSpeed; var vehicleSpeed = responseDriverDemand.VehicleSpeed;
var ratio = (vehicleSpeed / engineSpeed).Cast<Meter>(); var ratio = (vehicleSpeed / engineSpeed).Cast<Meter>();
var estimatedEngineSpeed = velocityAfterGearshift / ratio;
if (estimatedEngineSpeed < engineSpeedLowThreshold || estimatedEngineSpeed > engineSpeedHighThreshold) {
return null;
}
var averageAccelerationTorque = AverageAccelerationTorqueLookup.Interpolate( var averageAccelerationTorque = AverageAccelerationTorqueLookup.Interpolate(
responseDriverDemand.EngineSpeed, responseDriverDemand.EngineTorqueDemand); responseDriverDemand.EngineSpeed, responseDriverDemand.EngineTorqueDemand);
TestContainer.GearboxCtl.Gear = gear;
var initResponse = TestContainer.VehiclePort.Initialize(vehicleSpeed, estimatedGradient); var initResponse = TestContainer.VehiclePort.Initialize(vehicleSpeed, estimatedGradient);
var delta = initResponse.EngineTorqueDemand - averageAccelerationTorque; var delta = initResponse.EngineTorqueDemand - averageAccelerationTorque;
var acceleration = SearchAlgorithm.Search( var acceleration = SearchAlgorithm.Search(
0.SI<MeterPerSquareSecond>(), delta, 0.1.SI<MeterPerSquareSecond>(), 0.SI<MeterPerSquareSecond>(), delta, 0.1.SI<MeterPerSquareSecond>(),
getYValue: r => { getYValue: r => { return (r as AbstractResponse).EngineTorqueDemand - averageAccelerationTorque; },
return (r as AbstractResponse).EngineTorqueDemand - averageAccelerationTorque;
},
evaluateFunction: a => { evaluateFunction: a => {
return TestContainer.VehiclePort.Request( return TestContainer.VehiclePort.Request(
0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, a, estimatedGradient, true); 0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, a, estimatedGradient, true);
}, },
criterion: r => { criterion: r => { return ((r as AbstractResponse).EngineTorqueDemand - averageAccelerationTorque).Value(); }
return ((r as AbstractResponse).EngineTorqueDemand - averageAccelerationTorque).Value();
}
); );
var engineAcceleration = (acceleration / ratio).Cast<PerSquareSecond>(); var engineAcceleration = (acceleration / ratio).Cast<PerSquareSecond>();
...@@ -421,8 +508,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -421,8 +508,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return (deltaEngineSpeed / engineAcceleration).Cast<Second>(); return (deltaEngineSpeed / engineAcceleration).Cast<Second>();
} }
// TODO: make similar to matlab implementtion return null;
return 0.SI<Second>();
} }
private PerSecond GetEngineSpeedLimitHighDriveOff(uint gear) private PerSecond GetEngineSpeedLimitHighDriveOff(uint gear)
...@@ -457,44 +543,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -457,44 +543,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
} }
#endregion #endregion
}
internal struct GearRating public void WriteModalResults(IModalDataContainer container)
{
public GearRating(GearRatingCase ratingCase, double rating, PerSecond maxEngineSpeed)
{ {
RatingCase = ratingCase; foreach (var gear in ModelData.Gears.Keys) {
Rating = rating; container.SetDataValue(
MaxEngineSpeed = maxEngineSpeed; string.Format("Gear{0}-Rating", gear),
GearRatings.ContainsKey(gear)
? GearRatings[gear].NumericValue
: new GearRating(GearRatingCase.E, 0, null).NumericValue);
} }
public double Rating { get; } container.SetDataValue("acc_rsv", accRsv?.Value() ?? 0);
GearRatings.Clear();
public GearRatingCase RatingCase { get; } accRsv = null;
public PerSecond MaxEngineSpeed { get; set; }
public static bool operator <(GearRating first, GearRating second)
{
return first.RatingCase < second.RatingCase && first.Rating < second.Rating;
} }
public static bool operator >(GearRating first, GearRating second)
{
return first.RatingCase > second.RatingCase && first.Rating > second.Rating;
}
public override string ToString()
{
return string.Format("{0} / {1}", RatingCase, Rating);
}
}
internal enum GearRatingCase
{
A = 1, // inside preferred speed range and inside torque range
B, // inside engine speed limits, torque demand too high
C, // valid gear, gear residience time below threshold
D, // inside engine speed limits, outside preferred speed range
E // outside engine speed limits
} }
} }
using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
internal enum GearRatingCase
{
A = 1, // inside preferred speed range and inside torque range
B, // inside engine speed limits, torque demand too high
C, // valid gear, gear residience time below threshold
D, // inside engine speed limits, outside preferred speed range
E // outside engine speed limits
}
internal struct GearRating
{
public GearRating(GearRatingCase ratingCase, double rating, PerSecond maxEngineSpeed)
{
RatingCase = ratingCase;
Rating = rating;
MaxEngineSpeed = maxEngineSpeed;
}
public double Rating { get; }
public GearRatingCase RatingCase { get; }
public PerSecond MaxEngineSpeed { get; set; }
public double NumericValue
{
get { return ((int)RatingCase - 1) * 1e3 + (Rating * 100).LimitTo(0, 1e3-10); }
}
public static bool operator <(GearRating first, GearRating second)
{
return first.RatingCase < second.RatingCase || (first.RatingCase == second.RatingCase && first.Rating < second.Rating);
}
public static bool operator >(GearRating first, GearRating second)
{
return first.RatingCase > second.RatingCase || (first.RatingCase == second.RatingCase && first.Rating > second.Rating);
}
public override string ToString()
{
return string.Format("{0} / {1} ({2})", RatingCase, Rating, NumericValue);
}
}
}
\ No newline at end of file
...@@ -82,8 +82,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -82,8 +82,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
_strategy.Gearbox = this; _strategy.Gearbox = this;
} }
LastDownshift = -double.MaxValue.SI<Second>(); LastDownshift = double.MaxValue.SI<Second>();
LastUpshift = -double.MaxValue.SI<Second>(); LastUpshift = double.MaxValue.SI<Second>();
} }
public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity) public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
...@@ -175,8 +175,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -175,8 +175,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity); Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
if (DataBus.VehicleStopped) { if (DataBus.VehicleStopped) {
EngageTime = absTime; EngageTime = absTime;
LastDownshift = -double.MaxValue.SI<Second>(); LastDownshift = double.MaxValue.SI<Second>();
LastUpshift = -double.MaxValue.SI<Second>(); LastUpshift = double.MaxValue.SI<Second>();
} }
if (DataBus.DriverBehavior == DrivingBehavior.Halted) { if (DataBus.DriverBehavior == DrivingBehavior.Halted) {
EngageTime = absTime + dt; EngageTime = absTime + dt;
...@@ -410,6 +410,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl ...@@ -410,6 +410,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity + container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity +
CurrentState.OutAngularVelocity) / 2.0; CurrentState.OutAngularVelocity) / 2.0;
container[ModalResultField.T_gbx_out] = CurrentState.OutTorque; container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
(_strategy as AMTShiftStrategyV2)?.WriteModalResults(container);
} }
protected override void DoCommitSimulationStep() protected override void DoCommitSimulationStep()
......
...@@ -27,7 +27,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { ...@@ -27,7 +27,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
TestContainer.GearboxCtl.Gear = 1; TestContainer.GearboxCtl.Gear = 1;
var init = TestContainer.VehiclePort.Initialize(Data.GearshiftParameters.StartVelocity, 0.SI<Radian>()); var init = TestContainer.VehiclePort.Initialize(Data.GearshiftParameters.StartVelocity, 0.SI<Radian>());
var powertrainRatioWOGearbox = (Data.GearshiftParameters.StartVelocity / init.EngineSpeed / Data.GearboxData.Gears[1].Ratio).Cast<Meter>(); var powertrainRatioWOGearbox = (Data.GearshiftParameters.StartVelocity / init.EngineSpeed * Data.GearboxData.Gears[1].Ratio).Cast<Meter>();
var engineSpeedSteps = (Data.EngineData.FullLoadCurves[0].N95hSpeed - Data.EngineData.IdleSpeed) / 250; var engineSpeedSteps = (Data.EngineData.FullLoadCurves[0].N95hSpeed - Data.EngineData.IdleSpeed) / 250;
...@@ -38,7 +38,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { ...@@ -38,7 +38,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
engineSpeed < Data.EngineData.FullLoadCurves[0].N95hSpeed; engineSpeed < Data.EngineData.FullLoadCurves[0].N95hSpeed;
engineSpeed += engineSpeedSteps) { engineSpeed += engineSpeedSteps) {
var maxTorque = Data.EngineData.FullLoadCurves[gearData.Key].FullLoadStationaryTorque(engineSpeed); var maxTorque = Data.EngineData.FullLoadCurves[gearData.Key].FullLoadStationaryTorque(engineSpeed);
var vehicleSpeed = engineSpeed * powertrainRatioWOGearbox * gearData.Value.Ratio; var vehicleSpeed = engineSpeed * powertrainRatioWOGearbox / gearData.Value.Ratio;
var first = TestContainer.VehiclePort.Initialize(vehicleSpeed, 0.SI<Radian>()); var first = TestContainer.VehiclePort.Initialize(vehicleSpeed, 0.SI<Radian>());
var delta = first.EngineTorqueDemandTotal - maxTorque; var delta = first.EngineTorqueDemandTotal - maxTorque;
var grad = SearchAlgorithm.Search( var grad = SearchAlgorithm.Search(
......
...@@ -247,9 +247,9 @@ namespace TUGraz.VectoCore.OutputData ...@@ -247,9 +247,9 @@ namespace TUGraz.VectoCore.OutputData
ModalResultField.FCMap, ModalResultField.FCAUXc, ModalResultField.FCWHTCc, ModalResultField.FCMap, ModalResultField.FCAUXc, ModalResultField.FCWHTCc,
ModalResultField.FCAAUX, ModalResultField.FCFinal ModalResultField.FCAAUX, ModalResultField.FCFinal
}.Select(x => x.GetName())); }.Select(x => x.GetName()));
#if TRACE //#if TRACE
strCols = strCols.Concat(_additionalColumns); strCols = strCols.Concat(_additionalColumns);
#endif //#endif
if (WriteModalResults) { if (WriteModalResults) {
var filteredData = Data; var filteredData = Data;
foreach (var filter in _filters) { foreach (var filter in _filters) {
......
...@@ -199,6 +199,7 @@ ...@@ -199,6 +199,7 @@
<Compile Include="Models\SimulationComponent\Impl\DrivingCycleEnumerator.cs" /> <Compile Include="Models\SimulationComponent\Impl\DrivingCycleEnumerator.cs" />
<Compile Include="Models\SimulationComponent\Impl\EngineFanAuxiliary.cs" /> <Compile Include="Models\SimulationComponent\Impl\EngineFanAuxiliary.cs" />
<Compile Include="Models\SimulationComponent\Impl\EngineSpeedDriveOffPreprocessor.cs" /> <Compile Include="Models\SimulationComponent\Impl\EngineSpeedDriveOffPreprocessor.cs" />
<Compile Include="Models\SimulationComponent\Impl\GearRating.cs" />
<Compile Include="Models\SimulationComponent\Impl\MaxCardanTorqueLookup.cs" /> <Compile Include="Models\SimulationComponent\Impl\MaxCardanTorqueLookup.cs" />
<Compile Include="Models\SimulationComponent\Impl\MaxCardanTorquePreprocessor.cs" /> <Compile Include="Models\SimulationComponent\Impl\MaxCardanTorquePreprocessor.cs" />
<Compile Include="Models\SimulationComponent\Impl\MaxGradabilityLookup.cs" /> <Compile Include="Models\SimulationComponent\Impl\MaxGradabilityLookup.cs" />
......
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.FileIO.JSON; using TUGraz.VectoCore.InputData.FileIO.JSON;
using TUGraz.VectoCore.InputData.FileIO.XML.Declaration;
using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.Simulation.Impl;
using TUGraz.VectoCore.OutputData; using TUGraz.VectoCore.OutputData;
using TUGraz.VectoCore.OutputData.FileIO; using TUGraz.VectoCore.OutputData.FileIO;
...@@ -24,27 +28,37 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation ...@@ -24,27 +28,37 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
} }
[TestCase(Class9Decl), [TestCase(Class9Decl, 0),
TestCase(@"E:\QUAM\Downloads\2018-07-13_Prototype-TCU-VECTO_R2016a\a_input_Data\Cl-5_tractor_directdr_axle_2p53.xml", 0),
TestCase(@"E:\QUAM\Downloads\2018-07-13_Prototype-TCU-VECTO_R2016a\a_input_Data\Cl-5_tractor_directdr_axle_2p53.xml", 1),
TestCase(@"E:\QUAM\Downloads\2018-07-13_Prototype-TCU-VECTO_R2016a\a_input_Data\Cl-5_tractor_directdr_axle_2p53.xml", 4)
] ]
public void TestSShiftStrategyV2(string jobFile) public void TestSShiftStrategyV2(string jobFile, int i)
{ {
var fileWriter = new FileOutputWriter(jobFile); var fileWriter = new FileOutputWriter(jobFile);
var sumWriter = new SummaryDataContainer(fileWriter); var sumWriter = new SummaryDataContainer(fileWriter);
var jobContainer = new JobContainer(sumWriter); var jobContainer = new JobContainer(sumWriter);
var dataProvider = JSONInputDataFactory.ReadJsonJob(jobFile); var dataProvider = Path.GetExtension(jobFile) == ".vecto"
? JSONInputDataFactory.ReadJsonJob(jobFile)
: new XMLDeclarationInputDataProvider(jobFile, true);
var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter) { var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter) {
ModalResults1Hz = false, ModalResults1Hz = false,
WriteModalResults = true, WriteModalResults = true,
ActualModalData = false, ActualModalData = false,
Validate = false, Validate = false,
SumData = sumWriter,
}; };
jobContainer.AddRuns(runsFactory); var runs = runsFactory.SimulationRuns().ToArray();
jobContainer.AddRun(runs[i]);
var i = 0; jobContainer.Runs[0].Run.Run();
jobContainer.Runs[i].Run.Run(); Assert.IsTrue(jobContainer.Runs[0].Run.FinishedWithoutErrors);
jobContainer.Execute();
jobContainer.WaitFinished();
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment