From 04db86baa6ddf45ff348fc936bc72f40546f30ca Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 17 Mar 2019 19:08:53 +0100 Subject: [PATCH 01/26] cooling fans state indicator, minor diesel engine logic tweaks --- Driver.cpp | 11 ++++++++--- DynObj.cpp | 4 ++-- McZapkie/Mover.cpp | 7 ++++--- Train.cpp | 11 ++++++++++- Train.h | 1 + 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 533d2345..59794e20 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4108,9 +4108,14 @@ TController::UpdateSituation(double dt) { // TODO: check if this situation still happens and the hack is still needed if( ( false == AIControllFlag ) && ( iDrivigFlags & moveDoorOpened ) - && ( mvOccupied->Doors.close_control != control_t::driver ) - && ( mvControlling->MainCtrlPos > ( mvControlling->EngineType != TEngineType::DieselEngine ? 0 : 1 ) ) ) { // for diesel 1st position is effectively 0 - Doors( false ); + && ( mvOccupied->Doors.close_control != control_t::driver ) ) { + // for diesel engines react when engine is put past idle revolutions + // for others straightforward master controller check + if( ( mvControlling->EngineType == TEngineType::DieselEngine ? + mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 : + mvControlling->MainCtrlPos > 0 ) ) { + Doors( false ); + } } // basic situational ai operations diff --git a/DynObj.cpp b/DynObj.cpp index d17ec0bf..a5be27fd 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -4066,7 +4066,7 @@ void TDynamicObject::RenderSounds() { else { // basic clash couplersounds.dsbBufferClamp - .gain( 0.65f ) + .gain( 1.f ) .play( sound_flags::exclusive ); } } @@ -4091,7 +4091,7 @@ void TDynamicObject::RenderSounds() { else { // basic clash couplersounds.dsbCouplerStretch - .gain( 0.65f ) + .gain( 1.f ) .play( sound_flags::exclusive ); } } diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index dbe39204..8fa92475 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -6135,12 +6135,13 @@ bool TMoverParameters::dizel_StartupCheck() { // test the fuel pump // TODO: add fuel pressure check - if( false == FuelPump.is_active ) { + if( ( RList[ MainCtrlPos ].R == 0.0 ) + || ( false == FuelPump.is_active ) ) { engineisready = false; - if( FuelPump.start_type == start_t::manual ) { +// if( FuelPump.start_type == start_t::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 ) diff --git a/Train.cpp b/Train.cpp index 6977c69d..9b69059c 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5507,7 +5507,12 @@ bool TTrain::Update( double const Deltatime ) } if (ggIgnitionKey.SubModel) { - ggIgnitionKey.UpdateValue(mvControlled->dizel_startup); + ggIgnitionKey.UpdateValue( + ( mvControlled->Mains ) + || ( mvControlled->dizel_startup ) + || ( fMainRelayTimer > 0.f ) + || ( ggMainButton.GetDesiredValue() > 0.95 ) + || ( ggMainOnButton.GetDesiredValue() > 0.95 ) ); ggIgnitionKey.Update(); } } @@ -5718,6 +5723,7 @@ bool TTrain::Update( double const Deltatime ) // others btLampkaMalfunction.Turn( mvControlled->dizel_heat.PA ); btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ end::front ].is_active ) && ( mvControlled->MotorBlowers[ end::rear ].is_active ) ); + btLampkaCoolingFans.Turn( mvControlled->RventRot > 1.0 ); // universal devices state indicators for( auto idx = 0; idx < btUniversals.size(); ++idx ) { btUniversals[ idx ].Turn( ggUniversals[ idx ].GetValue() > 0.5 ); @@ -5778,6 +5784,7 @@ bool TTrain::Update( double const Deltatime ) // others btLampkaMalfunction.Turn( false ); btLampkaMotorBlowers.Turn( false ); + btLampkaCoolingFans.Turn( false ); // universal devices state indicators for( auto &universal : btUniversals ) { universal.Turn( false ); @@ -7415,6 +7422,7 @@ void TTrain::clear_cab_controls() btLampkaMalfunction.Clear(); btLampkaMalfunctionB.Clear(); btLampkaMotorBlowers.Clear(); + btLampkaCoolingFans.Clear(); ggLeftLightButton.Clear(); ggRightLightButton.Clear(); @@ -7759,6 +7767,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co { "i-highcurrent:", btLampkaWysRozr }, { "i-vent_trim:", btLampkaWentZaluzje }, { "i-motorblowers:", btLampkaMotorBlowers }, + { "i-coolingfans:", btLampkaCoolingFans }, { "i-trainheating:", btLampkaOgrzewanieSkladu }, { "i-security_aware:", btLampkaCzuwaka }, { "i-security_cabsignal:", btLampkaSHP }, diff --git a/Train.h b/Train.h index 837cdd22..1e49b3a0 100644 --- a/Train.h +++ b/Train.h @@ -582,6 +582,7 @@ public: // reszta może by?publiczna TButton btLampkaMalfunction; TButton btLampkaMalfunctionB; TButton btLampkaMotorBlowers; + TButton btLampkaCoolingFans; TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine // Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys From ea5f3ae27a1f058ccba63ddb942367beaf248e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 15 Mar 2019 12:31:34 +0100 Subject: [PATCH 02/26] Fixed SpeedControl for EN57-like EMUs --- DynObj.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DynObj.cpp b/DynObj.cpp index a5be27fd..13366a90 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2700,7 +2700,10 @@ bool TDynamicObject::Update(double dt, double dt1) auto osie { 0 }; // 0a. ustal aktualna nastawe zadania sily napedowej i hamowania if (MoverParameters->Power < 1) + { MoverParameters->MainCtrlPos = ctOwner->Controlling()->MainCtrlPos*MoverParameters->MainCtrlPosNo / std::max(1, ctOwner->Controlling()->MainCtrlPosNo); + MoverParameters->ScndCtrlActualPos = ctOwner->Controlling()->ScndCtrlActualPos; + } MoverParameters->CheckEIMIC(dt1); MoverParameters->CheckSpeedCtrl(); From fb36c1348b09205138ba8be69d27cbdd02f3d0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 15 Mar 2019 20:41:11 +0100 Subject: [PATCH 03/26] Fix for MHZ_K5P - no sudden overload in middle posistion --- McZapkie/MOVER.h | 2 ++ McZapkie/Mover.cpp | 3 +++ McZapkie/hamulce.cpp | 32 +++++++++++++++++++++----------- McZapkie/hamulce.h | 19 ++++++++++++------- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index ca040145..83106f5d 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -894,6 +894,8 @@ public: double P2FTrans = 0.0; double TrackBrakeForce = 0.0; /*sila nacisku hamulca szynowego*/ int BrakeMethod = 0; /*flaga rodzaju hamulca*/ + bool Handle_AutomaticOverload = false; + bool Handle_ManualOverload = false; /*max. cisnienie w cyl. ham., stala proporcjonalnosci p-K*/ double HighPipePress = 0.0; double LowPipePress = 0.0; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 8fa92475..030584de 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -8426,6 +8426,8 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { lookup->second : TBrakeHandle::NoHandle; } + Handle_AutomaticOverload = (extract_value("HAO", line) == "Yes"); + Handle_ManualOverload = (extract_value("HMO", line) == "Yes"); // brakelochandle { std::map locbrakehandles{ @@ -9258,6 +9260,7 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) default: Handle = std::make_shared(); } + Handle->SetParams(Handle_AutomaticOverload, Handle_ManualOverload, 0.0, 0.0); switch( BrakeLocHandle ) { case TBrakeHandle::FD1: diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index f01d6697..85b3d0f0 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -2274,6 +2274,11 @@ double TDriverHandle::GetEP(double pos) { return 0; } + +void TDriverHandle::OvrldButton(bool Active) +{ + ManualOvrldActive = Active; +} //---FV4a--- double TFV4a::GetPF(double i_bcp, double PP, double HP, double dt, double ep) @@ -2683,7 +2688,7 @@ bool TMHZ_EN57::EQ(double pos, double i_pos) double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) { static int const LBDelay = 100; - double LimPP; + double LimCP; double dpPipe; double dpMainValve; double ActFlowSpeed; @@ -2710,29 +2715,28 @@ double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) } if (EQ(i_bcp, 1)) //odcięcie - nie rób nic - LimPP = CP; + LimCP = CP; else if (i_bcp > 1) //hamowanie - LimPP = 3.4; + LimCP = 3.4; else //luzowanie - LimPP = 5.0; + LimCP = 5.0; pom = CP; - LimPP = Min0R(LimPP + TP + RedAdj, HP); // pozycja + czasowy lub zasilanie + LimCP = Min0R(LimCP, HP); // pozycja + czasowy lub zasilanie ActFlowSpeed = 4; - if ((LimPP > CP)) // podwyzszanie szybkie - CP = CP + 9 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy; + if ((LimCP > CP)) // podwyzszanie szybkie + CP = CP + 9 * Min0R(abs(LimCP - CP), 0.05) * PR(CP, LimCP) * dt; // zbiornik sterujacy; else - CP = CP + 9 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy + CP = CP + 9 * Min0R(abs(LimCP - CP), 0.05) * PR(CP, LimCP) * dt; // zbiornik sterujacy - LimPP = pom; // cp - dpPipe = Min0R(HP, LimPP); + dpPipe = Min0R(HP, CP + TP + RedAdj); if (dpPipe > PP) dpMainValve = -PFVa(HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4); else dpMainValve = PFVd(PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4); - if (EQ(i_bcp, -1)) + if ((EQ(i_bcp, -1)&&(AutoOvrld))||(ManualOvrld && ManualOvrldActive)) { if ((TP < 1)) TP = TP + 0.03 * dt; @@ -2786,6 +2790,12 @@ double TMHZ_K5P::GetCP() return RP; } +void TMHZ_K5P::SetParams(bool AO, bool MO, double, double) +{ + AutoOvrld = AO; + ManualOvrld = MO; +} + bool TMHZ_K5P::EQ(double pos, double i_pos) { return (pos <= i_pos + 0.5) && (pos > i_pos - 0.5); diff --git a/McZapkie/hamulce.h b/McZapkie/hamulce.h index ecec4c14..53d688ef 100644 --- a/McZapkie/hamulce.h +++ b/McZapkie/hamulce.h @@ -513,9 +513,11 @@ class TKE : public TBrake { //Knorr Einheitsbauart — jeden do wszystkiego //klasa obejmujaca krany class TDriverHandle { - private: + protected: // BCP: integer; - + bool AutoOvrld = false; //czy jest asymilacja automatyczna na pozycji -1 + bool ManualOvrld = false; //czy jest asymilacja reczna przyciskiem + bool ManualOvrldActive = false; //czy jest wcisniety przycisk asymilacji public: bool Time = false; bool TimeEP = false; @@ -524,10 +526,12 @@ class TDriverHandle { virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep); virtual void Init(double Press); virtual double GetCP(); - virtual void SetReductor(double nAdj); - virtual double GetSound(int i); - virtual double GetPos(int i); - virtual double GetEP(double pos); + virtual void SetReductor(double nAdj); //korekcja pozycji reduktora cisnienia + virtual double GetSound(int i); //pobranie glosnosci wybranego dzwieku + virtual double GetPos(int i); //pobranie numeru pozycji o zadanym kodzie (funkcji) + virtual double GetEP(double pos); //pobranie sily hamulca ep + virtual void SetParams(bool AO, bool MO, double, double) {}; //ustawianie jakichs parametrów dla zaworu + virtual void OvrldButton(bool Active); //przycisk recznego przeladowania/asymilacji inline TDriverHandle() { memset( Sounds, 0, sizeof( Sounds ) ); } }; @@ -609,7 +613,7 @@ private: double TP = 0.0; //zbiornik czasowy double RP = 0.0; //zbiornik redukcyjny double RedAdj = 0.0; //dostosowanie reduktora cisnienia (krecenie kapturkiem) - bool Fala = false; + bool Fala = false; //czy jest napelnianie uderzeniowe static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 }; bool EQ(double pos, double i_pos); @@ -621,6 +625,7 @@ public: double GetSound(int i)/*override*/; double GetPos(int i)/*override*/; double GetCP()/*override*/; + void SetParams(bool AO, bool MO, double, double); /*ovveride*/ inline TMHZ_K5P(void) : TDriverHandle() From 4855b3a5a57aa48e9f43594ee5b85a2784999c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 16 Mar 2019 20:43:12 +0100 Subject: [PATCH 04/26] New Handle type MHZ_6P for Traxx --- McZapkie/MOVER.h | 4 +- McZapkie/Mover.cpp | 8 ++- McZapkie/hamulce.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++ McZapkie/hamulce.h | 27 +++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 83106f5d..f9b3f0f7 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -369,7 +369,7 @@ enum class TBrakeSystem { Individual, Pneumatic, ElectroPneumatic }; /*podtypy hamulcow zespolonych*/ enum class TBrakeSubSystem { ss_None, ss_W, ss_K, ss_KK, ss_Hik, ss_ESt, ss_KE, ss_LSt, ss_MT, ss_Dako }; enum class TBrakeValve { NoValve, W, W_Lu_VI, W_Lu_L, W_Lu_XR, K, Kg, Kp, Kss, Kkg, Kkp, Kks, Hikg1, Hikss, Hikp1, KE, SW, EStED, NESt3, ESt3, LSt, ESt4, ESt3AL2, EP1, EP2, M483, CV1_L_TR, CV1, CV1_R, Other }; -enum class TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVE408, FVel6, D2, Knorr, FD1, BS2, testH, St113, MHZ_P, MHZ_T, MHZ_EN57, MHZ_K5P, MHZ_K8P }; +enum class TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVE408, FVel6, D2, Knorr, FD1, BS2, testH, St113, MHZ_P, MHZ_T, MHZ_EN57, MHZ_K5P, MHZ_K8P, MHZ_6P }; /*typy hamulcow indywidualnych*/ enum class TLocalBrake { NoBrake, ManualBrake, PneumaticBrake, HydraulicBrake }; /*dla osob/towar: opoznienie hamowania/odhamowania*/ @@ -896,6 +896,8 @@ public: int BrakeMethod = 0; /*flaga rodzaju hamulca*/ bool Handle_AutomaticOverload = false; bool Handle_ManualOverload = false; + double Handle_GenericDoubleParameter1 = 0.0; + double Handle_GenericDoubleParameter2 = 0.0; /*max. cisnienie w cyl. ham., stala proporcjonalnosci p-K*/ double HighPipePress = 0.0; double LowPipePress = 0.0; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 030584de..32ce19f7 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -8413,6 +8413,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { { "MHZ_EN57", TBrakeHandle::MHZ_EN57 }, { "MHZ_K5P", TBrakeHandle::MHZ_K5P }, { "MHZ_K8P", TBrakeHandle::MHZ_K8P }, + { "MHZ_6P", TBrakeHandle::MHZ_6P }, { "M394", TBrakeHandle::M394 }, { "Knorr", TBrakeHandle::Knorr }, { "Westinghouse", TBrakeHandle::West }, @@ -8428,6 +8429,8 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { } Handle_AutomaticOverload = (extract_value("HAO", line) == "Yes"); Handle_ManualOverload = (extract_value("HMO", line) == "Yes"); + extract_value(Handle_GenericDoubleParameter1, "HGDP1", line, ""); + extract_value(Handle_GenericDoubleParameter2, "HGDP2", line, ""); // brakelochandle { std::map locbrakehandles{ @@ -9257,10 +9260,13 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) case TBrakeHandle::MHZ_K5P: Handle = std::make_shared(); break; + case TBrakeHandle::MHZ_6P: + Handle = std::make_shared(); + break; default: Handle = std::make_shared(); } - Handle->SetParams(Handle_AutomaticOverload, Handle_ManualOverload, 0.0, 0.0); + Handle->SetParams(Handle_AutomaticOverload, Handle_ManualOverload, Handle_GenericDoubleParameter1, Handle_GenericDoubleParameter2); switch( BrakeLocHandle ) { case TBrakeHandle::FD1: diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 85b3d0f0..47bbebe6 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -24,6 +24,7 @@ static double const DPL = 0.25; double const TFV4aM::pos_table[11] = {-2, 6, -1, 0, -2, 1, 4, 6, 0, 0, 0}; double const TMHZ_EN57::pos_table[11] = {-1, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0}; double const TMHZ_K5P::pos_table[11] = { -1, 3, -1, 0, 1, 1, 2, 3, 0, 0, 0 }; +double const TMHZ_6P::pos_table[11] = { -1, 4, -1, 0, 2, 2, 3, 4, 0, 0, 0 }; double const TM394::pos_table[11] = {-1, 5, -1, 0, 1, 2, 4, 5, 0, 0, 0}; double const TH14K1::BPT_K[6][2] = {{10, 0}, {4, 1}, {0, 1}, {4, 0}, {4, -1}, {15, -1}}; double const TH14K1::pos_table[11] = {-1, 4, -1, 0, 1, 2, 3, 4, 0, 0, 0}; @@ -2801,6 +2802,133 @@ bool TMHZ_K5P::EQ(double pos, double i_pos) return (pos <= i_pos + 0.5) && (pos > i_pos - 0.5); } +//---MHZ_6P--- manipulator hamulca zespolonego 6-ciopozycyjny + +double TMHZ_6P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) { + static int const LBDelay = 100; + + double LimCP; + double dpPipe; + double dpMainValve; + double ActFlowSpeed; + double DP; + double pom; + + for (int idx = 0; idx < 5; ++idx) { + Sounds[idx] = 0; + } + + DP = 0; + + i_bcp = Max0R(Min0R(i_bcp, 3.999), -0.999); // na wszelki wypadek, zeby nie wyszlo poza zakres + + if ((TP > 0)) + { + DP = 0.004; + TP = TP - DP * dt; + Sounds[s_fv4a_t] = DP; + } + else + { + TP = 0; + } + + if (EQ(i_bcp, 2)) //odcięcie - nie rób nic + LimCP = CP; + else if (i_bcp > 2.5) //hamowanie + LimCP = 3.4; + else //luzowanie + LimCP = 5.0; + pom = CP; + LimCP = Min0R(LimCP, HP); // pozycja + czasowy lub zasilanie + ActFlowSpeed = 4; + + if ((LimCP > CP)) // podwyzszanie szybkie + CP = CP + 9 * Min0R(abs(LimCP - CP), 0.05) * PR(CP, LimCP) * dt; // zbiornik sterujacy; + else + CP = CP + 9 * Min0R(abs(LimCP - CP), 0.05) * PR(CP, LimCP) * dt; // zbiornik sterujacy + + dpPipe = Min0R(HP, CP + TP + RedAdj); + + if (Fala && EQ(i_bcp, -1)) + { + dpPipe = 5.0 + TP + RedAdj + UnbrakeOverPressure; + ActFlowSpeed = 12; + } + + if (dpPipe > PP) + dpMainValve = -PFVa(HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4); + else + dpMainValve = PFVd(PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4); + + if ((EQ(i_bcp, -1) && (AutoOvrld)) || (ManualOvrld && ManualOvrldActive)) + { + if ((TP < 1)) + TP = TP + 0.03 * dt; + } + + if (EQ(i_bcp, 4)) + { + DP = PF(0, PP, 2 * ActFlowSpeed / LBDelay); + dpMainValve = DP; + Sounds[s_fv4a_e] = DP; + Sounds[s_fv4a_u] = 0; + Sounds[s_fv4a_b] = 0; + Sounds[s_fv4a_x] = 0; + } + else + { + if (dpMainValve > 0) + Sounds[s_fv4a_b] = dpMainValve; + else + Sounds[s_fv4a_u] = -dpMainValve; + } + + return dpMainValve * dt; +} + +void TMHZ_6P::Init(double Press) +{ + CP = Press; +} + +void TMHZ_6P::SetReductor(double nAdj) +{ + RedAdj = nAdj; +} + +double TMHZ_6P::GetSound(int i) +{ + if (i > 4) + return 0; + else + return Sounds[i]; +} + +double TMHZ_6P::GetPos(int i) +{ + return pos_table[i]; +} + +double TMHZ_6P::GetCP() +{ + return RP; +} + +void TMHZ_6P::SetParams(bool AO, bool MO, double OverP, double) +{ + AutoOvrld = AO; + ManualOvrld = MO; + UnbrakeOverPressure = std::max(0.0, OverP); + Fala = (OverP > 0.01); + +} + +bool TMHZ_6P::EQ(double pos, double i_pos) +{ + return (pos <= i_pos + 0.5) && (pos > i_pos - 0.5); +} + //---M394--- Matrosow double TM394::GetPF(double i_bcp, double PP, double HP, double dt, double ep) diff --git a/McZapkie/hamulce.h b/McZapkie/hamulce.h index 53d688ef..d09427c5 100644 --- a/McZapkie/hamulce.h +++ b/McZapkie/hamulce.h @@ -632,6 +632,33 @@ public: {} }; +class TMHZ_6P : public TDriverHandle { + +private: + double CP = 0.0; //zbiornik sterujący + double TP = 0.0; //zbiornik czasowy + double RP = 0.0; //zbiornik redukcyjny + double RedAdj = 0.0; //dostosowanie reduktora cisnienia (krecenie kapturkiem) + bool Fala = false; //czy jest napelnianie uderzeniowe + double UnbrakeOverPressure = 0.0; //wartosc napelniania uderzeniowego + static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 }; + + bool EQ(double pos, double i_pos); + +public: + double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; + void Init(double Press)/*override*/; + void SetReductor(double nAdj)/*override*/; + double GetSound(int i)/*override*/; + double GetPos(int i)/*override*/; + double GetCP()/*override*/; + void SetParams(bool AO, bool MO, double, double); /*ovveride*/ + + inline TMHZ_6P(void) : + TDriverHandle() + {} +}; + /* FBS2= class(TTDriverHandle) private CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny From 3edd22e9fa3faf05e3d0d693474707c039d2806d Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 17 Mar 2019 19:45:45 +0100 Subject: [PATCH 05/26] diesel engine startup check fix --- McZapkie/Mover.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 32ce19f7..8055009c 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -6135,8 +6135,8 @@ bool TMoverParameters::dizel_StartupCheck() { // test the fuel pump // TODO: add fuel pressure check - if( ( RList[ MainCtrlPos ].R == 0.0 ) - || ( false == FuelPump.is_active ) ) { + if( ( false == FuelPump.is_active ) + || ( ( EngineType == TEngineType::DieselEngine ) && ( RList[ MainCtrlPos ].R == 0.0 ) ) ) { engineisready = false; // if( FuelPump.start_type == start_t::manual ) { // with manual pump control startup procedure is done only once per starter switch press From fe6789778fefa154ee717d0732feb00669ce1280 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 19 Mar 2019 22:38:46 +0100 Subject: [PATCH 06/26] vehicle controllers ai logic fixes, minor refactoring --- Driver.cpp | 150 +++++++++++++++++++++++++-------------------- Driver.h | 3 + DynObj.cpp | 4 +- McZapkie/MOVER.h | 3 + McZapkie/Mover.cpp | 89 +++++++++++++++++---------- Train.cpp | 8 +-- 6 files changed, 154 insertions(+), 103 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 59794e20..50c4be69 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1765,15 +1765,10 @@ void TController::Activation() if (iDirection) { // jeśli jest ustalony kierunek TDynamicObject *old = pVehicle, *d = pVehicle; // w tym siedzi AI - TController *drugi; // jakby były dwa, to zamienić miejscami, a nie robić wycieku pamięci - // poprzez nadpisanie + TController *drugi; // jakby były dwa, to zamienić miejscami, a nie robić wycieku pamięci poprzez nadpisanie auto const localbrakelevel { mvOccupied->LocalBrakePosA }; - while (mvControlling->MainCtrlPos) // samo zapętlenie DecSpeed() nie wystarcza :/ - DecSpeed(true); // wymuszenie zerowania nastawnika jazdy - while (mvOccupied->ActiveDir < 0) - mvOccupied->DirectionForward(); // kierunek na 0 - while (mvOccupied->ActiveDir > 0) - mvOccupied->DirectionBackward(); + ZeroSpeed(); + ZeroDirection(); if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? 1 : 0].CouplingFlag, ctrain_controll)) { mvControlling->MainSwitch( false); // dezaktywacja czuwaka, jeśli przejście do innego członu mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); // zwolnienie hamulca w opuszczanym pojeździe @@ -2396,7 +2391,7 @@ void TController::SetDriverPsyche() } if (mvControlling && mvOccupied) { // with Controlling do - if (mvControlling->MainCtrlPos < 3) + if (mvControlling->MainCtrlPowerPos() < 3) ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime; if (mvOccupied->BrakeCtrlPos > 1) ReactionTime = 0.5 * ReactionTime; @@ -2493,17 +2488,16 @@ bool TController::PrepareEngine() { // część wykonawcza dla sterowania przez komputer if (mvControlling->ConvOvldFlag) { // wywalił bezpiecznik nadmiarowy przetwornicy - while (DecSpeed(true)) - ; // zerowanie napędu + ZeroSpeed(); mvControlling->ConvOvldFlag = false; // reset nadmiarowego } else if (false == IsLineBreakerClosed) { - while (DecSpeed(true)) - ; // zerowanie napędu + ZeroSpeed(); if( mvOccupied->TrainType == dt_SN61 ) { // specjalnie dla SN61 żeby nie zgasł - if( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) { - mvControlling->IncMainCtrl( 1 ); + while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) + && ( mvControlling->IncMainCtrl( 1 ) ) ) { + ; } } if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector ) @@ -2562,9 +2556,7 @@ bool TController::ReleaseEngine() { VelDesired = 0.0; AccDesired = std::min( AccDesired, -1.25 ); // hamuj solidnie ReactionTime = 0.1; - while( DecSpeed( true ) ) { - ; // zerowanie nastawników - } + ZeroSpeed(); IncBrake(); // don't bother with the rest until we're standing still return false; @@ -2601,12 +2593,8 @@ bool TController::ReleaseEngine() { ; } } - while( DecSpeed( true ) ) { - ; // zerowanie nastawników - } - // set direction to neutral - while( ( mvOccupied->ActiveDir > 0 ) && ( mvOccupied->DirectionBackward() ) ) { ; } - while( ( mvOccupied->ActiveDir < 0 ) && ( mvOccupied->DirectionForward() ) ) { ; } + ZeroSpeed(); + ZeroDirection(); // zamykanie drzwi mvOccupied->OperateDoors( side::right, false ); @@ -2948,7 +2936,7 @@ bool TController::IncSpeed() return false; // to nici z ruszania } if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC - if ((mvControlling->MainCtrlPos == 0) || + if ((mvControlling->IsMainCtrlZero()) || (mvControlling->StLinFlag)) // youBy polecił dodać 2012-09-08 v367 // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) if (Ready || (iDrivigFlags & movePress)) { @@ -3030,7 +3018,7 @@ bool TController::IncSpeed() } if( ( mvControlling->Im == 0 ) - && ( mvControlling->MainCtrlPos > 2 ) ) { + && ( mvControlling->MainCtrlPowerPos() > 1 ) ) { // brak prądu na dalszych pozycjach // nie załączona lokomotywa albo wywalił nadmiarowy Need_TryAgain = true; @@ -3098,6 +3086,24 @@ bool TController::IncSpeed() return OK; } +void TController::ZeroSpeed( bool const Enforce ) { + + while( DecSpeed( Enforce ) ) { + ; + } +} + +void TController::ZeroMasterController( bool const Enforce ) { + + // combined controller may be set to braking, i.e. position lower than neutral + auto const neutralposition { mvControlling->MainCtrlZeroPos() }; + while( ( mvControlling->MainCtrlPos < neutralposition ) + && ( DecBrake() ) ) { + ; + } + ZeroSpeed( Enforce ); +} + bool TController::DecSpeed(bool force) { // zmniejszenie prędkości (ale nie hamowanie) bool OK = false; // domyślnie false, aby wyszło z pętli while @@ -3107,20 +3113,20 @@ bool TController::DecSpeed(bool force) iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi jazdy if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania if (mvControlling->MainCtrlPosNo > 0) // McZapkie-041003: wagon sterowniczy, np. EZT - mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0)); + mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 1 ? 2 : 1)); mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania return false; case TEngineType::ElectricSeriesMotor: OK = mvControlling->DecScndCtrl(2); // najpierw bocznik na zero if (!OK) - OK = mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0)); + OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 1 ? 2 : 1)); mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania break; case TEngineType::Dumb: case TEngineType::DieselElectric: OK = mvControlling->DecScndCtrl(2); if (!OK) - OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPos / 2)); + OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPowerPos() / 2)); break; case TEngineType::ElectricInductionMotor: OK = DecSpeedEIM(); @@ -3139,12 +3145,14 @@ bool TController::DecSpeed(bool force) if (mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0) OK = mvControlling->DecMainCtrl(1); } - else - while ((mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0) && - (mvControlling->MainCtrlPos > 1)) - OK = mvControlling->DecMainCtrl(1); + else { + while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 ) + && ( mvControlling->MainCtrlPowerPos() > 1 ) ) { + OK = mvControlling->DecMainCtrl( 1 ); + } + } if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania - OK = mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0)); + OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 2 ? 2 : 1)); break; } return OK; @@ -3244,8 +3252,7 @@ void TController::SpeedSet() if( ( false == mvControlling->StLinFlag ) && ( false == mvControlling->DelayCtrlFlag ) ) { // styczniki liniowe rozłączone yBARC - while( DecSpeed() ) - ; // zerowanie napędu + ZeroSpeed(); } else if (Ready || (iDrivigFlags & movePress)) // o ile może jechać if (fAccGravity < -0.10) // i jedzie pod górę większą niż 10 promil @@ -4113,7 +4120,7 @@ TController::UpdateSituation(double dt) { // for others straightforward master controller check if( ( mvControlling->EngineType == TEngineType::DieselEngine ? mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 : - mvControlling->MainCtrlPos > 0 ) ) { + mvControlling->MainCtrlPowerPos() > 0 ) ) { Doors( false ); } } @@ -4176,7 +4183,7 @@ TController::UpdateSituation(double dt) { // is moving if( ( fOverhead2 >= 0.0 ) || iOverheadZero ) { // jeśli jazda bezprądowa albo z opuszczonym pantografem - while( DecSpeed( true ) ) { ; } // zerowanie napędu + ZeroSpeed(); } if( ( fOverhead2 > 0.0 ) || iOverheadDown ) { // jazda z opuszczonymi pantografami @@ -4272,7 +4279,7 @@ TController::UpdateSituation(double dt) { if( ( true == TestFlag( iDrivigFlags, moveStartHornNow ) ) && ( true == Ready ) && ( iEngineActive != 0 ) - && ( mvControlling->MainCtrlPos > 0 ) ) { + && ( mvControlling->MainCtrlPowerPos() > 0 ) ) { // uruchomienie trąbienia przed ruszeniem fWarningDuration = 0.3; // czas trąbienia mvOccupied->WarningSignal = pVehicle->iHornWarning; // wysokość tonu (2=wysoki) @@ -4792,7 +4799,7 @@ TController::UpdateSituation(double dt) { // jeśli dociskanie w celu odczepienia // 3. faza odczepiania. SetVelocity(2, 0); // jazda w ustawionym kierunku z prędkością 2 - if( ( mvControlling->MainCtrlPos > 0 ) + if( ( mvControlling->MainCtrlPowerPos() > 0 ) || ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) { // jeśli jazda WriteLog(mvOccupied->Name + " odczepianie w kierunku " + std::to_string(mvOccupied->DirAbsolute)); @@ -4883,16 +4890,15 @@ TController::UpdateSituation(double dt) { if (iDrivigFlags & movePress) { // 4. faza odczepiania: zwolnij i zmień kierunek SetVelocity(0, 0, stopJoin); // wyłączyć przyspieszanie - if (!DecSpeed()) // jeśli już bardziej wyłączyć się nie da - { // ponowna zmiana kierunku - WriteLog( mvOccupied->Name + " ponowna zmiana kierunku" ); - DirectionForward(mvOccupied->ActiveDir < 0); // zmiana kierunku jazdy na właściwy - iDrivigFlags &= ~movePress; // koniec dociskania - JumpToNextOrder(); // zmieni światła - TableClear(); // skanowanie od nowa - iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem - SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie prędkości jazdy - } + ZeroSpeed(); + // ponowna zmiana kierunku + WriteLog( mvOccupied->Name + " ponowna zmiana kierunku" ); + DirectionForward(mvOccupied->ActiveDir < 0); // zmiana kierunku jazdy na właściwy + iDrivigFlags &= ~movePress; // koniec dociskania + JumpToNextOrder(); // zmieni światła + TableClear(); // skanowanie od nowa + iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem + SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie prędkości jazdy } } @@ -5458,7 +5464,7 @@ TController::UpdateSituation(double dt) { if( ( true == mvOccupied->RadioStopFlag ) // radio-stop && ( mvOccupied->Vel > 0.0 ) ) { // and still moving // if the radio-stop was issued don't waste effort trying to fight it - while( true == DecSpeed() ) { ; } // just throttle down... + ZeroSpeed(); // just throttle down... return; // ...and don't touch any other controls } @@ -5622,7 +5628,7 @@ TController::UpdateSituation(double dt) { if( false == TestFlag( iDrivigFlags, movePress ) ) { // jeśli nie dociskanie if( AccDesired < -0.05 ) { - while( true == DecSpeed() ) { ; } // jeśli hamujemy, to nie przyspieszamy + ZeroSpeed(); } else if( ( vel > VelDesired ) || ( fAccGravity < -0.01 ? @@ -6411,21 +6417,35 @@ void TController::TakeControl(bool yes) void TController::DirectionForward(bool forward) { // ustawienie jazdy do przodu dla true i do tyłu dla false (zależy od kabiny) - while (mvControlling->MainCtrlPos) // samo zapętlenie DecSpeed() nie wystarcza - DecSpeed(true); // wymuszenie zerowania nastawnika jazdy, inaczej się może zawiesić - if (forward) - while (mvOccupied->ActiveDir <= 0) - mvOccupied->DirectionForward(); // do przodu w obecnej kabinie - else - while (mvOccupied->ActiveDir >= 0) - mvOccupied->DirectionBackward(); // do tyłu w obecnej kabinie - if( mvOccupied->TrainType == dt_SN61 ) { - // specjalnie dla SN61 żeby nie zgasł - if( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) { - mvControlling->IncMainCtrl( 1 ); + ZeroSpeed( true ); // TODO: check if force switch is needed anymore here + if( forward ) { + // do przodu w obecnej kabinie + while( ( mvOccupied->ActiveDir <= 0 ) + && ( mvOccupied->DirectionForward() ) ) { + ; // all work is done in the header } } -}; + else { + // do tyłu w obecnej kabinie + while( ( mvOccupied->ActiveDir >= 0 ) + && ( mvOccupied->DirectionBackward() ) ) { + ; // all work is done in the header + } + } + if( mvOccupied->TrainType == dt_SN61 ) { + // specjalnie dla SN61 żeby nie zgasł + while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) + && ( mvControlling->IncMainCtrl( 1 ) ) ) { + ; // all work is done in the header + } + } +} + +void TController::ZeroDirection() { + + while( ( mvOccupied->ActiveDir > 0 ) && ( mvOccupied->DirectionBackward() ) ) { ; } + while( ( mvOccupied->ActiveDir < 0 ) && ( mvOccupied->DirectionForward() ) ) { ; } +} Mtable::TTrainParameters const * TController::TrainTimetable() const { diff --git a/Driver.h b/Driver.h index e1b29651..e437f160 100644 --- a/Driver.h +++ b/Driver.h @@ -211,6 +211,8 @@ private: bool DecBrake(); bool IncSpeed(); bool DecSpeed(bool force = false); + void ZeroSpeed( bool const Enforce = false ); + void ZeroMasterController( bool const Enforce = false ); bool IncBrakeEIM(); bool DecBrakeEIM(); bool IncSpeedEIM(); @@ -224,6 +226,7 @@ private: int CheckDirection(); void WaitingSet(double Seconds); void DirectionForward(bool forward); + void ZeroDirection(); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); void Lights(int head, int rear); std::string StopReasonText() const; diff --git a/DynObj.cpp b/DynObj.cpp index 13366a90..6df4c1ef 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1591,6 +1591,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" Error("Parameters mismatch: dynamic object " + asName + " from \"" + BaseDir + "/" + Type_Name + "\"" ); return 0.0; // zerowa długość to brak pojazdu } + // controller position + MoverParameters->MainCtrlPos = MoverParameters->MainCtrlZeroPos(); // ustawienie pozycji hamulca MoverParameters->LocalBrakePosA = 0.0; if (driveractive) @@ -2969,7 +2971,7 @@ bool TDynamicObject::Update(double dt, double dt1) } MEDLogTime += dt1; - if ((MoverParameters->Vel < 0.1) || (MoverParameters->MainCtrlPos > 0)) + if ((MoverParameters->Vel < 0.1) || (MoverParameters->MainCtrlPowerPos() > 0)) { MEDLogInactiveTime += dt1; } diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index f9b3f0f7..37a57692 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1392,6 +1392,9 @@ public: /*! glowny nastawnik:*/ bool IncMainCtrl(int CtrlSpeed); bool DecMainCtrl(int CtrlSpeed); + bool IsMainCtrlZero() const; + int MainCtrlZeroPos() const; + int MainCtrlPowerPos() const; /*! pomocniczy nastawnik:*/ bool IncScndCtrl(int CtrlSpeed); bool DecScndCtrl(int CtrlSpeed); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 8055009c..38ea60e1 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -502,7 +502,7 @@ bool TMoverParameters::Dettach(int ConnectNo) bool TMoverParameters::DirectionForward() { - if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (MainCtrlPos == 0)) + if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (IsMainCtrlZero())) { ++ActiveDir; DirAbsolute = ActiveDir * CabNo; @@ -512,7 +512,7 @@ bool TMoverParameters::DirectionForward() SendCtrlToNext("Direction", ActiveDir, CabNo); return true; } - else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) + else if ((ActiveDir == 1) && (IsMainCtrlZero()) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) return MinCurrentSwitch(true); //"wysoki rozruch" EN57 return false; }; @@ -641,7 +641,7 @@ TMoverParameters::CurrentSwitch(bool const State) { // for SM42/SP42 if( ( EngineType == TEngineType::DieselElectric ) && ( true == ShuntModeAllow ) - && ( MainCtrlPos == 0 ) ) { + && ( IsMainCtrlZero() ) ) { ShuntMode = State; return true; } @@ -1732,17 +1732,17 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed) case TEngineType::DieselEngine: { - if( CtrlSpeed > 1 ) { - while( MainCtrlPos < MainCtrlPosNo ) { - IncMainCtrl( 1 ); + if( CtrlSpeed > 1 ) { + while( ( MainCtrlPos < MainCtrlPosNo ) + && ( IncMainCtrl( 1 ) ) ) { + ; + } } + else { + ++MainCtrlPos; } - else { - ++MainCtrlPos; - if( MainCtrlPos > 0 ) { CompressorAllow = true; } - else { CompressorAllow = false; } - } - OK = true; + CompressorAllow = ( MainCtrlPowerPos() > 0 ); + OK = true; break; } @@ -1805,6 +1805,7 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed) } else { + // TBD, TODO: replace with mainctrlpowerpos() check? if (MainCtrlPos > 0) { if ((TrainType != dt_ET22) || @@ -1903,6 +1904,25 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed) return OK; } +bool TMoverParameters::IsMainCtrlZero() const { + // TODO: wrap controller pieces into a class for potential specializations, similar to brake subsystems + return MainCtrlPos == MainCtrlZeroPos(); +} + +int TMoverParameters::MainCtrlZeroPos() const { + + switch( EIMCtrlType ) { + case 1: { return 4; } + case 2: { return 2; } + default: { return 0; } + } +} + +int TMoverParameters::MainCtrlPowerPos() const { + + return MainCtrlPos - MainCtrlZeroPos(); +} + // ************************************************************************************************* // Q: 20160710 // zwiększenie bocznika @@ -1911,14 +1931,13 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed) { bool OK = false; - if ((MainCtrlPos == 0) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && - (DynamicBrakeFlag)) + if ((IsMainCtrlZero()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && (DynamicBrakeFlag)) { OK = DynamicBrakeSwitch(false); } else if ((ScndCtrlPosNo > 0) && (CabNo != 0) && !((TrainType == dt_ET42) && - ((Imax == ImaxHi) || ((DynamicBrakeFlag) && (MainCtrlPos > 0))))) + ((Imax == ImaxHi) || ((DynamicBrakeFlag) && (MainCtrlPowerPos() > 0))))) { // if (RList[MainCtrlPos].R=0) and (MainCtrlPos>0) and (ScndCtrlPos0 @@ -2320,13 +2339,16 @@ bool TMoverParameters::EpFuseSwitch(bool State) bool TMoverParameters::DirectionBackward(void) { bool DB = false; - if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) + if ( ( TrainType == dt_EZT ) + && ( EngineType != TEngineType::ElectricInductionMotor ) + && ( ActiveDir == 1 ) + && (IsMainCtrlZero() ) ) if (MinCurrentSwitch(false)) { DB = true; // return DB; // exit; TODO: czy dobrze przetlumaczone? } - if ((MainCtrlPosNo > 0) && (ActiveDir > -1) && (MainCtrlPos == 0)) + if ((MainCtrlPosNo > 0) && (ActiveDir > -1) && (IsMainCtrlZero())) { if (EngineType == TEngineType::WheelsDriven) CabNo--; @@ -2946,7 +2968,7 @@ bool TMoverParameters::DynamicBrakeSwitch(bool Switch) { bool DBS; - if ((DynamicBrakeType == dbrake_switch) && (MainCtrlPos == 0)) + if ((DynamicBrakeType == dbrake_switch) && (IsMainCtrlZero())) { DynamicBrakeFlag = Switch; DBS = true; @@ -3240,7 +3262,7 @@ void TMoverParameters::CompressorCheck(double dt) if( ( true == CompressorAllow ) && ( true == CompressorAllowLocal ) && ( true == Mains ) - && ( MainCtrlPos > 0 ) ) { + && ( MainCtrlPowerPos() > 0 ) ) { if( Compressor < MaxCompressor ) { if( ( EngineType == TEngineType::DieselElectric ) && ( CompressorPower > 0 ) ) { @@ -4489,7 +4511,7 @@ double TMoverParameters::TractionForce( double dt ) { } case TEngineType::DieselEngine: { EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 ); - if( MainCtrlPos > 1 ) { + if( MainCtrlPowerPos() > 1 ) { // dodatkowe opory z powodu sprezarki} dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax ); } @@ -4686,7 +4708,7 @@ double TMoverParameters::TractionForce( double dt ) { auto const tmpV { nrot * Pirazy2 * 0.5 * WheelDiameter * DirAbsolute }; //*CabNo*ActiveDir; // jazda manewrowa if( true == ShuntMode ) { - if( ( true == Mains ) && ( MainCtrlPos > 0 ) ) { + if( ( true == Mains ) && ( MainCtrlPowerPos() > 0 ) ) { Voltage = ( SST[ MainCtrlPos ].Umax * AnPos ) + ( SST[ MainCtrlPos ].Umin * ( 1.0 - AnPos ) ); // NOTE: very crude way to approximate power generated at current rpm instead of instant top output // NOTE, TODO: doesn't take into account potentially increased revolutions if heating is on, fix it @@ -4717,7 +4739,7 @@ double TMoverParameters::TractionForce( double dt ) { PosRatio = currentgenpower / DElist[MainCtrlPosNo].GenPower; // stosunek mocy teraz do mocy max // NOTE: Mains in this context is working diesel engine - if( ( true == Mains ) && ( MainCtrlPos > 0 ) ) { + if( ( true == Mains ) && ( MainCtrlPowerPos() > 0 ) ) { if( tmpV < ( Vhyp * power / DElist[ MainCtrlPosNo ].GenPower ) ) { // czy na czesci prostej, czy na hiperboli @@ -4819,7 +4841,7 @@ double TMoverParameters::TractionForce( double dt ) { Voltage = 0; // przekazniki bocznikowania, kazdy inny dla kazdej pozycji - if ((MainCtrlPos == 0) || (ShuntMode) || (false==Mains)) + if ((IsMainCtrlZero()) || (ShuntMode) || (false==Mains)) ScndCtrlPos = 0; else { @@ -5302,7 +5324,7 @@ bool TMoverParameters::FuseFlagCheck(void) const bool TMoverParameters::FuseOn(void) { bool FO = false; - if ((MainCtrlPos == 0) && (ScndCtrlPos == 0) && (TrainType != dt_ET40) && + if ((IsMainCtrlZero()) && (ScndCtrlPos == 0) && (TrainType != dt_ET40) && ((Mains) || (TrainType != dt_EZT)) && (!TestFlag(EngDmgFlag, 1))) { // w ET40 jest blokada nastawnika, ale czy działa dobrze? SendCtrlToNext("FuseSwitch", 1, CabNo); @@ -5790,7 +5812,7 @@ bool TMoverParameters::MotorConnectorsCheck() { ( false == Mains ) || ( true == FuseFlag ) || ( true == StLinSwitchOff ) - || ( MainCtrlPos == 0 ) + || ( IsMainCtrlZero() ) || ( ActiveDir == 0 ) }; if( connectorsoff ) { return false; } @@ -5798,8 +5820,9 @@ bool TMoverParameters::MotorConnectorsCheck() { auto const connectorson { ( true == StLinFlag ) || ( ( MainCtrlActualPos == 0 ) - && ( ( MainCtrlPos == 1 ) - || ( ( TrainType == dt_EZT ) && ( MainCtrlPos > 0 ) ) ) ) }; + && ( ( TrainType != dt_EZT ? + MainCtrlPowerPos() == 1 : + MainCtrlPowerPos() > 0 ) ) ) }; return connectorson; } @@ -6047,7 +6070,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void) { if (dizel_engagestate > 0) dizel_EngageSwitch(0); - if ((MainCtrlPos == 0) && (ScndCtrlActualPos > 0)) + if ((IsMainCtrlZero()) && (ScndCtrlActualPos > 0)) dizel_automaticgearstatus = -1; } else @@ -6331,10 +6354,10 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt) if (hydro_TC) //jesli przetwornik momentu { //napelnianie przetwornika - if ((MainCtrlPos > 0) && (Mains) && (enrot>dizel_nmin*0.9)) + if ((MainCtrlPowerPos() > 0) && (Mains) && (enrot>dizel_nmin*0.9)) hydro_TC_Fill += hydro_TC_FillRateInc * dt; //oproznianie przetwornika - if (((MainCtrlPos == 0) && (Vel<3)) + if (((IsMainCtrlZero()) && (Vel<3)) || (!Mains) || (enrot hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPos>0)) + if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPowerPos() > 0)) hydro_TC_LockupRate += hydro_TC_FillRateInc*dt; //luzowanie sprzegla blokujacego - if ((Vel < (MainCtrlPos>0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin)) + if ((Vel < (MainCtrlPowerPos() > 0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin)) hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt; //obcinanie zakresu hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0); diff --git a/Train.cpp b/Train.cpp index 9b69059c..3965a602 100644 --- a/Train.cpp +++ b/Train.cpp @@ -782,8 +782,8 @@ void TTrain::OnCommand_jointcontrollerset( TTrain *Train, command_data const &Co clamp( 1.0 - ( Command.param1 * 2 ), 0.0, 1.0 ) ); - if( Train->mvControlled->MainCtrlPos > 0 ) { - Train->set_master_controller( 0 ); + if( Train->mvControlled->MainCtrlPowerPos() > 0 ) { + Train->set_master_controller( Train->mvControlled->MainCtrlZeroPos() ); } } } @@ -839,7 +839,7 @@ void TTrain::OnCommand_mastercontrollerdecrease( TTrain *Train, command_data con if( Command.action != GLFW_RELEASE ) { // on press or hold if( ( Train->ggJointCtrl.SubModel != nullptr ) - && ( Train->mvControlled->MainCtrlPos == 0 ) ) { + && ( Train->mvControlled->IsMainCtrlZero() ) ) { OnCommand_independentbrakeincrease( Train, Command ); } else { @@ -859,7 +859,7 @@ void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data if( Command.action != GLFW_RELEASE ) { // on press or hold if( ( Train->ggJointCtrl.SubModel != nullptr ) - && ( Train->mvControlled->MainCtrlPos == 0 ) ) { + && ( Train->mvControlled->IsMainCtrlZero() ) ) { OnCommand_independentbrakeincreasefast( Train, Command ); } else { From ab16fc17d93dbf7be1d503b1f6c57131dc85e6e5 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 21 Mar 2019 01:36:29 +0100 Subject: [PATCH 07/26] vehicle controllers ai logic fixes --- Driver.cpp | 31 ++++++++++++++--------------- Driver.h | 1 - DynObj.cpp | 2 +- McZapkie/MOVER.h | 10 ++++++---- McZapkie/Mover.cpp | 49 +++++++++++++++++++++++++--------------------- Train.cpp | 6 +++--- 6 files changed, 52 insertions(+), 47 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 50c4be69..f14e01ac 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2706,9 +2706,17 @@ bool TController::IncBrake() } } } + + standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); + if( true == standalone ) { - OK = mvOccupied->IncLocalBrakeLevel( - 1 + static_cast( std::floor( 0.5 + std::fabs( AccDesired ) ) ) ); // hamowanie lokalnym bo luzem jedzie + if( mvControlling->EIMCtrlType > 0 ) { + OK = IncBrakeEIM(); + } + else { + OK = mvOccupied->IncLocalBrakeLevel( + 1 + static_cast( std::floor( 0.5 + std::fabs( AccDesired ) ) ) ); // hamowanie lokalnym bo luzem jedzie + } } else { if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) { @@ -2846,8 +2854,10 @@ bool TController::DecBrake() mvOccupied->BrakeLevelSet(0.0); } } - if (!OK) - OK = mvOccupied->DecLocalBrakeLevel(2); + if( !OK ) { + OK = DecBrakeEIM(); +// OK = mvOccupied->DecLocalBrakeLevel(2); + } if (mvOccupied->PipePress < 3.0) Need_BrakeRelease = true; break; @@ -2936,7 +2946,7 @@ bool TController::IncSpeed() return false; // to nici z ruszania } if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC - if ((mvControlling->IsMainCtrlZero()) || + if ((mvControlling->IsMainCtrlNoPowerPos()) || (mvControlling->StLinFlag)) // youBy polecił dodać 2012-09-08 v367 // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) if (Ready || (iDrivigFlags & movePress)) { @@ -3093,17 +3103,6 @@ void TController::ZeroSpeed( bool const Enforce ) { } } -void TController::ZeroMasterController( bool const Enforce ) { - - // combined controller may be set to braking, i.e. position lower than neutral - auto const neutralposition { mvControlling->MainCtrlZeroPos() }; - while( ( mvControlling->MainCtrlPos < neutralposition ) - && ( DecBrake() ) ) { - ; - } - ZeroSpeed( Enforce ); -} - bool TController::DecSpeed(bool force) { // zmniejszenie prędkości (ale nie hamowanie) bool OK = false; // domyślnie false, aby wyszło z pętli while diff --git a/Driver.h b/Driver.h index e437f160..0c0188e4 100644 --- a/Driver.h +++ b/Driver.h @@ -212,7 +212,6 @@ private: bool IncSpeed(); bool DecSpeed(bool force = false); void ZeroSpeed( bool const Enforce = false ); - void ZeroMasterController( bool const Enforce = false ); bool IncBrakeEIM(); bool DecBrakeEIM(); bool IncSpeedEIM(); diff --git a/DynObj.cpp b/DynObj.cpp index 6df4c1ef..d17294c3 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1592,7 +1592,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" return 0.0; // zerowa długość to brak pojazdu } // controller position - MoverParameters->MainCtrlPos = MoverParameters->MainCtrlZeroPos(); + MoverParameters->MainCtrlPos = MoverParameters->MainCtrlNoPowerPos(); // ustawienie pozycji hamulca MoverParameters->LocalBrakePosA = 0.0; if (driveractive) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 37a57692..782c9fd2 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1208,6 +1208,7 @@ public: int LightsPos = 0; int ActiveDir = 0; //czy lok. jest wlaczona i w ktorym kierunku: //względem wybranej kabiny: -1 - do tylu, +1 - do przodu, 0 - wylaczona + int MaxMainCtrlPosNoDirChange { 0 }; // can't change reverser state with master controller set above this position int CabNo = 0; //numer kabiny, z której jest sterowanie: 1 lub -1; w przeciwnym razie brak sterowania - rozrzad int DirAbsolute = 0; //zadany kierunek jazdy względem sprzęgów (1=w strone 0,-1=w stronę 1) int ActiveCab = 0; //numer kabiny, w ktorej jest obsada (zwykle jedna na skład) @@ -1356,6 +1357,7 @@ public: int DettachStatus(int ConnectNo); bool Dettach(int ConnectNo); bool DirectionForward(); + bool DirectionBackward( void );/*! kierunek ruchu*/ void BrakeLevelSet(double b); bool BrakeLevelAdd(double b); bool IncBrakeLevel(); // wersja na użytek AI @@ -1392,9 +1394,9 @@ public: /*! glowny nastawnik:*/ bool IncMainCtrl(int CtrlSpeed); bool DecMainCtrl(int CtrlSpeed); - bool IsMainCtrlZero() const; - int MainCtrlZeroPos() const; - int MainCtrlPowerPos() const; + bool IsMainCtrlNoPowerPos() const; // whether the master controller is set to position which won't generate any extra power + int MainCtrlNoPowerPos() const; // highest setting of master controller which won't cause engine to generate extra power + int MainCtrlPowerPos() const; // current setting of master controller, relative to the highest setting not generating extra power /*! pomocniczy nastawnik:*/ bool IncScndCtrl(int CtrlSpeed); bool DecScndCtrl(int CtrlSpeed); @@ -1458,7 +1460,6 @@ public: double ComputeRotatingWheel(double WForce, double dt, double n) const; /*--funkcje dla lokomotyw*/ - bool DirectionBackward(void);/*! kierunek ruchu*/ bool WaterPumpBreakerSwitch( bool State, range_t const Notify = range_t::consist ); // water pump breaker state toggle bool WaterPumpSwitch( bool State, range_t const Notify = range_t::consist ); // water pump state toggle bool WaterPumpSwitchOff( bool State, range_t const Notify = range_t::consist ); // water pump state toggle @@ -1582,6 +1583,7 @@ private: bool readLightsList( std::string const &Input ); void BrakeValveDecode( std::string const &s ); //Q 20160719 void BrakeSubsystemDecode(); //Q 20160719 + bool EIMDirectionChangeAllow( void ); }; //double Distance(TLocation Loc1, TLocation Loc2, TDimension Dim1, TDimension Dim2); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 38ea60e1..db89fbf7 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -502,7 +502,7 @@ bool TMoverParameters::Dettach(int ConnectNo) bool TMoverParameters::DirectionForward() { - if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (IsMainCtrlZero())) + if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (MainCtrlPos <= MaxMainCtrlPosNoDirChange) && (EIMDirectionChangeAllow())) { ++ActiveDir; DirAbsolute = ActiveDir * CabNo; @@ -512,7 +512,7 @@ bool TMoverParameters::DirectionForward() SendCtrlToNext("Direction", ActiveDir, CabNo); return true; } - else if ((ActiveDir == 1) && (IsMainCtrlZero()) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) + else if ((ActiveDir == 1) && (IsMainCtrlNoPowerPos()) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) return MinCurrentSwitch(true); //"wysoki rozruch" EN57 return false; }; @@ -641,7 +641,7 @@ TMoverParameters::CurrentSwitch(bool const State) { // for SM42/SP42 if( ( EngineType == TEngineType::DieselElectric ) && ( true == ShuntModeAllow ) - && ( IsMainCtrlZero() ) ) { + && ( IsMainCtrlNoPowerPos() ) ) { ShuntMode = State; return true; } @@ -1904,23 +1904,23 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed) return OK; } -bool TMoverParameters::IsMainCtrlZero() const { +bool TMoverParameters::IsMainCtrlNoPowerPos() const { // TODO: wrap controller pieces into a class for potential specializations, similar to brake subsystems - return MainCtrlPos == MainCtrlZeroPos(); + return MainCtrlPos <= MainCtrlNoPowerPos(); } -int TMoverParameters::MainCtrlZeroPos() const { +int TMoverParameters::MainCtrlNoPowerPos() const { switch( EIMCtrlType ) { - case 1: { return 4; } - case 2: { return 2; } + case 1: { return 3; } + case 2: { return 3; } default: { return 0; } } } int TMoverParameters::MainCtrlPowerPos() const { - return MainCtrlPos - MainCtrlZeroPos(); + return MainCtrlPos - MainCtrlNoPowerPos(); } // ************************************************************************************************* @@ -1931,7 +1931,7 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed) { bool OK = false; - if ((IsMainCtrlZero()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && (DynamicBrakeFlag)) + if ((IsMainCtrlNoPowerPos()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && (DynamicBrakeFlag)) { OK = DynamicBrakeSwitch(false); } @@ -1992,7 +1992,7 @@ bool TMoverParameters::DecScndCtrl(int CtrlSpeed) { bool OK = false; - if ((IsMainCtrlZero()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && + if ((IsMainCtrlNoPowerPos()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && !(DynamicBrakeFlag) && (CtrlSpeed == 1)) { // Ra: AI wywołuje z CtrlSpeed=2 albo gdy ScndCtrlPos>0 @@ -2339,16 +2339,13 @@ bool TMoverParameters::EpFuseSwitch(bool State) bool TMoverParameters::DirectionBackward(void) { bool DB = false; - if ( ( TrainType == dt_EZT ) - && ( EngineType != TEngineType::ElectricInductionMotor ) - && ( ActiveDir == 1 ) - && (IsMainCtrlZero() ) ) + if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) if (MinCurrentSwitch(false)) { DB = true; // return DB; // exit; TODO: czy dobrze przetlumaczone? } - if ((MainCtrlPosNo > 0) && (ActiveDir > -1) && (IsMainCtrlZero())) + if ((MainCtrlPosNo > 0) && (ActiveDir > -1) && (MainCtrlPos <= MaxMainCtrlPosNoDirChange) && (EIMDirectionChangeAllow())) { if (EngineType == TEngineType::WheelsDriven) CabNo--; @@ -2366,6 +2363,13 @@ bool TMoverParameters::DirectionBackward(void) return DB; } +bool TMoverParameters::EIMDirectionChangeAllow(void) +{ + bool OK = false; + OK = (EngineType != TEngineType::ElectricInductionMotor || ((eimic <= 0) && (eimic_real <= 0) && (Vel < 0.1))); + return OK; +} + // ************************************************************************************************* // Q: 20160710 // załączenie przycisku przeciwpoślizgowego @@ -2968,7 +2972,7 @@ bool TMoverParameters::DynamicBrakeSwitch(bool Switch) { bool DBS; - if ((DynamicBrakeType == dbrake_switch) && (IsMainCtrlZero())) + if ((DynamicBrakeType == dbrake_switch) && (IsMainCtrlNoPowerPos())) { DynamicBrakeFlag = Switch; DBS = true; @@ -4841,7 +4845,7 @@ double TMoverParameters::TractionForce( double dt ) { Voltage = 0; // przekazniki bocznikowania, kazdy inny dla kazdej pozycji - if ((IsMainCtrlZero()) || (ShuntMode) || (false==Mains)) + if ((IsMainCtrlNoPowerPos()) || (ShuntMode) || (false==Mains)) ScndCtrlPos = 0; else { @@ -5324,7 +5328,7 @@ bool TMoverParameters::FuseFlagCheck(void) const bool TMoverParameters::FuseOn(void) { bool FO = false; - if ((IsMainCtrlZero()) && (ScndCtrlPos == 0) && (TrainType != dt_ET40) && + if ((IsMainCtrlNoPowerPos()) && (ScndCtrlPos == 0) && (TrainType != dt_ET40) && ((Mains) || (TrainType != dt_EZT)) && (!TestFlag(EngDmgFlag, 1))) { // w ET40 jest blokada nastawnika, ale czy działa dobrze? SendCtrlToNext("FuseSwitch", 1, CabNo); @@ -5812,7 +5816,7 @@ bool TMoverParameters::MotorConnectorsCheck() { ( false == Mains ) || ( true == FuseFlag ) || ( true == StLinSwitchOff ) - || ( IsMainCtrlZero() ) + || ( IsMainCtrlNoPowerPos() ) || ( ActiveDir == 0 ) }; if( connectorsoff ) { return false; } @@ -6070,7 +6074,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void) { if (dizel_engagestate > 0) dizel_EngageSwitch(0); - if ((IsMainCtrlZero()) && (ScndCtrlActualPos > 0)) + if ((IsMainCtrlNoPowerPos()) && (ScndCtrlActualPos > 0)) dizel_automaticgearstatus = -1; } else @@ -6357,7 +6361,7 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt) if ((MainCtrlPowerPos() > 0) && (Mains) && (enrot>dizel_nmin*0.9)) hydro_TC_Fill += hydro_TC_FillRateInc * dt; //oproznianie przetwornika - if (((IsMainCtrlZero()) && (Vel<3)) + if (((IsMainCtrlNoPowerPos()) && (Vel<3)) || (!Mains) || (enrotmvControlled->MainCtrlPowerPos() > 0 ) { - Train->set_master_controller( Train->mvControlled->MainCtrlZeroPos() ); + Train->set_master_controller( Train->mvControlled->MainCtrlNoPowerPos() ); } } } @@ -839,7 +839,7 @@ void TTrain::OnCommand_mastercontrollerdecrease( TTrain *Train, command_data con if( Command.action != GLFW_RELEASE ) { // on press or hold if( ( Train->ggJointCtrl.SubModel != nullptr ) - && ( Train->mvControlled->IsMainCtrlZero() ) ) { + && ( Train->mvControlled->IsMainCtrlNoPowerPos() ) ) { OnCommand_independentbrakeincrease( Train, Command ); } else { @@ -859,7 +859,7 @@ void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data if( Command.action != GLFW_RELEASE ) { // on press or hold if( ( Train->ggJointCtrl.SubModel != nullptr ) - && ( Train->mvControlled->IsMainCtrlZero() ) ) { + && ( Train->mvControlled->IsMainCtrlNoPowerPos() ) ) { OnCommand_independentbrakeincreasefast( Train, Command ); } else { From 72fa1c22a2676df122a0551defe2e72ac0eaece5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 09:50:40 +0100 Subject: [PATCH 08/26] Vehicles with EIMCtrlType>0 use integrated controller instead of localbrake handle --- Driver.cpp | 39 +++++++++++++++++++++++++++++++++++---- Driver.h | 2 ++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index f14e01ac..2fdb2f99 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2707,7 +2707,7 @@ bool TController::IncBrake() } } - standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); + //standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); if( true == standalone ) { if( mvControlling->EIMCtrlType > 0 ) { @@ -2855,9 +2855,11 @@ bool TController::DecBrake() } } if( !OK ) { - OK = DecBrakeEIM(); -// OK = mvOccupied->DecLocalBrakeLevel(2); + OK = mvOccupied->DecLocalBrakeLevel(2); } + if (!OK) { + OK = DecBrakeEIM(); + } if (mvOccupied->PipePress < 3.0) Need_BrakeRelease = true; break; @@ -3352,6 +3354,33 @@ void TController::SpeedCntrl(double DesiredSpeed) } }; +void TController::SetTimeControllers() +{ + +}; + +void TController::CheckTimeControllers() +{ + //1. Check the type of Main Brake Handle + + //2. Check the type of Secondary Brake Handle + + //3. Check the type od EIMCtrlType + if (mvOccupied->EIMCtrlType > 0) + { + if (mvOccupied->EIMCtrlType == 1) //traxx + { + if (mvOccupied->MainCtrlPos > 3) mvOccupied->MainCtrlPos = 5; + if (mvOccupied->MainCtrlPos < 3) mvOccupied->MainCtrlPos = 1; + } + else if (mvOccupied->EIMCtrlType == 2) //elf + { + if (mvOccupied->eimic > 0) mvOccupied->MainCtrlPos = 3; + if (mvOccupied->eimic < 0) mvOccupied->MainCtrlPos = 2; + } + } +}; + // otwieranie/zamykanie drzwi w składzie albo (tylko AI) EZT void TController::Doors( bool const Open, int const Side ) { @@ -4291,6 +4320,8 @@ TController::UpdateSituation(double dt) { auto const reactiontime = std::min( ReactionTime, 2.0 ); if( LastReactionTime < reactiontime ) { return; } + CheckTimeControllers(); + LastReactionTime -= reactiontime; // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ // yB: otóż jest to jedna trzecia czasu napełniania na towarowym; może się przydać przy @@ -5509,7 +5540,7 @@ TController::UpdateSituation(double dt) { } } if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P) { if( mvOccupied->BrakeCtrlPos == -2 ) { mvOccupied->BrakeLevelSet( 0 ); diff --git a/Driver.h b/Driver.h index 0c0188e4..1b7c32bd 100644 --- a/Driver.h +++ b/Driver.h @@ -218,6 +218,8 @@ private: bool DecSpeedEIM(); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); + void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ + void CheckTimeControllers(); /*checking state of time controllers to reset them to stable position*/ double ESMVelocity(bool Main); bool UpdateHeating(); // uaktualnia informacje o prędkości From ef1ccb448acec4bbf76a7570bc81db9eae85d3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 15:27:10 +0100 Subject: [PATCH 09/26] Preparation for rework of main brake handle usage by AI --- Driver.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- Driver.h | 3 +++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Driver.cpp b/Driver.cpp index 2fdb2f99..e61d9db7 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -3181,6 +3181,16 @@ bool TController::DecSpeedEIM() return OK; } +bool TController::BrakeLevelSet(double b) +{ + return false; +} + +bool TController::BrakeLevelAdd(double b) +{ + return false; +} + void TController::SpeedSet() { // Ra: regulacja prędkości, wykonywana w każdym przebłysku świadomości AI // ma dokręcać do bezoporowych i zdejmować pozycje w przypadku przekroczenia prądu @@ -3356,13 +3366,52 @@ void TController::SpeedCntrl(double DesiredSpeed) void TController::SetTimeControllers() { + //1. Check the type of Main Brake Handle + if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) + { + if (mvOccupied->Handle->Time) + { + if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); + else if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + else if (BrakeCtrlPosition == 0) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + else if (BrakeCtrlPosition == -1) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); + } + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); + } + //2. Check the type of Secondary Brake Handle + //3. Check the type od EIMCtrlType + if (mvOccupied->EIMCtrlType > 0) + { + if (mvOccupied->EIMCtrlType == 1) //traxx + { + if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 0; + } + else if (mvOccupied->EIMCtrlType == 2) //elf + { + if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 1; + } + } }; void TController::CheckTimeControllers() { //1. Check the type of Main Brake Handle - + if (mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP) + { + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN)); + } + if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic && mvOccupied->Handle->Time) + { + if (BrakeCtrlPosition > 0) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); + else + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + } //2. Check the type of Secondary Brake Handle //3. Check the type od EIMCtrlType diff --git a/Driver.h b/Driver.h index 1b7c32bd..0b8156bc 100644 --- a/Driver.h +++ b/Driver.h @@ -216,6 +216,8 @@ private: bool DecBrakeEIM(); bool IncSpeedEIM(); bool DecSpeedEIM(); + bool BrakeLevelSet(double b); + bool BrakeLevelAdd(double b); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ @@ -310,6 +312,7 @@ private: double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently + double BrakeCtrlPosition = 0.0; // intermediate position of main brake controller double LastReactionTime = 0.0; double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations From 3fd408bd46759d38c4ea4fb9132d1f93c7d39f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 17:25:05 +0100 Subject: [PATCH 10/26] Reworked main brake handle usage by AI - it can use time-dependent handles now. --- Driver.cpp | 104 ++++++++++++++++++++++++++----------------- Driver.h | 8 +++- McZapkie/hamulce.cpp | 6 ++- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index e61d9db7..e9fdf7c9 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1776,6 +1776,7 @@ void TController::Activation() // zaworze maszynisty, FVel6 po drugiej stronie nie luzuje mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos(bh_NP)); // odcięcie na zaworze maszynisty + BrakeLevelSet(gbh_NP); //ustawienie zmiennej GBH } mvOccupied->ActiveCab = mvOccupied->CabNo; // użytkownik moze zmienić ActiveCab wychodząc mvOccupied->CabDeactivisation(); // tak jest w Train.cpp @@ -2354,7 +2355,7 @@ double TController::BrakeAccFactor() const double Factor = 1.0; if( ( ActualProximityDist > fMinProximityDist ) || ( mvOccupied->Vel > VelDesired + fVelPlus ) ) { - Factor += ( fBrakeReaction * ( mvOccupied->BrakeCtrlPosR < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); + Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); } return Factor; } @@ -2393,7 +2394,7 @@ void TController::SetDriverPsyche() { // with Controlling do if (mvControlling->MainCtrlPowerPos() < 3) ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime; - if (mvOccupied->BrakeCtrlPos > 1) + if (/* GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 1) ReactionTime = 0.5 * ReactionTime; } }; @@ -2518,6 +2519,7 @@ bool TController::PrepareEngine() // enable train brake if it's off if( mvOccupied->fBrakeCtrlPos == mvOccupied->Handle->GetPos( bh_NP ) ) { mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + BrakeLevelSet(gbh_RP); // GBH } } } @@ -2719,9 +2721,9 @@ bool TController::IncBrake() } } else { - if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == mvOccupied->BrakeCtrlPosNo ) { if (AccDesired < -1.5) // hamowanie nagle - OK = mvOccupied->BrakeLevelAdd(1.0); + OK = /*mvOccupied->*/BrakeLevelAdd(1.0); //GBH else OK = false; } @@ -2745,12 +2747,12 @@ bool TController::IncBrake() pos_corr += mvOccupied->Handle->GetCP()*0.2; } - double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (mvOccupied->BrakeCtrlPosR - 1 - pos_corr)*fBrake_a1[0]); + double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition - 1 - pos_corr)*fBrake_a1[0]); if( deltaAcc > fBrake_a1[0]) { - if( mvOccupied->BrakeCtrlPosR < 0.1 ) { - OK = mvOccupied->BrakeLevelAdd( BrakingInitialLevel ); + if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) { + OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH /* // HACK: stronger braking to overcome SA134 engine behaviour if( ( mvOccupied->TrainType == dt_DMU ) @@ -2765,19 +2767,23 @@ bool TController::IncBrake() } else { - OK = mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); + OK = /*mvOccupied->*/BrakeLevelAdd( BrakingLevelIncrease ); //GBH // brake harder if the acceleration is much higher than desired - if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) + /*if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) && ( mvOccupied->BrakeCtrlPosR + BrakingLevelIncrease <= 5.0 ) ) { mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); - } + } GBH */ + if ((deltaAcc > 2 * fBrake_a1[0]) + && (BrakeCtrlPosition + BrakingLevelIncrease <= 5.0)) { + /*mvOccupied->*/BrakeLevelAdd(BrakingLevelIncrease); + } } } else OK = false; } } - if( mvOccupied->BrakeCtrlPos > 0 ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 0 ) { mvOccupied->BrakeReleaser( 0 ); } break; @@ -2842,16 +2848,17 @@ bool TController::DecBrake() OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case TBrakeSystem::Pneumatic: - deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR-1.0)*fBrake_a1[0]); + deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition -1.0)*fBrake_a1[0]); if (deltaAcc < 0) { - if (mvOccupied->BrakeCtrlPosR > 0) + if (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition > 0) { - OK = mvOccupied->BrakeLevelAdd(-0.25); + OK = /*mvOccupied->*/BrakeLevelAdd(-0.25); //if ((deltaAcc < 5 * fBrake_a1[0]) && (mvOccupied->BrakeCtrlPosR >= 1.2)) // mvOccupied->BrakeLevelAdd(-1.0); - if (mvOccupied->BrakeCtrlPosR < 0.74) - mvOccupied->BrakeLevelSet(0.0); + /* if (mvOccupied->BrakeCtrlPosR < 0.74) GBH */ + if (BrakeCtrlPosition < 0.74) + /*mvOccupied->*/BrakeLevelSet(0.0); } } if( !OK ) { @@ -3181,14 +3188,20 @@ bool TController::DecSpeedEIM() return OK; } -bool TController::BrakeLevelSet(double b) -{ - return false; +void TController::BrakeLevelSet(double b) +{ // ustawienie pozycji hamulca na wartość (b) w zakresie od -2 do BrakeCtrlPosNo + // jedyny dopuszczalny sposób przestawienia hamulca zasadniczego + if (BrakeCtrlPosition == b) + return; // nie przeliczać, jak nie ma zmiany + BrakeCtrlPosition = clamp(b, (double)gbh_MIN, (double)gbh_MAX); } bool TController::BrakeLevelAdd(double b) -{ - return false; +{ // dodanie wartości (b) do pozycji hamulca (w tym ujemnej) + // zwraca false, gdy po dodaniu było by poza zakresem + BrakeLevelSet(BrakeCtrlPosition + b); + return b > 0.0 ? (BrakeCtrlPosition < gbh_MAX) : + (BrakeCtrlPosition > -1.0); // true, jeśli można kontynuować } void TController::SpeedSet() @@ -3371,14 +3384,16 @@ void TController::SetTimeControllers() { if (mvOccupied->Handle->Time) { - if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) - mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); - else if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FB)); + else if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); else if (BrakeCtrlPosition == 0) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); else if (BrakeCtrlPosition == -1) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); + else if (BrakeCtrlPosition == -2) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); } if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); } @@ -3389,11 +3404,11 @@ void TController::SetTimeControllers() { if (mvOccupied->EIMCtrlType == 1) //traxx { - if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 0; + if (mvOccupied->LocalBrakePosA > 0.95) mvOccupied->MainCtrlPos = 0; } else if (mvOccupied->EIMCtrlType == 2) //elf { - if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 1; + if (mvOccupied->LocalBrakePosA > 0.95) mvOccupied->MainCtrlPos = 1; } } }; @@ -4103,7 +4118,7 @@ TController::UpdateSituation(double dt) { // Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka... if (AIControllFlag) // skład jak dotąd był wyluzowany { - if( ( mvOccupied->BrakeCtrlPos == 0 ) // jest pozycja jazdy + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) // jest pozycja jazdy && ( ( vehicle->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken && ( vehicle->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy && ( vehicle->Hamulec->GetCRP() > vehicle->PipePress + 0.12 ) ) { // za dużo w zbiorniku @@ -4490,12 +4505,13 @@ TController::UpdateSituation(double dt) { if( mvOccupied->SecuritySystem.Status > 1 ) { // jak zadziałało CA/SHP if( !mvOccupied->SecuritySystemReset() ) { // to skasuj - if( ( mvOccupied->BrakeCtrlPos == 0 ) + if( ( /*mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) && ( AccDesired > 0.0 ) && ( ( TestFlag( mvOccupied->SecuritySystem.Status, s_SHPebrake ) ) || ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAebrake ) ) ) ) { //!!! hm, może po prostu normalnie sterować hamulcem? - mvOccupied->BrakeLevelSet( 0 ); + //mvOccupied->BrakeLevelSet( 0 ); GBH + BrakeLevelSet(gbh_RP); } } } @@ -4897,7 +4913,8 @@ TController::UpdateSituation(double dt) { // (ustalić po czym poznać taki tor) ++n; // to liczymy człony jako jeden p->MoverParameters->BrakeReleaser(1); // wyluzuj pojazd, aby dało się dopychać - p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował + // GBH p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował + BrakeLevelSet(gbh_RP); if (n) { // jeśli jeszcze nie koniec p = p->Prev(); // kolejny w stronę czoła składu (licząc od tyłu), bo dociskamy @@ -5589,17 +5606,18 @@ TController::UpdateSituation(double dt) { } } if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P) + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P + || mvOccupied->BrakeHandle == TBrakeHandle::M394) { - if( mvOccupied->BrakeCtrlPos == -2 ) { - mvOccupied->BrakeLevelSet( 0 ); + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == -2 ) { + /*mvOccupied->*/BrakeLevelSet( gbh_RP ); } if( ( mvOccupied->PipePress < 3.0 ) && ( AccDesired > -0.03 ) ) { mvOccupied->BrakeReleaser( 1 ); } - if( ( mvOccupied->BrakeCtrlPos == 0 ) + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) && ( AbsAccS < 0.03 ) && ( AccDesired > -0.03 ) && ( VelDesired - mvOccupied->Vel > 2.0 ) ) { @@ -5611,7 +5629,8 @@ TController::UpdateSituation(double dt) { if( ( iDrivigFlags & moveOerlikons ) || ( true == IsCargoTrain ) ) { // napełnianie w Oerlikonie - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); + /* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */ + BrakeLevelSet(gbh_FS); // don't charge the brakes too often, or we risk overcharging BrakeChargingCooldown = -120.0; } @@ -5622,9 +5641,10 @@ TController::UpdateSituation(double dt) { } } - if( ( mvOccupied->BrakeCtrlPos < 0 ) + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) && ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) { - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + /* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */ + BrakeLevelSet(gbh_RP); } } #if LOGVELOCITY @@ -5727,7 +5747,7 @@ TController::UpdateSituation(double dt) { std::max( -0.2, fAccThreshold ) ) }; if( ( AccDesired <= accthreshold ) // jeśli hamować - u góry ustawia się hamowanie na fAccThreshold && ( ( AbsAccS > AccDesired ) - || ( mvOccupied->BrakeCtrlPos < 0 ) ) ) { + || ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) ) ) { // hamować bardziej, gdy aktualne opóźnienie hamowania mniejsze niż (AccDesired) IncBrake(); } @@ -5735,7 +5755,7 @@ TController::UpdateSituation(double dt) { // przy odłączaniu nie zwalniamy tu hamulca if( AbsAccS < AccDesired - 0.05 ) { // jeśli opóźnienie większe od wymaganego (z histerezą) luzowanie, gdy za dużo - if( mvOccupied->BrakeCtrlPos >= 0 ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition >= 0 ) { DecBrake(); // tutaj zmniejszało o 1 przy odczepianiu } } @@ -5758,7 +5778,7 @@ TController::UpdateSituation(double dt) { // u góry ustawia się hamowanie na fAccThreshold if( ( fBrakeTime < 0.0 ) || ( AccDesired < fAccGravity - 0.5 ) - || ( mvOccupied->BrakeCtrlPos <= 0 ) ) { + || ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition <= 0 ) ) { // jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował if( true == IncBrake() ) { fBrakeTime = @@ -5831,13 +5851,15 @@ TController::UpdateSituation(double dt) { mvOccupied->IncLocalBrakeLevel( 1 ); } else { - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); //GBH + BrakeLevelSet(gbh_RP); } } } } break; // rzeczy robione przy jezdzie } // switch (OrderList[OrderPos]) + if (AIControllFlag) SetTimeControllers(); } // configures vehicle heating given current situation; returns: true if vehicle can be operated normally, false otherwise diff --git a/Driver.h b/Driver.h index 0b8156bc..1c4034d1 100644 --- a/Driver.h +++ b/Driver.h @@ -169,6 +169,12 @@ static const int maxorders = 64; // ilość rozkazów w tabelce static const int maxdriverfails = 4; // ile błędów może zrobić AI zanim zmieni nastawienie extern bool WriteLogFlag; // logowanie parametrów fizycznych static const int BrakeAccTableSize = 20; + +static const int gbh_NP = -2; //odciecie w hamulcu ogolnym +static const int gbh_RP = 0; //jazda w hamulcu ogolnym +static const int gbh_FS = -1; //napelnianie uderzeniowe w hamulcu ogolnym +static const int gbh_MIN = -2; //minimalna pozycja w hamulcu ogolnym +static const int gbh_MAX = 6; //maksymalna pozycja w hamulcu ogolnym //---------------------------------------------------------------------------- class TController { @@ -216,7 +222,7 @@ private: bool DecBrakeEIM(); bool IncSpeedEIM(); bool DecSpeedEIM(); - bool BrakeLevelSet(double b); + void BrakeLevelSet(double b); bool BrakeLevelAdd(double b); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 47bbebe6..8916b2cd 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -2788,7 +2788,7 @@ double TMHZ_K5P::GetPos(int i) double TMHZ_K5P::GetCP() { - return RP; + return CP; } void TMHZ_K5P::SetParams(bool AO, bool MO, double, double) @@ -2890,6 +2890,8 @@ double TMHZ_6P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) void TMHZ_6P::Init(double Press) { CP = Press; + Time = true; + TimeEP = true; } void TMHZ_6P::SetReductor(double nAdj) @@ -2912,7 +2914,7 @@ double TMHZ_6P::GetPos(int i) double TMHZ_6P::GetCP() { - return RP; + return CP; } void TMHZ_6P::SetParams(bool AO, bool MO, double OverP, double) From 403c29746d01a187d52dec6d1a702f2fe961cf03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 17:47:16 +0100 Subject: [PATCH 11/26] AI does not fear accelerating a bit too fast --- Driver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Driver.cpp b/Driver.cpp index e9fdf7c9..8ac0229f 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5732,8 +5732,9 @@ TController::UpdateSituation(double dt) { else if( ( vel > VelDesired ) || ( fAccGravity < -0.01 ? AccDesired < 0.0 : - AbsAccS > AccDesired ) ) { + (AbsAccS > AccDesired && AccDesired < 0.75) ) ) { // jak za bardzo przyspiesza albo prędkość przekroczona + // dodany wyjatek na "pelna w przod" DecSpeed(); // pojedyncze cofnięcie pozycji, bo na zero to przesada } } From 91a7a94682ea8c3c7d8dc948878c2ff91446fc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 21:47:35 +0100 Subject: [PATCH 12/26] Fix for autoreturning controller --- Driver.cpp | 4 +++- McZapkie/MOVER.h | 19 +++++++++++++++ McZapkie/Mover.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 8ac0229f..120e1ef1 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4384,7 +4384,9 @@ TController::UpdateSituation(double dt) { auto const reactiontime = std::min( ReactionTime, 2.0 ); if( LastReactionTime < reactiontime ) { return; } - CheckTimeControllers(); + if (AIControllFlag) { + CheckTimeControllers(); + } LastReactionTime -= reactiontime; // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 782c9fd2..77ed3e3f 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -96,6 +96,7 @@ static int const maxcc = 4; /*max. ilosc odbierakow pradu*/ //static int const MainBrakeMaxPos = 10; /*max. ilosc nastaw hamulca zasadniczego*/ static int const ManualBrakePosNo = 20; /*ilosc nastaw hamulca recznego*/ static int const LightsSwitchPosNo = 16; +static int const UniversalCtrlArraySize = 32; /*max liczba pozycji uniwersalnego nastawnika*/ /*uszkodzenia toru*/ static int const dtrack_railwear = 2; @@ -572,6 +573,20 @@ struct TMotorParameters } }; +struct TUniversalCtrl +{ + int mode = 0; /*tryb pracy zadajnika - pomocnicze*/ + double MinCtrlVal = 0.0; /*minimalna wartosc nastawy*/ + double MaxCtrlVal = 0.0; /*maksymalna wartosc nastawy*/ + double SetCtrlVal = 0.0; /*docelowa wartosc nastawy*/ + double SpeedUp = 0.0; /*szybkosc zwiekszania nastawy*/ + double SpeedDown = 0.0; /*szybkosc zmniejszania nastawy*/ + int ReturnPosition = 0; /*pozycja na ktora odskakuje zadajnik*/ + int NextPosFastInc = 0; /*nastepna duza pozycja przy przechodzeniu szybkim*/ + int PrevPosFastDec = 0; /*poprzednia duza pozycja przy przechodzeniu szybkim*/ +}; +typedef TUniversalCtrl TUniversalCtrlTable[UniversalCtrlArraySize + 1]; /*tablica sterowania uniwersalnego nastawnika*/ + struct TSecuritySystem { int SystemType { 0 }; /*0: brak, 1: czuwak aktywny, 2: SHP/sygnalizacja kabinowa*/ @@ -940,6 +955,8 @@ public: bool MBrake = false; /*Czy jest hamulec reczny*/ double StopBrakeDecc = 0.0; TSecuritySystem SecuritySystem; + TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/ + int UniCtrlListSize = 0; /*wielkosc listy pozycji uniwersalnego nastawnika*/ /*-sekcja parametrow dla lokomotywy elektrycznej*/ TSchemeTable RList; /*lista rezystorow rozruchowych i polaczen silnikow, dla dizla: napelnienia*/ @@ -1563,6 +1580,7 @@ private: void LoadFIZ_MotorParamTable( std::string const &Input ); void LoadFIZ_Circuit( std::string const &Input ); void LoadFIZ_RList( std::string const &Input ); + void LoadFIZ_UCList(std::string const &Input); void LoadFIZ_DList( std::string const &Input ); void LoadFIZ_FFList( std::string const &Input ); void LoadFIZ_LightsList( std::string const &Input ); @@ -1577,6 +1595,7 @@ private: bool readMPTDieselEngine( std::string const &line ); bool readBPT(/*int const ln,*/ std::string const &line); //Q 20160721 bool readRList( std::string const &Input ); + bool readUCList(std::string const &Input); bool readDList( std::string const &line ); bool readFFList( std::string const &line ); bool readWWList( std::string const &line ); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index db89fbf7..acad6b49 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5994,6 +5994,10 @@ void TMoverParameters::CheckEIMIC(double dt) break; } break; + case 3: + eimic -= clamp(-UniCtrlList[MainCtrlPos].SetCtrlVal + eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedDown); //odejmuj do X + eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedUp); //dodawaj do X + eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal); } eimic = clamp(eimic, -1.0, 1.0); } @@ -7242,7 +7246,7 @@ bool TMoverParameters::switch_physics(bool const State) // DO PRZETLUMACZENIA NA // ************************************************************************************************* bool startBPT; bool startMPT, startMPT0; -bool startRLIST; +bool startRLIST, startUCLIST; bool startDLIST, startFFLIST, startWWLIST; bool startLIGHTSLIST; int LISTLINE; @@ -7437,6 +7441,31 @@ bool TMoverParameters::readRList( std::string const &Input ) { return true; } +bool TMoverParameters::readUCList(std::string const &line) { + + cParser parser(line); + parser.getTokens(10, false); + auto idx = LISTLINE++; + if (idx >= sizeof(UniCtrlList) / sizeof(TUniversalCtrl)) { + WriteLog("Read UCList: number of entries exceeded capacity of the data table"); + return false; + } + int i = 0; + parser + >> i + >> UniCtrlList[idx].mode + >> UniCtrlList[idx].MinCtrlVal + >> UniCtrlList[idx].MaxCtrlVal + >> UniCtrlList[idx].SetCtrlVal + >> UniCtrlList[idx].SpeedUp + >> UniCtrlList[idx].SpeedDown + >> UniCtrlList[idx].ReturnPosition + >> UniCtrlList[idx].NextPosFastInc + >> UniCtrlList[idx].PrevPosFastDec; + + return true; +} + bool TMoverParameters::readDList( std::string const &line ) { cParser parser( line ); @@ -7626,6 +7655,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) startMPT = false; startMPT0 = false; startRLIST = false; + startUCLIST = false; startDLIST = false; startFFLIST = false; startWWLIST = false; @@ -7677,6 +7707,11 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) startRLIST = false; continue; } + if (issection("END-RL", inputline)) { + startBPT = false; + startUCLIST = false; + continue; + } if( issection( "END-DL", inputline ) ) { startBPT = false; startDLIST = false; @@ -7880,6 +7915,15 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) continue; } + if (issection("UCList:", inputline)) + { + startBPT = false; + fizlines.emplace("UCList", inputline); + startUCLIST = true; LISTLINE = 0; + LoadFIZ_RList(inputline); + continue; + } + if( issection( "DList:", inputline ) ) { startBPT = false; @@ -7929,6 +7973,10 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) readRList( inputline ); continue; } + if (true == startUCLIST) { + readRList(inputline); + continue; + } if( true == startDLIST ) { readDList( inputline ); continue; @@ -8537,7 +8585,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { extract_value( CoupledCtrl, "CoupledCtrl", line, "" ); extract_value( EIMCtrlType, "EIMCtrlType", line, "" ); - clamp( EIMCtrlType, 0, 2 ); + clamp( EIMCtrlType, 0, 3 ); extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR @@ -8966,6 +9014,12 @@ void TMoverParameters::LoadFIZ_RList( std::string const &Input ) { extract_value( DynamicBrakeRes2, "DynBrakeRes2", Input, ""); } +void TMoverParameters::LoadFIZ_UCList(std::string const &Input) { + + extract_value(UniCtrlListSize, "Size", Input, ""); + +} + void TMoverParameters::LoadFIZ_DList( std::string const &Input ) { extract_value( dizel_Mmax, "Mmax", Input, "" ); From be63aa74524993518579146bee1ee3429ab7fc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 23:17:41 +0100 Subject: [PATCH 13/26] Fix for Handle=H14K1 with BrakeValve=K --- Driver.cpp | 2 +- McZapkie/hamulce.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 120e1ef1..15c969e2 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2721,7 +2721,7 @@ bool TController::IncBrake() } } else { - if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == mvOccupied->BrakeCtrlPosNo ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == gbh_MAX ) { if (AccDesired < -1.5) // hamowanie nagle OK = /*mvOccupied->*/BrakeLevelAdd(1.0); //GBH else diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 8916b2cd..3544b002 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -346,7 +346,7 @@ double TBrake::GetVRP() // cisnienie zbiornika sterujacego double TBrake::GetCRP() { - return 0; + return GetBRP(); } // przeplyw z przewodu glowneg From 3f12f9231faefd7e94e61899ac37cd320dcc7d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 09:50:40 +0100 Subject: [PATCH 14/26] Vehicles with EIMCtrlType>0 use integrated controller instead of localbrake handle --- Driver.cpp | 39 +++++++++++++++++++++++++++++++++++---- Driver.h | 2 ++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index f14e01ac..2fdb2f99 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2707,7 +2707,7 @@ bool TController::IncBrake() } } - standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); + //standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); if( true == standalone ) { if( mvControlling->EIMCtrlType > 0 ) { @@ -2855,9 +2855,11 @@ bool TController::DecBrake() } } if( !OK ) { - OK = DecBrakeEIM(); -// OK = mvOccupied->DecLocalBrakeLevel(2); + OK = mvOccupied->DecLocalBrakeLevel(2); } + if (!OK) { + OK = DecBrakeEIM(); + } if (mvOccupied->PipePress < 3.0) Need_BrakeRelease = true; break; @@ -3352,6 +3354,33 @@ void TController::SpeedCntrl(double DesiredSpeed) } }; +void TController::SetTimeControllers() +{ + +}; + +void TController::CheckTimeControllers() +{ + //1. Check the type of Main Brake Handle + + //2. Check the type of Secondary Brake Handle + + //3. Check the type od EIMCtrlType + if (mvOccupied->EIMCtrlType > 0) + { + if (mvOccupied->EIMCtrlType == 1) //traxx + { + if (mvOccupied->MainCtrlPos > 3) mvOccupied->MainCtrlPos = 5; + if (mvOccupied->MainCtrlPos < 3) mvOccupied->MainCtrlPos = 1; + } + else if (mvOccupied->EIMCtrlType == 2) //elf + { + if (mvOccupied->eimic > 0) mvOccupied->MainCtrlPos = 3; + if (mvOccupied->eimic < 0) mvOccupied->MainCtrlPos = 2; + } + } +}; + // otwieranie/zamykanie drzwi w składzie albo (tylko AI) EZT void TController::Doors( bool const Open, int const Side ) { @@ -4291,6 +4320,8 @@ TController::UpdateSituation(double dt) { auto const reactiontime = std::min( ReactionTime, 2.0 ); if( LastReactionTime < reactiontime ) { return; } + CheckTimeControllers(); + LastReactionTime -= reactiontime; // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ // yB: otóż jest to jedna trzecia czasu napełniania na towarowym; może się przydać przy @@ -5509,7 +5540,7 @@ TController::UpdateSituation(double dt) { } } if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P) { if( mvOccupied->BrakeCtrlPos == -2 ) { mvOccupied->BrakeLevelSet( 0 ); diff --git a/Driver.h b/Driver.h index 0c0188e4..1b7c32bd 100644 --- a/Driver.h +++ b/Driver.h @@ -218,6 +218,8 @@ private: bool DecSpeedEIM(); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); + void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ + void CheckTimeControllers(); /*checking state of time controllers to reset them to stable position*/ double ESMVelocity(bool Main); bool UpdateHeating(); // uaktualnia informacje o prędkości From 019a0c2cf6c9598be71ac4b09a3953e33d02ee26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 15:27:10 +0100 Subject: [PATCH 15/26] Preparation for rework of main brake handle usage by AI --- Driver.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- Driver.h | 3 +++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Driver.cpp b/Driver.cpp index 2fdb2f99..e61d9db7 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -3181,6 +3181,16 @@ bool TController::DecSpeedEIM() return OK; } +bool TController::BrakeLevelSet(double b) +{ + return false; +} + +bool TController::BrakeLevelAdd(double b) +{ + return false; +} + void TController::SpeedSet() { // Ra: regulacja prędkości, wykonywana w każdym przebłysku świadomości AI // ma dokręcać do bezoporowych i zdejmować pozycje w przypadku przekroczenia prądu @@ -3356,13 +3366,52 @@ void TController::SpeedCntrl(double DesiredSpeed) void TController::SetTimeControllers() { + //1. Check the type of Main Brake Handle + if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) + { + if (mvOccupied->Handle->Time) + { + if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); + else if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + else if (BrakeCtrlPosition == 0) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + else if (BrakeCtrlPosition == -1) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); + } + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); + } + //2. Check the type of Secondary Brake Handle + //3. Check the type od EIMCtrlType + if (mvOccupied->EIMCtrlType > 0) + { + if (mvOccupied->EIMCtrlType == 1) //traxx + { + if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 0; + } + else if (mvOccupied->EIMCtrlType == 2) //elf + { + if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 1; + } + } }; void TController::CheckTimeControllers() { //1. Check the type of Main Brake Handle - + if (mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP) + { + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN)); + } + if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic && mvOccupied->Handle->Time) + { + if (BrakeCtrlPosition > 0) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); + else + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + } //2. Check the type of Secondary Brake Handle //3. Check the type od EIMCtrlType diff --git a/Driver.h b/Driver.h index 1b7c32bd..0b8156bc 100644 --- a/Driver.h +++ b/Driver.h @@ -216,6 +216,8 @@ private: bool DecBrakeEIM(); bool IncSpeedEIM(); bool DecSpeedEIM(); + bool BrakeLevelSet(double b); + bool BrakeLevelAdd(double b); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ @@ -310,6 +312,7 @@ private: double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently + double BrakeCtrlPosition = 0.0; // intermediate position of main brake controller double LastReactionTime = 0.0; double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations From a3af2453a06f6ae0a1b1c57b93c648bbcea42b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 17:25:05 +0100 Subject: [PATCH 16/26] Reworked main brake handle usage by AI - it can use time-dependent handles now. --- Driver.cpp | 104 ++++++++++++++++++++++++++----------------- Driver.h | 8 +++- McZapkie/hamulce.cpp | 6 ++- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index e61d9db7..e9fdf7c9 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1776,6 +1776,7 @@ void TController::Activation() // zaworze maszynisty, FVel6 po drugiej stronie nie luzuje mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos(bh_NP)); // odcięcie na zaworze maszynisty + BrakeLevelSet(gbh_NP); //ustawienie zmiennej GBH } mvOccupied->ActiveCab = mvOccupied->CabNo; // użytkownik moze zmienić ActiveCab wychodząc mvOccupied->CabDeactivisation(); // tak jest w Train.cpp @@ -2354,7 +2355,7 @@ double TController::BrakeAccFactor() const double Factor = 1.0; if( ( ActualProximityDist > fMinProximityDist ) || ( mvOccupied->Vel > VelDesired + fVelPlus ) ) { - Factor += ( fBrakeReaction * ( mvOccupied->BrakeCtrlPosR < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); + Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); } return Factor; } @@ -2393,7 +2394,7 @@ void TController::SetDriverPsyche() { // with Controlling do if (mvControlling->MainCtrlPowerPos() < 3) ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime; - if (mvOccupied->BrakeCtrlPos > 1) + if (/* GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 1) ReactionTime = 0.5 * ReactionTime; } }; @@ -2518,6 +2519,7 @@ bool TController::PrepareEngine() // enable train brake if it's off if( mvOccupied->fBrakeCtrlPos == mvOccupied->Handle->GetPos( bh_NP ) ) { mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + BrakeLevelSet(gbh_RP); // GBH } } } @@ -2719,9 +2721,9 @@ bool TController::IncBrake() } } else { - if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == mvOccupied->BrakeCtrlPosNo ) { if (AccDesired < -1.5) // hamowanie nagle - OK = mvOccupied->BrakeLevelAdd(1.0); + OK = /*mvOccupied->*/BrakeLevelAdd(1.0); //GBH else OK = false; } @@ -2745,12 +2747,12 @@ bool TController::IncBrake() pos_corr += mvOccupied->Handle->GetCP()*0.2; } - double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (mvOccupied->BrakeCtrlPosR - 1 - pos_corr)*fBrake_a1[0]); + double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition - 1 - pos_corr)*fBrake_a1[0]); if( deltaAcc > fBrake_a1[0]) { - if( mvOccupied->BrakeCtrlPosR < 0.1 ) { - OK = mvOccupied->BrakeLevelAdd( BrakingInitialLevel ); + if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) { + OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH /* // HACK: stronger braking to overcome SA134 engine behaviour if( ( mvOccupied->TrainType == dt_DMU ) @@ -2765,19 +2767,23 @@ bool TController::IncBrake() } else { - OK = mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); + OK = /*mvOccupied->*/BrakeLevelAdd( BrakingLevelIncrease ); //GBH // brake harder if the acceleration is much higher than desired - if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) + /*if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) && ( mvOccupied->BrakeCtrlPosR + BrakingLevelIncrease <= 5.0 ) ) { mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); - } + } GBH */ + if ((deltaAcc > 2 * fBrake_a1[0]) + && (BrakeCtrlPosition + BrakingLevelIncrease <= 5.0)) { + /*mvOccupied->*/BrakeLevelAdd(BrakingLevelIncrease); + } } } else OK = false; } } - if( mvOccupied->BrakeCtrlPos > 0 ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 0 ) { mvOccupied->BrakeReleaser( 0 ); } break; @@ -2842,16 +2848,17 @@ bool TController::DecBrake() OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case TBrakeSystem::Pneumatic: - deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR-1.0)*fBrake_a1[0]); + deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition -1.0)*fBrake_a1[0]); if (deltaAcc < 0) { - if (mvOccupied->BrakeCtrlPosR > 0) + if (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition > 0) { - OK = mvOccupied->BrakeLevelAdd(-0.25); + OK = /*mvOccupied->*/BrakeLevelAdd(-0.25); //if ((deltaAcc < 5 * fBrake_a1[0]) && (mvOccupied->BrakeCtrlPosR >= 1.2)) // mvOccupied->BrakeLevelAdd(-1.0); - if (mvOccupied->BrakeCtrlPosR < 0.74) - mvOccupied->BrakeLevelSet(0.0); + /* if (mvOccupied->BrakeCtrlPosR < 0.74) GBH */ + if (BrakeCtrlPosition < 0.74) + /*mvOccupied->*/BrakeLevelSet(0.0); } } if( !OK ) { @@ -3181,14 +3188,20 @@ bool TController::DecSpeedEIM() return OK; } -bool TController::BrakeLevelSet(double b) -{ - return false; +void TController::BrakeLevelSet(double b) +{ // ustawienie pozycji hamulca na wartość (b) w zakresie od -2 do BrakeCtrlPosNo + // jedyny dopuszczalny sposób przestawienia hamulca zasadniczego + if (BrakeCtrlPosition == b) + return; // nie przeliczać, jak nie ma zmiany + BrakeCtrlPosition = clamp(b, (double)gbh_MIN, (double)gbh_MAX); } bool TController::BrakeLevelAdd(double b) -{ - return false; +{ // dodanie wartości (b) do pozycji hamulca (w tym ujemnej) + // zwraca false, gdy po dodaniu było by poza zakresem + BrakeLevelSet(BrakeCtrlPosition + b); + return b > 0.0 ? (BrakeCtrlPosition < gbh_MAX) : + (BrakeCtrlPosition > -1.0); // true, jeśli można kontynuować } void TController::SpeedSet() @@ -3371,14 +3384,16 @@ void TController::SetTimeControllers() { if (mvOccupied->Handle->Time) { - if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) - mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); - else if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FB)); + else if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); else if (BrakeCtrlPosition == 0) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); else if (BrakeCtrlPosition == -1) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); + else if (BrakeCtrlPosition == -2) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); } if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); } @@ -3389,11 +3404,11 @@ void TController::SetTimeControllers() { if (mvOccupied->EIMCtrlType == 1) //traxx { - if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 0; + if (mvOccupied->LocalBrakePosA > 0.95) mvOccupied->MainCtrlPos = 0; } else if (mvOccupied->EIMCtrlType == 2) //elf { - if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 1; + if (mvOccupied->LocalBrakePosA > 0.95) mvOccupied->MainCtrlPos = 1; } } }; @@ -4103,7 +4118,7 @@ TController::UpdateSituation(double dt) { // Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka... if (AIControllFlag) // skład jak dotąd był wyluzowany { - if( ( mvOccupied->BrakeCtrlPos == 0 ) // jest pozycja jazdy + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) // jest pozycja jazdy && ( ( vehicle->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken && ( vehicle->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy && ( vehicle->Hamulec->GetCRP() > vehicle->PipePress + 0.12 ) ) { // za dużo w zbiorniku @@ -4490,12 +4505,13 @@ TController::UpdateSituation(double dt) { if( mvOccupied->SecuritySystem.Status > 1 ) { // jak zadziałało CA/SHP if( !mvOccupied->SecuritySystemReset() ) { // to skasuj - if( ( mvOccupied->BrakeCtrlPos == 0 ) + if( ( /*mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) && ( AccDesired > 0.0 ) && ( ( TestFlag( mvOccupied->SecuritySystem.Status, s_SHPebrake ) ) || ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAebrake ) ) ) ) { //!!! hm, może po prostu normalnie sterować hamulcem? - mvOccupied->BrakeLevelSet( 0 ); + //mvOccupied->BrakeLevelSet( 0 ); GBH + BrakeLevelSet(gbh_RP); } } } @@ -4897,7 +4913,8 @@ TController::UpdateSituation(double dt) { // (ustalić po czym poznać taki tor) ++n; // to liczymy człony jako jeden p->MoverParameters->BrakeReleaser(1); // wyluzuj pojazd, aby dało się dopychać - p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował + // GBH p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował + BrakeLevelSet(gbh_RP); if (n) { // jeśli jeszcze nie koniec p = p->Prev(); // kolejny w stronę czoła składu (licząc od tyłu), bo dociskamy @@ -5589,17 +5606,18 @@ TController::UpdateSituation(double dt) { } } if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P) + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P + || mvOccupied->BrakeHandle == TBrakeHandle::M394) { - if( mvOccupied->BrakeCtrlPos == -2 ) { - mvOccupied->BrakeLevelSet( 0 ); + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == -2 ) { + /*mvOccupied->*/BrakeLevelSet( gbh_RP ); } if( ( mvOccupied->PipePress < 3.0 ) && ( AccDesired > -0.03 ) ) { mvOccupied->BrakeReleaser( 1 ); } - if( ( mvOccupied->BrakeCtrlPos == 0 ) + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) && ( AbsAccS < 0.03 ) && ( AccDesired > -0.03 ) && ( VelDesired - mvOccupied->Vel > 2.0 ) ) { @@ -5611,7 +5629,8 @@ TController::UpdateSituation(double dt) { if( ( iDrivigFlags & moveOerlikons ) || ( true == IsCargoTrain ) ) { // napełnianie w Oerlikonie - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); + /* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */ + BrakeLevelSet(gbh_FS); // don't charge the brakes too often, or we risk overcharging BrakeChargingCooldown = -120.0; } @@ -5622,9 +5641,10 @@ TController::UpdateSituation(double dt) { } } - if( ( mvOccupied->BrakeCtrlPos < 0 ) + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) && ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) { - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + /* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */ + BrakeLevelSet(gbh_RP); } } #if LOGVELOCITY @@ -5727,7 +5747,7 @@ TController::UpdateSituation(double dt) { std::max( -0.2, fAccThreshold ) ) }; if( ( AccDesired <= accthreshold ) // jeśli hamować - u góry ustawia się hamowanie na fAccThreshold && ( ( AbsAccS > AccDesired ) - || ( mvOccupied->BrakeCtrlPos < 0 ) ) ) { + || ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) ) ) { // hamować bardziej, gdy aktualne opóźnienie hamowania mniejsze niż (AccDesired) IncBrake(); } @@ -5735,7 +5755,7 @@ TController::UpdateSituation(double dt) { // przy odłączaniu nie zwalniamy tu hamulca if( AbsAccS < AccDesired - 0.05 ) { // jeśli opóźnienie większe od wymaganego (z histerezą) luzowanie, gdy za dużo - if( mvOccupied->BrakeCtrlPos >= 0 ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition >= 0 ) { DecBrake(); // tutaj zmniejszało o 1 przy odczepianiu } } @@ -5758,7 +5778,7 @@ TController::UpdateSituation(double dt) { // u góry ustawia się hamowanie na fAccThreshold if( ( fBrakeTime < 0.0 ) || ( AccDesired < fAccGravity - 0.5 ) - || ( mvOccupied->BrakeCtrlPos <= 0 ) ) { + || ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition <= 0 ) ) { // jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował if( true == IncBrake() ) { fBrakeTime = @@ -5831,13 +5851,15 @@ TController::UpdateSituation(double dt) { mvOccupied->IncLocalBrakeLevel( 1 ); } else { - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); //GBH + BrakeLevelSet(gbh_RP); } } } } break; // rzeczy robione przy jezdzie } // switch (OrderList[OrderPos]) + if (AIControllFlag) SetTimeControllers(); } // configures vehicle heating given current situation; returns: true if vehicle can be operated normally, false otherwise diff --git a/Driver.h b/Driver.h index 0b8156bc..1c4034d1 100644 --- a/Driver.h +++ b/Driver.h @@ -169,6 +169,12 @@ static const int maxorders = 64; // ilość rozkazów w tabelce static const int maxdriverfails = 4; // ile błędów może zrobić AI zanim zmieni nastawienie extern bool WriteLogFlag; // logowanie parametrów fizycznych static const int BrakeAccTableSize = 20; + +static const int gbh_NP = -2; //odciecie w hamulcu ogolnym +static const int gbh_RP = 0; //jazda w hamulcu ogolnym +static const int gbh_FS = -1; //napelnianie uderzeniowe w hamulcu ogolnym +static const int gbh_MIN = -2; //minimalna pozycja w hamulcu ogolnym +static const int gbh_MAX = 6; //maksymalna pozycja w hamulcu ogolnym //---------------------------------------------------------------------------- class TController { @@ -216,7 +222,7 @@ private: bool DecBrakeEIM(); bool IncSpeedEIM(); bool DecSpeedEIM(); - bool BrakeLevelSet(double b); + void BrakeLevelSet(double b); bool BrakeLevelAdd(double b); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 47bbebe6..8916b2cd 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -2788,7 +2788,7 @@ double TMHZ_K5P::GetPos(int i) double TMHZ_K5P::GetCP() { - return RP; + return CP; } void TMHZ_K5P::SetParams(bool AO, bool MO, double, double) @@ -2890,6 +2890,8 @@ double TMHZ_6P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) void TMHZ_6P::Init(double Press) { CP = Press; + Time = true; + TimeEP = true; } void TMHZ_6P::SetReductor(double nAdj) @@ -2912,7 +2914,7 @@ double TMHZ_6P::GetPos(int i) double TMHZ_6P::GetCP() { - return RP; + return CP; } void TMHZ_6P::SetParams(bool AO, bool MO, double OverP, double) From ea8b38489a51619ddd5456af120ded2bd1e4da63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 17:47:16 +0100 Subject: [PATCH 17/26] AI does not fear accelerating a bit too fast --- Driver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Driver.cpp b/Driver.cpp index e9fdf7c9..8ac0229f 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5732,8 +5732,9 @@ TController::UpdateSituation(double dt) { else if( ( vel > VelDesired ) || ( fAccGravity < -0.01 ? AccDesired < 0.0 : - AbsAccS > AccDesired ) ) { + (AbsAccS > AccDesired && AccDesired < 0.75) ) ) { // jak za bardzo przyspiesza albo prędkość przekroczona + // dodany wyjatek na "pelna w przod" DecSpeed(); // pojedyncze cofnięcie pozycji, bo na zero to przesada } } From 75cc0b2a2412d35e3da323288b7090d1a42e1ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 21:47:35 +0100 Subject: [PATCH 18/26] Fix for autoreturning controller --- Driver.cpp | 4 +++- McZapkie/MOVER.h | 19 +++++++++++++++ McZapkie/Mover.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 8ac0229f..120e1ef1 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4384,7 +4384,9 @@ TController::UpdateSituation(double dt) { auto const reactiontime = std::min( ReactionTime, 2.0 ); if( LastReactionTime < reactiontime ) { return; } - CheckTimeControllers(); + if (AIControllFlag) { + CheckTimeControllers(); + } LastReactionTime -= reactiontime; // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 782c9fd2..77ed3e3f 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -96,6 +96,7 @@ static int const maxcc = 4; /*max. ilosc odbierakow pradu*/ //static int const MainBrakeMaxPos = 10; /*max. ilosc nastaw hamulca zasadniczego*/ static int const ManualBrakePosNo = 20; /*ilosc nastaw hamulca recznego*/ static int const LightsSwitchPosNo = 16; +static int const UniversalCtrlArraySize = 32; /*max liczba pozycji uniwersalnego nastawnika*/ /*uszkodzenia toru*/ static int const dtrack_railwear = 2; @@ -572,6 +573,20 @@ struct TMotorParameters } }; +struct TUniversalCtrl +{ + int mode = 0; /*tryb pracy zadajnika - pomocnicze*/ + double MinCtrlVal = 0.0; /*minimalna wartosc nastawy*/ + double MaxCtrlVal = 0.0; /*maksymalna wartosc nastawy*/ + double SetCtrlVal = 0.0; /*docelowa wartosc nastawy*/ + double SpeedUp = 0.0; /*szybkosc zwiekszania nastawy*/ + double SpeedDown = 0.0; /*szybkosc zmniejszania nastawy*/ + int ReturnPosition = 0; /*pozycja na ktora odskakuje zadajnik*/ + int NextPosFastInc = 0; /*nastepna duza pozycja przy przechodzeniu szybkim*/ + int PrevPosFastDec = 0; /*poprzednia duza pozycja przy przechodzeniu szybkim*/ +}; +typedef TUniversalCtrl TUniversalCtrlTable[UniversalCtrlArraySize + 1]; /*tablica sterowania uniwersalnego nastawnika*/ + struct TSecuritySystem { int SystemType { 0 }; /*0: brak, 1: czuwak aktywny, 2: SHP/sygnalizacja kabinowa*/ @@ -940,6 +955,8 @@ public: bool MBrake = false; /*Czy jest hamulec reczny*/ double StopBrakeDecc = 0.0; TSecuritySystem SecuritySystem; + TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/ + int UniCtrlListSize = 0; /*wielkosc listy pozycji uniwersalnego nastawnika*/ /*-sekcja parametrow dla lokomotywy elektrycznej*/ TSchemeTable RList; /*lista rezystorow rozruchowych i polaczen silnikow, dla dizla: napelnienia*/ @@ -1563,6 +1580,7 @@ private: void LoadFIZ_MotorParamTable( std::string const &Input ); void LoadFIZ_Circuit( std::string const &Input ); void LoadFIZ_RList( std::string const &Input ); + void LoadFIZ_UCList(std::string const &Input); void LoadFIZ_DList( std::string const &Input ); void LoadFIZ_FFList( std::string const &Input ); void LoadFIZ_LightsList( std::string const &Input ); @@ -1577,6 +1595,7 @@ private: bool readMPTDieselEngine( std::string const &line ); bool readBPT(/*int const ln,*/ std::string const &line); //Q 20160721 bool readRList( std::string const &Input ); + bool readUCList(std::string const &Input); bool readDList( std::string const &line ); bool readFFList( std::string const &line ); bool readWWList( std::string const &line ); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index db89fbf7..acad6b49 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5994,6 +5994,10 @@ void TMoverParameters::CheckEIMIC(double dt) break; } break; + case 3: + eimic -= clamp(-UniCtrlList[MainCtrlPos].SetCtrlVal + eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedDown); //odejmuj do X + eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedUp); //dodawaj do X + eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal); } eimic = clamp(eimic, -1.0, 1.0); } @@ -7242,7 +7246,7 @@ bool TMoverParameters::switch_physics(bool const State) // DO PRZETLUMACZENIA NA // ************************************************************************************************* bool startBPT; bool startMPT, startMPT0; -bool startRLIST; +bool startRLIST, startUCLIST; bool startDLIST, startFFLIST, startWWLIST; bool startLIGHTSLIST; int LISTLINE; @@ -7437,6 +7441,31 @@ bool TMoverParameters::readRList( std::string const &Input ) { return true; } +bool TMoverParameters::readUCList(std::string const &line) { + + cParser parser(line); + parser.getTokens(10, false); + auto idx = LISTLINE++; + if (idx >= sizeof(UniCtrlList) / sizeof(TUniversalCtrl)) { + WriteLog("Read UCList: number of entries exceeded capacity of the data table"); + return false; + } + int i = 0; + parser + >> i + >> UniCtrlList[idx].mode + >> UniCtrlList[idx].MinCtrlVal + >> UniCtrlList[idx].MaxCtrlVal + >> UniCtrlList[idx].SetCtrlVal + >> UniCtrlList[idx].SpeedUp + >> UniCtrlList[idx].SpeedDown + >> UniCtrlList[idx].ReturnPosition + >> UniCtrlList[idx].NextPosFastInc + >> UniCtrlList[idx].PrevPosFastDec; + + return true; +} + bool TMoverParameters::readDList( std::string const &line ) { cParser parser( line ); @@ -7626,6 +7655,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) startMPT = false; startMPT0 = false; startRLIST = false; + startUCLIST = false; startDLIST = false; startFFLIST = false; startWWLIST = false; @@ -7677,6 +7707,11 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) startRLIST = false; continue; } + if (issection("END-RL", inputline)) { + startBPT = false; + startUCLIST = false; + continue; + } if( issection( "END-DL", inputline ) ) { startBPT = false; startDLIST = false; @@ -7880,6 +7915,15 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) continue; } + if (issection("UCList:", inputline)) + { + startBPT = false; + fizlines.emplace("UCList", inputline); + startUCLIST = true; LISTLINE = 0; + LoadFIZ_RList(inputline); + continue; + } + if( issection( "DList:", inputline ) ) { startBPT = false; @@ -7929,6 +7973,10 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) readRList( inputline ); continue; } + if (true == startUCLIST) { + readRList(inputline); + continue; + } if( true == startDLIST ) { readDList( inputline ); continue; @@ -8537,7 +8585,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { extract_value( CoupledCtrl, "CoupledCtrl", line, "" ); extract_value( EIMCtrlType, "EIMCtrlType", line, "" ); - clamp( EIMCtrlType, 0, 2 ); + clamp( EIMCtrlType, 0, 3 ); extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR @@ -8966,6 +9014,12 @@ void TMoverParameters::LoadFIZ_RList( std::string const &Input ) { extract_value( DynamicBrakeRes2, "DynBrakeRes2", Input, ""); } +void TMoverParameters::LoadFIZ_UCList(std::string const &Input) { + + extract_value(UniCtrlListSize, "Size", Input, ""); + +} + void TMoverParameters::LoadFIZ_DList( std::string const &Input ) { extract_value( dizel_Mmax, "Mmax", Input, "" ); From df068534d4927e96dbcfaabfaac78f8d1df7345c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 23:17:41 +0100 Subject: [PATCH 19/26] Fix for Handle=H14K1 with BrakeValve=K --- Driver.cpp | 2 +- McZapkie/hamulce.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 120e1ef1..15c969e2 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2721,7 +2721,7 @@ bool TController::IncBrake() } } else { - if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == mvOccupied->BrakeCtrlPosNo ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == gbh_MAX ) { if (AccDesired < -1.5) // hamowanie nagle OK = /*mvOccupied->*/BrakeLevelAdd(1.0); //GBH else diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 8916b2cd..3544b002 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -346,7 +346,7 @@ double TBrake::GetVRP() // cisnienie zbiornika sterujacego double TBrake::GetCRP() { - return 0; + return GetBRP(); } // przeplyw z przewodu glowneg From faaabf116b9247ea7827963d7d0c80230ffca00d Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 22 Mar 2019 15:45:20 +0100 Subject: [PATCH 20/26] build 190322. support for vehicle load visualization model override, skydome brightness tweaks --- DynObj.cpp | 25 ++++++++++++++++++++++++- DynObj.h | 1 + simulationenvironment.cpp | 5 +++++ skydome.cpp | 2 +- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index d17294c3..41856d78 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -4332,6 +4332,20 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co mdLowPolyInt = TModelsManager::GetModel(asModel, true); } + else if(token == "loads:") { + // default load visualization models overrides + // content provided as "key: value" pairs together enclosed in "{}" + // value can be optionally set of values enclosed in "[]" in which case one value will be picked randomly + while( ( ( token = parser.getToken() ) != "" ) + && ( token != "}" ) ) { + if( token[ token.size() - 1 ] == ':' ) { + auto loadmodel { deserialize_random_set( parser ) }; + replace_slashes( loadmodel ); + LoadModelOverrides.emplace( token.erase( token.size() - 1 ), loadmodel ); + } + } + } + else if( token == "brakemode:" ) { // Ra 15-01: gałka nastawy hamulca parser.getTokens(); @@ -5644,8 +5658,17 @@ TDynamicObject::LoadMMediaFile_mdload( std::string const &Name ) const { if( Name.empty() ) { return nullptr; } - // try first specialized version of the load model, vehiclename_loadname TModel3d *loadmodel { nullptr }; + + // check if we don't have model override for this load type + auto const lookup { LoadModelOverrides.find( Name ) }; + if( lookup != LoadModelOverrides.end() ) { + loadmodel = TModelsManager::GetModel( asBaseDir + lookup->second, true ); + // if the override was succesfully loaded call it a day + if( loadmodel != nullptr ) { return loadmodel; } + } + // regular routine if there's no override or it couldn't be loaded + // try first specialized version of the load model, vehiclename_loadname auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + Name }; if( ( true == FileExists( specializedloadfilename + ".e3d" ) ) || ( true == FileExists( specializedloadfilename + ".t3d" ) ) ) { diff --git a/DynObj.h b/DynObj.h index 2ae80db9..f683cce9 100644 --- a/DynObj.h +++ b/DynObj.h @@ -202,6 +202,7 @@ public: bool JointCabs{ false }; // flag for vehicles with multiple virtual 'cabs' sharing location and 3d model(s) float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?) float LoadOffset { 0.f }; + std::unordered_map LoadModelOverrides; // potential overrides of default load visualization models glm::vec3 InteriorLight { 0.9f * 255.f / 255.f, 0.9f * 216.f / 255.f, 0.9f * 176.f / 255.f }; // tungsten light. TODO: allow definition of light type? float InteriorLightLevel { 0.0f }; // current level of interior lighting struct vehicle_section { diff --git a/simulationenvironment.cpp b/simulationenvironment.cpp index 2bc27b25..0a980c1d 100644 --- a/simulationenvironment.cpp +++ b/simulationenvironment.cpp @@ -118,6 +118,11 @@ world_environment::update() { duskfactor ); } // ...update skydome to match the current sun position as well... + // turbidity varies from 2-3 during the day based on overcast, 3-4 after sunset to deal with sunlight bleeding too much into the sky from below horizon + m_skydome.SetTurbidity( + 2.f + + clamp( Global.Overcast, 0.f, 1.f ) + + interpolate( 0.f, 1.f, clamp( twilightfactor * 1.5f, 0.f, 1.f ) ) ); m_skydome.SetOvercastFactor( Global.Overcast ); m_skydome.Update( m_sun.getDirection() ); // ...retrieve current sky colour and brightness... diff --git a/skydome.cpp b/skydome.cpp index 020ead60..c09a0d37 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -169,7 +169,7 @@ bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) { void CSkyDome::SetTurbidity( float const Turbidity ) { - m_turbidity = clamp( Turbidity, 1.0f, 512.0f ); + m_turbidity = clamp( Turbidity, 1.f, 4.f ); } void CSkyDome::SetExposure( bool const Linearexposure, float const Expfactor ) { From 14e3a2702672e5cdd6a4e1f197638be176dc2e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 22 Mar 2019 20:26:59 +0100 Subject: [PATCH 21/26] AI does not fear SlippingWheels when driving ElectricInductionMotor vehicle + fix for adhesion calculation when slipping --- Driver.cpp | 2 +- McZapkie/Mover.cpp | 26 +++++++++++++------------- driveruipanels.cpp | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 15c969e2..9c82e860 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5542,7 +5542,7 @@ TController::UpdateSituation(double dt) { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy // zapobieganie poslizgowi u nas - if (mvControlling->SlippingWheels) { + if (mvControlling->SlippingWheels && mvControlling->EngineType != TEngineType::ElectricInductionMotor) { if( false == mvControlling->DecScndCtrl( 2 ) ) { // bocznik na zero diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index acad6b49..2dfc3537 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4001,12 +4001,18 @@ void TMoverParameters::ComputeTotalForce(double dt) { && ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) { SlippingWheels = true; } - if( true == SlippingWheels ) { + double temp_nrot = nrot; + if (true == SlippingWheels) { - double temp_nrot = ComputeRotatingWheel(Fwheels - - Sign(nrot * M_PI * WheelDiameter - V) * - Adhesive(RunningTrack.friction) * TotalMassxg, - dt, nrot); + temp_nrot = ComputeRotatingWheel(Fwheels - Sign(nrot * M_PI * WheelDiameter - V) * + Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); + if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) + { + SlippingWheels = false; + temp_nrot = V / M_PI / WheelDiameter; + } + } + if (true == SlippingWheels) { Fwheels = Sign(temp_nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction); if (Fwheels*Sign(V)>0) { @@ -4025,12 +4031,6 @@ void TMoverParameters::ComputeTotalForce(double dt) { { WheelFlat = sqrt(square(WheelFlat) + abs(Fwheels) / NAxles*Vel*0.000002); } - if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) - { - SlippingWheels = false; - temp_nrot = V / M_PI / WheelDiameter; - } - nrot = temp_nrot; } @@ -5368,9 +5368,9 @@ double TMoverParameters::v2n(void) n = V / (M_PI * WheelDiameter); // predkosc obrotowa wynikajaca z liniowej [obr/s] deltan = n - nrot; //"pochodna" prędkości obrotowej - if (SlippingWheels) + /* if (SlippingWheels) if (std::abs(deltan) < 0.001) - SlippingWheels = false; // wygaszenie poslizgu + SlippingWheels = false; // wygaszenie poslizgu */ //poslizg jest w innym miejscu wygaszany też if (SlippingWheels) // nie ma zwiazku z predkoscia liniowa V { // McZapkie-221103: uszkodzenia kol podczas poslizgu if (deltan > dmgn) diff --git a/driveruipanels.cpp b/driveruipanels.cpp index f10ae4c9..bcd5c623 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -820,7 +820,8 @@ debug_panel::update_section_ai( std::vector &Output ) { + ", slope: " + to_string( mechanik.fAccGravity + 0.001f, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")" + "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 ) + ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) - + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ); + + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ) + + "\n virtual brake position: " + to_string(mechanik.BrakeCtrlPosition, 2); Output.emplace_back( textline, Global.UITextColor ); From 73af7673122e680cb4591429fae1c3cb4769251f Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 22 Mar 2019 21:43:36 +0100 Subject: [PATCH 22/26] audio transcript sound volume based filtering, minor ai logic fixes --- Driver.cpp | 10 ++++++---- audiorenderer.h | 4 +--- driveruipanels.cpp | 4 ++-- sound.cpp | 7 +++++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 15c969e2..e8226dc5 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4950,10 +4950,12 @@ TController::UpdateSituation(double dt) { // za radą yB ustawiamy pozycję 3 kranu (ruszanie kranem w innych miejscach // powino zostać wyłączone) // WriteLog("Zahamowanie składu"); - mvOccupied->BrakeLevelSet( - mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ? - 1 : - 3 ); + if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) { + mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) ); + } + else { + BrakeCtrlPosition = 3; + } double p = mvOccupied->BrakePressureActual.PipePressureVal; if( p < 3.9 ) { // tu może być 0 albo -1 nawet diff --git a/audiorenderer.h b/audiorenderer.h index 22ec13f7..260d0850 100644 --- a/audiorenderer.h +++ b/audiorenderer.h @@ -172,9 +172,7 @@ openal_source::bind( sound_source *Controller, uint32_sequence Sounds, Iterator_ First, Last, [&]( audio::buffer_handle const &bufferhandle ) { auto const &buffer { audio::renderer.buffer( bufferhandle ) }; - buffers.emplace_back( buffer.id ); - if( false == buffer.caption.empty() ) { - ui::Transcripts.Add( buffer.caption ); } } ); + buffers.emplace_back( buffer.id ); } ); if( id != audio::null_resource ) { ::alSourceQueueBuffers( id, static_cast( buffers.size() ), buffers.data() ); diff --git a/driveruipanels.cpp b/driveruipanels.cpp index f10ae4c9..ad323770 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -211,7 +211,7 @@ scenario_panel::render() { auto const assignmentheader { locale::strings[ locale::string::driver_scenario_assignment ] }; if( ( false == owner->assignment().empty() ) && ( true == ImGui::CollapsingHeader( assignmentheader.c_str() ) ) ) { - ImGui::TextWrapped( owner->assignment().c_str() ); + ImGui::TextWrapped( "%s", owner->assignment().c_str() ); ImGui::Separator(); } } @@ -1034,7 +1034,7 @@ transcripts_panel::render() { if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) { // header section for( auto const &line : text_lines ) { - ImGui::TextWrapped( line.data.c_str() ); + ImGui::TextWrapped( "%s", line.data.c_str() ); } } ImGui::End(); diff --git a/sound.cpp b/sound.cpp index 702c31f7..f3306e78 100644 --- a/sound.cpp +++ b/sound.cpp @@ -861,6 +861,13 @@ sound_source::update_counter( sound_handle const Sound, int const Value ) { // sound( Sound ).playing = std::max( 0, sound( Sound ).playing + Value ); sound( Sound ).playing += Value; + if( ( m_properties.gain > 0.f ) + && ( sound( Sound ).playing == 1 ) ) { + auto const &buffer { audio::renderer.buffer( sound( Sound ).buffer ) }; + if( false == buffer.caption.empty() ) { + ui::Transcripts.Add( buffer.caption ); + } + } assert( sound( Sound ).playing >= 0 ); } From a767e36be87cc8070d36dca19d4e1edcc0d79892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 22 Mar 2019 20:26:59 +0100 Subject: [PATCH 23/26] AI does not fear SlippingWheels when driving ElectricInductionMotor vehicle + fix for adhesion calculation when slipping --- Driver.cpp | 2 +- McZapkie/Mover.cpp | 26 +++++++++++++------------- driveruipanels.cpp | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index e8226dc5..8af73c5d 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5544,7 +5544,7 @@ TController::UpdateSituation(double dt) { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy // zapobieganie poslizgowi u nas - if (mvControlling->SlippingWheels) { + if (mvControlling->SlippingWheels && mvControlling->EngineType != TEngineType::ElectricInductionMotor) { if( false == mvControlling->DecScndCtrl( 2 ) ) { // bocznik na zero diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index acad6b49..2dfc3537 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4001,12 +4001,18 @@ void TMoverParameters::ComputeTotalForce(double dt) { && ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) { SlippingWheels = true; } - if( true == SlippingWheels ) { + double temp_nrot = nrot; + if (true == SlippingWheels) { - double temp_nrot = ComputeRotatingWheel(Fwheels - - Sign(nrot * M_PI * WheelDiameter - V) * - Adhesive(RunningTrack.friction) * TotalMassxg, - dt, nrot); + temp_nrot = ComputeRotatingWheel(Fwheels - Sign(nrot * M_PI * WheelDiameter - V) * + Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); + if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) + { + SlippingWheels = false; + temp_nrot = V / M_PI / WheelDiameter; + } + } + if (true == SlippingWheels) { Fwheels = Sign(temp_nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction); if (Fwheels*Sign(V)>0) { @@ -4025,12 +4031,6 @@ void TMoverParameters::ComputeTotalForce(double dt) { { WheelFlat = sqrt(square(WheelFlat) + abs(Fwheels) / NAxles*Vel*0.000002); } - if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) - { - SlippingWheels = false; - temp_nrot = V / M_PI / WheelDiameter; - } - nrot = temp_nrot; } @@ -5368,9 +5368,9 @@ double TMoverParameters::v2n(void) n = V / (M_PI * WheelDiameter); // predkosc obrotowa wynikajaca z liniowej [obr/s] deltan = n - nrot; //"pochodna" prędkości obrotowej - if (SlippingWheels) + /* if (SlippingWheels) if (std::abs(deltan) < 0.001) - SlippingWheels = false; // wygaszenie poslizgu + SlippingWheels = false; // wygaszenie poslizgu */ //poslizg jest w innym miejscu wygaszany też if (SlippingWheels) // nie ma zwiazku z predkoscia liniowa V { // McZapkie-221103: uszkodzenia kol podczas poslizgu if (deltan > dmgn) diff --git a/driveruipanels.cpp b/driveruipanels.cpp index ad323770..1a9c8815 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -820,7 +820,8 @@ debug_panel::update_section_ai( std::vector &Output ) { + ", slope: " + to_string( mechanik.fAccGravity + 0.001f, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")" + "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 ) + ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) - + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ); + + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ) + + "\n virtual brake position: " + to_string(mechanik.BrakeCtrlPosition, 2); Output.emplace_back( textline, Global.UITextColor ); From ae5daac939be20b7041d011b4ac1a593cf6aa3d7 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 23 Mar 2019 01:54:26 +0100 Subject: [PATCH 24/26] minor bug fixes --- Driver.cpp | 9 ++++++--- driveruipanels.cpp | 6 ++---- simulationenvironment.cpp | 19 +++++++++++-------- uitranscripts.cpp | 24 +++++++++++++++++++----- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 8af73c5d..39c1d15b 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1408,9 +1408,12 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // if (v==0.0) fAcc=-0.9; //hamowanie jeśli stop continue; // i tyle wystarczy } - else // event trzyma tylko jeśli VelNext=0, nawet po przejechaniu (nie powinno - // dotyczyć samochodów?) - a = (v == 0.0 ? -1.0 : fAcc); // ruszanie albo hamowanie + else // event trzyma tylko jeśli VelNext=0, nawet po przejechaniu (nie powinno dotyczyć samochodów?) + a = (v > 0.0 ? + fAcc : + mvOccupied->Vel < 0.01 ? + 0.0 : // already standing still so no need to bother with brakes + -2.0 ); // ruszanie albo hamowanie if ((a < fAcc) && (v == std::min(v, fNext))) { // mniejsze przyspieszenie to mniejsza możliwość rozpędzenia się albo konieczność hamowania diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 1a9c8815..8efa947d 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -1003,10 +1003,8 @@ transcripts_panel::update() { text_lines.clear(); for( auto const &transcript : ui::Transcripts.aLines ) { - if( Global.fTimeAngleDeg >= transcript.fShow ) { - // NOTE: legacy transcript lines use | as new line mark - text_lines.emplace_back( ExchangeCharInString( transcript.asText, '|', ' ' ), colors::white ); - } + if( Global.fTimeAngleDeg + ( transcript.fShow - Global.fTimeAngleDeg > 180 ? 360 : 0 ) < transcript.fShow ) { continue; } + text_lines.emplace_back( ExchangeCharInString( transcript.asText, '|', ' ' ), colors::white ); } } diff --git a/simulationenvironment.cpp b/simulationenvironment.cpp index 0a980c1d..f105faa2 100644 --- a/simulationenvironment.cpp +++ b/simulationenvironment.cpp @@ -92,6 +92,17 @@ world_environment::update() { // NOTE: sun light receives extra padding to prevent moon from kicking in too soon auto const sunlightlevel = m_sun.getIntensity() + 0.05f * ( 1.f - twilightfactor ); auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise + + // ...update skydome to match the current sun position as well... + // twilight factor can be reset later down, so we do it here while it's still reflecting state of the sun + // turbidity varies from 2-3 during the day based on overcast, 3-4 after sunset to deal with sunlight bleeding too much into the sky from below horizon + m_skydome.SetTurbidity( + 2.f + + clamp( Global.Overcast, 0.f, 1.f ) + + interpolate( 0.f, 1.f, clamp( twilightfactor * 1.5f, 0.f, 1.f ) ) ); + m_skydome.SetOvercastFactor( Global.Overcast ); + m_skydome.Update( m_sun.getDirection() ); + float keylightintensity; glm::vec3 keylightcolor; if( moonlightlevel > sunlightlevel ) { @@ -117,14 +128,6 @@ world_environment::update() { glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ), duskfactor ); } - // ...update skydome to match the current sun position as well... - // turbidity varies from 2-3 during the day based on overcast, 3-4 after sunset to deal with sunlight bleeding too much into the sky from below horizon - m_skydome.SetTurbidity( - 2.f - + clamp( Global.Overcast, 0.f, 1.f ) - + interpolate( 0.f, 1.f, clamp( twilightfactor * 1.5f, 0.f, 1.f ) ) ); - m_skydome.SetOvercastFactor( Global.Overcast ); - m_skydome.Update( m_sun.getDirection() ); // ...retrieve current sky colour and brightness... auto const skydomecolour = m_skydome.GetAverageColor(); auto const skydomehsv = colors::RGBtoHSV( skydomecolour ); diff --git a/uitranscripts.cpp b/uitranscripts.cpp index d3abb0fe..02664a4a 100644 --- a/uitranscripts.cpp +++ b/uitranscripts.cpp @@ -17,11 +17,12 @@ TTranscripts::AddLine( std::string const &txt, float show, float hide, bool it ) if( show == hide ) { return; } // komentarz jest ignorowany + // TODO: replace the timeangledeg mess with regular time points math show = Global.fTimeAngleDeg + show / 240.0; // jeśli doba to 360, to 1s będzie równe 1/240 hide = Global.fTimeAngleDeg + hide / 240.0; TTranscript transcript; - transcript.asText = txt; + transcript.asText = ExchangeCharInString( txt, '|', ' ' ); // NOTE: legacy transcript lines use | as new line mark transcript.fShow = show; transcript.fHide = hide; transcript.bItalic = it; @@ -64,12 +65,25 @@ TTranscripts::Add( std::string const &txt, bool backgorund ) { void TTranscripts::Update() { + // HACK: detect day change + if( fRefreshTime - Global.fTimeAngleDeg > 180 ) { + fRefreshTime -= 360; + } + if( Global.fTimeAngleDeg < fRefreshTime ) { return; } // nie czas jeszcze na zmiany - while( ( false == aLines.empty() ) - && ( Global.fTimeAngleDeg >= aLines.front().fHide ) ) { - // remove expired lines - aLines.pop_front(); + // remove expired lines + while( false == aLines.empty() ) { + // HACK: detect day change + if( aLines.front().fHide - Global.fTimeAngleDeg > 180 ) { + aLines.front().fShow -= 360; + aLines.front().fHide -= 360; + } + if( Global.fTimeAngleDeg <= aLines.front().fHide ) { + // no expired lines yet + break; + } + aLines.pop_front(); // this line expired, discard it and start anew with the next one } // update next refresh time if( false == aLines.empty() ) { fRefreshTime = aLines.front().fHide; } From 8fddbadbafed9cf02d6f610b768e9b416ff494cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 23 Mar 2019 08:52:47 +0100 Subject: [PATCH 25/26] Fix for AI decoupling old Knorr/West locomotives --- Driver.cpp | 1 + McZapkie/hamulce.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Driver.cpp b/Driver.cpp index 39c1d15b..cb4397bb 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5002,6 +5002,7 @@ TController::UpdateSituation(double dt) { TableClear(); // skanowanie od nowa iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie prędkości jazdy + mvOccupied->BrakeReleaser(0); // wyłączyć luzowanie } } diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 3544b002..6d258f8e 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -481,6 +481,12 @@ double TWest::GetPF( double const PP, double const dt, double const Vel ) dv = 0; BrakeCyl->Flow(-dv); + if ((BrakeStatus & b_rls) == b_rls) //odluzniacz + dv = PF(0, CVP, 0.1 * SizeBC) * dt; + else + dv = 0; + BrakeCyl->Flow(-dv); + // hamulec EP temp = BVP * int(EPS > 0); dv = PF(temp, LBP, 0.0015) * dt * EPS * EPS * int(LBP * EPS < MaxBP * LoadC); From 511d1c57d9245924646a16ea2b398eea0aeb7344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 23 Mar 2019 11:51:24 +0100 Subject: [PATCH 26/26] Added SpeedCtrl for TRAXX --- McZapkie/MOVER.h | 1 + McZapkie/Mover.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- Train.cpp | 1 + 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 77ed3e3f..f02bd64d 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1306,6 +1306,7 @@ public: double eimic = 0; /*aktualna pozycja zintegrowanego sterowania jazda i hamowaniem*/ double eimic_real = 0; /*faktycznie uzywana pozycja zintegrowanego sterowania jazda i hamowaniem*/ int EIMCtrlType = 0; /*rodzaj wariantu zadajnika jazdy*/ + bool SpeedCtrlTypeTime = false; /*czy tempomat sterowany czasowo*/ double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/ double eimv[21]; static std::vector const eimv_labels; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 2dfc3537..c3f0c534 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5011,7 +5011,44 @@ double TMoverParameters::TractionForce( double dt ) { { if( true == Mains ) { //tempomat - if (ScndCtrlPosNo > 1) + if (ScndCtrlPosNo == 4 && SpeedCtrlTypeTime) + { + switch (ScndCtrlPos) { + case 0: + NewSpeed = 0; + ScndCtrlActualPos = 0; + SpeedCtrlTimer = 10; + break; + case 1: + if (SpeedCtrlTimer > SpeedCtrlDelay) { + SpeedCtrlTimer = 0; + NewSpeed -= 10; + if (NewSpeed < 0) NewSpeed = 0; + } + else + SpeedCtrlTimer += dt; + break; + case 2: + SpeedCtrlTimer = 10; + ScndCtrlActualPos = NewSpeed; + break; + case 3: + if (SpeedCtrlTimer > SpeedCtrlDelay) { + SpeedCtrlTimer = 0; + NewSpeed += 10; + if (NewSpeed > Vmax) NewSpeed = Vmax; + } + else + SpeedCtrlTimer += dt; + break; + case 4: + NewSpeed = Vmax; + ScndCtrlActualPos = Vmax; + SpeedCtrlTimer = 10; + break; + } + } + else if (ScndCtrlPosNo > 1) { if (ScndCtrlPos != NewSpeed) { @@ -8604,6 +8641,10 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { // speed control extract_value( SpeedCtrlDelay, "SpeedCtrlDelay", line, "" ); + SpeedCtrlTypeTime = + (extract_value("SpeedCtrlType", line) == "Time") ? + true : + false; // converter { diff --git a/Train.cpp b/Train.cpp index 41c0416a..6c2da0f5 100644 --- a/Train.cpp +++ b/Train.cpp @@ -453,6 +453,7 @@ dictionary_source *TTrain::GetTrainState() { dict->insert( "main_ctrl_actual_pos", mover->MainCtrlActualPos ); dict->insert( "scndctrl_pos", mover->ScndCtrlPos ); dict->insert( "scnd_ctrl_actual_pos", mover->ScndCtrlActualPos ); + dict->insert( "new_speed", mover->NewSpeed); // brakes dict->insert( "manual_brake", ( mvOccupied->ManualBrakePos > 0 ) ); bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );