mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 12:09:18 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
11
Driver.cpp
11
Driver.cpp
@@ -2224,8 +2224,12 @@ bool TController::PrepareEngine()
|
|||||||
}
|
}
|
||||||
if (AIControllFlag) {
|
if (AIControllFlag) {
|
||||||
// część wykonawcza dla sterowania przez komputer
|
// część wykonawcza dla sterowania przez komputer
|
||||||
mvOccupied->BatterySwitch(true);
|
mvOccupied->BatterySwitch( true );
|
||||||
mvOccupied->FuelPumpSwitch( true );
|
if( ( mvOccupied->EngineType == DieselElectric )
|
||||||
|
|| ( mvOccupied->EngineType == DieselEngine ) ) {
|
||||||
|
mvOccupied->FuelPumpSwitch( true );
|
||||||
|
mvOccupied->OilPumpSwitch( true );
|
||||||
|
}
|
||||||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
||||||
{ // jeśli silnikowy jest pantografującym
|
{ // jeśli silnikowy jest pantografującym
|
||||||
mvControlling->PantFront( true );
|
mvControlling->PantFront( true );
|
||||||
@@ -2293,7 +2297,7 @@ bool TController::PrepareEngine()
|
|||||||
else if (false == mvControlling->Mains) {
|
else if (false == mvControlling->Mains) {
|
||||||
while (DecSpeed(true))
|
while (DecSpeed(true))
|
||||||
; // zerowanie napędu
|
; // zerowanie napędu
|
||||||
|
/*
|
||||||
if( ( mvOccupied->EngineType == DieselEngine )
|
if( ( mvOccupied->EngineType == DieselEngine )
|
||||||
|| ( mvOccupied->EngineType == DieselElectric ) ) {
|
|| ( mvOccupied->EngineType == DieselElectric ) ) {
|
||||||
// start helper devices before spinning up the engine
|
// start helper devices before spinning up the engine
|
||||||
@@ -2301,6 +2305,7 @@ bool TController::PrepareEngine()
|
|||||||
mvOccupied->ConverterSwitch( true );
|
mvOccupied->ConverterSwitch( true );
|
||||||
mvOccupied->CompressorSwitch( true );
|
mvOccupied->CompressorSwitch( true );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if( mvOccupied->TrainType == dt_SN61 ) {
|
if( mvOccupied->TrainType == dt_SN61 ) {
|
||||||
// specjalnie dla SN61 żeby nie zgasł
|
// specjalnie dla SN61 żeby nie zgasł
|
||||||
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) {
|
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) {
|
||||||
|
|||||||
54
DynObj.cpp
54
DynObj.cpp
@@ -4892,6 +4892,12 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
m_powertrainsounds.engine_revving.owner( this );
|
m_powertrainsounds.engine_revving.owner( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( token == "oilpump:" ) {
|
||||||
|
// plik z dzwiekiem wentylatora, mnozniki i ofsety amp. i czest.
|
||||||
|
m_powertrainsounds.oil_pump.deserialize( parser, sound_type::single );
|
||||||
|
m_powertrainsounds.oil_pump.owner( this );
|
||||||
|
}
|
||||||
|
|
||||||
else if( ( token == "tractionmotor:" )
|
else if( ( token == "tractionmotor:" )
|
||||||
&& ( MoverParameters->Power > 0 ) ) {
|
&& ( MoverParameters->Power > 0 ) ) {
|
||||||
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
|
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
|
||||||
@@ -5948,9 +5954,37 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
double frequency { 1.0 };
|
double frequency { 1.0 };
|
||||||
double volume { 0.0 };
|
double volume { 0.0 };
|
||||||
|
|
||||||
|
// oil pump
|
||||||
|
if( true == Vehicle.OilPump.is_active ) {
|
||||||
|
oil_pump
|
||||||
|
.pitch( oil_pump.m_frequencyoffset + oil_pump.m_frequencyfactor * 1.f )
|
||||||
|
.gain( oil_pump.m_amplitudeoffset + oil_pump.m_amplitudefactor * 1.f )
|
||||||
|
.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oil_pump.stop();
|
||||||
|
}
|
||||||
|
|
||||||
// engine sounds
|
// engine sounds
|
||||||
if( ( true == Vehicle.Mains )
|
// ignition
|
||||||
&& ( false == Vehicle.dizel_enginestart ) ) {
|
if( engine_state_last != Vehicle.Mains ) {
|
||||||
|
|
||||||
|
if( true == Vehicle.Mains ) {
|
||||||
|
// main circuit/engine activation
|
||||||
|
// TODO: separate engine and main circuit
|
||||||
|
engine_ignition
|
||||||
|
.pitch( engine_ignition.m_frequencyoffset + engine_ignition.m_frequencyfactor * 1.f )
|
||||||
|
.gain( engine_ignition.m_amplitudeoffset + engine_ignition.m_amplitudefactor * 1.f )
|
||||||
|
.play( sound_flags::exclusive );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// main circuit/engine deactivation
|
||||||
|
engine_ignition.stop();
|
||||||
|
}
|
||||||
|
engine_state_last = Vehicle.Mains;
|
||||||
|
}
|
||||||
|
// main engine sound
|
||||||
|
if( true == Vehicle.Mains ) {
|
||||||
|
|
||||||
if( ( std::fabs( Vehicle.enrot ) > 0.01 )
|
if( ( std::fabs( Vehicle.enrot ) > 0.01 )
|
||||||
// McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach
|
// McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach
|
||||||
@@ -6062,7 +6096,6 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
engine.stop();
|
engine.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// youBy - przenioslem, bo diesel tez moze miec turbo
|
// youBy - przenioslem, bo diesel tez moze miec turbo
|
||||||
if( Vehicle.TurboTest > 0 ) {
|
if( Vehicle.TurboTest > 0 ) {
|
||||||
// udawanie turbo:
|
// udawanie turbo:
|
||||||
@@ -6104,19 +6137,6 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// diesel startup
|
|
||||||
if( ( Vehicle.EngineType == DieselEngine )
|
|
||||||
|| ( Vehicle.EngineType == DieselElectric ) ) {
|
|
||||||
|
|
||||||
if( true == Vehicle.dizel_enginestart ) {
|
|
||||||
engine_ignition
|
|
||||||
.pitch( engine_ignition.m_frequencyoffset + engine_ignition.m_frequencyfactor * 1.f )
|
|
||||||
.gain( engine_ignition.m_amplitudeoffset + engine_ignition.m_amplitudefactor * 1.f )
|
|
||||||
.play( sound_flags::exclusive );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( Vehicle.dizel_engage > 0.1 ) {
|
if( Vehicle.dizel_engage > 0.1 ) {
|
||||||
if( std::abs( Vehicle.dizel_engagedeltaomega ) > 0.2 ) {
|
if( std::abs( Vehicle.dizel_engagedeltaomega ) > 0.2 ) {
|
||||||
frequency = rsEngageSlippery.m_frequencyoffset + rsEngageSlippery.m_frequencyfactor * std::fabs( Vehicle.dizel_engagedeltaomega );
|
frequency = rsEngageSlippery.m_frequencyoffset + rsEngageSlippery.m_frequencyfactor * std::fabs( Vehicle.dizel_engagedeltaomega );
|
||||||
@@ -6142,7 +6162,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
// motor sounds
|
// motor sounds
|
||||||
volume = 0.0;
|
volume = 0.0;
|
||||||
if( ( true == Vehicle.Mains )
|
if( ( true == Vehicle.Mains )
|
||||||
&& ( false == Vehicle.dizel_enginestart )
|
&& ( false == Vehicle.dizel_ignition )
|
||||||
&& ( false == motors.empty() ) ) {
|
&& ( false == motors.empty() ) ) {
|
||||||
|
|
||||||
if( std::fabs( Vehicle.enrot ) > 0.01 ) {
|
if( std::fabs( Vehicle.enrot ) > 0.01 ) {
|
||||||
|
|||||||
2
DynObj.h
2
DynObj.h
@@ -315,12 +315,14 @@ private:
|
|||||||
sound_source rsWentylator { sound_placement::engine }; // McZapkie-030302
|
sound_source rsWentylator { sound_placement::engine }; // McZapkie-030302
|
||||||
sound_source engine { sound_placement::engine }; // generally diesel engine
|
sound_source engine { sound_placement::engine }; // generally diesel engine
|
||||||
sound_source engine_ignition { sound_placement::engine }; // moved from cab
|
sound_source engine_ignition { sound_placement::engine }; // moved from cab
|
||||||
|
bool engine_state_last { false }; // helper, cached previous state of the engine
|
||||||
double engine_volume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
|
double engine_volume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
|
||||||
sound_source engine_revving { sound_placement::engine }; // youBy
|
sound_source engine_revving { sound_placement::engine }; // youBy
|
||||||
float engine_revs_last { -1.f }; // helper, cached rpm of the engine
|
float engine_revs_last { -1.f }; // helper, cached rpm of the engine
|
||||||
float engine_revs_change { 0.f }; // recent change in engine revolutions
|
float engine_revs_change { 0.f }; // recent change in engine revolutions
|
||||||
sound_source engine_turbo { sound_placement::engine };
|
sound_source engine_turbo { sound_placement::engine };
|
||||||
double engine_turbo_pitch { 1.0 };
|
double engine_turbo_pitch { 1.0 };
|
||||||
|
sound_source oil_pump { sound_placement::engine };
|
||||||
sound_source transmission { sound_placement::engine };
|
sound_source transmission { sound_placement::engine };
|
||||||
sound_source rsEngageSlippery { sound_placement::engine }; // moved from cab
|
sound_source rsEngageSlippery { sound_placement::engine }; // moved from cab
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ enum range {
|
|||||||
// start method for devices; exclusive
|
// start method for devices; exclusive
|
||||||
enum start {
|
enum start {
|
||||||
manual,
|
manual,
|
||||||
automatic
|
automatic,
|
||||||
|
manualwithautofallback
|
||||||
};
|
};
|
||||||
// recognized vehicle light locations and types; can be combined
|
// recognized vehicle light locations and types; can be combined
|
||||||
enum light {
|
enum light {
|
||||||
@@ -626,6 +627,19 @@ struct fuel_pump {
|
|||||||
start start_type { start::manual };
|
start start_type { start::manual };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// basic approximation of a fuel pump
|
||||||
|
// TODO: fuel consumption, optional automatic engine start after activation
|
||||||
|
struct oil_pump {
|
||||||
|
|
||||||
|
bool is_enabled { false }; // device is allowed/requested to operate
|
||||||
|
bool is_active { false }; // device is working
|
||||||
|
start start_type { start::manual };
|
||||||
|
float resource_amount { 1.f };
|
||||||
|
float pressure_minimum { 0.f }; // lowest acceptable working pressure
|
||||||
|
float pressure_target { 0.f };
|
||||||
|
float pressure_present { 0.f };
|
||||||
|
};
|
||||||
|
|
||||||
class TMoverParameters
|
class TMoverParameters
|
||||||
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
||||||
public:
|
public:
|
||||||
@@ -913,6 +927,7 @@ public:
|
|||||||
bool ConverterAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
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*/
|
bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/
|
||||||
fuel_pump FuelPump;
|
fuel_pump FuelPump;
|
||||||
|
oil_pump OilPump;
|
||||||
|
|
||||||
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
|
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
|
||||||
double BrakeCtrlPosR = 0.0; /*nastawa hamulca zespolonego - plynna dla FV4a*/
|
double BrakeCtrlPosR = 0.0; /*nastawa hamulca zespolonego - plynna dla FV4a*/
|
||||||
@@ -1010,7 +1025,8 @@ public:
|
|||||||
double dizel_engagestate = 0.0; /*sprzeglo skrzyni biegow: 0 - luz, 1 - wlaczone, 0.5 - wlaczone 50% (z poslizgiem)*/
|
double dizel_engagestate = 0.0; /*sprzeglo skrzyni biegow: 0 - luz, 1 - wlaczone, 0.5 - wlaczone 50% (z poslizgiem)*/
|
||||||
double dizel_engage = 0.0; /*sprzeglo skrzyni biegow: aktualny docisk*/
|
double dizel_engage = 0.0; /*sprzeglo skrzyni biegow: aktualny docisk*/
|
||||||
double dizel_automaticgearstatus = 0.0; /*0 - bez zmiany, -1 zmiana na nizszy +1 zmiana na wyzszy*/
|
double dizel_automaticgearstatus = 0.0; /*0 - bez zmiany, -1 zmiana na nizszy +1 zmiana na wyzszy*/
|
||||||
bool dizel_enginestart = false; /*czy trwa rozruch silnika*/
|
bool dizel_startup { false }; // engine startup procedure request indicator
|
||||||
|
bool dizel_ignition = false; // engine ignition request indicator
|
||||||
double dizel_engagedeltaomega = 0.0; /*roznica predkosci katowych tarcz sprzegla*/
|
double dizel_engagedeltaomega = 0.0; /*roznica predkosci katowych tarcz sprzegla*/
|
||||||
double dizel_n_old = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
double dizel_n_old = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
||||||
double dizel_Torque = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
double dizel_Torque = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
||||||
@@ -1200,6 +1216,7 @@ public:
|
|||||||
/*--funkcje dla lokomotyw*/
|
/*--funkcje dla lokomotyw*/
|
||||||
bool DirectionBackward(void);/*! kierunek ruchu*/
|
bool DirectionBackward(void);/*! kierunek ruchu*/
|
||||||
bool FuelPumpSwitch( bool State, int const Notify = range::consist ); // fuel pump state toggle
|
bool FuelPumpSwitch( bool State, int const Notify = range::consist ); // fuel pump state toggle
|
||||||
|
bool OilPumpSwitch( bool State, int const Notify = range::consist ); // oil pump state toggle
|
||||||
bool MainSwitch( bool const State, int const Notify = range::consist );/*! wylacznik glowny*/
|
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 ConverterSwitch( bool State, int const Notify = range::consist );/*! wl/wyl przetwornicy*/
|
||||||
bool CompressorSwitch( bool State, int const Notify = range::consist );/*! wl/wyl sprezarki*/
|
bool CompressorSwitch( bool State, int const Notify = range::consist );/*! wl/wyl sprezarki*/
|
||||||
@@ -1207,7 +1224,8 @@ public:
|
|||||||
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
||||||
void ConverterCheck( double const Timestep ); // przetwornica
|
void ConverterCheck( double const Timestep ); // przetwornica
|
||||||
void FuelPumpCheck( double const Timestep );
|
void FuelPumpCheck( double const Timestep );
|
||||||
bool FuseOn(void); //bezpiecznik nadamiary
|
void OilPumpCheck( double const Timestep );
|
||||||
|
bool FuseOn(void); //bezpiecznik nadamiary
|
||||||
bool FuseFlagCheck(void); // sprawdzanie flagi nadmiarowego
|
bool FuseFlagCheck(void); // sprawdzanie flagi nadmiarowego
|
||||||
void FuseOff(void); // wylaczenie nadmiarowego
|
void FuseOff(void); // wylaczenie nadmiarowego
|
||||||
double ShowCurrent( int AmpN ); //pokazuje bezwgl. wartosc pradu na wybranym amperomierzu
|
double ShowCurrent( int AmpN ); //pokazuje bezwgl. wartosc pradu na wybranym amperomierzu
|
||||||
@@ -1238,7 +1256,8 @@ public:
|
|||||||
bool dizel_AutoGearCheck(void);
|
bool dizel_AutoGearCheck(void);
|
||||||
double dizel_fillcheck(int mcp);
|
double dizel_fillcheck(int mcp);
|
||||||
double dizel_Momentum(double dizel_fill, double n, double dt);
|
double dizel_Momentum(double dizel_fill, double n, double dt);
|
||||||
bool dizel_Update(double dt);
|
bool dizel_StartupCheck();
|
||||||
|
bool dizel_Update(double dt);
|
||||||
|
|
||||||
/* funckje dla wagonow*/
|
/* funckje dla wagonow*/
|
||||||
bool LoadingDone(double LSpeed, std::string LoadInit);
|
bool LoadingDone(double LSpeed, std::string LoadInit);
|
||||||
|
|||||||
@@ -1552,6 +1552,10 @@ double TMoverParameters::ShowEngineRotation(int VehN)
|
|||||||
// sprawdzanie przetwornicy
|
// sprawdzanie przetwornicy
|
||||||
void TMoverParameters::ConverterCheck( double const Timestep ) {
|
void TMoverParameters::ConverterCheck( double const Timestep ) {
|
||||||
// TODO: move other converter checks here, to have it all in one place for potential device object
|
// TODO: move other converter checks here, to have it all in one place for potential device object
|
||||||
|
if( ConverterStart == start::automatic ) {
|
||||||
|
ConverterAllow = Mains;
|
||||||
|
}
|
||||||
|
|
||||||
if( ( ConverterAllow )
|
if( ( ConverterAllow )
|
||||||
&& ( ConverterAllowLocal )
|
&& ( ConverterAllowLocal )
|
||||||
&& ( false == PantPressLockActive )
|
&& ( false == PantPressLockActive )
|
||||||
@@ -1573,11 +1577,56 @@ void TMoverParameters::ConverterCheck( double const Timestep ) {
|
|||||||
// fuel pump status update
|
// fuel pump status update
|
||||||
void TMoverParameters::FuelPumpCheck( double const Timestep ) {
|
void TMoverParameters::FuelPumpCheck( double const Timestep ) {
|
||||||
|
|
||||||
|
if( FuelPump.start_type == start::automatic ) {
|
||||||
|
FuelPump.is_enabled = ( dizel_startup || Mains );
|
||||||
|
}
|
||||||
FuelPump.is_active = (
|
FuelPump.is_active = (
|
||||||
( true == FuelPump.is_enabled )
|
( true == FuelPump.is_enabled )
|
||||||
&& ( true == Battery ) );
|
&& ( true == Battery ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// oil pump status update
|
||||||
|
void TMoverParameters::OilPumpCheck( double const Timestep ) {
|
||||||
|
|
||||||
|
OilPump.is_active =
|
||||||
|
( ( true == Battery )
|
||||||
|
&& ( OilPump.start_type == start::manual ? ( OilPump.is_enabled ) :
|
||||||
|
OilPump.start_type == start::automatic ? ( dizel_startup || Mains ) :
|
||||||
|
OilPump.start_type == start::manualwithautofallback ? ( OilPump.is_enabled || dizel_startup || Mains ) :
|
||||||
|
false ) ); // shouldn't ever get this far but, eh
|
||||||
|
|
||||||
|
auto const maxrevolutions {
|
||||||
|
EngineType == DieselEngine ?
|
||||||
|
dizel_nmax :
|
||||||
|
DElist[ MainCtrlPosNo ].RPM / 60.0 };
|
||||||
|
auto const minpressure {
|
||||||
|
OilPump.pressure_minimum > 0.f ?
|
||||||
|
OilPump.pressure_minimum :
|
||||||
|
0.1f }; // arbitrary fallback value
|
||||||
|
auto const maxpressure { 0.65f }; // arbitrary value
|
||||||
|
|
||||||
|
OilPump.pressure_target = (
|
||||||
|
false == OilPump.is_active ? 0.f :
|
||||||
|
enrot > 0.1 ? std::max<float>( minpressure, maxpressure * clamp( enrot / maxrevolutions, 0.0, 1.0 ) ) * OilPump.resource_amount :
|
||||||
|
minpressure );
|
||||||
|
|
||||||
|
if( OilPump.pressure_present < OilPump.pressure_target ) {
|
||||||
|
// TODO: scale change rate from 0.01-0.05 with oil/engine temperature/idle time
|
||||||
|
OilPump.pressure_present =
|
||||||
|
std::min<float>(
|
||||||
|
OilPump.pressure_target,
|
||||||
|
OilPump.pressure_present + ( enrot > 5.0 ? 0.05 : 0.035 ) * Timestep );
|
||||||
|
}
|
||||||
|
if( OilPump.pressure_present > OilPump.pressure_target ) {
|
||||||
|
OilPump.pressure_present =
|
||||||
|
std::max<float>(
|
||||||
|
OilPump.pressure_target,
|
||||||
|
OilPump.pressure_present - 0.01 * Timestep );
|
||||||
|
}
|
||||||
|
OilPump.pressure_present = clamp( OilPump.pressure_present, 0.f, 1.5f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double TMoverParameters::ShowCurrent(int AmpN)
|
double TMoverParameters::ShowCurrent(int AmpN)
|
||||||
{ // Odczyt poboru prądu na podanym amperomierzu
|
{ // Odczyt poboru prądu na podanym amperomierzu
|
||||||
switch (EngineType)
|
switch (EngineType)
|
||||||
@@ -2370,13 +2419,38 @@ bool TMoverParameters::FuelPumpSwitch( bool State, int const Notify ) {
|
|||||||
return ( FuelPump.is_enabled != initialstate );
|
return ( FuelPump.is_enabled != initialstate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// oil pump state toggle
|
||||||
|
bool TMoverParameters::OilPumpSwitch( bool State, int const Notify ) {
|
||||||
|
|
||||||
|
if( OilPump.start_type == start::automatic ) {
|
||||||
|
// automatic pump ignores 'manual' state commands
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool const initialstate { OilPump.is_enabled };
|
||||||
|
|
||||||
|
OilPump.is_enabled = State;
|
||||||
|
|
||||||
|
if( Notify != range::local ) {
|
||||||
|
SendCtrlToNext(
|
||||||
|
"OilPumpSwitch",
|
||||||
|
( OilPump.is_enabled ? 1 : 0 ),
|
||||||
|
CabNo,
|
||||||
|
( Notify == range::unit ?
|
||||||
|
coupling::control | coupling::permanent :
|
||||||
|
coupling::control ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( OilPump.is_enabled != initialstate );
|
||||||
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Q: 20160713
|
// Q: 20160713
|
||||||
// włączenie / wyłączenie obwodu głownego
|
// włączenie / wyłączenie obwodu głownego
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
||||||
{
|
{
|
||||||
bool const initialstate { Mains };
|
bool const initialstate { Mains || dizel_startup };
|
||||||
|
|
||||||
if( ( Mains != State )
|
if( ( Mains != State )
|
||||||
&& ( MainCtrlPosNo > 0 ) ) {
|
&& ( MainCtrlPosNo > 0 ) ) {
|
||||||
@@ -2392,17 +2466,8 @@ bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
|||||||
// switch on
|
// switch on
|
||||||
if( ( EngineType == DieselEngine )
|
if( ( EngineType == DieselEngine )
|
||||||
|| ( EngineType == DieselElectric ) ) {
|
|| ( EngineType == DieselElectric ) ) {
|
||||||
|
// launch diesel engine startup procedure
|
||||||
if( true == FuelPump.start_type == start::automatic ) {
|
dizel_startup = true;
|
||||||
// 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 {
|
else {
|
||||||
Mains = true;
|
Mains = true;
|
||||||
@@ -2410,10 +2475,6 @@ bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Mains = false;
|
Mains = false;
|
||||||
if( true == FuelPump.start_type == start::automatic ) {
|
|
||||||
// if the engine is off, switch off automatic fuel pump
|
|
||||||
FuelPump.is_enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( TrainType == dt_EZT )
|
if( ( TrainType == dt_EZT )
|
||||||
@@ -2436,11 +2497,10 @@ bool TMoverParameters::MainSwitch( bool const State, int const Notify )
|
|||||||
coupling::control | coupling::permanent :
|
coupling::control | coupling::permanent :
|
||||||
coupling::control ) );
|
coupling::control ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else MainSwitch:=false;
|
|
||||||
return ( Mains != initialstate );
|
return ( ( Mains || dizel_startup ) != initialstate );
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
@@ -2455,8 +2515,6 @@ bool TMoverParameters::ConverterSwitch( bool State, int const Notify )
|
|||||||
{
|
{
|
||||||
ConverterAllow = State;
|
ConverterAllow = State;
|
||||||
CS = true;
|
CS = true;
|
||||||
if (CompressorPower == 2)
|
|
||||||
CompressorAllow = ConverterAllow;
|
|
||||||
}
|
}
|
||||||
if( ConverterAllow == true ) {
|
if( ConverterAllow == true ) {
|
||||||
if( Notify != range::local ) {
|
if( Notify != range::local ) {
|
||||||
@@ -2486,11 +2544,13 @@ bool TMoverParameters::ConverterSwitch( bool State, int const Notify )
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
bool TMoverParameters::CompressorSwitch( bool State, int const Notify )
|
bool TMoverParameters::CompressorSwitch( bool State, int const Notify )
|
||||||
{
|
{
|
||||||
|
if( CompressorPower > 1 ) {
|
||||||
|
// only pay attention if the compressor can be controlled manually
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CS = false; // Ra: normalnie chyba tak?
|
bool CS = false; // Ra: normalnie chyba tak?
|
||||||
// if State=true then
|
if ( CompressorAllow != State )
|
||||||
// if ((CompressorPower=2) and (not ConverterAllow)) then
|
|
||||||
// State:=false; //yB: to juz niepotrzebne
|
|
||||||
if ((CompressorAllow != State) && (CompressorPower < 2))
|
|
||||||
{
|
{
|
||||||
CompressorAllow = State;
|
CompressorAllow = State;
|
||||||
CS = true;
|
CS = true;
|
||||||
@@ -3092,6 +3152,10 @@ void TMoverParameters::CompressorCheck(double dt)
|
|||||||
CompressorGovernorLock = false;
|
CompressorGovernorLock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( CompressorPower == 2 ) {
|
||||||
|
CompressorAllow = ConverterAllow;
|
||||||
|
}
|
||||||
|
|
||||||
if (MaxCompressor - MinCompressor < 0.0001) {
|
if (MaxCompressor - MinCompressor < 0.0001) {
|
||||||
// TODO: investigate purpose of this branch and whether it can be removed as it duplicates later code
|
// TODO: investigate purpose of this branch and whether it can be removed as it duplicates later code
|
||||||
if( ( true == CompressorAllow )
|
if( ( true == CompressorAllow )
|
||||||
@@ -3122,10 +3186,7 @@ void TMoverParameters::CompressorCheck(double dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( ( ( CompressorPower == 0 )
|
if( CompressorPower == 3 ) {
|
||||||
|| ( CompressorPower == 3 ) )
|
|
||||||
&& ( ( EngineType == DieselEngine )
|
|
||||||
|| ( EngineType == DieselElectric ) ) ) {
|
|
||||||
// experimental: make sure compressor coupled with diesel engine is always ready for work
|
// experimental: make sure compressor coupled with diesel engine is always ready for work
|
||||||
CompressorAllow = true;
|
CompressorAllow = true;
|
||||||
}
|
}
|
||||||
@@ -3165,10 +3226,7 @@ void TMoverParameters::CompressorCheck(double dt)
|
|||||||
if( Compressor > MaxCompressor ) {
|
if( Compressor > MaxCompressor ) {
|
||||||
// wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
|
// wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
|
||||||
// TBD, TODO: don't operate the lock without battery power?
|
// TBD, TODO: don't operate the lock without battery power?
|
||||||
if( ( ( CompressorPower == 0 )
|
if( CompressorPower == 3 ) {
|
||||||
|| ( CompressorPower == 3 ) )
|
|
||||||
&& ( ( EngineType == DieselEngine )
|
|
||||||
|| ( EngineType == DieselElectric ) ) ) {
|
|
||||||
// if the compressor is powered directly by the engine the lock can't turn it off and instead just changes the output
|
// if the compressor is powered directly by the engine the lock can't turn it off and instead just changes the output
|
||||||
if( false == CompressorGovernorLock ) {
|
if( false == CompressorGovernorLock ) {
|
||||||
// emit relay sound when the lock engages (the state change itself is below) and presumably changes where the air goes
|
// emit relay sound when the lock engages (the state change itself is below) and presumably changes where the air goes
|
||||||
@@ -3268,42 +3326,29 @@ void TMoverParameters::CompressorCheck(double dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( CompressorFlag ) {
|
if( CompressorFlag ) {
|
||||||
if( ( EngineType == DieselElectric )
|
// working compressor adds air to the air reservoir
|
||||||
&& ( ( CompressorPower == 0 )
|
if( CompressorPower == 3 ) {
|
||||||
|| ( CompressorPower == 3 ) ) ) {
|
// the compressor is coupled with the diesel engine, engine revolutions affect the output
|
||||||
if( false == CompressorGovernorLock ) {
|
if( false == CompressorGovernorLock ) {
|
||||||
|
auto const enginefactor { (
|
||||||
|
EngineType == DieselElectric ? ( DElist[ MainCtrlPos ].RPM / DElist[ MainCtrlPosNo ].RPM ) :
|
||||||
|
EngineType == DieselEngine ? ( std::abs( enrot ) / nmax ) :
|
||||||
|
1.0 ) }; // shouldn't ever get here but, eh
|
||||||
CompressedVolume +=
|
CompressedVolume +=
|
||||||
CompressorSpeed
|
CompressorSpeed
|
||||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||||
* ( DElist[ MainCtrlPos ].RPM / DElist[ MainCtrlPosNo ].RPM )
|
* enginefactor
|
||||||
* dt;
|
* dt;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
else {
|
else {
|
||||||
// the lock is active, air is being vented out
|
// the lock is active, air is being vented out at arbitrary rate
|
||||||
CompressedVolume -= 0.1 * dt;
|
CompressedVolume -= 0.01 * dt;
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else if( ( EngineType == DieselEngine )
|
|
||||||
&& ( ( CompressorPower == 0 )
|
|
||||||
|| ( CompressorPower == 3 ) ) ) {
|
|
||||||
if( false == CompressorGovernorLock ) {
|
|
||||||
// experimental: compressor coupled with diesel engine, output scaled by current engine rotational speed
|
|
||||||
CompressedVolume +=
|
|
||||||
CompressorSpeed
|
|
||||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
|
||||||
* ( std::abs( enrot ) / nmax )
|
|
||||||
* dt;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else {
|
|
||||||
// the lock is active, air is being vented out
|
|
||||||
CompressedVolume -= 0.1 * dt;
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// the compressor is a stand-alone device, working at steady pace
|
||||||
CompressedVolume +=
|
CompressedVolume +=
|
||||||
CompressorSpeed
|
CompressorSpeed
|
||||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||||
@@ -5778,32 +5823,67 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// performs diesel engine startup procedure; potentially clears startup switch; returns: true if the engine can be started, false otherwise
|
||||||
|
bool TMoverParameters::dizel_StartupCheck() {
|
||||||
|
|
||||||
|
auto engineisready { true }; // make inital optimistic presumption, then watch the reality crush it
|
||||||
|
|
||||||
|
// test the fuel pump
|
||||||
|
if( false == FuelPump.is_active ) {
|
||||||
|
engineisready = false;
|
||||||
|
if( FuelPump.start_type == start::manual ) {
|
||||||
|
// with manual pump control startup procedure is done only once per starter switch press
|
||||||
|
dizel_startup = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// test the oil pump
|
||||||
|
if( ( false == OilPump.is_active )
|
||||||
|
|| ( OilPump.pressure_present < OilPump.pressure_minimum ) ) {
|
||||||
|
engineisready = false;
|
||||||
|
if( OilPump.start_type == start::manual ) {
|
||||||
|
// with manual pump control startup procedure is done only once per starter switch press
|
||||||
|
dizel_startup = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return engineisready;
|
||||||
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Q: 20160715
|
// Q: 20160715
|
||||||
// Aktualizacja stanu silnika
|
// Aktualizacja stanu silnika
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
bool TMoverParameters::dizel_Update(double dt)
|
bool TMoverParameters::dizel_Update(double dt) {
|
||||||
{
|
|
||||||
|
OilPumpCheck( dt );
|
||||||
FuelPumpCheck( dt );
|
FuelPumpCheck( dt );
|
||||||
// potentially automatic engine start after fuel pump was activated
|
if( ( true == dizel_startup )
|
||||||
if( ( true == Mains )
|
&& ( true == dizel_StartupCheck() ) ) {
|
||||||
&& ( false == FuelPump.is_active ) ) {
|
dizel_ignition = true;
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( true == dizel_enginestart )
|
if( ( true == dizel_ignition )
|
||||||
&& ( LastSwitchingTime >= InitialCtrlDelay ) ) {
|
&& ( LastSwitchingTime >= InitialCtrlDelay ) ) {
|
||||||
dizel_enginestart = false;
|
|
||||||
LastSwitchingTime = 0;
|
|
||||||
|
|
||||||
|
dizel_startup = false;
|
||||||
|
dizel_ignition = false;
|
||||||
|
// TODO: split engine and main circuit state indicator in two separate flags
|
||||||
|
Mains = true;
|
||||||
|
LastSwitchingTime = 0;
|
||||||
enrot = std::max(
|
enrot = std::max(
|
||||||
enrot,
|
enrot,
|
||||||
0.35 * ( // TODO: dac zaleznie od temperatury i baterii
|
0.35 * ( // TODO: dac zaleznie od temperatury i baterii
|
||||||
EngineType == DieselEngine ?
|
EngineType == DieselEngine ?
|
||||||
dizel_nmin :
|
dizel_nmin :
|
||||||
DElist[ 0 ].RPM / 60.0 ) );
|
DElist[ 0 ].RPM / 60.0 ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DU { false };
|
bool DU { false };
|
||||||
@@ -5830,9 +5910,11 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
|||||||
&& ( MainCtrlPosNo > 0 )
|
&& ( MainCtrlPosNo > 0 )
|
||||||
&& ( true == FuelPump.is_active ) ) {
|
&& ( true == FuelPump.is_active ) ) {
|
||||||
|
|
||||||
if( ( true == dizel_enginestart )
|
if( ( true == dizel_ignition )
|
||||||
&& ( LastSwitchingTime >= 0.9 * InitialCtrlDelay ) ) {
|
&& ( LastSwitchingTime >= 0.9 * InitialCtrlDelay ) ) {
|
||||||
// wzbogacenie przy rozruchu
|
// wzbogacenie przy rozruchu
|
||||||
|
// NOTE: ignition flag is reset before this code is executed
|
||||||
|
// TODO: sort this out
|
||||||
realfill = 1;
|
realfill = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -5897,7 +5979,7 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
// wstrzymywanie przy malych obrotach
|
// wstrzymywanie przy malych obrotach
|
||||||
Moment -= dizel_Mstand;
|
Moment -= dizel_Mstand;
|
||||||
}
|
}
|
||||||
if (true == dizel_enginestart)
|
if (true == dizel_ignition)
|
||||||
Moment += dizel_Mstand / (0.3 + std::max(0.0, enrot/dizel_nmin)); //rozrusznik
|
Moment += dizel_Mstand / (0.3 + std::max(0.0, enrot/dizel_nmin)); //rozrusznik
|
||||||
|
|
||||||
dizel_Torque = Moment;
|
dizel_Torque = Moment;
|
||||||
@@ -6008,7 +6090,7 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((enrot <= 0) && (!dizel_enginestart))
|
if ((enrot <= 0) && (!dizel_ignition))
|
||||||
{
|
{
|
||||||
Mains = false;
|
Mains = false;
|
||||||
enrot = 0;
|
enrot = 0;
|
||||||
@@ -7678,6 +7760,19 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
start::manual;
|
start::manual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// oil pump
|
||||||
|
{
|
||||||
|
std::map<std::string, start> starts {
|
||||||
|
{ "Manual", start::manual },
|
||||||
|
{ "Automatic", start::automatic },
|
||||||
|
{ "Mixed", start::manualwithautofallback }
|
||||||
|
};
|
||||||
|
auto lookup = starts.find( extract_value( "OilStart", line ) );
|
||||||
|
OilPump.start_type =
|
||||||
|
lookup != starts.end() ?
|
||||||
|
lookup->second :
|
||||||
|
start::manual;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Light( std::string const &line ) {
|
void TMoverParameters::LoadFIZ_Light( std::string const &line ) {
|
||||||
@@ -7831,6 +7926,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
extract_value( OilPump.pressure_minimum, "MinOilPressure", Input, "" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DieselElectric: { //youBy
|
case DieselElectric: { //youBy
|
||||||
@@ -7851,6 +7947,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
ImaxHi = 2;
|
ImaxHi = 2;
|
||||||
ImaxLo = 1;
|
ImaxLo = 1;
|
||||||
}
|
}
|
||||||
|
extract_value( OilPump.pressure_minimum, "OilMinPressure", Input, "" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ElectricInductionMotor: {
|
case ElectricInductionMotor: {
|
||||||
@@ -8130,6 +8227,13 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
|||||||
|
|
||||||
Sand = SandCapacity;
|
Sand = SandCapacity;
|
||||||
|
|
||||||
|
// NOTE: for diesel-powered vehicles we automatically convert legacy "main" power source to more accurate "engine"
|
||||||
|
if( ( CompressorPower == 0 )
|
||||||
|
&& ( ( EngineType == DieselEngine )
|
||||||
|
|| ( EngineType == DieselElectric ) ) ) {
|
||||||
|
CompressorPower = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// WriteLog("aa = " + AxleArangement + " " + std::string( Pos("o", AxleArangement)) );
|
// WriteLog("aa = " + AxleArangement + " " + std::string( Pos("o", AxleArangement)) );
|
||||||
|
|
||||||
if( ( AxleArangement.find( "o" ) != std::string::npos ) && ( EngineType == ElectricSeriesMotor ) ) {
|
if( ( AxleArangement.find( "o" ) != std::string::npos ) && ( EngineType == ElectricSeriesMotor ) ) {
|
||||||
@@ -8572,22 +8676,20 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
}
|
}
|
||||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
}
|
}
|
||||||
|
else if (Command == "OilPumpSwitch") {
|
||||||
|
if( OilPump.start_type == start::manual ) {
|
||||||
|
// automatic pump ignores 'manual' state commands
|
||||||
|
OilPump.is_enabled = ( CValue1 == 1 );
|
||||||
|
}
|
||||||
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
|
}
|
||||||
else if (Command == "MainSwitch")
|
else if (Command == "MainSwitch")
|
||||||
{
|
{
|
||||||
if (CValue1 == 1) {
|
if (CValue1 == 1) {
|
||||||
|
|
||||||
if( ( EngineType == DieselEngine )
|
if( ( EngineType == DieselEngine )
|
||||||
|| ( EngineType == DieselElectric ) ) {
|
|| ( EngineType == DieselElectric ) ) {
|
||||||
if( true == FuelPump.start_type == start::automatic ) {
|
dizel_startup = true;
|
||||||
// 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 {
|
else {
|
||||||
Mains = true;
|
Mains = true;
|
||||||
@@ -8595,10 +8697,6 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Mains = false;
|
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 );
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
}
|
}
|
||||||
|
|||||||
88
Train.cpp
88
Train.cpp
@@ -226,6 +226,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
|||||||
{ user_command::fuelpumptoggle, &TTrain::OnCommand_fuelpumptoggle },
|
{ user_command::fuelpumptoggle, &TTrain::OnCommand_fuelpumptoggle },
|
||||||
{ user_command::fuelpumpenable, &TTrain::OnCommand_fuelpumpenable },
|
{ user_command::fuelpumpenable, &TTrain::OnCommand_fuelpumpenable },
|
||||||
{ user_command::fuelpumpdisable, &TTrain::OnCommand_fuelpumpdisable },
|
{ user_command::fuelpumpdisable, &TTrain::OnCommand_fuelpumpdisable },
|
||||||
|
{ user_command::oilpumptoggle, &TTrain::OnCommand_oilpumptoggle },
|
||||||
|
{ user_command::oilpumpenable, &TTrain::OnCommand_oilpumpenable },
|
||||||
|
{ user_command::oilpumpdisable, &TTrain::OnCommand_oilpumpdisable },
|
||||||
{ user_command::convertertoggle, &TTrain::OnCommand_convertertoggle },
|
{ user_command::convertertoggle, &TTrain::OnCommand_convertertoggle },
|
||||||
{ user_command::converterenable, &TTrain::OnCommand_converterenable },
|
{ user_command::converterenable, &TTrain::OnCommand_converterenable },
|
||||||
{ user_command::converterdisable, &TTrain::OnCommand_converterdisable },
|
{ user_command::converterdisable, &TTrain::OnCommand_converterdisable },
|
||||||
@@ -1978,17 +1981,15 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
|
|||||||
|
|
||||||
if( Train->m_linebreakerstate == 1 ) { return; } // already in the desired state
|
if( Train->m_linebreakerstate == 1 ) { return; } // already in the desired state
|
||||||
|
|
||||||
if( Train->m_linebreakerstate > 1 ) {
|
if( Train->m_linebreakerstate == 2 ) {
|
||||||
// we don't need to start the diesel twice, but the other types (with impulse switch setup) still need to be launched
|
// we don't need to start the diesel twice, but the other types (with impulse switch setup) still need to be launched
|
||||||
if( ( Train->mvControlled->EngineType != DieselEngine )
|
if( ( Train->mvControlled->EngineType != DieselEngine )
|
||||||
&& ( Train->mvControlled->EngineType != DieselElectric ) ) {
|
&& ( Train->mvControlled->EngineType != DieselElectric ) ) {
|
||||||
if( Train->mvControlled->MainSwitch( true ) ) {
|
// try to finalize state change of the line breaker, set the state based on the outcome
|
||||||
// side-effects
|
Train->m_linebreakerstate = (
|
||||||
Train->mvControlled->ConverterSwitch( ( Train->ggConverterButton.GetValue() > 0.5 ) || ( Train->mvControlled->ConverterStart == start::automatic ) );
|
Train->mvControlled->MainSwitch( true ) ?
|
||||||
Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 );
|
1 :
|
||||||
// finalize state change of the line breaker
|
0 );
|
||||||
Train->m_linebreakerstate = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// on button release reset the closing timer
|
// on button release reset the closing timer
|
||||||
@@ -2035,6 +2036,45 @@ void TTrain::OnCommand_fuelpumpdisable( TTrain *Train, command_data const &Comma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_oilpumptoggle( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||||
|
if( false == Train->mvControlled->OilPump.is_enabled ) {
|
||||||
|
// turn on
|
||||||
|
OnCommand_oilpumpenable( Train, Command );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//turn off
|
||||||
|
OnCommand_oilpumpdisable( Train, Command );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_oilpumpenable( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
// visual feedback
|
||||||
|
Train->ggOilPumpButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
|
||||||
|
if( true == Train->mvControlled->OilPump.is_enabled ) { return; } // already enabled
|
||||||
|
|
||||||
|
Train->mvControlled->OilPumpSwitch( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_oilpumpdisable( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
// visual feedback
|
||||||
|
Train->ggOilPumpButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
|
||||||
|
if( false == Train->mvControlled->OilPump.is_enabled ) { return; } // already disabled
|
||||||
|
|
||||||
|
Train->mvControlled->OilPumpSwitch( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
@@ -3937,20 +3977,14 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
}
|
}
|
||||||
if( m_linebreakerstate == 2 ) {
|
if( m_linebreakerstate == 2 ) {
|
||||||
// for diesels and/or vehicles with toggle switch setup we complete the engine start here
|
// for diesels and/or vehicles with toggle switch setup we complete the engine start here
|
||||||
// TBD, TODO: arrange a better way to start the diesel engines
|
|
||||||
if( ( ggMainOnButton.SubModel == nullptr )
|
if( ( ggMainOnButton.SubModel == nullptr )
|
||||||
|| ( ( mvControlled->EngineType == DieselEngine )
|
|| ( ( mvControlled->EngineType == DieselEngine )
|
||||||
|| ( mvControlled->EngineType == DieselElectric ) ) ) {
|
|| ( mvControlled->EngineType == DieselElectric ) ) ) {
|
||||||
if( mvControlled->MainSwitch( true ) ) {
|
// try to finalize state change of the line breaker, set the state based on the outcome
|
||||||
// side-effects
|
m_linebreakerstate = (
|
||||||
mvControlled->ConverterSwitch( ( ggConverterButton.GetDesiredValue() > 0.95 ) || ( mvControlled->ConverterStart == start::automatic ) );
|
mvControlled->MainSwitch( true ) ?
|
||||||
mvControlled->CompressorSwitch( ggCompressorButton.GetDesiredValue() > 0.95 );
|
1 :
|
||||||
// finalize state change of the line breaker
|
0 );
|
||||||
m_linebreakerstate = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_linebreakerstate = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4367,7 +4401,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
}
|
}
|
||||||
if (ggIgnitionKey.SubModel)
|
if (ggIgnitionKey.SubModel)
|
||||||
{
|
{
|
||||||
ggIgnitionKey.UpdateValue(mvControlled->dizel_enginestart);
|
ggIgnitionKey.UpdateValue(mvControlled->dizel_startup);
|
||||||
ggIgnitionKey.Update();
|
ggIgnitionKey.Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4933,6 +4967,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggBatteryButton.Update();
|
ggBatteryButton.Update();
|
||||||
|
|
||||||
ggFuelPumpButton.Update();
|
ggFuelPumpButton.Update();
|
||||||
|
ggOilPumpButton.Update();
|
||||||
//------
|
//------
|
||||||
pyScreens.update();
|
pyScreens.update();
|
||||||
}
|
}
|
||||||
@@ -5985,6 +6020,7 @@ void TTrain::clear_cab_controls()
|
|||||||
ggIgnitionKey.Clear();
|
ggIgnitionKey.Clear();
|
||||||
|
|
||||||
ggFuelPumpButton.Clear();
|
ggFuelPumpButton.Clear();
|
||||||
|
ggOilPumpButton.Clear();
|
||||||
|
|
||||||
btLampkaPrzetw.Clear();
|
btLampkaPrzetw.Clear();
|
||||||
btLampkaPrzetwB.Clear();
|
btLampkaPrzetwB.Clear();
|
||||||
@@ -6255,6 +6291,11 @@ void TTrain::set_cab_controls() {
|
|||||||
mvOccupied->FuelPump.is_enabled ?
|
mvOccupied->FuelPump.is_enabled ?
|
||||||
1.0 :
|
1.0 :
|
||||||
0.0 );
|
0.0 );
|
||||||
|
// oil pump
|
||||||
|
ggOilPumpButton.PutValue(
|
||||||
|
mvOccupied->OilPump.is_enabled ?
|
||||||
|
1.0 :
|
||||||
|
0.0 );
|
||||||
|
|
||||||
// we reset all indicators, as they're set during the update pass
|
// we reset all indicators, as they're set during the update pass
|
||||||
// TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it
|
// TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it
|
||||||
@@ -6420,6 +6461,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "converteroff_sw:", ggConverterOffButton },
|
{ "converteroff_sw:", ggConverterOffButton },
|
||||||
{ "main_sw:", ggMainButton },
|
{ "main_sw:", ggMainButton },
|
||||||
{ "fuelpump_sw:", ggFuelPumpButton },
|
{ "fuelpump_sw:", ggFuelPumpButton },
|
||||||
|
{ "oilpump_sw:", ggOilPumpButton },
|
||||||
{ "radio_sw:", ggRadioButton },
|
{ "radio_sw:", ggRadioButton },
|
||||||
{ "radiochannel_sw:", ggRadioChannelSelector },
|
{ "radiochannel_sw:", ggRadioChannelSelector },
|
||||||
{ "radiochannelprev_sw:", ggRadioChannelPrevious },
|
{ "radiochannelprev_sw:", ggRadioChannelPrevious },
|
||||||
@@ -6579,6 +6621,12 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
gauge.Load(Parser, DynamicObject, DynamicObject->mdKabina, nullptr, 0.1);
|
gauge.Load(Parser, DynamicObject, DynamicObject->mdKabina, nullptr, 0.1);
|
||||||
gauge.AssignDouble(&mvOccupied->Compressor);
|
gauge.AssignDouble(&mvOccupied->Compressor);
|
||||||
}
|
}
|
||||||
|
else if( Label == "oilpress:" ) {
|
||||||
|
// oil pressure
|
||||||
|
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka
|
||||||
|
gauge.Load( Parser, DynamicObject, DynamicObject->mdKabina, nullptr );
|
||||||
|
gauge.AssignFloat( &mvOccupied->OilPump.pressure_present );
|
||||||
|
}
|
||||||
// yB - dla drugiej sekcji
|
// yB - dla drugiej sekcji
|
||||||
else if (Label == "hvbcurrent1:")
|
else if (Label == "hvbcurrent1:")
|
||||||
{
|
{
|
||||||
|
|||||||
4
Train.h
4
Train.h
@@ -218,6 +218,9 @@ class TTrain
|
|||||||
static void OnCommand_fuelpumptoggle( TTrain *Train, command_data const &Command );
|
static void OnCommand_fuelpumptoggle( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_fuelpumpenable( TTrain *Train, command_data const &Command );
|
static void OnCommand_fuelpumpenable( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_fuelpumpdisable( TTrain *Train, command_data const &Command );
|
static void OnCommand_fuelpumpdisable( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_oilpumptoggle( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_oilpumpenable( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_oilpumpdisable( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
|
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_converterenable( TTrain *Train, command_data const &Command );
|
static void OnCommand_converterenable( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_converterdisable( TTrain *Train, command_data const &Command );
|
static void OnCommand_converterdisable( TTrain *Train, command_data const &Command );
|
||||||
@@ -408,6 +411,7 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggDoorSignallingButton;
|
TGauge ggDoorSignallingButton;
|
||||||
|
|
||||||
TGauge ggFuelPumpButton; // fuel pump switch
|
TGauge ggFuelPumpButton; // fuel pump switch
|
||||||
|
TGauge ggOilPumpButton; // fuel pump switch
|
||||||
|
|
||||||
TButton btLampkaPoslizg;
|
TButton btLampkaPoslizg;
|
||||||
TButton btLampkaStyczn;
|
TButton btLampkaStyczn;
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{ "fuelpumptoggle", command_target::vehicle },
|
{ "fuelpumptoggle", command_target::vehicle },
|
||||||
{ "fuelpumpenable", command_target::vehicle },
|
{ "fuelpumpenable", command_target::vehicle },
|
||||||
{ "fuelpumpdisable", command_target::vehicle },
|
{ "fuelpumpdisable", command_target::vehicle },
|
||||||
|
{ "oilpumptoggle", command_target::vehicle },
|
||||||
|
{ "oilpumpenable", command_target::vehicle },
|
||||||
|
{ "oilpumpdisable", command_target::vehicle },
|
||||||
{ "linebreakertoggle", command_target::vehicle },
|
{ "linebreakertoggle", command_target::vehicle },
|
||||||
{ "linebreakeropen", command_target::vehicle },
|
{ "linebreakeropen", command_target::vehicle },
|
||||||
{ "linebreakerclose", command_target::vehicle },
|
{ "linebreakerclose", command_target::vehicle },
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ enum class user_command {
|
|||||||
fuelpumptoggle,
|
fuelpumptoggle,
|
||||||
fuelpumpenable,
|
fuelpumpenable,
|
||||||
fuelpumpdisable,
|
fuelpumpdisable,
|
||||||
|
oilpumptoggle,
|
||||||
|
oilpumpenable,
|
||||||
|
oilpumpdisable,
|
||||||
linebreakertoggle,
|
linebreakertoggle,
|
||||||
linebreakeropen,
|
linebreakeropen,
|
||||||
linebreakerclose,
|
linebreakerclose,
|
||||||
|
|||||||
@@ -261,6 +261,12 @@ keyboard_input::default_bindings() {
|
|||||||
{ -1 },
|
{ -1 },
|
||||||
// fuelpumpdisable,
|
// fuelpumpdisable,
|
||||||
{ -1 },
|
{ -1 },
|
||||||
|
// oilpumptoggle
|
||||||
|
{ GLFW_KEY_F | keymodifier::shift },
|
||||||
|
// oilpumpenable,
|
||||||
|
{ -1 },
|
||||||
|
// oilpumpdisable,
|
||||||
|
{ -1 },
|
||||||
// linebreakertoggle
|
// linebreakertoggle
|
||||||
{ GLFW_KEY_M },
|
{ GLFW_KEY_M },
|
||||||
// linebreakeropen
|
// linebreakeropen
|
||||||
|
|||||||
@@ -246,6 +246,9 @@ mouse_input::default_bindings() {
|
|||||||
{ "fuelpump_sw:", {
|
{ "fuelpump_sw:", {
|
||||||
user_command::fuelpumptoggle,
|
user_command::fuelpumptoggle,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
{ "oilpump_sw:", {
|
||||||
|
user_command::oilpumptoggle,
|
||||||
|
user_command::none } },
|
||||||
{ "main_off_bt:", {
|
{ "main_off_bt:", {
|
||||||
user_command::linebreakeropen,
|
user_command::linebreakeropen,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
|||||||
@@ -552,12 +552,8 @@ state_manager::deserialize_time( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
if( true == Global.ScenarioTimeCurrent ) {
|
if( true == Global.ScenarioTimeCurrent ) {
|
||||||
// calculate time shift required to match scenario time with local clock
|
// calculate time shift required to match scenario time with local clock
|
||||||
auto timenow = std::time( 0 );
|
auto timenow = std::time( 0 );
|
||||||
auto *localtime = std::localtime( &timenow );
|
auto const *localtime = std::localtime( &timenow );
|
||||||
Global.ScenarioTimeOffset =
|
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
||||||
clamp_circular(
|
|
||||||
( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ),
|
|
||||||
24 * 60 )
|
|
||||||
/ 60.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
|
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ static std::unordered_map<std::string, std::string> m_cabcontrols = {
|
|||||||
{ "brakeprofiler_sw:", "brake acting speed: rapid" },
|
{ "brakeprofiler_sw:", "brake acting speed: rapid" },
|
||||||
{ "maxcurrent_sw:", "motor overload relay threshold" },
|
{ "maxcurrent_sw:", "motor overload relay threshold" },
|
||||||
{ "fuelpump_sw:", "fuel pump" },
|
{ "fuelpump_sw:", "fuel pump" },
|
||||||
|
{ "oilpump_sw:", "oil pump" },
|
||||||
{ "main_off_bt:", "line breaker" },
|
{ "main_off_bt:", "line breaker" },
|
||||||
{ "main_on_bt:", "line breaker" },
|
{ "main_on_bt:", "line breaker" },
|
||||||
{ "security_reset_bt:", "alerter" },
|
{ "security_reset_bt:", "alerter" },
|
||||||
|
|||||||
10
uilayer.cpp
10
uilayer.cpp
@@ -444,10 +444,11 @@ ui_layer::update() {
|
|||||||
// equipment flags
|
// equipment flags
|
||||||
uitextline2 = ( vehicle->MoverParameters->Battery ? "B" : "." );
|
uitextline2 = ( vehicle->MoverParameters->Battery ? "B" : "." );
|
||||||
uitextline2 += ( vehicle->MoverParameters->Mains ? "M" : "." );
|
uitextline2 += ( vehicle->MoverParameters->Mains ? "M" : "." );
|
||||||
uitextline2 += ( vehicle->MoverParameters->PantRearUp ? ( vehicle->MoverParameters->PantRearVolt > 0.0 ? "O" : "o" ) : "." );;
|
uitextline2 += ( vehicle->MoverParameters->PantRearUp ? ( vehicle->MoverParameters->PantRearVolt > 0.0 ? "O" : "o" ) : "." );
|
||||||
uitextline2 += ( vehicle->MoverParameters->PantFrontUp ? ( vehicle->MoverParameters->PantFrontVolt > 0.0 ? "P" : "p" ) : "." );;
|
uitextline2 += ( vehicle->MoverParameters->PantFrontUp ? ( vehicle->MoverParameters->PantFrontVolt > 0.0 ? "P" : "p" ) : "." );
|
||||||
uitextline2 += ( vehicle->MoverParameters->PantPressLockActive ? "!" : ( vehicle->MoverParameters->PantPressSwitchActive ? "*" : "." ) );
|
uitextline2 += ( vehicle->MoverParameters->PantPressLockActive ? "!" : ( vehicle->MoverParameters->PantPressSwitchActive ? "*" : "." ) );
|
||||||
uitextline2 += ( vehicle->MoverParameters->FuelPump.is_enabled ? ( vehicle->MoverParameters->FuelPump.is_active ? "F" : "f" ) : "." );;
|
uitextline2 += ( vehicle->MoverParameters->FuelPump.is_enabled ? ( vehicle->MoverParameters->FuelPump.is_active ? "F" : "f" ) : "." );
|
||||||
|
uitextline2 += ( vehicle->MoverParameters->OilPump.is_active ? "O" : ( vehicle->MoverParameters->OilPump.is_enabled ? "o" : "." ) );
|
||||||
uitextline2 += ( false == vehicle->MoverParameters->ConverterAllowLocal ? "-" : ( vehicle->MoverParameters->ConverterAllow ? ( vehicle->MoverParameters->ConverterFlag ? "X" : "x" ) : "." ) );
|
uitextline2 += ( false == vehicle->MoverParameters->ConverterAllowLocal ? "-" : ( vehicle->MoverParameters->ConverterAllow ? ( vehicle->MoverParameters->ConverterFlag ? "X" : "x" ) : "." ) );
|
||||||
uitextline2 += ( vehicle->MoverParameters->ConvOvldFlag ? "!" : "." );
|
uitextline2 += ( vehicle->MoverParameters->ConvOvldFlag ? "!" : "." );
|
||||||
uitextline2 += ( false == vehicle->MoverParameters->CompressorAllowLocal ? "-" : ( ( vehicle->MoverParameters->CompressorAllow || vehicle->MoverParameters->CompressorPower > 1 ) ? ( vehicle->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ) );
|
uitextline2 += ( false == vehicle->MoverParameters->CompressorAllowLocal ? "-" : ( ( vehicle->MoverParameters->CompressorAllow || vehicle->MoverParameters->CompressorPower > 1 ) ? ( vehicle->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ) );
|
||||||
@@ -718,7 +719,10 @@ ui_layer::update() {
|
|||||||
VelPrev = vehicle->MoverParameters->Vel;
|
VelPrev = vehicle->MoverParameters->Vel;
|
||||||
}
|
}
|
||||||
uitextline2 += "; As=" + to_string( Acc, 2 ); // przyspieszenie wzdłużne
|
uitextline2 += "; As=" + to_string( Acc, 2 ); // przyspieszenie wzdłużne
|
||||||
|
/*
|
||||||
uitextline2 += " eAngle=" + to_string( std::cos( vehicle->MoverParameters->eAngle ), 2 );
|
uitextline2 += " eAngle=" + to_string( std::cos( vehicle->MoverParameters->eAngle ), 2 );
|
||||||
|
*/
|
||||||
|
uitextline2 += " oilP=" + to_string( vehicle->MoverParameters->OilPump.pressure_present, 3 );
|
||||||
|
|
||||||
uitextline3 =
|
uitextline3 =
|
||||||
"cyl.ham. " + to_string( vehicle->MoverParameters->BrakePress, 2 )
|
"cyl.ham. " + to_string( vehicle->MoverParameters->BrakePress, 2 )
|
||||||
|
|||||||
Reference in New Issue
Block a user