mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 16:19:19 +02:00
basic fuel pump, brake reservoirs air leaks, support for combined axle clatter sounds, dedicated loud buffer clash and coupler stretch sounds
This commit is contained in:
@@ -85,7 +85,6 @@ const double Steel2Steel_friction = 0.15; //tarcie statyczne
|
||||
const double g = 9.81; //przyspieszenie ziemskie
|
||||
const double SandSpeed = 0.1; //ile kg/s}
|
||||
const double Pirazy2 = 6.2831853071794f;
|
||||
#define PI 3.1415926535897f
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
static bool const Go = true;
|
||||
@@ -618,6 +617,15 @@ struct TCoupling {
|
||||
int sounds { 0 }; // sounds emitted by the coupling devices
|
||||
};
|
||||
|
||||
// basic approximation of a fuel pump
|
||||
// TODO: fuel consumption, optional automatic engine start after activation
|
||||
struct fuel_pump {
|
||||
|
||||
bool is_enabled { false }; // device is allowed/requested to operate
|
||||
bool is_active { false }; // device is working
|
||||
start start_type { start::manual };
|
||||
};
|
||||
|
||||
class TMoverParameters
|
||||
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
||||
public:
|
||||
@@ -904,6 +912,7 @@ public:
|
||||
bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/
|
||||
bool ConverterAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
||||
bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/
|
||||
fuel_pump FuelPump;
|
||||
|
||||
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
|
||||
double BrakeCtrlPosR = 0.0; /*nastawa hamulca zespolonego - plynna dla FV4a*/
|
||||
@@ -1190,12 +1199,14 @@ public:
|
||||
|
||||
/*--funkcje dla lokomotyw*/
|
||||
bool DirectionBackward(void);/*! kierunek ruchu*/
|
||||
bool FuelPumpSwitch( bool State, int const Notify = range::consist ); // fuel pump state toggle
|
||||
bool MainSwitch( bool const State, int const Notify = range::consist );/*! wylacznik glowny*/
|
||||
bool ConverterSwitch( bool State, int const Notify = range::consist );/*! wl/wyl przetwornicy*/
|
||||
bool CompressorSwitch( bool State, int const Notify = range::consist );/*! wl/wyl sprezarki*/
|
||||
|
||||
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
||||
void ConverterCheck( double const Timestep ); // przetwornica
|
||||
void FuelPumpCheck( double const Timestep );
|
||||
bool FuseOn(void); //bezpiecznik nadamiary
|
||||
bool FuseFlagCheck(void); // sprawdzanie flagi nadmiarowego
|
||||
void FuseOff(void); // wylaczenie nadmiarowego
|
||||
|
||||
@@ -1572,6 +1572,14 @@ void TMoverParameters::ConverterCheck( double const Timestep ) {
|
||||
}
|
||||
};
|
||||
|
||||
// fuel pump status update
|
||||
void TMoverParameters::FuelPumpCheck( double const Timestep ) {
|
||||
|
||||
FuelPump.is_active = (
|
||||
( true == FuelPump.is_enabled )
|
||||
&& ( true == Battery ) );
|
||||
}
|
||||
|
||||
double TMoverParameters::ShowCurrent(int AmpN)
|
||||
{ // Odczyt poboru prądu na podanym amperomierzu
|
||||
switch (EngineType)
|
||||
@@ -2339,13 +2347,38 @@ bool TMoverParameters::AntiSlippingButton(void)
|
||||
return (AntiSlippingBrake() /*|| Sandbox(true)*/);
|
||||
}
|
||||
|
||||
// fuel pump state toggle
|
||||
bool TMoverParameters::FuelPumpSwitch( bool State, int const Notify ) {
|
||||
|
||||
if( FuelPump.start_type == start::automatic ) {
|
||||
// automatic fuel pump ignores 'manual' state commands
|
||||
return false;
|
||||
}
|
||||
|
||||
bool const initialstate { FuelPump.is_enabled };
|
||||
|
||||
FuelPump.is_enabled = State;
|
||||
|
||||
if( Notify != range::local ) {
|
||||
SendCtrlToNext(
|
||||
"FuelPumpSwitch",
|
||||
( FuelPump.is_enabled ? 1 : 0 ),
|
||||
CabNo,
|
||||
( Notify == range::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
}
|
||||
|
||||
return ( FuelPump.is_enabled != initialstate );
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Q: 20160713
|
||||
// włączenie / wyłączenie obwodu głownego
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
||||
{
|
||||
bool MS = false; // Ra: przeniesione z końca
|
||||
bool const initialstate { Mains };
|
||||
|
||||
if( ( Mains != State )
|
||||
&& ( MainCtrlPosNo > 0 ) ) {
|
||||
@@ -2357,46 +2390,59 @@ bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
||||
&& ( false == TestFlag( DamageFlag, dtrain_out ) )
|
||||
&& ( false == TestFlag( EngDmgFlag, 1 ) ) ) ) {
|
||||
|
||||
if( true == Mains ) {
|
||||
// jeśli był załączony
|
||||
if( Notify != range::local ) {
|
||||
// wysłanie wyłączenia do pozostałych?
|
||||
SendCtrlToNext(
|
||||
"MainSwitch", int( State ), CabNo,
|
||||
( Notify == range::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
if( true == State ) {
|
||||
// switch on
|
||||
if( ( EngineType == DieselEngine )
|
||||
|| ( EngineType == DieselElectric ) ) {
|
||||
|
||||
if( true == FuelPump.start_type == start::automatic ) {
|
||||
// potentially force start of the fuel pump
|
||||
// TODO: the whole diesel start sequence is a special kind of a mess, clean it up when refactoring
|
||||
FuelPump.is_enabled = true;
|
||||
FuelPumpCheck( 0.0 );
|
||||
}
|
||||
if( true == FuelPump.is_active ) {
|
||||
Mains = true;
|
||||
dizel_enginestart = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Mains = true;
|
||||
}
|
||||
}
|
||||
Mains = State;
|
||||
MS = true; // wartość zwrotna
|
||||
LastSwitchingTime = 0;
|
||||
|
||||
if( true == Mains ) {
|
||||
// jeśli został załączony
|
||||
if( Notify != range::local ) {
|
||||
// wysłanie wyłączenia do pozostałych?
|
||||
SendCtrlToNext(
|
||||
"MainSwitch", int( State ), CabNo,
|
||||
( Notify == range::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
else {
|
||||
Mains = false;
|
||||
if( true == FuelPump.start_type == start::automatic ) {
|
||||
// if the engine is off, switch off automatic fuel pump
|
||||
FuelPump.is_enabled = false;
|
||||
}
|
||||
}
|
||||
if( ( EngineType == DieselEngine )
|
||||
|| ( EngineType == DieselElectric ) ) {
|
||||
|
||||
dizel_enginestart = State;
|
||||
}
|
||||
if( ( TrainType == dt_EZT )
|
||||
&& ( false == State ) ) {
|
||||
|
||||
ConvOvldFlag = true;
|
||||
}
|
||||
|
||||
if( Mains != initialstate ) {
|
||||
LastSwitchingTime = 0;
|
||||
}
|
||||
|
||||
if( Notify != range::local ) {
|
||||
// pass the command to other vehicles
|
||||
SendCtrlToNext(
|
||||
"MainSwitch",
|
||||
( State ? 1 : 0 ),
|
||||
CabNo,
|
||||
( Notify == range::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// else MainSwitch:=false;
|
||||
return MS;
|
||||
return ( Mains != initialstate );
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
@@ -3023,6 +3069,8 @@ void TMoverParameters::UpdateBrakePressure(double dt)
|
||||
dpLocalValve = 0;
|
||||
dpBrake = 0;
|
||||
|
||||
Hamulec->ForceLeak( dt * AirLeakRate * 0.25 ); // fake air leaks from brake system reservoirs
|
||||
|
||||
BrakePress = Hamulec->GetBCP();
|
||||
// BrakePress:=(Hamulec as TEst4).ImplsRes.pa;
|
||||
Volume = Hamulec->GetBRP();
|
||||
@@ -3066,8 +3114,9 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( EngineType == DieselEngine )
|
||||
&& ( CompressorPower == 0 ) ) {
|
||||
if( ( CompressorPower == 0 )
|
||||
&& ( ( EngineType == DieselEngine )
|
||||
|| ( EngineType == DieselElectric ) ) ) {
|
||||
// experimental: make sure compressor coupled with diesel engine is always ready for work
|
||||
CompressorAllow = true;
|
||||
}
|
||||
@@ -4065,7 +4114,7 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
|
||||
// 090503: dzwieki pracy sprzegu
|
||||
SetFlag(
|
||||
Couplers[ CouplerN ].sounds,
|
||||
( absdV > 0.1 ?
|
||||
( absdV > 0.035 ?
|
||||
( sound::couplerstretch | sound::loud ) :
|
||||
sound::couplerstretch ) );
|
||||
}
|
||||
@@ -4168,8 +4217,9 @@ double TMoverParameters::TractionForce(double dt)
|
||||
// youBy
|
||||
switch( EngineType ) {
|
||||
case DieselElectric: {
|
||||
if( true == ConverterFlag ) {
|
||||
// NOTE: converter is currently a stand-in for a fuel pump
|
||||
if( ( true == Mains )
|
||||
&& ( true == FuelPump.is_active ) ) {
|
||||
|
||||
tmp = DElist[ MainCtrlPos ].RPM / 60.0;
|
||||
|
||||
if( ( true == Heating )
|
||||
@@ -4436,7 +4486,8 @@ double TMoverParameters::TractionForce(double dt)
|
||||
|
||||
PosRatio = currentgenpower / DElist[MainCtrlPosNo].GenPower;
|
||||
// stosunek mocy teraz do mocy max
|
||||
if( ( MainCtrlPos > 0 ) && ( ConverterFlag ) ) {
|
||||
// NOTE: Mains in this context is working diesel engine
|
||||
if( ( true == Mains ) && ( MainCtrlPos > 0 ) ) {
|
||||
|
||||
if( tmpV < ( Vhyp * power / DElist[ MainCtrlPosNo ].GenPower ) ) {
|
||||
// czy na czesci prostej, czy na hiperboli
|
||||
@@ -5690,10 +5741,15 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::dizel_Update(double dt)
|
||||
{
|
||||
double const fillspeed { 2 };
|
||||
bool DU { false };
|
||||
FuelPumpCheck( dt );
|
||||
// potentially automatic engine start after fuel pump was activated
|
||||
if( ( true == Mains )
|
||||
&& ( false == FuelPump.is_active ) ) {
|
||||
// knock out the engine if the fuel pump isn't feeding it
|
||||
// TBD, TODO: grace period before the engine is starved for fuel and knocked out
|
||||
MainSwitch( false );
|
||||
}
|
||||
|
||||
// dizel_Update:=false;
|
||||
if( ( true == dizel_enginestart )
|
||||
&& ( LastSwitchingTime >= InitialCtrlDelay ) ) {
|
||||
dizel_enginestart = false;
|
||||
@@ -5707,9 +5763,12 @@ bool TMoverParameters::dizel_Update(double dt)
|
||||
DElist[ 0 ].RPM / 60.0 ) );
|
||||
}
|
||||
|
||||
bool DU { false };
|
||||
|
||||
if( EngineType == DieselEngine ) {
|
||||
dizel_EngageChange( dt );
|
||||
DU = dizel_AutoGearCheck();
|
||||
double const fillspeed { 2 };
|
||||
dizel_fill = dizel_fill + fillspeed * dt * ( dizel_fillcheck( MainCtrlPos ) - dizel_fill );
|
||||
}
|
||||
|
||||
@@ -5722,19 +5781,24 @@ bool TMoverParameters::dizel_Update(double dt)
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
{
|
||||
double realfill, nreg;
|
||||
auto realfill { 0.0 };
|
||||
|
||||
realfill = 0;
|
||||
nreg = 0;
|
||||
if (Mains && (MainCtrlPosNo > 0))
|
||||
{
|
||||
if (dizel_enginestart &&
|
||||
(LastSwitchingTime >= 0.9 * InitialCtrlDelay)) // wzbogacenie przy rozruchu
|
||||
realfill = 1;
|
||||
else
|
||||
realfill = RList[mcp].R; // napelnienie zalezne od MainCtrlPos
|
||||
if( ( true == Mains )
|
||||
&& ( MainCtrlPosNo > 0 )
|
||||
&& ( true == FuelPump.is_active ) ) {
|
||||
|
||||
if( ( true == dizel_enginestart )
|
||||
&& ( LastSwitchingTime >= 0.9 * InitialCtrlDelay ) ) {
|
||||
// wzbogacenie przy rozruchu
|
||||
realfill = 1;
|
||||
}
|
||||
else {
|
||||
// napelnienie zalezne od MainCtrlPos
|
||||
realfill = RList[ mcp ].R;
|
||||
}
|
||||
if (dizel_nmax_cutoff > 0)
|
||||
{
|
||||
auto nreg { 0.0 };
|
||||
switch (RList[MainCtrlPos].Mn)
|
||||
{
|
||||
case 0:
|
||||
@@ -5749,13 +5813,8 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
break;
|
||||
default:
|
||||
realfill = 0; // sluczaj
|
||||
break;
|
||||
}
|
||||
/*if (enrot > nreg)
|
||||
realfill = realfill * (3.9 - 3.0 * abs(enrot) / nreg);
|
||||
if (enrot > dizel_nmax_cutoff)
|
||||
realfill = realfill * (9.8 - 9.0 * abs(enrot) / dizel_nmax_cutoff);
|
||||
if (enrot < dizel_nmin)
|
||||
realfill = realfill * (1.0 + (dizel_nmin - abs(enrot)) / dizel_nmin);*/
|
||||
if (enrot > nreg) //nad predkoscia regulatora zeruj dawke
|
||||
realfill = 0;
|
||||
if (enrot < nreg) //pod predkoscia regulatora dawka zadana
|
||||
@@ -5764,11 +5823,8 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
realfill = 1;
|
||||
}
|
||||
}
|
||||
if (realfill < 0)
|
||||
realfill = 0;
|
||||
if (realfill > 1)
|
||||
realfill = 1;
|
||||
return realfill;
|
||||
|
||||
return clamp( realfill, 0.0, 1.0 );
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
@@ -5794,7 +5850,7 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
||||
Moment = -dizel_Mstand;
|
||||
}
|
||||
if( ( enrot < dizel_nmin / 10.0 )
|
||||
&& ( eAngle < PI / 2.0 ) ) {
|
||||
&& ( eAngle < M_PI_2 ) ) {
|
||||
// wstrzymywanie przy malych obrotach
|
||||
Moment -= dizel_Mstand;
|
||||
}
|
||||
@@ -7553,7 +7609,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
||||
|
||||
// converter
|
||||
{
|
||||
std::map<std::string, start> starts{
|
||||
std::map<std::string, start> starts {
|
||||
{ "Manual", start::manual },
|
||||
{ "Automatic", start::automatic }
|
||||
};
|
||||
@@ -7564,6 +7620,20 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
||||
start::manual;
|
||||
}
|
||||
extract_value( ConverterStartDelay, "ConverterStartDelay", line, "" );
|
||||
|
||||
// fuel pump
|
||||
{
|
||||
std::map<std::string, start> starts {
|
||||
{ "Manual", start::manual },
|
||||
{ "Automatic", start::automatic }
|
||||
};
|
||||
auto lookup = starts.find( extract_value( "FuelStart", line ) );
|
||||
FuelPump.start_type =
|
||||
lookup != starts.end() ?
|
||||
lookup->second :
|
||||
start::manual;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_Light( std::string const &line ) {
|
||||
@@ -8451,16 +8521,41 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
||||
OK = BrakeReleaser(Round(CValue1)); // samo się przesyła dalej
|
||||
// OK:=SendCtrlToNext(command,CValue1,CValue2); //to robiło kaskadę 2^n
|
||||
}
|
||||
else if (Command == "FuelPumpSwitch") {
|
||||
if( FuelPump.start_type == start::manual ) {
|
||||
// automatic fuel pump ignores 'manual' state commands
|
||||
FuelPump.is_enabled = ( CValue1 == 1 );
|
||||
}
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
else if (Command == "MainSwitch")
|
||||
{
|
||||
if (CValue1 == 1)
|
||||
{
|
||||
Mains = true;
|
||||
if ((EngineType == DieselEngine) && Mains)
|
||||
dizel_enginestart = true;
|
||||
if (CValue1 == 1) {
|
||||
|
||||
if( ( EngineType == DieselEngine )
|
||||
|| ( EngineType == DieselElectric ) ) {
|
||||
if( true == FuelPump.start_type == start::automatic ) {
|
||||
// potentially force start of the fuel pump
|
||||
// TODO: the whole diesel start sequence is a special kind of mess, clean it up when refactoring
|
||||
FuelPump.is_enabled = true;
|
||||
FuelPumpCheck( 0.0 );
|
||||
}
|
||||
if( true == FuelPump.is_active ) {
|
||||
Mains = true;
|
||||
dizel_enginestart = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Mains = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
Mains = false;
|
||||
else {
|
||||
Mains = false;
|
||||
if( true == FuelPump.start_type == start::automatic ) {
|
||||
// if the engine is off, switch off automatic fuel pump
|
||||
FuelPump.is_enabled = false;
|
||||
}
|
||||
}
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
else if (Command == "Direction")
|
||||
|
||||
@@ -412,6 +412,17 @@ void TBrake::ForceEmptiness()
|
||||
BrakeRes->Act();
|
||||
}
|
||||
|
||||
// removes specified amount of air from the reservoirs
|
||||
// NOTE: experimental feature, for now limited only to brake reservoir
|
||||
void TBrake::ForceLeak( double const Amount ) {
|
||||
|
||||
BrakeRes->Flow( -Amount * BrakeRes->P() );
|
||||
ValveRes->Flow( -Amount * ValveRes->P() * 0.01 ); // this reservoir has hard coded, tiny capacity compared to other parts
|
||||
|
||||
BrakeRes->Act();
|
||||
ValveRes->Act();
|
||||
}
|
||||
|
||||
//---WESTINGHOUSE---
|
||||
|
||||
void TWest::Init( double const PP, double const HPP, double const LPP, double const BP, int const BDF )
|
||||
|
||||
@@ -211,6 +211,8 @@ class TBrake {
|
||||
int GetStatus(); //flaga statusu, moze sie przydac do odglosow
|
||||
void SetASBP( double const Press ); //ustalenie cisnienia pp
|
||||
virtual void ForceEmptiness();
|
||||
// removes specified amount of air from the reservoirs
|
||||
virtual void ForceLeak( double const Amount );
|
||||
int GetSoundFlag();
|
||||
int GetBrakeStatus() const { return BrakeStatus; }
|
||||
void SetBrakeStatus( int const Status ) { BrakeStatus = Status; }
|
||||
|
||||
Reference in New Issue
Block a user