Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Emergency brake doesn't drain the brake pipe completely #1095

Open
hotdamndel opened this issue Nov 23, 2024 · 1 comment
Open

[Bug] Emergency brake doesn't drain the brake pipe completely #1095

hotdamndel opened this issue Nov 23, 2024 · 1 comment

Comments

@hotdamndel
Copy link

On trains with brakes that include a brake pipe, throwing handle to emergency will still keep some pressure left, even though the concept of automatic air brakes universally means venting the brake pipe to atmosphere at emergency setting so the pressure should drop to zero. Currently, it leaves a small inconfigurable amount of pressure (probably not all pressures are calculated relative to atmospheric?) in it, which is physically impossible in reality.

@leezer3
Copy link
Owner

leezer3 commented Nov 28, 2024

Basically, pressure is only actually changed if the difference in values between that required and the current is above the tolerance value of 5000pa (a small fraction of atmospheric pressure, let alone brake air pressure)
See the process from the Automatic Air Brake:

if (brakePipe.CurrentPressure > equalizingReservoir.CurrentPressure + Tolerance)
{
// brake pipe exhaust valve
double r = Car.baseTrain.Handles.EmergencyBrake.Actual ? brakePipe.EmergencyRate : brakePipe.ServiceRate;
double d = brakePipe.CurrentPressure - equalizingReservoir.CurrentPressure;
double m = equalizingReservoir.NormalPressure;
r = (0.5 + 1.5 * d / m) * r * TimeElapsed;
if (r > d) r = d;
brakePipe.CurrentPressure -= r;
}
else if (brakePipe.CurrentPressure + Tolerance < equalizingReservoir.CurrentPressure)
{
// fill brake pipe from main reservoir
double r = brakePipe.ChargeRate;
double d = equalizingReservoir.CurrentPressure - brakePipe.CurrentPressure;
double m = equalizingReservoir.NormalPressure;
r = (0.5 + 1.5 * d / m) * r * TimeElapsed;
if (r > d) r = d;
d = brakePipe.NormalPressure - brakePipe.CurrentPressure;
if (r > d) r = d;
double f = mainReservoir.BrakePipeCoefficient;
double s = r * f;
if (s > mainReservoir.CurrentPressure)
{
r *= mainReservoir.CurrentPressure / s;
s = mainReservoir.CurrentPressure;
}
brakePipe.CurrentPressure += 0.5 * r;
mainReservoir.CurrentPressure -= 0.5 * s;
}
}
if (brakePipe.CurrentPressure + Tolerance < auxiliaryReservoir.CurrentPressure)
{
if (auxiliaryReservoir.CurrentPressure + Tolerance < brakeCylinder.CurrentPressure)
{
// back-flow from brake cylinder to auxillary reservoir
double u = (brakeCylinder.CurrentPressure - auxiliaryReservoir.CurrentPressure - Tolerance) / Tolerance;
if (u > 1.0) u = 1.0;
double f = auxiliaryReservoir.BrakeCylinderCoefficient;
double r = brakeCylinder.ServiceChargeRate * f;
double d = brakeCylinder.CurrentPressure - auxiliaryReservoir.CurrentPressure;
double m = auxiliaryReservoir.MaximumPressure;
r = GetRate(d * u / m, r * TimeElapsed);
if (auxiliaryReservoir.CurrentPressure + r > m)
{
r = m - auxiliaryReservoir.CurrentPressure;
}
if (r > d) r = d;
double s = r / f;
if (s > d)
{
r *= d / s;
s = d;
}
if (s > brakeCylinder.CurrentPressure)
{
r *= brakeCylinder.CurrentPressure / s;
s = brakeCylinder.CurrentPressure;
}
auxiliaryReservoir.CurrentPressure += 0.5 * r;
brakeCylinder.CurrentPressure -= 0.5 * s;
}
else if (auxiliaryReservoir.CurrentPressure > brakeCylinder.CurrentPressure + Tolerance)
{
// refill brake cylinder from auxillary reservoir
double u = (auxiliaryReservoir.CurrentPressure - brakeCylinder.CurrentPressure - Tolerance) / Tolerance;
if (u > 1.0) u = 1.0;
double f = auxiliaryReservoir.BrakeCylinderCoefficient;
double r = brakeCylinder.ServiceChargeRate * f;
double d = auxiliaryReservoir.CurrentPressure - brakeCylinder.CurrentPressure;
double m = auxiliaryReservoir.MaximumPressure;
r = GetRate(d * u / m, r * TimeElapsed);
if (r > auxiliaryReservoir.CurrentPressure)
{
r = auxiliaryReservoir.CurrentPressure;
}
if (r > d) r = d;
double s = r / f;
if (s > d)
{
r *= d / s;
s = d;
}
d = brakeCylinder.EmergencyMaximumPressure - brakeCylinder.CurrentPressure;
if (s > d)
{
r *= d / s;
s = d;
}
auxiliaryReservoir.CurrentPressure -= 0.5 * r;
brakeCylinder.CurrentPressure += 0.5 * s;
// as the pressure is now *increasing* stop our decrease sounds
AirHigh?.Stop();
Air?.Stop();
AirZero?.Stop();
}
// air sound
brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure;
}
else if (brakePipe.CurrentPressure > auxiliaryReservoir.CurrentPressure + Tolerance)
{
double u = (brakePipe.CurrentPressure - auxiliaryReservoir.CurrentPressure - Tolerance) / Tolerance;
if (u > 1.0) u = 1.0;
{
// refill auxillary reservoir from brake pipe
double r = auxiliaryReservoir.ChargeRate;
double d = brakePipe.CurrentPressure - auxiliaryReservoir.CurrentPressure;
double m = auxiliaryReservoir.MaximumPressure;
r = GetRate(d * u / m, r * TimeElapsed);
if (r > brakePipe.CurrentPressure)
{
r = brakePipe.CurrentPressure;
}
if (r > d) r = d;
d = auxiliaryReservoir.MaximumPressure - auxiliaryReservoir.CurrentPressure;
if (r > d) r = d;
double f = auxiliaryReservoir.BrakePipeCoefficient;
double s = r / f;
if (s > brakePipe.CurrentPressure)
{
r *= brakePipe.CurrentPressure / s;
s = brakePipe.CurrentPressure;
}
if (s > d)
{
r *= d / s;
s = d;
}
auxiliaryReservoir.CurrentPressure += 0.5 * r;
brakePipe.CurrentPressure -= 0.5 * s;
}
{
// brake cylinder release
double r = brakeCylinder.ReleaseRate;
double d = brakeCylinder.CurrentPressure;
double m = brakeCylinder.EmergencyMaximumPressure;
r = GetRate(d * u / m, r * TimeElapsed);
if (r > brakeCylinder.CurrentPressure) r = brakeCylinder.CurrentPressure;
brakeCylinder.CurrentPressure -= r;
// air sound
if (r > 0.0 & brakeCylinder.CurrentPressure < brakeCylinder.SoundPlayedForPressure)
{
double p = 0.8 * brakeCylinder.CurrentPressure - 0.2 * brakeCylinder.EmergencyMaximumPressure;
if (p < 0.0) p = 0.0;
brakeCylinder.SoundPlayedForPressure = p;
airSound = p < Tolerance ? AirZero : brakeCylinder.CurrentPressure > m - Tolerance ? AirHigh : Air;
}
}
}
else
{
// air sound
brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure;
}
double pressureratio = brakeCylinder.CurrentPressure / brakeCylinder.ServiceMaximumPressure;
deceleration = pressureratio * DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed);
}

I suspect the tolerance value was intended to stop fluttering of gauges, especially at either end of the range.

At present, I think this is probably a 'feature' of the brake system simulation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants