diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 382948dc..4c8fa8e7 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -861,6 +861,30 @@ private: float temperatura2 { 40.0 }; }; + struct spring_brake { + std::shared_ptr Cylinder; + bool Activate { false }; //Input: switching brake on/off in exploitation - main valve/switch + bool ShuttOff { true }; //Input: shutting brake off during failure - valve in pneumatic container + bool Release { false }; //Input: emergency releasing rod + + bool IsReady{ false }; //Output: readyness to braking - cylinder is armed, spring is tentioned + bool IsActive{ false }; //Output: brake is working + + bool PNBrakeConnection{ false }; //Conf: connection to pneumatic brake cylinders + double MaxSetPressure { 0.0 }; //Conf: Maximal pressure for switched off brake + double ResetPressure{ 0.0 }; //Conf: Pressure for arming brake cylinder + double MinForcePressure{ 0.1 }; //Conf: Minimal pressure for zero force + double MaxBrakeForce{ 0.0 }; //Conf: Maximal tension for brake pads/shoes + double PressureOn{ -2.0 }; //Conf: Pressure changing ActiveFlag to "On" + double PressureOff{ -1.0 }; //Conf: Pressure changing ActiveFlag to "Off" + double ValveOffArea{ 0.0 }; //Conf: Area of filling valve + double ValveOnArea{ 0.0 }; //Conf: Area of dumping valve + double ValvePNBrakeArea{ 0.0 }; //Conf: Area of bypass to brake cylinders + + int MultiTractionCoupler{ 127 }; //Conf: Coupling flag necessary for transmitting the command + + }; + public: double dMoveLen = 0.0; @@ -920,6 +944,7 @@ public: std::shared_ptr LocHandle; std::shared_ptr Pipe; std::shared_ptr Pipe2; + spring_brake SpringBrake; TLocalBrake LocalBrake = TLocalBrake::NoBrake; /*rodzaj hamulca indywidualnego*/ TBrakePressureTable BrakePressureTable; /*wyszczegolnienie cisnien w rurze*/ @@ -1471,6 +1496,9 @@ public: bool BatterySwitch(bool State); bool EpFuseSwitch(bool State); + bool SpringBrakeActivate(bool State); + bool SpringBrakeShutOff(bool State); + bool SpringBrakeRelease(); /*! stopnie hamowania - hamulec zasadniczy*/ bool IncBrakeLevelOld(void); @@ -1500,6 +1528,7 @@ public: void CompressorCheck(double dt);/*wlacza, wylacza kompresor, laduje zbiornik*/ void UpdatePantVolume(double dt); //Ra void UpdateScndPipePressure(double dt); + void UpdateSpringBrake(double dt); double GetDVc(double dt); /*funkcje obliczajace sily*/ @@ -1617,6 +1646,7 @@ private: void LoadFIZ_Cntrl( std::string const &line ); void LoadFIZ_Blending(std::string const &line); void LoadFIZ_DCEMUED(std::string const &line); + void LoadFIZ_SpringBrake(std::string const &line); void LoadFIZ_Light( std::string const &line ); void LoadFIZ_Security( std::string const &line ); void LoadFIZ_Clima( std::string const &line ); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 2e2bf60e..0c7ccbc5 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -2567,6 +2567,57 @@ bool TMoverParameters::EpFuseSwitch(bool State) // else SendCtrlToNext("EpFuseSwitch", 0, CabNo); } +// ************************************************************************************************* +// yB: 20190906 +// włączenie / wyłączenie hamulca sprezynowego +// ************************************************************************************************* +bool TMoverParameters::SpringBrakeActivate(bool State) +{ + if (Battery) + { + SendCtrlToNext("SpringBrakeActivate", int(State), CabNo, SpringBrake.MultiTractionCoupler); + + if (SpringBrake.Activate != State) + { + SpringBrake.Activate = State; + return true; + } + } + return false; +} + +// ************************************************************************************************* +// yB: 20190906 +// włączenie / wyłączenie odciecia hamulca sprezynowego +// ************************************************************************************************* +bool TMoverParameters::SpringBrakeShutOff(bool State) +{ + if (SpringBrake.ShuttOff != State) + { + SpringBrake.ShuttOff = State; + return true; + } + else + return false; + +} + +// ************************************************************************************************* +// yB: 20190906 +// wyluzowanie hamulca sprezynowego +// ************************************************************************************************* +bool TMoverParameters::SpringBrakeRelease() +{ + if (SpringBrake.IsReady && SpringBrake.Cylinder->P() < SpringBrake.MinForcePressure) + { + SpringBrake.IsReady = false; + return true; + } + else + return false; + +} + // ************************************************************************************************* // Q: 20160710 // kierunek do tyłu @@ -3980,6 +4031,8 @@ void TMoverParameters::UpdateScndPipePressure(double dt) TMoverParameters *c; double dv1, dv2, dV; + UpdateSpringBrake(dt); + dv1 = 0; dv2 = 0; @@ -4032,6 +4085,34 @@ void TMoverParameters::UpdateScndPipePressure(double dt) } } + +// ************************************************************************************************* +// yB: 20190906 +// Aktualizacja ciśnienia w hamulcu sprezynowym +// ************************************************************************************************* +void TMoverParameters::UpdateSpringBrake(double dt) +{ + double SBP = SpringBrake.Cylinder->P(); + double BP = SpringBrake.PNBrakeConnection ? BrakePress : 0; + double MSP = SpringBrake.ShuttOff ? 0 : SpringBrake.MaxSetPressure; + if (!SpringBrake.Activate) + { + double desired_press = std::min(std::max(MSP, BP), Pipe2->P()); + double dv = PF(desired_press, SBP, SpringBrake.ValveOffArea); + SpringBrake.Cylinder->Flow(-dv); + Pipe2->Flow(std::max(dv,0.0)); + } + else + { + double dv = PF(BP, SBP, SpringBrake.ValveOnArea); + SpringBrake.Cylinder->Flow(-dv); + } + if (SBP > SpringBrake.ResetPressure) + SpringBrake.IsReady = true; + SpringBrake.Release = false; + SpringBrake.Cylinder->Act(); +} + // ************************************************************************************************* // Q: 20160715 // oblicza i zwraca przepływ powietrza pomiędzy pojazdami @@ -4373,6 +4454,9 @@ double TMoverParameters::BrakeForce( TTrackParam const &Track ) { K = MaxBrakeForce * ManualBrakeRatio(); } + if (SpringBrake.IsReady) + K += std::max(0.0, SpringBrake.MinForcePressure - SpringBrake.Cylinder->P()) * SpringBrake.MaxBrakeForce; + u = ((BrakePress * P2FTrans) - BrakeCylSpring) * BrakeCylMult[0] - BrakeSlckAdj; if (u * BrakeRigEff > Ntotal) // histereza na nacisku klockow Ntotal = u * BrakeRigEff; @@ -8314,7 +8398,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) if (issection("Blending:", inputline)) { - startBPT = true; LISTLINE = 0; + startBPT = false; LISTLINE = 0; fizlines.emplace( "Blending", inputline); LoadFIZ_Blending( inputline ); continue; @@ -8322,12 +8406,20 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) if (issection("DCEMUED:", inputline)) { - startBPT = true; LISTLINE = 0; + startBPT = false; LISTLINE = 0; fizlines.emplace("DCEMUED", inputline); LoadFIZ_DCEMUED(inputline); continue; } + if (issection("SpringBrake:", inputline)) { + + startBPT = false; LISTLINE = 0; + fizlines.emplace("SpringBrake", inputline); + LoadFIZ_SpringBrake(inputline); + continue; + } + if( issection( "Light:", inputline ) ) { startBPT = false; @@ -9195,6 +9287,30 @@ void TMoverParameters::LoadFIZ_DCEMUED(std::string const &line) { } + +void TMoverParameters::LoadFIZ_SpringBrake(std::string const &line) { + + double vol; + extract_value(vol, "Volume", line, "1"); + if (!SpringBrake.Cylinder) + SpringBrake.Cylinder = std::make_shared(); + SpringBrake.Cylinder->CreateCap(vol); + extract_value(SpringBrake.MaxBrakeForce, "MBF", line, ""); + extract_value(SpringBrake.MaxSetPressure, "MaxSP", line, ""); + extract_value(SpringBrake.ResetPressure, "ResetP", line, ""); + extract_value(SpringBrake.MinForcePressure, "MinFP", line, ""); + extract_value(SpringBrake.PressureOff, "PressOff", line, ""); + extract_value(SpringBrake.PressureOn, "PressOn", line, ""); + extract_value(SpringBrake.ValveOffArea, "ValveOnArea", line, ""); + extract_value(SpringBrake.ValveOnArea, "ValveOffArea", line, ""); + extract_value(SpringBrake.ValvePNBrakeArea, "ValvePNBArea", line, ""); + SpringBrake.PNBrakeConnection = SpringBrake.ValvePNBrakeArea > 0; + extract_value(SpringBrake.MultiTractionCoupler, "MTC", line, ""); + SpringBrake.ShuttOff = false; + SpringBrake.Activate = false; + SpringBrake.IsReady = true; +} + void TMoverParameters::LoadFIZ_Light( std::string const &line ) { LightPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "Light", line ) ); @@ -9929,6 +10045,11 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) Pipe2 = std::make_shared(); // zabezpieczenie, bo sie PG wywala... :( Pipe->CreateCap( ( std::max( Dim.L, 14.0 ) + 0.5 ) * Spg * 1 ); // dlugosc x przekroj x odejscia i takie tam Pipe2->CreateCap( ( std::max( Dim.L, 14.0 ) + 0.5 ) * Spg * 1 ); + if (!SpringBrake.Cylinder) + { + SpringBrake.Cylinder = std::make_shared(); + SpringBrake.Cylinder->CreateCap(1); + } if( LightsPosNo > 0 ) LightsPos = LightsDefPos; @@ -10700,6 +10821,16 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C ScndCtrlActualPos = static_cast(round(CValue1)); OK = SendCtrlToNext(Command, CValue1, CValue2, Couplertype); } + else if (Command == "SpringBrakeActivate") + { + if (Battery) + { + SpringBrake.Activate = CValue1 > 0; + OK = SendCtrlToNext(Command, CValue1, CValue2, Couplertype); + } + else + OK = true; + } return OK; // dla true komenda będzie usunięta, dla false wykonana ponownie } diff --git a/Train.cpp b/Train.cpp index f670d74e..fb938be1 100644 --- a/Train.cpp +++ b/Train.cpp @@ -352,7 +352,14 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::generictoggle6, &TTrain::OnCommand_generictoggle }, { user_command::generictoggle7, &TTrain::OnCommand_generictoggle }, { user_command::generictoggle8, &TTrain::OnCommand_generictoggle }, - { user_command::generictoggle9, &TTrain::OnCommand_generictoggle } + { user_command::generictoggle9, &TTrain::OnCommand_generictoggle }, + { user_command::springbraketoggle, &TTrain::OnCommand_springbraketoggle }, + { user_command::springbrakeenable, &TTrain::OnCommand_springbrakeenable }, + { user_command::springbrakedisable, &TTrain::OnCommand_springbrakedisable }, + { user_command::springbrakeshutofftoggle, &TTrain::OnCommand_springbrakeshutofftoggle }, + { user_command::springbrakeshutoffenable, &TTrain::OnCommand_springbrakeshutoffenable }, + { user_command::springbrakeshutoffdisable, &TTrain::OnCommand_springbrakeshutoffdisable }, + { user_command::springbrakerelease, &TTrain::OnCommand_springbrakerelease } }; std::vector const TTrain::fPress_labels = { @@ -4224,6 +4231,73 @@ void TTrain::OnCommand_generictoggle( TTrain *Train, command_data const &Command } } +void TTrain::OnCommand_springbraketoggle(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->mvOccupied->SpringBrake.Activate) { + // turn on + OnCommand_springbrakeenable(Train, Command); + } + else { + //turn off + OnCommand_springbrakedisable(Train, Command); + } + } +}; + +void TTrain::OnCommand_springbrakeenable(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 + Train->mvOccupied->SpringBrakeActivate(true); + } +}; + +void TTrain::OnCommand_springbrakedisable(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 + Train->mvOccupied->SpringBrakeActivate(false); + } +}; +void TTrain::OnCommand_springbrakeshutofftoggle(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->mvOccupied->SpringBrake.ShuttOff) { + // turn on + OnCommand_springbrakeshutoffenable(Train, Command); + } + else { + //turn off + OnCommand_springbrakeshutoffdisable(Train, Command); + } + } +}; + +void TTrain::OnCommand_springbrakeshutoffenable(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 + Train->mvOccupied->SpringBrakeShutOff(true); + } +}; + +void TTrain::OnCommand_springbrakeshutoffdisable(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 + Train->mvOccupied->SpringBrakeShutOff(false); + } +}; + +void TTrain::OnCommand_springbrakerelease(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 + + auto *vehicle{ Train->find_nearest_consist_vehicle() }; + if (vehicle == nullptr) { return; } + Train->mvOccupied->SpringBrakeRelease(); + } +}; + void TTrain::OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command ) { if( Train->ggDoorSignallingButton.SubModel == nullptr ) { diff --git a/Train.h b/Train.h index 62a44097..842af209 100644 --- a/Train.h +++ b/Train.h @@ -349,6 +349,13 @@ class TTrain { static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ); static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command ); static void OnCommand_generictoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_springbraketoggle(TTrain *Train, command_data const &Command); + static void OnCommand_springbrakeenable(TTrain *Train, command_data const &Command); + static void OnCommand_springbrakedisable(TTrain *Train, command_data const &Command); + static void OnCommand_springbrakeshutofftoggle(TTrain *Train, command_data const &Command); + static void OnCommand_springbrakeshutoffenable(TTrain *Train, command_data const &Command); + static void OnCommand_springbrakeshutoffdisable(TTrain *Train, command_data const &Command); + static void OnCommand_springbrakerelease(TTrain *Train, command_data const &Command); // members diff --git a/command.cpp b/command.cpp index 5b27f32f..9d7bdc6e 100644 --- a/command.cpp +++ b/command.cpp @@ -228,7 +228,14 @@ commanddescription_sequence Commands_descriptions = { { "motorblowerstogglerear", command_target::vehicle }, { "motorblowersdisableall", command_target::vehicle }, { "coolingfanstoggle", command_target::vehicle }, - { "tempomattoggle", command_target::vehicle } + { "tempomattoggle", command_target::vehicle }, + { "springbraketoggle", command_target::vehicle }, + { "springbrakeenable", command_target::vehicle }, + { "springbrakedisable", command_target::vehicle }, + { "springbrakeshutofftoggle", command_target::vehicle }, + { "springbrakeshutoffenable", command_target::vehicle }, + { "springbrakeshutoffdisable", command_target::vehicle }, + { "springbrakerelease", command_target::vehicle } }; diff --git a/command.h b/command.h index 9a06cd14..89904862 100644 --- a/command.h +++ b/command.h @@ -222,6 +222,13 @@ enum class user_command { motorblowersdisableall, coolingfanstoggle, tempomattoggle, + springbraketoggle, + springbrakeenable, + springbrakedisable, + springbrakeshutofftoggle, + springbrakeshutoffenable, + springbrakeshutoffdisable, + springbrakerelease, none = -1 };