Skip to content

Commit

Permalink
Automatic merge of T1.4-426-gd95a98c1f2 and 17 pull requests
Browse files Browse the repository at this point in the history
- Pull request #525 at 614b222: TCS extensions
- Pull request #613 at 39fb000: fix: Use properly FPS-independent smoothing function
- Pull request #615 at 75bf3a4:  Management of EOT devices  https://blueprints.launchpad.net/or/+spec/eot
- Pull request #616 at 1b168a0: Improvements in graduated/full release braking
- Pull request #617 at 99c6474: 02m: Removed menu option Debrief Evaluation. Now always available.
- Pull request #619 at ea10bfc: Adjust HuD to display relevant parameters for DM locomotive
- Pull request #620 at 67c67f1: Adjust kinietic friction calculations
- Pull request #622 at c01c4a6: Bug fix for https://bugs.launchpad.net/or/+bug/1965311. TDI: The vacuum brake value is misaligned.
- Pull request #624 at 01231e1: Menu option04 - invert controls
- Pull request #625 at b161625: Menu > Options - Change defaults for best graphics
- Pull request #626 at d294ec8: Timetable loading bar added
- Pull request #627 at 121de22: Improve advanced adhesion model
- Pull request #629 at 34abd9c: Refined label for downloading Testing Version
- Pull request #630 at 688d0cd: Sky Color Fix (Addresses Trello Roadmap Card #367 for More accurate sunrise and sunset)
- Pull request #631 at 443fc13: Get correct signal id if signal ahead is in same Track Circuit
- Pull request #633 at 7ce52a7: Removed ViewDispatcher setting
- Pull request #634 at 1a44f03: Out of range exception with >= 256 cab controls
  • Loading branch information
openrails-bot committed Mar 31, 2022
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -629,70 +629,50 @@ public virtual void Update(float timeSpan)
// Hence CompensatedAxleForce is the actual output force on the axle.
var compensateAxleForceN = axleForceN;

switch (driveType)
float motiveAxleForceN = -axleForceN;
if (driveType == AxleDriveType.ForceDriven)
motiveAxleForceN += driveForceN * transmissionEfficiency;
else if (driveType == AxleDriveType.MotorDriven)
motiveAxleForceN += motor.DevelopedTorqueNm * transmissionEfficiency * AxleDiameterM / 2;

float frictionalForceN = brakeRetardForceN
+ slipDerivationMpSS * dampingNs
+ Math.Abs(SlipSpeedMpS) * frictionN; // Dissipative forces: they will never increase wheel speed
float totalAxleForceN = motiveAxleForceN - Math.Sign(axleSpeedMpS) * frictionalForceN;
if (axleSpeedMpS == 0)
{
case AxleDriveType.NotDriven:
//Axle revolutions integration
axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
axleDiameterM * axleDiameterM / (4.0f * (totalInertiaKgm2))
* (2.0f * transmissionRatio / axleDiameterM * (-Math.Abs(brakeRetardForceN)) - AxleForceN));
break;
case AxleDriveType.MotorDriven:
//Axle revolutions integration
if (TrainSpeedMpS == 0.0f)
{
dampingNs = 0.0f;
brakeRetardForceN = 0.0f;
}
axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
axleDiameterM * axleDiameterM / (4.0f * (totalInertiaKgm2))
* (2.0f * transmissionRatio / axleDiameterM * motor.DevelopedTorqueNm * transmissionEfficiency
- Math.Abs(brakeRetardForceN) - (axleSpeedMpS > 0.0 ? Math.Abs(dampingNs) : 0.0f)) - AxleForceN);

//update motor values
motor.RevolutionsRad = axleSpeedMpS * 2.0f * transmissionRatio / (axleDiameterM);
motor.Update(timeSpan);
break;
case AxleDriveType.ForceDriven:
//Axle revolutions integration
float frictionalForceN = brakeRetardForceN
+ slipDerivationMpSS * dampingNs
+ Math.Abs(SlipSpeedMpS) * frictionN; // Dissipative forces: they will never increase wheel speed
float motiveAxleForceN = driveForceN - axleForceN; // Rest of forces that can increase or decrease wheel speed
float totalAxleForceN = motiveAxleForceN - Math.Sign(axleSpeedMpS) * frictionalForceN;
if (axleSpeedMpS == 0)
{
if (motiveAxleForceN > frictionalForceN) totalAxleForceN = motiveAxleForceN - frictionalForceN;
else if (motiveAxleForceN < -frictionalForceN) totalAxleForceN = motiveAxleForceN + frictionalForceN;
else
{
totalAxleForceN = 0;
frictionalForceN = Math.Abs(motiveAxleForceN);
}
}
float prevSpeedMpS = axleSpeedMpS;
if (totalAxleForceN != 0)
{
axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
totalAxleForceN * axleDiameterM * axleDiameterM / 4
/ totalInertiaKgm2
);
}
if ((prevSpeedMpS > 0 && axleSpeedMpS < 0 && motiveAxleForceN > -frictionalForceN) || (prevSpeedMpS < 0 && axleSpeedMpS > 0 && motiveAxleForceN < frictionalForceN))
{
Reset();
axleSpeedMpS = 0;
}
// TODO: We should calculate frictional brake force here
// Adding and substracting the brake force is correct for normal operation,
// but during wheelslip this will produce wrong results
if (axleSpeedMpS > 0) compensateAxleForceN = axleForceN + brakeRetardForceN;
else if (axleSpeedMpS < 0) compensateAxleForceN = axleForceN - brakeRetardForceN;
else compensateAxleForceN = 0;
break;
default:
totalInertiaKgm2 = inertiaKgm2;
break;
if (motiveAxleForceN > frictionalForceN) totalAxleForceN = motiveAxleForceN - frictionalForceN;
else if (motiveAxleForceN < -frictionalForceN) totalAxleForceN = motiveAxleForceN + frictionalForceN;
else
{
totalAxleForceN = 0;
frictionalForceN -= Math.Abs(motiveAxleForceN);
}
}
float prevSpeedMpS = axleSpeedMpS;
if (totalAxleForceN != 0)
{
axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
totalAxleForceN * axleDiameterM * axleDiameterM / 4
/ totalInertiaKgm2
);
}
if ((prevSpeedMpS > 0 && axleSpeedMpS < 0 && motiveAxleForceN > -frictionalForceN) || (prevSpeedMpS < 0 && axleSpeedMpS > 0 && motiveAxleForceN < frictionalForceN))
{
Reset();
axleSpeedMpS = 0;
}
// TODO: We should calculate brake force here
// Adding and substracting the brake force is correct for normal operation,
// but during wheelslip this will produce wrong results
if (axleSpeedMpS > 0) compensateAxleForceN = axleForceN + brakeRetardForceN;
else if (axleSpeedMpS < 0) compensateAxleForceN = axleForceN - brakeRetardForceN;
else compensateAxleForceN = 0;

if (driveType == AxleDriveType.MotorDriven)
{
motor.RevolutionsRad = axleSpeedMpS * 2.0f * transmissionRatio / (axleDiameterM);
motor.Update(timeSpan);
}
if (timeSpan > 0.0f)
{
Expand Down Expand Up @@ -756,30 +736,33 @@ public void Reset(double resetTime, float initValue)
/// umax^2*dv^2 + K^2
/// For high slip speeds (after the inflexion point of u), the formula is
/// replaced with an exponentially decaying function (with smooth coupling)
/// reaching half of maximum adhesion at infinity. Quick fix until
/// further investigation is done to get non zero adhesion at infinity
/// reaching a 40% of maximum adhesion at infinity. Quick fix until
/// further investigation is done to get a single formula that provides
/// non zero adhesion at infinity.
/// </summary>
/// <param name="slipSpeed">Difference between train speed and wheel speed MpS</param>
/// <param name="speed">Current speed MpS</param>
/// <param name="K">Slip speed correction. If is set K = 0 then K = 0.7 is used</param>
/// <param name="conditions">Relative weather conditions, usually from 0.2 to 1.0</param>
/// <returns>Relative force transmitted to the rail</returns>
public float SlipCharacteristics(float slipSpeed, float speed, float K, float conditions, float Adhesion2)
public float SlipCharacteristics(float slipSpeedMpS, float speedMpS, float K, float conditions, float Adhesion2)
{
speed = Math.Abs(3.6f*speed);
float umax = (CurtiusKnifflerA / (speed + CurtiusKnifflerB) + CurtiusKnifflerC);// *Adhesion2 / 0.331455f; // Curtius - Kniffler equation
var speedKpH = Math.Abs(MpS.ToKpH(speedMpS));
float umax = (CurtiusKnifflerA / (speedKpH + CurtiusKnifflerB) + CurtiusKnifflerC);// *Adhesion2 / 0.331455f; // Curtius - Kniffler equation
umax *= conditions;
if (K == 0.0)
K = 1;
slipSpeed *= 3.6f;
float x = Math.Abs(slipSpeed * umax / K);
var slipSpeedKpH = MpS.ToKpH(slipSpeedMpS);
float x = Math.Abs(slipSpeedKpH * umax / K);
float sqrt3 = (float)Math.Sqrt(3);
if (x > sqrt3)
{
float inftyFactor = 0.4f; // At infinity, adhesion is 40% of maximum
return Math.Sign(slipSpeed) * umax * ((sqrt3 / 2 - inftyFactor) * (float)Math.Exp((sqrt3 - x) / (2 * sqrt3 - 4 * inftyFactor)) + inftyFactor);
{
// At infinity, adhesion is 40% of maximum (Polach, 2005)
// The value must be lower than 85% for the formula to work
float inftyFactor = 0.4f;
return Math.Sign(slipSpeedKpH) * umax * ((sqrt3 / 2 - inftyFactor) * (float)Math.Exp((sqrt3 - x) / (2 * sqrt3 - 4 * inftyFactor)) + inftyFactor);
}
return 2.0f * K * umax * umax * (slipSpeed / (umax * umax * slipSpeed * slipSpeed + K * K));
return 2.0f * K * umax * umax * (slipSpeedKpH / (umax * umax * slipSpeedKpH * slipSpeedKpH + K * K));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car)

#region Create Control renderers
ControlMap = new Dictionary<int, CabViewControlRenderer>();
int[] count = new int[256];//enough to hold all types, count the occurence of each type
int[] count = new int[Enum.GetNames(typeof(CABViewControlTypes)).Length];//enough to hold all types, count the occurence of each type
var i = 0;
foreach (var cabView in car.CabViewList)
{
Expand Down Expand Up @@ -1242,7 +1242,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car)

#region Create Control renderers
ControlMap = new Dictionary<int, CabViewControlRenderer>();
int[] count = new int[256];//enough to hold all types, count the occurence of each type
int[] count = new int[Enum.GetNames(typeof(CABViewControlTypes)).Length];//enough to hold all types, count the occurence of each type
var i = 0;

var controlSortIndex = 1; // Controls are drawn atop the cabview and in order they appear in the CVF file.
Expand Down

0 comments on commit 6947881

Please sign in to comment.