/*fizyka hamulcow dla symulatora*/
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
MaSzyna EU07 - SPKS
Brakes.
Copyright (C) 2007-2014 Maciej Cierniak
*/
/*
(C) youBy
Co brakuje:
moze jeszcze jakis SW
*/
/*
Zrobione:
ESt3, ESt3AL2, ESt4R, LSt, FV4a, FD1, EP2, prosty westinghouse
duzo wersji żeliwa
KE
Tarcze od 152A
Magnetyki (implementacja w mover.pas)
Matrosow 394
H14K1 (zasadniczy), H1405 (pomocniczy), St113 (ep)
Knorr/West EP - żeby był
*/
#pragma once
#include "friction.h" // Pascal unit
/// Number of positions of the local (auxiliary/manual) brake handle.
static int const LocalBrakePosNo = 10; /*ilosc nastaw hamulca recznego lub pomocniczego*/
/// Maximum number of positions of the main (train) brake handle.
static int const MainBrakeMaxPos = 10; /*max. ilosc nastaw hamulca zasadniczego*/
/*nastawy hamulca*/
/// Brake delay setting flag: G (goods/freight slow).
static int const bdelay_G = 1; // G
/// Brake delay setting flag: P (passenger fast).
static int const bdelay_P = 2; // P
/// Brake delay setting flag: R (rapid - high braking force).
static int const bdelay_R = 4; // R
/// Brake delay setting flag: Mg (magnetic rail brake enabled).
static int const bdelay_M = 8; // Mg
/*stan hamulca*/
/// Brake state flag: brake released (no action).
static int const b_off = 0; // luzowanie
/// Brake state flag: hold (lap) - keep current cylinder pressure.
static int const b_hld = 1; // trzymanie
/// Brake state flag: applying - filling brake cylinder.
static int const b_on = 2; // napelnianie
/// Brake state flag: replenishing the auxiliary reservoir.
static int const b_rfl = 4; // uzupelnianie
/// Brake state flag: releaser engaged (vents the control reservoir to release brakes).
static int const b_rls = 8; // odluzniacz
/// Brake state flag: electro-pneumatic action active.
static int const b_ep = 16; // elektropneumatyczny
/// Brake state flag: anti-slip protection holding the brake (preventing further filling).
static int const b_asb = 32; // przeciwposlizg-wstrzymanie
/// Brake state flag: anti-slip protection releasing the brake.
static int const b_asb_unbrake = 64; // przeciwposlizg-luzowanie
/// Brake state flag: brake disabled / damaged.
static int const b_dmg = 128; // wylaczony z dzialania
/*uszkodzenia hamulca*/
/// Brake damage flag: faulty filling phase.
static int const df_on = 1; // napelnianie
/// Brake damage flag: faulty release phase.
static int const df_off = 2; // luzowanie
/// Brake damage flag: leak in auxiliary reservoir (ZP).
static int const df_br = 4; // wyplyw z ZP
/// Brake damage flag: leak in valve pre-chamber.
static int const df_vv = 8; // wyplyw z komory wstepnej
/// Brake damage flag: leak in brake cylinder.
static int const df_bc = 16; // wyplyw z silownika
/// Brake damage flag: leak in control reservoir (ZS).
static int const df_cv = 32; // wyplyw z ZS
/// Brake damage flag: stuck at low load step.
static int const df_PP = 64; // zawsze niski stopien
/// Brake damage flag: stuck at high load step.
static int const df_RR = 128; // zawsze wysoki stopien
/*indeksy dzwiekow FV4a*/
/// FV4a sound index: braking flow.
static int const s_fv4a_b = 0; // hamowanie
/// FV4a sound index: release flow.
static int const s_fv4a_u = 1; // luzowanie
/// FV4a sound index: emergency braking flow.
static int const s_fv4a_e = 2; // hamowanie nagle
/// FV4a sound index: control wave outflow.
static int const s_fv4a_x = 3; // wyplyw sterujacego fala
/// FV4a sound index: timing chamber outflow.
static int const s_fv4a_t = 4; // wyplyw z czasowego
/*pary cierne*/
/// Friction pair: P10 (default cast iron).
static int const bp_P10 = 0;
/// Friction pair: P10 phosphoric cast iron with Bg block.
static int const bp_P10Bg = 2; // żeliwo fosforowe P10
/// Friction pair: P10 phosphoric cast iron with Bgu block.
static int const bp_P10Bgu = 1;
/// Friction pair: low-friction composite (b.n.t.) with Bg block.
static int const bp_LLBg = 4; // komp. b.n.t.
/// Friction pair: low-friction composite (b.n.t.) with Bgu block.
static int const bp_LLBgu = 3;
/// Friction pair: low-friction composite (n.t.) with Bg block.
static int const bp_LBg = 6; // komp. n.t.
/// Friction pair: low-friction composite (n.t.) with Bgu block.
static int const bp_LBgu = 5;
/// Friction pair: high-friction composite (w.t.) with Bg block.
static int const bp_KBg = 8; // komp. w.t.
/// Friction pair: high-friction composite (w.t.) with Bgu block.
static int const bp_KBgu = 7;
/// Friction pair: disc brake type 1.
static int const bp_D1 = 9; // tarcze
/// Friction pair: disc brake type 2.
static int const bp_D2 = 10;
/// Friction pair: Frenoplast FR513 composite.
static int const bp_FR513 = 11; // Frenoplast FR513
/// Friction pair: Cosid composite.
static int const bp_Cosid = 12; // jakistam kompozyt :D
/// Friction pair: PKP cast iron with Bg block.
static int const bp_PKPBg = 13; // żeliwo PKP
/// Friction pair: PKP cast iron with Bgu block.
static int const bp_PKPBgu = 14;
/// Friction pair flag: magnetic rail brake (added bitwise to other types).
static int const bp_MHS = 128; // magnetyczny hamulec szynowy
/// Friction pair: P10y phosphoric cast iron with Bg block.
static int const bp_P10yBg = 15; // żeliwo fosforowe P10
/// Friction pair: P10y phosphoric cast iron with Bgu block.
static int const bp_P10yBgu = 16;
/// Friction pair: Frenoplast FR510 composite.
static int const bp_FR510 = 17; // Frenoplast FR510
/// Sound flag: accelerator (rapid pressure drop in valve pre-chamber).
static int const sf_Acc = 1; // przyspieszacz
/// Sound flag: brake transmission/load relay actuating.
static int const sf_BR = 2; // przekladnia
/// Sound flag: brake cylinder filling.
static int const sf_CylB = 4; // cylinder - napelnianie
/// Sound flag: brake cylinder venting.
static int const sf_CylU = 8; // cylinder - oproznianie
/// Sound flag: releaser actuated.
static int const sf_rel = 16; // odluzniacz
/// Sound flag: electro-pneumatic valves switching.
static int const sf_ep = 32; // zawory ep
/// Brake handle position index: minimum position.
static int const bh_MIN = 0; // minimalna pozycja
/// Brake handle position index: maximum position.
static int const bh_MAX = 1; // maksymalna pozycja
/// Brake handle position index: filling stroke (high-pressure overcharge); if not present, equivalent to running.
static int const bh_FS = 2; // napelnianie uderzeniowe //jesli nie ma, to jazda
/// Brake handle position index: running (driving) position.
static int const bh_RP = 3; // jazda
/// Brake handle position index: cut-off (double traction / neutral).
static int const bh_NP = 4; // odciecie - podwojna trakcja
/// Brake handle position index: minimum braking step (lap or first step).
static int const bh_MB = 5; // odciecie - utrzymanie stopnia hamowania/pierwszy 1 stopien hamowania
/// Brake handle position index: full service brake.
static int const bh_FB = 6; // pelne
/// Brake handle position index: emergency brake.
static int const bh_EB = 7; // nagle
/// Brake handle position index: EP release (full release for angular EP).
static int const bh_EPR = 8; // ep - luzowanie //pelny luz dla ep kątowego
/// Brake handle position index: EP hold/lap; if equal to release, button-only EP control.
static int const bh_EPN = 9; // ep - utrzymanie //jesli rowne luzowaniu, wtedy sterowanie przyciskiem
/// Brake handle position index: EP brake (full braking for angular EP).
static int const bh_EPB = 10; // ep - hamowanie //pelne hamowanie dla ep kątowego
/// Diameter of the brake pipe (1") used in flow calculations.
static double const SpgD = 0.7917;
/// Cross-section of a 1" brake pipe expressed in l/m (used to keep volumes in liters and lengths in meters).
static double const SpO = 0.5067; // przekroj przewodu 1" w l/m
// wyj: jednostka dosyc dziwna, ale wszystkie obliczenia
// i pojemnosci sa podane w litrach (rozsadne wielkosci)
// zas dlugosc pojazdow jest podana w metrach
// a predkosc przeplywu w m/s //3.5
// 7//1.5
// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (14, 5.4), (9, 5.0), (6, 4.6), (9, 4.5), (9, 4.0), (9, 3.5), (9, 2.8), (34, 2.8));
// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (7, 5.0), (2.0, 5.0), (4.5, 4.6), (4.5, 4.2), (4.5, 3.8), (4.5, 3.4), (4.5, 2.8), (8, 2.8));
///
/// Brake handle position table for FV4a-family valves (range -2..6).
/// Each row holds {flow speed, target brake pipe pressure [bar]} for the matching position index (offset by +2).
///
static double const BPT[9][2] = {{0, 5.0}, {7, 5.0}, {2.0, 5.0}, {4.5, 4.6}, {4.5, 4.2}, {4.5, 3.8}, {4.5, 3.4}, {4.5, 2.8}, {8, 2.8}};
///
/// Brake handle position table for the Matrosow 394 valve (range -1..5).
/// Each row holds {flow speed, target brake pipe pressure [bar]} for the matching position index (offset by +1).
///
static double const BPT_394[7][2] = {{13, 10.0}, {5, 5.0}, {0, -1}, {5, -1}, {5, 0.0}, {5, 0.0}, {18, 0.0}};
// double *BPT = zero_based_BPT[2]; //tablica pozycji hamulca dla zakresu -2..6
// double *BPT_394 = zero_based_BPT_394[1]; //tablica pozycji hamulca dla zakresu -1..5
// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (12, 5.4), (9, 5.0), (9, 4.6), (9, 4.2), (9, 3.8), (9, 3.4), (9, 2.8), (34, 2.8));
// BPT: array[-2..6] of array [0..1] of real= ((0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0));
// static double const pi = 3.141592653589793; //definicja w mctools
///
/// Bit flags for the universal brake button — actions that can be triggered
/// from a single hardware button on the driver's stand. Combined bitwise.
///
enum TUniversalBrake // możliwe działania uniwersalnego przycisku hamulca
{ // kolejne flagi
/// Releaser (ZR) — vents control reservoir to release brakes on this vehicle.
ub_Release = 0x01, // odluźniacz - ZR
/// Brake pipe unlock / safety brake bridging (vehicle-level).
ub_UnlockPipe = 0x02, // odblok PG / mostkowanie hamulca bezpieczeństwa - POJAZD
/// High-pressure pulse (ZM) — overcharge stroke.
ub_HighPressure = 0x04, // impuls wysokiego ciśnienia - ZM
/// Assimilation / controlled overcharge button (ZM).
ub_Overload = 0x08, // przycisk asymilacji / kontrolowanego przeładowania - ZM
/// Anti-slip light braking button (ZR).
ub_AntiSlipBrake = 0x10, // przycisk przyhamowania przeciwposlizgowego - ZR
/// Reserved sentinel — last bit flag (highest bit).
ub_Ostatni = 0x80000000 // ostatnia flaga bitowa
};
///
/// Single pneumatic reservoir. Tracks capacity (Cap), current volume (Vol)
/// and the pending flow (dVol) accumulated during a simulation step.
///
class TReservoir
{
protected:
/// Reservoir capacity in liters.
double Cap{1.0};
/// Current air volume contained, scaled by capacity (Vol/Cap == pressure).
double Vol{0.0};
/// Accumulated flow (in/out) for the current step; applied by .
double dVol{0.0};
public:
///
/// Sets reservoir capacity.
///
/// Capacity in liters.
void CreateCap(double Capacity);
///
/// Initialises the reservoir to a given absolute pressure (clears pending flow).
///
/// Pressure in bar (atm).
void CreatePress(double Press);
///
/// Returns absolute (atmospheric) pressure inside the reservoir.
///
/// Pressure value (0.1 * Vol / Cap).
virtual double pa();
///
/// Returns gauge pressure inside the reservoir.
///
/// Pressure value (Vol / Cap), in bar.
virtual double P();
///
/// Accumulates a flow into the reservoir for the current step (positive = in, negative = out).
///
/// Volume change to add to dVol.
void Flow(double dv);
///
/// Applies the accumulated flow (dVol) to the volume and resets dVol.
/// Volume is clamped to be non-negative.
///
void Act();
/// Default constructor — creates a 1 L reservoir at zero pressure.
TReservoir() = default;
};
/// Pointer typedef for a reservoir instance.
typedef TReservoir *PReservoir;
///
/// Brake cylinder reservoir — overrides pressure functions to model the
/// non-linear behaviour of a piston cylinder (initial dead volume, working stroke,
/// fully extended piston).
///
class TBrakeCyl : public TReservoir
{
public:
///
/// Returns absolute pressure inside the brake cylinder (P() * 0.1).
///
/// Absolute cylinder pressure.
virtual double pa() /*override*/;
///
/// Returns gauge pressure inside the brake cylinder, modelling the
/// piston-stroke pressure curve (dead volume, linear stroke, fully extended).
///
/// Cylinder pressure in bar.
virtual double P() /*override*/;
/// Default constructor.
TBrakeCyl() : TReservoir() {};
};
///
/// Base class for the complete pneumatic brake system of a single vehicle.
/// Holds the brake cylinder, auxiliary reservoir, valve pre-chamber and the
/// generic logic shared by every distributor type. Concrete distributor
/// behaviour is implemented in derived classes (TWest, TESt, TLSt, TKE, ...).
///
class TBrake
{
protected:
/// Brake cylinder (silownik) — actuator that pushes the brake blocks.
std::shared_ptr BrakeCyl; // silownik
/// Auxiliary reservoir (ZP) — local source of compressed air for the cylinder.
std::shared_ptr BrakeRes; // ZP
/// Valve pre-chamber (komora wstepna) — small volume connected to the brake pipe / distributor.
std::shared_ptr ValveRes; // komora wstepna
/// Number of brake cylinders on the vehicle.
int BCN = 0; // ilosc silownikow
/// Brake transmission ratio (mechanical leverage between cylinder and shoes).
double BCM = 0.0; // przekladnia hamulcowa
/// Combined cross-section area of all brake cylinders.
double BCA = 0.0; // laczny przekroj silownikow
/// Bitfield of available brake delay positions (combination of bdelay_* flags).
int BrakeDelays = 0; // dostepne opoznienia
/// Currently selected brake delay (one of bdelay_* values).
int BrakeDelayFlag = 0; // aktualna nastawa
/// Friction material model used for the shoes/discs.
std::shared_ptr FM; // material cierny
/// Maximum brake cylinder pressure [bar] in service braking.
double MaxBP = 0.0; // najwyzsze cisnienie
/// Number of braked axles on the vehicle.
int BA = 0; // osie hamowane
/// Number of brake blocks per axle.
int NBpA = 0; // klocki na os
/// Squared size of the auxiliary reservoir relative to a 14" reference cylinder.
double SizeBR = 0.0; // rozmiar^2 ZP (w stosunku do 14")
/// Squared size of the brake cylinder relative to a 14" reference cylinder.
double SizeBC = 0.0; // rozmiar^2 CH (w stosunku do 14")
/// True when the double check valve (auxiliary brake -> cylinder) is engaged.
bool DCV = false; // podwojny zawor zwrotny
/// Anti-slip brake target pressure.
double ASBP = 0.0; // cisnienie hamulca pp
/// Velocity threshold above which the rapid braking step is enabled.
double RV = 0.0; // rapid activation vehicle velocity threshold
/// Bitfield with the currently active universal-button actions (see TUniversalBrake).
int UniversalFlag = 0; // flaga wcisnietych przyciskow uniwersalnych
/// Current brake state (combination of b_off / b_hld / b_on / b_rls / ... flags).
int BrakeStatus{b_off}; // flaga stanu
/// Bitfield of pending sound events (sf_* flags). Cleared after each read.
int SoundFlag = 0;
public:
///
/// Builds a brake unit and selects the friction material.
///
/// Maximum brake cylinder pressure [bar].
/// Brake cylinder radius [m].
/// Brake cylinder working stroke [m].
/// Auxiliary reservoir capacity [l].
/// Number of brake cylinders.
/// Available brake delay positions (bitwise of bdelay_* flags).
/// Friction material id (one of bp_* constants, optionally OR'ed with bp_MHS).
/// Number of braked axles.
/// Number of blocks per axle.
TBrake(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa);
// maksymalne cisnienie, promien, skok roboczy, pojemnosc ZP, ilosc cylindrow, opoznienia hamulca, material klockow, osie hamowane, klocki na os;
///
/// Initialises the brake to a given starting state (pressures and delay).
///
/// Brake pipe pressure [bar].
/// High (control) pressure [bar].
/// Low pressure threshold [bar].
/// Initial brake cylinder pressure [bar].
/// Initial brake delay flag.
virtual void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF); // inicjalizacja hamulca
///
/// Returns the current friction coefficient between blocks and the wheel/disc.
/// Delegates to the friction material model.
///
/// Current vehicle velocity [m/s or km/h depending on FM].
/// Normal force on the block [N].
/// Friction coefficient.
double GetFC(double const Vel, double const N); // wspolczynnik tarcia - hamulec wie lepiej
///
/// Advances the brake distributor for one simulation step and returns the net
/// volume exchanged with the brake pipe (positive = drawn from the brake pipe).
///
/// Brake pipe pressure [bar] at the connection point.
/// Time step [s].
/// Vehicle velocity [m/s].
/// Volume exchanged between the valve pre-chamber and the brake pipe.
virtual double GetPF(double const PP, double const dt, double const Vel); // przeplyw miedzy komora wstepna i PG
///
/// Returns the piston force produced by the brake cylinder pressure.
///
/// Force in arbitrary engine units (BCA * 100 * P).
double GetBCF(); // sila tlokowa z tloka
///
/// Computes the airflow drawn from the high-pressure (8 bar / main) line for one step.
///
/// High-pressure source pressure [bar].
/// Time step [s].
/// Net flow from the high-pressure line.
virtual double GetHPFlow(double const HP, double const dt); // przeplyw - 8 bar
/// Returns brake cylinder gauge pressure [bar].
double GetBCP(); // cisnienie cylindrow hamulcowych
///
/// Returns brake cylinder pressure originating only from the pneumatic
/// (main) brake — used to drive the ED (electrodynamic) brake e.g. in EP09.
///
virtual double GetEDBCP(); // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09
/// Returns auxiliary reservoir (ZP) pressure [bar].
double GetBRP(); // cisnienie zbiornika pomocniczego
/// Returns valve pre-chamber pressure [bar].
double GetVRP(); // cisnienie komory wstepnej rozdzielacza
/// Returns control reservoir (ZS) pressure [bar]; defaults to the auxiliary reservoir for valves without a dedicated ZS.
virtual double GetCRP(); // cisnienie zbiornika sterujacego
///
/// Sets the brake delay (G/P/R/M) selector if requested mode is supported.
///
/// Requested delay flag (bdelay_*).
/// True if accepted (mode supported and changed); false otherwise.
bool SetBDF(int const nBDF); // nastawiacz GPRM
///
/// Engages or disengages the releaser (odluzniacz), updating the brake state flags.
///
/// 1 to engage releaser, 0 to disengage.
void Releaser(int const state); // odluzniacz
/// Returns true if the releaser is currently engaged.
bool Releaser() const;
///
/// Sets the electro-pneumatic state (EP) — strength of the EP brake action.
/// Default no-op; overridden by EP-capable distributors.
///
/// EP intensity (typically -1..1).
virtual void SetEPS(double const nEPS); // hamulec EP
/// Sets the rapid step ratio. Default no-op; overridden where supported.
/// Rapid ratio.
virtual void SetRM(double const RMR) {}; // ustalenie przelozenia rapida
/// Sets the velocity threshold for the rapid step.
/// Velocity threshold (same unit as Vel passed to GetPF).
virtual void SetRV(double const RVR)
{
RV = RVR;
}; // ustalenie przelozenia rapida
///
/// Sets the load-weighing parameters (empty/loaded mass, empty-mass cylinder pressure).
/// Default no-op; overridden where load-weighing is supported.
///
/// Tare (empty) mass.
/// Loaded mass.
/// Brake cylinder pressure for the tare mass.
virtual void SetLP(double const TM, double const LM, double const TBP) {}; // parametry przystawki wazacej
/// Sets the auxiliary (local) brake target pressure.
/// Local brake pressure [bar].
virtual void SetLBP(double const P) {}; // cisnienie z hamulca pomocniczego
/// Updates the load-weighing pressure coefficient based on current vehicle mass.
/// Current vehicle mass.
virtual void PLC(double const mass) {}; // wspolczynnik cisnienia przystawki wazacej
///
/// Engages the anti-slip brake function (set hold and/or release flags).
///
/// Two-bit value: bit1 = hold (b_asb), bit0 = release (b_asb_unbrake).
void ASB(int state); // hamulec przeciwposlizgowy
/// Returns the raw BrakeStatus flags (for sound/visual cues).
int GetStatus(); // flaga statusu, moze sie przydac do odglosow
/// Sets the anti-slip target pressure.
/// Pressure [bar].
void SetASBP(double const Press); // ustalenie cisnienia pp
/// Vents all reservoirs to zero pressure (used when the vehicle is decoupled or reset).
virtual void ForceEmptiness();
///
/// Removes a specified relative amount of air from the reservoirs to simulate leaks.
///
/// Fraction of pressure to bleed (0..1) per call.
virtual void ForceLeak(double const Amount);
/// Returns and clears the accumulated SoundFlag bitfield.
int GetSoundFlag();
/// Returns the current brake status flags.
int GetBrakeStatus() const
{
return BrakeStatus;
}
/// Overwrites the brake status flags.
/// New BrakeStatus value.
void SetBrakeStatus(int const Status)
{
BrakeStatus = Status;
}
///
/// Sets the ED (electrodynamic) brake state, used to release the pneumatic
/// brake when ED braking is sufficient. Default no-op; overridden where supported.
///
/// ED brake intensity (0..1).
virtual void SetED(double const EDstate) {}; // stan hamulca ED do luzowania
/// Sets the universal-button flags (see TUniversalBrake).
/// Combined ub_* flags.
virtual void SetUniversalFlag(int flag)
{
UniversalFlag = flag;
} // przycisk uniwersalny
};
///
/// Simple Westinghouse triple-valve distributor with optional EP brake and
/// load-weighing equipment. The auxiliary brake (cab handle) feeds straight
/// into the cylinder via the double check valve (DCV).
///
class TWest : public TBrake
{
private:
/// Auxiliary (local) brake pressure [bar].
double LBP = 0.0; // cisnienie hamulca pomocniczego
/// High-pressure flow drawn during the last step (for the main reservoir bookkeeping).
double dVP = 0.0; // pobor powietrza wysokiego cisnienia
/// Current EP brake intensity (-1..1).
double EPS = 0.0; // stan elektropneumatyka
/// Tare (empty) vehicle mass.
double TareM = 0.0; // masa proznego
/// Loaded vehicle mass.
double LoadM = 0.0; // i pelnego
/// Cylinder pressure for tare mass.
double TareBP = 0.0; // cisnienie dla proznego
/// Computed load-weighing coefficient (1.0 for fully loaded).
double LoadC = 0.0; // wspolczynnik przystawki wazacej
public:
/// Initialises pressures: PP into ValveRes, BP into BrakeCyl, average of PP/HPP into BrakeRes.
/// Brake pipe pressure.
/// High pressure.
/// Low pressure.
/// Initial cylinder pressure.
/// Initial brake delay flag.
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// Sets the auxiliary brake target pressure and engages the DCV when above cylinder.
/// Pressure [bar].
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
/// One-step distributor advance (Westinghouse logic).
/// Net flow exchanged with the brake pipe.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Returns the high-pressure flow drawn during the last GetPF step.
double GetHPFlow(double const HP, double const dt) /*override*/;
/// Recomputes the load-weighing pressure coefficient for the current mass.
/// Vehicle mass.
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
/// Sets the EP brake state and toggles the DCV / latches LBP from cylinder pressure on release.
/// New EP intensity.
void SetEPS(double const nEPS) /*override*/; // stan hamulca EP
/// Stores the load-weighing parameters (TareM, LoadM, TareBP).
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
/// Constructs the distributor by forwarding all parameters to TBrake.
inline TWest(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
};
///
/// Oerlikon ESt distributor base. Adds a control reservoir (ZS) and the
/// classical "main slide-valve" logic (CheckState/CheckReleaser/CVs/BVs).
/// Concrete variants (ESt3, ESt3AL2, ESt4R, LSt, EStED, EStEP1/2) refine GetPF.
///
class TESt : public TBrake
{
private:
protected:
/// Control reservoir (ZS) — long-term reference pressure.
std::shared_ptr CntrlRes; // zbiornik sterujący
/// Brake-pipe to brake-cylinder transmission ratio (BVM = MaxBP / (HPP-LPP)).
double BVM = 0.0; // przelozenie PG-CH
public:
/// Initialises the ESt distributor; sizes the control reservoir (15 l) and computes BVM.
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// One-step distributor advance for the ESt baseline.
/// Net flow exchanged with the brake pipe.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Sets ESt-specific characteristic parameters (placeholder; used by some variants).
/// Characteristic value.
void EStParams(double i_crc); // parametry charakterystyczne dla ESt
/// Returns the control reservoir (ZS) pressure.
double GetCRP() /*override*/;
///
/// Updates BrakeStatus (b_on/b_hld) according to the relations between
/// pre-chamber, cylinder and control reservoir pressures (the main slide valve).
/// Triggers the accelerator (sf_Acc) at the start of braking.
///
/// Brake cylinder (or impulse) pressure.
/// In/out accumulator for the brake pipe flow correction.
void CheckState(double BCP, double &dV1); // glowny przyrzad rozrzadczy
/// Drives the releaser logic — bleeds the control reservoir while the releaser is engaged.
/// Time step [s].
void CheckReleaser(double dt); // odluzniacz
///
/// Returns the effective opening factor of the ZS-filling slide valve as a
/// function of cylinder pressure and current pre-chamber/reservoir state.
///
/// Cylinder pressure (or impulse-chamber pressure).
/// Dimensionless opening coefficient.
double CVs(double BP); // napelniacz sterujacego
///
/// Returns the effective opening factor of the auxiliary-reservoir filling
/// slide valve (ZP <-> pre-chamber path).
///
/// Brake cylinder pressure.
/// Dimensionless opening coefficient.
double BVs(double BCP); // napelniacz pomocniczego
/// Vents the valve, brake and control reservoirs to zero.
void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
/// Constructs the ESt distributor and creates the control reservoir.
inline TESt(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
CntrlRes = std::make_shared();
}
};
///
/// ESt3 variant — adjusts the cylinder fill/release rates depending on the
/// G/P delay setting; otherwise keeps the ESt slide-valve logic.
///
class TESt3 : public TESt
{
private:
// double CylFlowSpeed[2][2]; //zmienna nie uzywana
public:
/// One-step distributor advance for ESt3 (G/P-dependent fill/release curves).
/// Net flow exchanged with the brake pipe.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Constructs the ESt3 distributor.
inline TESt3(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TESt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
};
///
/// ESt3 with AL2 load-weighing equipment. Adds an impulse chamber and a
/// load-pressure relay that scales the cylinder pressure between empty/loaded.
///
class TESt3AL2 : public TESt3
{
private:
/// Impulse chamber (KI) — drives the load relay output to the brake cylinder.
std::shared_ptr ImplsRes; // komora impulsowa
/// Tare (empty) vehicle mass.
double TareM = 0.0; // masa proznego
/// Loaded vehicle mass.
double LoadM = 0.0; // i pelnego
/// Cylinder pressure for tare mass.
double TareBP = 0.0; // cisnienie dla proznego
/// Computed load-weighing coefficient.
double LoadC = 0.0;
public:
/// Initialises the impulse chamber on top of the ESt initialisation.
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// One-step distributor advance for ESt3/AL2 with load-weighing relay.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Recomputes LoadC for the current vehicle mass.
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
/// Stores the load-weighing parameters.
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
/// Constructs the distributor and creates the impulse chamber.
inline TESt3AL2(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TESt3(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
ImplsRes = std::make_shared();
}
};
///
/// ESt4 with rapid (R) step. Adds a separately controlled impulse chamber
/// and a velocity-driven rapid factor that boosts cylinder pressure above a
/// configurable speed threshold.
///
class TESt4R : public TESt
{
private:
/// Hysteretic rapid-step latch (true while rapid is active).
bool RapidStatus = false;
protected:
/// Impulse chamber (KI) — intermediate pressure feeding the load relay.
std::shared_ptr ImplsRes; // komora impulsowa
/// Smoothed rapid-step coefficient (current effective ratio).
double RapidTemp = 0.0; // aktualne, zmienne przelozenie
public:
/// Initialises the ESt4R; sizes the impulse chamber and selects the R delay.
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// One-step distributor advance for ESt4R (rapid step active above velocity threshold).
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Constructs the distributor and creates the impulse chamber.
inline TESt4R(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TESt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
ImplsRes = std::make_shared();
}
};
///
/// LSt distributor — locomotive variant of ESt4R with a double check valve
/// (auxiliary brake LBP), configurable rapid ratio and ED-brake release input.
///
class TLSt : public TESt4R
{
private:
// double CylFlowSpeed[2][2]; // zmienna nie używana
protected:
/// Auxiliary (local) brake pressure feeding the DCV.
double LBP = 0.0; // cisnienie hamulca pomocniczego
/// Rapid step ratio (1 - RMR; see SetRM).
double RM = 0.0; // przelozenie rapida
/// ED brake state (0..1) — relaxes the pneumatic brake when ED is active.
double EDFlag = 0.0; // luzowanie hamulca z powodu zalaczonego ED
public:
/// Initialises the LSt; resizes the valve and impulse reservoirs and presets pressures.
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// Sets the auxiliary brake target pressure for the DCV.
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
/// Sets the rapid step ratio (RM = 1 - RMR).
/// Reduction ratio (0 disables rapid, > 0 enables).
void SetRM(double const RMR); // ustalenie przelozenia rapida
/// One-step distributor advance for LSt (DCV + rapid + ED release).
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Computes the high-pressure inflow (replenishes the auxiliary reservoir from the main line).
double GetHPFlow(double const HP, double const dt) /*override*/; // przeplyw - 8 bar
/// Returns the brake-cylinder reference pressure used by the ED brake controller (CVP-BCP * BVM).
virtual double GetEDBCP(); // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09
/// Sets the ED brake state used to relax the pneumatic brake.
/// ED intensity (0..1).
virtual void SetED(double const EDstate); // stan hamulca ED do luzowania
/// Constructs the LSt distributor.
inline TLSt(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TESt4R(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
};
///
/// EStED distributor (used in EP09): ESt4R with a separate load relay,
/// rapid-step control, intermediate reservoir (Miedzypoj) and a fully
/// nozzle-tuned ZP/ZS filling characteristic.
///
class TEStED : public TLSt
{ // zawor z EP09 - Est4 z oddzielnym przekladnikiem, kontrola rapidu i takie tam
private:
/// Intermediate (virtual) reservoir used to refill ZP and ZS.
std::shared_ptr Miedzypoj; // pojemnosc posrednia (urojona) do napelniania ZP i ZS
/// Effective cross-sections of the internal nozzles (squared diameters).
double Nozzles[11]; // dysze
/// Closing-valve memory latch.
bool Zamykajacy = false; // pamiec zaworka zamykajacego
/// Accelerator-block latch (prevents the accelerator from triggering twice).
bool Przys_blok = false; // blokada przyspieszacza
/// Tare (empty) vehicle mass.
double TareM = 0.0; // masa proznego
/// Loaded vehicle mass.
double LoadM = 0.0; // i pelnego
/// Cylinder pressure for tare mass.
double TareBP = 0.0; // cisnienie dla proznego
/// Computed load-weighing coefficient.
double LoadC = 0.0;
public:
/// Initialises the EStED — sets up Miedzypoj, ImplsRes and the nozzle characteristics.
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// One-step distributor advance for EStED (full EP09 logic with intermediate reservoir).
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Returns ED-brake reference pressure (ImplsRes pressure scaled by load coefficient).
double GetEDBCP() /*override*/; // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED
/// Recomputes LoadC for the current vehicle mass.
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
/// Stores the load-weighing parameters.
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
/// Constructs the distributor and creates the intermediate reservoir.
inline TEStED(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TLSt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
Miedzypoj = std::make_shared();
}
};
///
/// ESt with EP2 electro-pneumatic add-on (continuous EP brake, two-wire
/// driver). Uses the LSt base and supplies its own EP-flow calculation.
///
class TEStEP2 : public TLSt
{
protected:
/// Tare (empty) vehicle mass.
double TareM = 0.0; // masa proznego
/// Loaded vehicle mass.
double LoadM = 0.0; // masa pelnego
/// Cylinder pressure for tare mass.
double TareBP = 0.0; // cisnienie dla proznego
/// Computed load-weighing coefficient.
double LoadC = 0.0;
/// EP intensity (-1..1).
double EPS = 0.0;
public:
/// Initialises the EP2-equipped distributor (impulse chamber, P delay).
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/; // inicjalizacja
/// One-step distributor advance with EP2 EP brake logic.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Recomputes LoadC for the current vehicle mass.
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
/// Sets EP intensity; if EP is active and LBP < cylinder pressure, latches LBP from cylinder.
void SetEPS(double const nEPS) /*override*/; // stan hamulca EP
/// Stores the load-weighing parameters.
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
/// EP brake flow integration step. Override in EP1 for proportional control.
/// Time step [s].
void virtual EPCalc(double dt);
/// Constructs the EP2 distributor.
inline TEStEP2(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TLSt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
};
///
/// EP1 variant of the EP brake (continuous, proportional). Reuses EP2's
/// distributor pneumatics but replaces the EP-flow integrator with a
/// proportional model based on the fractional part of EPS.
///
class TEStEP1 : public TEStEP2
{
public:
/// Proportional EP flow integration step (uses fractional part of EPS as the EP target).
void EPCalc(double dt);
/// Stores the EP intensity.
/// Target EP value (integer part = direction, fractional part = magnitude).
void SetEPS(double const nEPS) override; // stan hamulca EP
/// Constructs the EP1 distributor.
inline TEStEP1(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TEStEP2(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
}
};
///
/// DAKO CV1 distributor — Czech triple-valve with control reservoir and a
/// simpler slide-valve characteristic than ESt.
///
class TCV1 : public TBrake
{
private:
/// Brake-pipe to brake-cylinder transmission ratio.
double BVM = 0.0; // przelozenie PG-CH
protected:
/// Control reservoir (ZS).
std::shared_ptr CntrlRes; // zbiornik sterujący
public:
/// Initialises the CV1 distributor (sizes ZS, sets pressures, computes BVM).
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// One-step distributor advance for the CV1 baseline.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Returns the control reservoir (ZS) pressure.
double GetCRP() /*override*/;
/// Updates BrakeStatus based on pre-chamber/cylinder/control reservoir relations and the releaser.
/// Cylinder (or impulse) pressure.
/// In/out brake pipe flow correction.
void CheckState(double const BCP, double &dV1);
/// Returns the ZS-filling slide valve opening factor for the given cylinder pressure.
double CVs(double const BP);
/// Returns the ZP-filling slide valve opening factor for the given cylinder pressure.
double BVs(double const BCP);
/// Vents valve, brake and control reservoirs to zero.
void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
/// Constructs the CV1 distributor and creates the control reservoir.
inline TCV1(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
CntrlRes = std::make_shared();
}
};
// class TCV1R : public TCV1
//{
// private:
// TReservoir *ImplsRes; //komora impulsowa
// bool RapidStatus;
// public:
// // function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG
// // procedure Init(PP, HPP, LPP, BP: real; BDF: int); override;
// inline TCV1R(double i_mbp, double i_bcr, double i_bcd, double i_brc,
// int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa,
// double PP, double HPP, double LPP, double BP, int BDF) : TCV1(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
// , i_BD, i_mat, i_ba, i_nbpa, PP, HPP, LPP, BP, BDF) { }
//};
///
/// CV1-L-TR distributor — locomotive variant of CV1 with auxiliary (local)
/// brake input, impulse chamber and a high-pressure replenishing path.
///
class TCV1L_TR : public TCV1
{
private:
/// Impulse chamber (KI) — drives the relay output to the brake cylinder.
std::shared_ptr ImplsRes; // komora impulsowa
/// Auxiliary (local) brake pressure feeding the DCV.
double LBP = 0.0; // cisnienie hamulca pomocniczego
public:
/// Initialises the CV1-L-TR (sizes the impulse chamber on top of CV1::Init).
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// One-step distributor advance for CV1-L-TR (impulse chamber + DCV).
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Sets the auxiliary brake target pressure for the DCV.
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
/// Computes the high-pressure (8 bar) inflow used to replenish the auxiliary reservoir.
double GetHPFlow(double const HP, double const dt) /*override*/; // przeplyw - 8 bar
/// Constructs the CV1-L-TR and creates the impulse chamber.
inline TCV1L_TR(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TCV1(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
ImplsRes = std::make_shared();
}
};
///
/// Knorr KE (Einheitsbauart) — universal distributor with control reservoir,
/// impulse chamber, optional auxiliary reservoir, rapid step driven by speed
/// and friction-pair type, and load-weighing equipment.
///
class TKE : public TBrake
{ // Knorr Einheitsbauart — jeden do wszystkiego
private:
/// Impulse chamber (KI).
std::shared_ptr ImplsRes; // komora impulsowa
/// Control reservoir (ZS).
std::shared_ptr CntrlRes; // zbiornik sterujący
/// Secondary auxiliary reservoir (ZP2) — used in some variants for additional capacity.
std::shared_ptr Brak2Res; // zbiornik pomocniczy 2
/// Hysteretic rapid-step latch.
bool RapidStatus = false;
/// Brake-pipe to brake-cylinder transmission ratio.
double BVM = 0.0; // przelozenie PG-CH
/// Tare (empty) vehicle mass.
double TareM = 0.0; // masa proznego
/// Loaded vehicle mass.
double LoadM = 0.0; // masa pelnego
/// Cylinder pressure for tare mass.
double TareBP = 0.0; // cisnienie dla proznego
/// Computed load-weighing coefficient.
double LoadC = 0.0; // wspolczynnik zaladowania
/// Rapid step coefficient (RM = 1 - RMR).
double RM = 0.0; // przelozenie rapida
/// Auxiliary (local) brake pressure feeding the DCV.
double LBP = 0.0; // cisnienie hamulca pomocniczego
public:
/// Initialises the KE distributor (control / impulse / auxiliary reservoirs and BVM).
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
/// Sets the rapid step ratio (RM = 1 - RMR).
void SetRM(double const RMR); // ustalenie przelozenia rapida
/// One-step distributor advance for the KE distributor.
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
/// Computes the high-pressure (8 bar) inflow used to replenish the auxiliary reservoir.
double GetHPFlow(double const HP, double const dt) /*override*/; // przeplyw - 8 bar
/// Returns the control reservoir (ZS) pressure.
double GetCRP() /*override*/;
/// Updates BrakeStatus from cylinder/pre-chamber/control reservoir pressures (KE-specific thresholds).
void CheckState(double const BCP, double &dV1);
/// Drives the releaser logic for KE — bleeds the control reservoir while engaged.
void CheckReleaser(double const dt); // odluzniacz
/// ZS-filling slide valve opening factor for the given cylinder pressure.
double CVs(double const BP); // napelniacz sterujacego
/// ZP-filling slide valve opening factor for the given cylinder pressure.
double BVs(double const BCP); // napelniacz pomocniczego
/// Recomputes LoadC for the current vehicle mass.
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
/// Stores the load-weighing parameters.
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
/// Sets the auxiliary brake target pressure for the DCV.
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
/// Vents valve, brake, control, impulse and secondary auxiliary reservoirs to zero.
void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
/// Constructs the KE distributor and creates the control / impulse / secondary reservoirs.
inline TKE(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{
ImplsRes = std::make_shared();
CntrlRes = std::make_shared();
Brak2Res = std::make_shared();
}
};
///
/// Base class for the driver's brake handle (cab valve / kran maszynisty).
/// Concrete handles (FV4a, FV4a/M, MHZ_*, M394, H14K1, St113, FVel6, ...)
/// implement to compute the brake pipe flow for a given
/// handle position and supply additional gauges (control, equalising, EP).
///
class TDriverHandle
{
protected:
// BCP: integer;
/// True if the handle automatically overcharges in the high-pressure position (e.g. -1).
bool AutoOvrld = false; // czy jest asymilacja automatyczna na pozycji -1
/// True if the handle supports manual overcharge/assimilation via a dedicated button.
bool ManualOvrld = false; // czy jest asymilacja reczna przyciskiem
/// Whether the manual overcharge button is currently pressed.
bool ManualOvrldActive = false; // czy jest wcisniety przycisk asymilacji
/// Bitfield with the active universal-button actions (see TUniversalBrake).
int UniversalFlag = 0; // flaga wcisnietych przyciskow uniwersalnych
/// Number of the highest (last) handle position.
int i_bcpno = 6;
public:
/// True if the handle has a "time" (delay/charge) chamber.
bool Time = false;
/// True if the handle has an EP-time chamber.
bool TimeEP = false;
/// Per-event sound flow magnitudes (indices defined by s_fv4a_*).
double Sounds[5]; // wielkosci przeplywow dla dzwiekow
///
/// Computes the brake pipe flow produced by the handle in one simulation step.
///
/// Handle position (continuous; integer values map to detents).
/// Brake pipe pressure [bar].
/// High-pressure source [bar].
/// Time step [s].
/// EP / equalising input pressure [bar].
/// Volume change of the brake pipe (positive = into pipe).
virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep);
/// Initialises internal pressures from the supplied reference.
/// Initial pressure [bar].
virtual void Init(double Press);
/// Returns the control-reservoir / equalising pressure displayed on the cab gauge.
virtual double GetCP();
/// Returns the EP brake intensity reported by the handle (0 by default).
virtual double GetEP();
/// Returns the regulator (reduction) pressure target.
virtual double GetRP();
/// Adjusts the pressure reductor offset (turning the cap of the reductor).
/// Pressure correction [bar].
virtual void SetReductor(double nAdj); // korekcja pozycji reduktora cisnienia
/// Returns the requested sound channel magnitude (index 0..4 defined by s_fv4a_*).
/// Sound index.
virtual double GetSound(int i); // pobranie glosnosci wybranego dzwieku
///
/// Returns the position value (number of detents) for the requested function code.
///
/// Function index (bh_* constants).
virtual double GetPos(int i); // pobranie numeru pozycji o zadanym kodzie (funkcji)
/// Returns EP brake force at the given handle position.
/// Handle position.
virtual double GetEP(double pos); // pobranie sily hamulca ep
///
/// Configures handle-specific behaviour (overcharge mode, filling stroke factor and overcharge dynamics).
///
/// Auto-overcharge enabled.
/// Manual-overcharge enabled.
/// Unbrake over-pressure [bar].
/// Overload (assimilation) max pressure [bar].
/// Overload pressure decay rate [bar/s].
virtual void SetParams(bool AO, bool MO, double, double, double OMP, double OPD) {}; // ustawianie jakichs parametrow dla zaworu
/// Sets the manual overcharge button state.
/// True while the button is pressed.
virtual void OvrldButton(bool Active); // przycisk recznego przeladowania/asymilacji
/// Stores the universal-button flags (see TUniversalBrake).
/// Combined ub_* flags.
virtual void SetUniversalFlag(int flag); // przycisk uniwersalny
/// Default constructor — clears the Sounds[] array.
inline TDriverHandle()
{
memset(Sounds, 0, sizeof(Sounds));
}
};
///
/// FV4a driver's handle (classic Polish PKP cab valve, 6-position).
///
class TFV4a : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący
/// Time chamber pressure [bar].
double TP = 0.0; // zbiornik czasowy
/// Reductor reservoir pressure [bar].
double RP = 0.0; // zbiornik redukcyjny
public:
/// Computes brake pipe flow for the FV4a handle (uses BPT[] table).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP and RP to the supplied pressure.
void Init(double Press) /*override*/;
/// Default constructor.
inline TFV4a() : TDriverHandle() {}
};
///
/// FV4a/M — modernised FV4a without the IC correction. Adds a reductor air
/// chamber to model the brake pipe pressure wave at the start of a release.
///
class TFV4aM : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący
/// Time chamber pressure [bar].
double TP = 0.0; // zbiornik czasowy
/// Reductor reservoir pressure [bar].
double RP = 0.0; // zbiornik redukcyjny
/// Reductor air chamber pressure (models the release pressure wave).
double XP = 0.0; // komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali
/// Reductor adjustment offset (turning the cap).
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow
/// True while the release pressure wave is active.
bool Fala = false;
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; // = { -2, 6, -1, 0, -2, 1, 4, 6, 0, 0, 0 };
///
/// Returns the brake pipe pressure target interpolated from BPT[] for the given handle position.
///
/// Handle position.
double LPP_RP(double pos);
/// Returns true if pos is within ±0.5 of i_pos (detent comparison).
bool EQ(double pos, double i_pos);
public:
/// Computes brake pipe flow for the FV4a/M handle (interpolated BPT, wave modelling, accelerator).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP and RP.
void Init(double Press) /*override*/;
/// Sets the reductor adjustment offset.
void SetReductor(double nAdj) /*override*/;
/// Returns Sounds[i] (or 0 if i > 4).
double GetSound(int i) /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Returns the time chamber pressure (TP).
double GetCP();
/// Returns the regulator pressure (5 + TP*0.08 + RedAdj).
double GetRP();
/// Default constructor.
inline TFV4aM() : TDriverHandle() {}
};
///
/// MHZ_EN57 — combined brake handle for EN57 EMUs (10-position, EP brake plus pneumatic).
///
class TMHZ_EN57 : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący
/// Time chamber pressure [bar].
double TP = 0.0; // zbiornik czasowy
/// Reductor reservoir pressure [bar].
double RP = 0.0; // zbiornik redukcyjny
/// Reductor adjustment offset.
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
/// True while the release pressure wave is active.
bool Fala = false;
/// Configured unbrake over-pressure [bar].
double UnbrakeOverPressure = 0.0;
/// Maximum overcharge pressure when assimilating.
double OverloadMaxPressure = 1.0; // maksymalne zwiekszenie cisnienia przy asymilacji
/// Decay rate of the overcharge pressure.
double OverloadPressureDecrease = 0.045; // predkosc spadku cisnienia przy asymilacji
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 };
/// Returns the brake pipe pressure target for the given handle position (piecewise).
double LPP_RP(double pos);
/// Returns true if pos is within ±0.5 of i_pos.
bool EQ(double pos, double i_pos);
public:
/// Computes brake pipe flow for MHZ_EN57 (covers handle positions -1..10 with EP/pneumatic mix).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP.
void Init(double Press) /*override*/;
/// Sets the reductor adjustment offset.
void SetReductor(double nAdj) /*override*/;
/// Returns Sounds[i] (or 0 if i > 4).
double GetSound(int i) /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Returns the regulator pressure (RP).
double GetCP() /*override*/;
/// Returns the regulator target (5 + RedAdj).
double GetRP() /*override*/;
/// Returns EP brake intensity for the given handle position.
double GetEP(double pos);
/// Configures handle parameters (auto/manual overcharge, over-pressure, overcharge dynamics).
void SetParams(bool AO, bool MO, double OverP, double, double OMP, double OPD);
/// Default constructor.
inline TMHZ_EN57(void) : TDriverHandle() {}
};
///
/// MHZ_K5P — Knorr 5-position combined brake handle.
///
class TMHZ_K5P : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący
/// Time chamber pressure [bar].
double TP = 0.0; // zbiornik czasowy
/// Reductor reservoir pressure [bar].
double RP = 0.0; // zbiornik redukcyjny
/// Reductor adjustment offset.
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
/// True while filling-stroke / release wave is active.
bool Fala = false; // czy jest napelnianie uderzeniowe
/// Configured unbrake over-pressure [bar].
double UnbrakeOverPressure = 0.0;
/// Maximum overcharge pressure when assimilating.
double OverloadMaxPressure = 1.0; // maksymalne zwiekszenie cisnienia przy asymilacji
/// Decay rate of the overcharge pressure.
double OverloadPressureDecrease = 0.002; // predkosc spadku cisnienia przy asymilacji
/// Filling-stroke valve opening multiplier when no wave is active.
double FillingStrokeFactor = 1.0; // mnożnik otwarcia zaworu przy uderzeniowym (bez fali)
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 };
/// Returns true if pos is within ±0.5 of i_pos.
bool EQ(double pos, double i_pos);
public:
/// Computes brake pipe flow for the K5P 5-position handle (release / cut-off / brake / emergency).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP and enables the time chambers.
void Init(double Press) /*override*/;
/// Sets the reductor adjustment offset.
void SetReductor(double nAdj) /*override*/;
/// Returns Sounds[i] (or 0 if i > 4).
double GetSound(int i) /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns the regulator target (5 + TP + RedAdj).
double GetRP() /*override*/;
/// Configures handle parameters (auto/manual overcharge, over-pressure, filling-stroke factor, overcharge dynamics).
void SetParams(bool AO, bool MO, double, double, double OMP, double OPD); /*ovveride*/
/// Default constructor.
inline TMHZ_K5P(void) : TDriverHandle() {}
};
///
/// MHZ_6P — 6-position combined brake handle (similar logic to K5P with one more detent).
///
class TMHZ_6P : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący
/// Time chamber pressure [bar].
double TP = 0.0; // zbiornik czasowy
/// Reductor reservoir pressure [bar].
double RP = 0.0; // zbiornik redukcyjny
/// Reductor adjustment offset.
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
/// True while filling-stroke / release wave is active.
bool Fala = false; // czy jest napelnianie uderzeniowe
/// Configured filling-stroke over-pressure value.
double UnbrakeOverPressure = 0.0; // wartosc napelniania uderzeniowego
/// Maximum overcharge pressure when assimilating.
double OverloadMaxPressure = 1.0; // maksymalne zwiekszenie cisnienia przy asymilacji
/// Decay rate of the overcharge pressure.
double OverloadPressureDecrease = 0.002; // predkosc spadku cisnienia przy asymilacji
/// Filling-stroke valve opening multiplier when no wave is active.
double FillingStrokeFactor = 1.0; // mnożnik otwarcia zaworu przy uderzeniowym (bez fali)
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 };
/// Returns true if pos is within ±0.5 of i_pos.
bool EQ(double pos, double i_pos);
public:
/// Computes brake pipe flow for the 6P handle.
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP and enables the time chambers.
void Init(double Press) /*override*/;
/// Sets the reductor adjustment offset.
void SetReductor(double nAdj) /*override*/;
/// Returns Sounds[i] (or 0 if i > 4).
double GetSound(int i) /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns the regulator target (5 + TP + RedAdj).
double GetRP() /*override*/;
/// Configures handle parameters (auto/manual overcharge, over-pressure, filling-stroke factor, overcharge dynamics).
void SetParams(bool AO, bool MO, double, double, double OMP, double OPD); /*ovveride*/
/// Default constructor.
inline TMHZ_6P(void) : TDriverHandle() {}
};
/* FBS2= class(TTDriverHandle)
private
CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny
XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali
RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem)
// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow
Fala: boolean;
public
function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override;
procedure Init(press: real); override;
procedure SetReductor(nAdj: real); override;
function GetSound(i: int): real; override;
function GetPos(i: int): real; override;
end; */
/* TD2= class(TTDriverHandle)
private
CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny
XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali
RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem)
// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow
Fala: boolean;
public
function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override;
procedure Init(press: real); override;
procedure SetReductor(nAdj: real); override;
function GetSound(i: int): real; override;
function GetPos(i: int): real; override;
end;*/
///
/// Matrosow 394 — Russian/Soviet 5-position cab valve. Uses the BPT_394 table.
///
class TM394 : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący, czasowy, redukcyjny
/// Reductor adjustment offset.
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; // = { -1, 5, -1, 0, 1, 2, 4, 5, 0, 0, 0 };
public:
/// Computes brake pipe flow for the M394 handle (uses BPT_394).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP and enables the time chamber.
void Init(double Press) /*override*/;
/// Sets the reductor adjustment offset.
void SetReductor(double nAdj) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns max(5, CP) + RedAdj.
double GetRP() /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Default constructor — sets the maximum handle position to 5.
inline TM394(void) : TDriverHandle()
{
i_bcpno = 5;
}
};
///
/// H14K1 — Knorr auxiliary (independent) brake handle (4-position).
///
class TH14K1 : public TDriverHandle
{
private:
/// Position table for the H14K1 (range -1..4): {flow speed, target multiplier}.
static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2];
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; // = {-1, 4, -1, 0, 1, 2, 3, 4, 0, 0, 0};
protected:
/// Control reservoir pressure [bar].
double CP = 0.0; // zbiornik sterujący, czasowy, redukcyjny
/// Reductor adjustment offset.
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
public:
/// Computes brake pipe flow for the H14K1 handle.
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP and enables the time chambers.
void Init(double Press) /*override*/;
/// Sets the reductor adjustment offset.
void SetReductor(double nAdj) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns the regulator target (5 + RedAdj).
double GetRP() /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Default constructor — sets the maximum handle position to 4.
inline TH14K1(void) : TDriverHandle()
{
i_bcpno = 4;
}
};
///
/// St113 — Knorr EP-equipped 5-position brake handle (extends H14K1 with EP step).
///
class TSt113 : public TH14K1
{
private:
/// Current EP intensity reported by the handle.
double EPS = 0.0;
/// Position table (override of H14K1's, with adjusted parameters).
static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2];
/// EP table — EP intensity per handle position (range -1..5).
static double const BEP_K[/*?*/ /*-1..5*/ (5) - (-1) + 1];
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; // = {-1, 5, -1, 0, 2, 3, 4, 5, 0, 0, 1};
/// Local control pressure (mirrors PP).
double CP = 0;
public:
/// Computes brake pipe flow for the St113 handle (with EP).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns the regulator target (5 + RedAdj).
double GetRP() /*override*/;
/// Returns the current EP intensity.
double GetEP() /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Enables the time chambers (no pressure init).
void Init(double Press) /*override*/;
/// Default constructor.
inline TSt113(void) : TH14K1() {}
};
///
/// Test handle — minimal implementation used during development for verifying
/// brake pipe responses with the BPT[] table.
///
class Ttest : public TDriverHandle
{
private:
/// Control reservoir pressure [bar].
double CP = 0.0;
public:
/// Computes brake pipe flow using the FV4a-style BPT table for testing.
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises CP.
void Init(double Press) /*override*/;
/// Default constructor.
inline Ttest(void) : TDriverHandle() {}
};
///
/// FD1 auxiliary brake handle — directly drives the cylinder pressure between
/// 0 and MaxBP based on the handle position (linear scaling with configurable speed).
///
class TFD1 : public TDriverHandle
{
private:
/// Maximum cylinder pressure [bar] commandable by this handle.
double MaxBP = 0.0; // najwyzsze cisnienie
/// Current commanded cylinder pressure [bar].
double BP = 0.0; // aktualne cisnienie
public:
/// Action speed multiplier — scales the response time.
double Speed = 0.0; // szybkosc dzialania
/// Computes the auxiliary brake outflow for this step.
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises MaxBP and the action speed.
void Init(double Press) /*override*/;
/// Returns the currently commanded cylinder pressure (BP).
double GetCP() /*override*/;
/// Sets the action speed multiplier.
void SetSpeed(double nSpeed);
// procedure Init(press: real; MaxBP: real); overload;
/// Default constructor.
inline TFD1(void) : TDriverHandle() {}
};
///
/// H1405 — Knorr auxiliary brake handle (continuous, independent brake).
///
class TH1405 : public TDriverHandle
{
private:
/// Maximum cylinder pressure [bar].
double MaxBP = 0.0; // najwyzsze cisnienie
/// Current commanded cylinder pressure [bar].
double BP = 0.0; // aktualne cisnienie
public:
/// Computes the auxiliary brake outflow for this step (proportional to handle deflection).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Initialises MaxBP and enables the time chamber.
void Init(double Press) /*override*/;
/// Returns the currently commanded cylinder pressure (BP).
double GetCP() /*override*/;
// procedure Init(press: real; MaxBP: real); overload;
/// Default constructor.
inline TH1405(void) : TDriverHandle() {}
};
///
/// FVel6 — combined EP + pneumatic brake handle (Czech, 6+1 positions).
///
class TFVel6 : public TDriverHandle
{
private:
/// Current EP intensity reported by the handle.
double EPS = 0.0;
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
/// Local control pressure (mirrors PP).
double CP = 0.0;
public:
/// Computes brake pipe flow for FVel6 (continuous EP brake plus pneumatic emergency).
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns the regulator target (constant 5 bar).
double GetRP() /*override*/;
/// Returns the current EP intensity.
double GetEP() /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Returns Sounds[i] (or 0 if i > 2).
double GetSound(int i) /*override*/;
/// Enables the time chambers.
void Init(double Press) /*override*/;
/// Default constructor.
inline TFVel6(void) : TDriverHandle() {}
};
///
/// FVE408 — newer combined EP + pneumatic brake handle (10 positions).
/// EP intensity is set to fixed steps for positions 1..5.
///
class TFVE408 : public TDriverHandle
{
private:
/// Current EP intensity reported by the handle.
double EPS = 0.0;
/// Lookup of bh_* function codes to handle position values.
static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
/// Local control pressure (mirrors PP).
double CP = 0.0;
public:
/// Computes brake pipe flow for the FVE408 handle.
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
/// Returns CP.
double GetCP() /*override*/;
/// Returns the current EP intensity.
double GetEP() /*override*/;
/// Returns the regulator target (constant 5 bar).
double GetRP() /*override*/;
/// Returns pos_table[i].
double GetPos(int i) /*override*/;
/// Returns Sounds[i] (or 0 if i > 2).
double GetSound(int i) /*override*/;
/// Enables the time chamber, disables the EP-time chamber.
void Init(double Press) /*override*/;
/// Default constructor.
inline TFVE408(void) : TDriverHandle() {}
};
///
/// Pneumatic flow rate from one pressure to another through an orifice of area S.
/// Models choked vs. subsonic flow (critical pressure ratio = 0.5) and softens
/// the response near zero pressure difference using a DP-wide ramp.
///
/// Source pressure [bar].
/// Destination pressure [bar].
/// Effective orifice cross-section.
/// Soft-clip pressure delta — softens flow for tiny PH-PL differences (default 0.25).
/// Volumetric flow rate (signed; positive = P1->P2 direction).
extern double PF(double const P1, double const P2, double const S, double const DP = 0.25);
///
/// Variant of that uses the dimensionless pressure ratio (sg)
/// for the soft-clip threshold instead of an absolute pressure delta.
///
/// Source pressure [bar].
/// Destination pressure [bar].
/// Effective orifice cross-section.
/// Volumetric flow rate.
extern double PF1(double const P1, double const P2, double const S);
///
/// Filling valve flow: flows from PH to PL until PL reaches LIM. The valve
/// throttles smoothly as PL approaches LIM (within DP of the target).
/// Returns 0 once PL is already >= LIM.
///
/// High-pressure source [bar].
/// Low-pressure side [bar].
/// Effective orifice cross-section.
/// Target pressure for PL [bar].
/// Throttling distance from LIM (default 0.1).
/// Flow rate from PH to PL (positive into PL).
extern double PFVa(double PH, double PL, double const S, double LIM, double const DP = 0.1); // zawor napelniajacy z PH do PL, PL do LIM
///
/// Venting valve flow: flows from PH to PL until PH falls to LIM. The valve
/// throttles smoothly as PH approaches LIM. Returns 0 once PH <= LIM.
///
/// High-pressure side that is being vented [bar].
/// Low-pressure destination [bar].
/// Effective orifice cross-section.
/// Lower bound for PH [bar].
/// Throttling distance from LIM (default 0.1).
/// Flow rate from PH to PL.
extern double PFVd(double PH, double PL, double const S, double LIM, double const DP = 0.1); // zawor wypuszczajacy z PH do PL, PH do LIM