From 40518920665f96fec42f7dcd3ade0782ffd3838a Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 12 Mar 2019 18:49:06 +0100 Subject: [PATCH 01/17] maintenance: minor code tweaks --- DynObj.cpp | 2 ++ simulationtime.cpp | 16 +++++++++++----- simulationtime.h | 3 +++ sun.cpp | 14 ++++---------- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index 6ca495d3..5f17393f 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2298,6 +2298,8 @@ void TDynamicObject::LoadExchange( int const Disembark, int const Embark, int co } } */ + if( Platform == 0 ) { return; } // edge case, if there's no accessible platforms discard the request + m_exchange.unload_count += Disembark; m_exchange.load_count += Embark; m_exchange.platforms = Platform; diff --git a/simulationtime.cpp b/simulationtime.cpp index b2574756..f1c5531e 100644 --- a/simulationtime.cpp +++ b/simulationtime.cpp @@ -121,7 +121,7 @@ scenario_time::update( double const Deltatime ) { } m_time.wHour -= 24; } - int leap { ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 ) }; + int leap { is_leap( m_time.wYear ) }; while( m_time.wDay > m_monthdaycounts[ leap ][ m_time.wMonth ] ) { m_time.wDay -= m_monthdaycounts[ leap ][ m_time.wMonth ]; @@ -130,7 +130,7 @@ scenario_time::update( double const Deltatime ) { if( m_time.wMonth > 12 ) { ++m_time.wYear; - leap = ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 ); + leap = is_leap( m_time.wYear ); m_time.wMonth -= 12; } } @@ -144,7 +144,7 @@ scenario_time::year_day( int Day, const int Month, const int Year ) const { { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; - int const leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) }; + int const leap { is_leap( Year ) }; for( int i = 1; i < Month; ++i ) Day += daytab[ leap ][ i ]; @@ -159,7 +159,7 @@ scenario_time::daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yea { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; - int const leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) }; + int const leap { is_leap( Year ) }; WORD idx = 1; while( ( idx < 13 ) && ( Yearday >= daytab[ leap ][ idx ] ) ) { @@ -222,7 +222,7 @@ scenario_time::day_of_month( int const Week, int const Weekday, int const Month, { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; - int const leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) }; + int const leap { is_leap( Year ) }; while( day > daytab[ leap ][ Month ] ) { day -= 7; @@ -248,4 +248,10 @@ scenario_time::convert_transition_time( SYSTEMTIME &Time ) const { Time.wDay = day_of_month( Time.wDay, Time.wDayOfWeek + 1, Time.wMonth, m_time.wYear ); } +bool +scenario_time::is_leap( int const Year ) const { + + return ( ( Year % 4 == 0 ) && ( ( Year % 100 != 0 ) || ( Year % 400 == 0 ) ) ); + +} //--------------------------------------------------------------------------- diff --git a/simulationtime.h b/simulationtime.h index 45f4352e..58a8b317 100644 --- a/simulationtime.h +++ b/simulationtime.h @@ -61,6 +61,9 @@ private: // returns number of days between specified days of week int weekdays( int const First, int const Second ) const; + // returns true if specified year is a leap year, false otherwise + bool + is_leap( int const Year ) const; SYSTEMTIME m_time; double m_milliseconds{ 0.0 }; diff --git a/sun.cpp b/sun.cpp index 0acf3864..b2cce6a6 100644 --- a/sun.cpp +++ b/sun.cpp @@ -185,17 +185,11 @@ void cSun::move() { m_body.rascen = clamp_circular( radtodeg * std::atan2( top, bottom ) ); - // Greenwich mean sidereal time - m_observer.gmst = 6.697375 + 0.0657098242 * daynumber + m_observer.utime; + // Greenwich mean sidereal time (hours) + m_observer.gmst = clamp_circular( 6.697375 + 0.0657098242 * daynumber + m_observer.utime, 24.0 ); - m_observer.gmst -= 24.0 * (int)( m_observer.gmst / 24.0 ); - if( m_observer.gmst < 0.0 ) m_observer.gmst += 24.0; - - // local mean sidereal time - m_observer.lmst = m_observer.gmst * 15.0 + m_observer.longitude; - - m_observer.lmst -= 360.0 * (int)( m_observer.lmst / 360.0 ); - if( m_observer.lmst < 0.0 ) m_observer.lmst += 360.0; + // local mean sidereal time (deg) + m_observer.lmst = clamp_circular( m_observer.gmst * 15.0 + m_observer.longitude ); // hour angle m_body.hrang = m_observer.lmst - m_body.rascen; From 90df9b9b121ce2f775d0d10709732f05d13a905e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Wed, 6 Mar 2019 20:05:26 +0100 Subject: [PATCH 02/17] Unified multiplier for "brakes" gauge with other pneumatic gauges --- Train.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Train.cpp b/Train.cpp index d19a87df..d9c3c7f1 100644 --- a/Train.cpp +++ b/Train.cpp @@ -8035,7 +8035,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con Parser.getTokens(2, false); Parser >> i >> j; auto &gauge = Cabine[Cabindex].Gauge(-1); // pierwsza wolna gałka - gauge.Load(Parser, DynamicObject); + gauge.Load(Parser, DynamicObject, 0.1); gauge.AssignFloat(&fPress[i - 1][j]); } else if ((Label == "brakepress:") || (Label == "brakepressb:")) From 69ad8943aefb96077a6bcb979569181fd727bb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 8 Mar 2019 19:35:34 +0100 Subject: [PATCH 03/17] New MainCtrlTypes for EIM Integrated Control dedicated to Traxx and Elf --- DynObj.cpp | 24 ++++++--- McZapkie/MOVER.h | 7 +++ McZapkie/Mover.cpp | 123 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 123 insertions(+), 31 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index 5f17393f..01f86f8f 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2686,7 +2686,7 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG if( ( Mechanik->Primary() ) && ( MoverParameters->EngineType == TEngineType::ElectricInductionMotor ) ) { - // jesli glowny i z asynchronami, to niech steruje hamulcem lacznie dla calego pociagu/ezt + // jesli glowny i z asynchronami, to niech steruje hamulcem i napedem lacznie dla calego pociagu/ezt auto const kier = (DirectionGet() * MoverParameters->ActiveCab > 0); auto FED { 0.0 }; auto np { 0 }; @@ -2698,6 +2698,16 @@ bool TDynamicObject::Update(double dt, double dt1) auto FmaxED { 0.0 }; auto Frj { 0.0 }; 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->CheckEIMIC(dt1); + MoverParameters->CheckSpeedCtrl(); + + MoverParameters->eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl); + MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, MoverParameters->eimic), MoverParameters->CabNo); + auto LBR = Max0R(-MoverParameters->eimic, 0); + // 1. ustal wymagana sile hamowania calego pociagu // - opoznienie moze byc ustalane na podstawie charakterystyki // - opoznienie moze byc ustalane na podstawie mas i cisnien granicznych @@ -2760,22 +2770,22 @@ bool TDynamicObject::Update(double dt, double dt1) if (MoverParameters->ShuntMode) { MoverParameters->ShuntModeAllow = ( false == doorisopen ) && - (MoverParameters->LocalBrakeRatio() < 0.01); + (LBR < 0.01); } if( ( MoverParameters->Vel > 1 ) && ( false == doorisopen ) ) { MoverParameters->ShuntMode = false; MoverParameters->ShuntModeAllow = (MoverParameters->BrakePress > 0.2) && - (MoverParameters->LocalBrakeRatio() < 0.01); + (LBR < 0.01); } - auto Fzad = amax * MoverParameters->LocalBrakeRatio() * masa; + auto Fzad = amax * LBR * masa; if ((MoverParameters->BrakeCtrlPos == MoverParameters->Handle->GetPos(bh_EB)) && (MoverParameters->eimc[eimc_p_abed] < 0.001)) Fzad = amax * masa; //pętla bezpieczeństwa - pełne służbowe if ((MoverParameters->ScndS) && (MoverParameters->Vel > MoverParameters->eimc[eimc_p_Vh1]) && (FmaxED > 0)) { - Fzad = std::min(MoverParameters->LocalBrakeRatio() * FmaxED, FfulED); + Fzad = std::min(LBR * FmaxED, FfulED); } if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) || (MoverParameters->V * MoverParameters->DirAbsolute < -0.2)) @@ -2847,7 +2857,7 @@ bool TDynamicObject::Update(double dt, double dt1) PrzekrF[i] = false; FzED[i] = (FmaxED > 0 ? FzadED / FmaxED : 0); p->MoverParameters->AnPos = - (MoverParameters->ScndS ? MoverParameters->LocalBrakeRatio() : FzED[i]); + (MoverParameters->ScndS ? LBR : FzED[i]); FzEP[ i ] = static_cast( FzadPN * p->MoverParameters->NAxles ) / static_cast( osie ); ++i; p->MoverParameters->ShuntMode = MoverParameters->ShuntMode; @@ -6599,7 +6609,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub if( Vehicle.EngineType == TEngineType::ElectricInductionMotor ) { if( Vehicle.InverterFrequency > 0.1 ) { - volume = inverter.m_amplitudeoffset + inverter.m_amplitudefactor * std::sqrt( std::abs( Vehicle.dizel_fill ) ); + volume = inverter.m_amplitudeoffset + inverter.m_amplitudefactor * std::sqrt( std::abs( Vehicle.eimv_pr) ); inverter .pitch( inverter.m_frequencyoffset + inverter.m_frequencyfactor * Vehicle.InverterFrequency ) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index d8f210aa..814e3258 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1280,9 +1280,13 @@ public: double hydro_R_n = 0.0; /*predkosc obrotowa retardera*/ /*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/ + double eimic = 0; /*aktualna pozycja zintegrowanego sterowania jazda i hamowaniem*/ + int EIMCtrlType = 0; /*rodzaj wariantu zadajnika jazdy*/ + double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/ double eimv[21]; static std::vector const eimv_labels; double SpeedCtrlTimer = 0; /*zegar dzialania tempomatu z wybieralna predkoscia*/ + double eimicSpeedCtrl = 0; /*pozycja sugerowana przez tempomat*/ double NewSpeed = 0; /*nowa predkosc do zadania*/ double MED_EPVC_CurrentTime = 0; /*aktualny czas licznika czasu korekcji siły EP*/ @@ -1496,6 +1500,9 @@ public: bool PantFront( bool const State, range_t const Notify = range_t::consist ); //obsluga pantografou przedniego bool PantRear( bool const State, range_t const Notify = range_t::consist ); //obsluga pantografu tylnego + void CheckEIMIC(double dt); //sprawdzenie i zmiana nastawy zintegrowanego nastawnika jazdy/hamowania + void CheckSpeedCtrl(); + /*-funkcje typowe dla lokomotywy spalinowej z przekladnia mechaniczna*/ bool dizel_EngageSwitch(double state); bool dizel_EngageChange(double dt); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index cfb0a013..f3de4a89 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -1613,7 +1613,7 @@ double TMoverParameters::ShowCurrent(int AmpN) const case 1: return WindingRes * Mm / Vadd; case 2: - return dizel_fill * WindingRes; + return eimv_pr * WindingRes; default: return ShowCurrentP(AmpN); // T_MoverParameters:: } @@ -4998,25 +4998,24 @@ double TMoverParameters::TractionForce( double dt ) { if (NewSCAP != ScndCtrlActualPos) { ScndCtrlActualPos = NewSCAP; - SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo); +// SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo); } } } } - - dtrans = Hamulec->GetEDBCP(); + double edBCP = Hamulec->GetEDBCP(); if( ( false == Doors.instances[ side::left ].is_closed ) || ( false == Doors.instances[ side::right ].is_closed ) || ( Doors.permit_needed && ( Doors.instances[ side::left ].open_permit || Doors.instances[ side::right ].open_permit ) ) ) { DynamicBrakeFlag = true; } - else if (((dtrans < 0.25) && (LocHandle->GetCP() < 0.25) && (AnPos < 0.01)) || - ((dtrans < 0.25) && (ShuntModeAllow) && (LocalBrakePosA < 0.01))) + else if (((edBCP < 0.25) && (LocHandle->GetCP() < 0.25) && (AnPos < 0.01)) || + ((edBCP < 0.25) && (ShuntModeAllow) && (LocalBrakePosA < 0.01))) DynamicBrakeFlag = false; - else if ((((BrakePress > 0.25) && (dtrans > 0.25) || (LocHandle->GetCP() > 0.25))) || + else if ((((BrakePress > 0.25) && (edBCP > 0.25) || (LocHandle->GetCP() > 0.25))) || (AnPos > 0.02)) DynamicBrakeFlag = true; - dtrans = Hamulec->GetEDBCP() * eimc[eimc_p_abed]; // stala napedu + edBCP = Hamulec->GetEDBCP() * eimc[eimc_p_abed]; // stala napedu if ((DynamicBrakeFlag)) { // ustalanie współczynnika blendingu do luzowania hamulca PN @@ -5024,7 +5023,7 @@ double TMoverParameters::TractionForce( double dt ) { { PosRatio = -Sign(V) * DirAbsolute * eimv[eimv_Fr] / (eimc[eimc_p_Fh] * - Max0R(dtrans,Max0R(0.01,Hamulec->GetEDBCP())) / MaxBrakePress[0]); + Max0R(edBCP,Max0R(0.01,Hamulec->GetEDBCP())) / MaxBrakePress[0]); PosRatio = clamp(PosRatio, 0.0, 1.0); } else @@ -5043,29 +5042,30 @@ double TMoverParameters::TractionForce( double dt ) { } else { - PosRatio = -std::max(std::min(dtrans * 1.0 / MaxBrakePress[0], 1.0), AnPos) * + PosRatio = -std::max(std::min(edBCP * 1.0 / MaxBrakePress[0], 1.0), AnPos) * std::max(0.0, std::min(1.0, (Vel - eimc[eimc_p_Vh0]) / (eimc[eimc_p_Vh1] - eimc[eimc_p_Vh0]))); - eimv[eimv_Fzad] = -std::max(LocalBrakeRatio(), dtrans / MaxBrakePress[0]); + eimv[eimv_Fzad] = -std::min(1.0,std::max(LocalBrakeRatio(), edBCP / MaxBrakePress[0])); } tmp = 5; } else { PosRatio = static_cast( MainCtrlPos ) / static_cast( MainCtrlPosNo ); + PosRatio = Max0R(eimic, 0); eimv[eimv_Fzad] = PosRatio; if ((Flat) && (eimc[eimc_p_F0] * eimv[eimv_Fful] > 0)) PosRatio = Min0R(PosRatio * eimc[eimc_p_F0] / eimv[eimv_Fful], 1); - if (ScndCtrlActualPos > 0) //speed control +/* if (ScndCtrlActualPos > 0) //speed control if (Vmax < 250) PosRatio = Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos - Vel))); else PosRatio = - Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos * 2 - Vel))); + Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos * 2 - Vel))); */ // PosRatio = 1.0 * (PosRatio * 0 + 1) * PosRatio; // 1 * 1 * PosRatio = PosRatio Hamulec->SetED(0); // (Hamulec as TLSt).SetLBP(LocBrakePress); - if ((PosRatio > dizel_fill)) + if ((PosRatio > eimv_pr)) tmp = 4; else tmp = 4; // szybkie malenie, powolne wzrastanie @@ -5083,8 +5083,8 @@ double TMoverParameters::TractionForce( double dt ) { Sandbox( false, range_t::unit ); } - dizel_fill += Max0R(Min0R(PosRatio - dizel_fill, 0.02), -0.02) * 12 * - (tmp /*2{+4*byte(PosRatio 0.01 ? -LocalBrakeRatio() : (double)MainCtrlPos / (double)MainCtrlPosNo); + break; + case 1: + switch (MainCtrlPos) + { + case 0: //B+ + eimic -= clamp(1.0 + eimic, 0.0, dt*0.3); //odejmuj do -1 + break; + case 1: //B + eimic -= clamp(0.0 + eimic, 0.0, dt*0.3); //odejmuj do 0 + break; + case 2: //B- + case 3: //0 + case 4: //T- + eimic -= clamp(0.0 + eimic, 0.0, dt*0.3); //odejmuj do 0 + eimic += clamp(0.0 - eimic, 0.0, dt*0.3); //dodawaj do 0 + break; + case 5: //T + eimic += clamp(0.0 - eimic, 0.0, dt*0.3); //dodawaj do 0 + break; + case 6: //T+ + eimic += clamp(1.0 - eimic, 0.0, dt*0.3); //dodawaj do 1 + break; + case 7: //TMax + eimic += clamp(1.0 - eimic, 0.0, dt*0.3); //dodawaj do 1, max + break; + } + break; + case 2: + switch (MainCtrlPos) + { + case 0: + eimic = -1.0; + break; + case 1: + eimic -= clamp(1.0 + eimic, 0.0, dt*0.3); //odejmuj do -1 + break; + case 2: + eimic -= clamp(0.0 + eimic, 0.0, dt*0.3); //odejmuj do 0 + break; + case 3: + eimic += clamp(0.0 - eimic, 0.0, dt*0.3); //dodawaj do 0 + break; + case 4: + eimic += clamp(1.0 - eimic, 0.0, dt*0.3); //dodawaj do 1 + break; + } + break; + } + eimic = clamp(eimic, -1.0, 1.0); +} + +void TMoverParameters::CheckSpeedCtrl() +{ + if (ScndCtrlActualPos > 0) //speed control + if (Vmax < 250) + eimicSpeedCtrl = clamp(0.5 * (ScndCtrlActualPos - Vel), -1.0, 1.0); + else + eimicSpeedCtrl = clamp(0.5 * (ScndCtrlActualPos * 2 - Vel), -1.0, 1.0); + else + eimicSpeedCtrl = 1; +} + // ************************************************************************************************* // Q: 20160715 // Zmienia parametr do którego dąży sprzęgło @@ -8427,6 +8495,8 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { else { AutoRelayType = 0; } extract_value( CoupledCtrl, "CoupledCtrl", line, "" ); + extract_value( EIMCtrlType, "EIMCtrlType", line, "" ); + clamp( EIMCtrlType, 0, 2 ); extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR @@ -9475,6 +9545,11 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C OK:=SendCtrlToNext(command,CValue1,CValue2); end; end */ + else if (Command == "EIMIC") // ElectricInductionMotor Integrated Control - propulsion and brakes in relative values + { + eimic = CValue1; + OK = SendCtrlToNext(Command, CValue1, CValue2, Couplertype); + } else if (Command == "Brake") // youBy - jak sie EP hamuje, to trza sygnal wyslac... { if (CValue1 < 0.001) From 868c86c6e2fc6483129a0f868545064da81526e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 8 Mar 2019 20:49:23 +0100 Subject: [PATCH 04/17] Corrected "desired percent" for Python screens --- Train.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Train.cpp b/Train.cpp index d9c3c7f1..85359348 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5256,11 +5256,12 @@ bool TTrain::Update( double const Deltatime ) } } - if (mvControlled == mvOccupied) - fEIMParams[0][3] = mvControlled->eimv[eimv_Fzad]; // procent zadany - else - fEIMParams[0][3] = - mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany +// if (mvControlled == mvOccupied) +// fEIMParams[0][3] = mvControlled->eimv[eimv_Fzad]; // procent zadany +// else +// fEIMParams[0][3] = +// mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany + fEIMParams[0][3] = mvOccupied->eimic; fEIMParams[0][4] = Max0R(fEIMParams[0][3], 0); fEIMParams[0][5] = -Min0R(fEIMParams[0][3], 0); fEIMParams[0][1] = fEIMParams[0][4] * mvControlled->eimv[eimv_Fful]; From 18e46aa0631e7a0f2a92ee75fbf49f9c7d7782f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 9 Mar 2019 22:12:48 +0100 Subject: [PATCH 05/17] Corrected shifting speed for EIMCtrlType == 2 --- DynObj.cpp | 6 +++--- McZapkie/Mover.cpp | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index 01f86f8f..a1c606bd 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2704,9 +2704,9 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->CheckEIMIC(dt1); MoverParameters->CheckSpeedCtrl(); - MoverParameters->eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl); - MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, MoverParameters->eimic), MoverParameters->CabNo); - auto LBR = Max0R(-MoverParameters->eimic, 0); + auto eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl); + MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, eimic), MoverParameters->CabNo); + auto LBR = Max0R(-eimic, 0); // 1. ustal wymagana sile hamowania calego pociagu // - opoznienie moze byc ustalane na podstawie charakterystyki diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index f3de4a89..9567615f 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5947,16 +5947,18 @@ void TMoverParameters::CheckEIMIC(double dt) eimic = -1.0; break; case 1: - eimic -= clamp(1.0 + eimic, 0.0, dt*0.3); //odejmuj do -1 + eimic -= clamp(1.0 + eimic, 0.0, dt*0.15); //odejmuj do -1 + if (eimic > 0) eimic = 0; break; case 2: - eimic -= clamp(0.0 + eimic, 0.0, dt*0.3); //odejmuj do 0 + eimic -= clamp(0.0 + eimic, 0.0, dt*0.15); //odejmuj do 0 break; case 3: - eimic += clamp(0.0 - eimic, 0.0, dt*0.3); //dodawaj do 0 + eimic += clamp(0.0 - eimic, 0.0, dt*0.15); //dodawaj do 0 break; case 4: - eimic += clamp(1.0 - eimic, 0.0, dt*0.3); //dodawaj do 1 + eimic += clamp(1.0 - eimic, 0.0, dt*0.15); //dodawaj do 1 + if (eimic < 0) eimic = 0; break; } break; From 05f0fbb7dd99104d5bd6499047a0f625cc3d2d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sun, 10 Mar 2019 08:49:07 +0100 Subject: [PATCH 06/17] Added instant 0 for EIMCtrlType == 1 (Traxx) --- McZapkie/Mover.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 9567615f..5c8f8f9e 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5939,6 +5939,8 @@ void TMoverParameters::CheckEIMIC(double dt) eimic += clamp(1.0 - eimic, 0.0, dt*0.3); //dodawaj do 1, max break; } + if (MainCtrlPos >= 3 && eimic < 0) eimic = 0; + if (MainCtrlPos <= 3 && eimic > 0) eimic = 0; break; case 2: switch (MainCtrlPos) From b8ff8703c53c5f4f0a0417dee765821a5deba082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Tue, 12 Mar 2019 18:37:14 +0100 Subject: [PATCH 07/17] AI now uses EIMCtrlType no 1 and 2 correctly --- Driver.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++--- Driver.h | 4 +++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index c8783c5e..35208c67 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2789,7 +2789,7 @@ bool TController::IncBrake() OK = mvOccupied->BrakeLevelAdd(1.0); } else { - OK = mvOccupied->IncLocalBrakeLevel(1); + OK = IncBrakeEIM(); } } else if( mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos( bh_EPB ) ) { @@ -2807,6 +2807,28 @@ bool TController::IncBrake() return OK; } +bool TController::IncBrakeEIM() +{ // zwiększenie hamowania + bool OK = false; + switch (mvControlling->EIMCtrlType) + { + case 0: + OK = mvControlling->IncLocalBrakeLevel(1); + break; + case 1: + OK = mvControlling->MainCtrlPos > 0; + if (OK) + mvControlling->MainCtrlPos = 0; + break; + case 2: + OK = mvControlling->MainCtrlPos > 1; + if (OK) + mvControlling->MainCtrlPos = 1; + break; + } + return OK; +} + bool TController::DecBrake() { // zmniejszenie siły hamowania bool OK = false; @@ -2844,7 +2866,7 @@ bool TController::DecBrake() OK = mvOccupied->BrakeLevelAdd(-1.0); } else { - OK = mvOccupied->DecLocalBrakeLevel(1); + OK = DecBrakeEIM(); } } else if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPR)) @@ -2863,6 +2885,28 @@ bool TController::DecBrake() return OK; }; +bool TController::DecBrakeEIM() +{ // zmniejszenie siły hamowania + bool OK = false; + switch (mvControlling->EIMCtrlType) + { + case 0: + OK = mvControlling->DecLocalBrakeLevel(1); + break; + case 1: + OK = mvControlling->MainCtrlPos < 2; + if (OK) + mvControlling->MainCtrlPos = 2; + break; + case 2: + OK = mvControlling->MainCtrlPos < 3; + if (OK) + mvControlling->MainCtrlPos = 3; + break; + } + return OK; +} + bool TController::IncSpeed() { // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać if( true == tsGuardSignal.is_playing() ) { @@ -3075,7 +3119,7 @@ bool TController::DecSpeed(bool force) OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPos / 2)); break; case TEngineType::ElectricInductionMotor: - OK = mvControlling->DecMainCtrl(1); + OK = DecSpeedEIM(); break; case TEngineType::WheelsDriven: if (!mvControlling->CabNo) @@ -3102,6 +3146,28 @@ bool TController::DecSpeed(bool force) return OK; }; +bool TController::DecSpeedEIM() +{ // zmniejszenie prędkości (ale nie hamowanie) + bool OK = false; // domyślnie false, aby wyszło z pętli while + switch (mvControlling->EIMCtrlType) + { + case 0: + OK = mvControlling->DecMainCtrl(1); + break; + case 1: + OK = mvControlling->MainCtrlPos > 4; + if (OK) + mvControlling->MainCtrlPos = 4; + break; + case 2: + OK = mvControlling->MainCtrlPos > 2; + if (OK) + mvControlling->MainCtrlPos = 2; + break; + } + return OK; +} + 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 diff --git a/Driver.h b/Driver.h index 53f8900a..e1b29651 100644 --- a/Driver.h +++ b/Driver.h @@ -211,6 +211,10 @@ private: bool DecBrake(); bool IncSpeed(); bool DecSpeed(bool force = false); + bool IncBrakeEIM(); + bool DecBrakeEIM(); + bool IncSpeedEIM(); + bool DecSpeedEIM(); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); double ESMVelocity(bool Main); From cf91f7e03149aa4b077e2b93eee029e631583a75 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 14 Mar 2019 20:09:30 +0100 Subject: [PATCH 08/17] cooling fan cab control, dedicated tempomat cab control, minor vehicle preparation ai logic tweaks, minor timetable ui panel tweaks --- Driver.cpp | 4 +++ McZapkie/MOVER.h | 3 +- McZapkie/Mover.cpp | 10 ++++-- Train.cpp | 69 ++++++++++++++++++++++++++++++++++++++--- Train.h | 4 ++- command.cpp | 4 ++- command.h | 2 ++ driverkeyboardinput.cpp | 3 +- drivermouseinput.cpp | 6 ++++ driveruipanels.cpp | 6 ++-- translation.cpp | 10 ++++-- translation.h | 4 ++- 12 files changed, 108 insertions(+), 17 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 35208c67..533d2345 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2521,6 +2521,10 @@ bool TController::PrepareEngine() mvOccupied->MotorBlowersSwitch( true, end::front ); mvOccupied->MotorBlowersSwitchOff( false, end::rear ); mvOccupied->MotorBlowersSwitch( true, end::rear ); + // enable train brake if it's off + if( mvOccupied->fBrakeCtrlPos == mvOccupied->Handle->GetPos( bh_NP ) ) { + mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + } } } else diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 814e3258..aa439b6f 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -976,12 +976,13 @@ public: double TUHEX_Sum2 = 750; /*nastawa2 sterownika hamowania ED*/ double TUHEX_Sum3 = 750; /*nastawa3 sterownika hamowania ED*/ int TUHEX_Stages = 0; /*liczba stopni hamowania ED*/ - + // TODO: wrap resistor fans variables and state into a device int RVentType = 0; /*0 - brak, 1 - jest, 2 - automatycznie wlaczany*/ double RVentnmax = 1.0; /*maks. obroty wentylatorow oporow rozruchowych*/ double RVentCutOff = 0.0; /*rezystancja wylaczania wentylatorow dla RVentType=2*/ double RVentSpeed { 0.5 }; //rozpedzanie sie wentylatora obr/s^2} double RVentMinI { 50.0 }; //przy jakim pradzie sie wylaczaja} + bool RVentForceOn { false }; // forced activation switch int CompressorPower = 1; // 0: main circuit, 1: z przetwornicy, reczne, 2: w przetwornicy, stale, 3: diesel engine, 4: converter of unit in front, 5: converter of unit behind int SmallCompressorPower = 0; /*Winger ZROBIC*/ bool Trafo = false; /*pojazd wyposażony w transformator*/ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 5c8f8f9e..851f0aaa 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4400,8 +4400,9 @@ double TMoverParameters::TractionForce( double dt ) { switch( RVentType ) { case 1: { // manual - if( ( ActiveDir != 0 ) - && ( RList[ MainCtrlActualPos ].R > RVentCutOff ) ) { + if( ( true == RVentForceOn ) + || ( ( ActiveDir != 0 ) + && ( RList[ MainCtrlActualPos ].R > RVentCutOff ) ) ) { RventRot += ( RVentnmax - RventRot ) * RVentSpeed * dt; } else { @@ -4423,9 +4424,12 @@ double TMoverParameters::TractionForce( double dt ) { * RVentSpeed * dt; } else if( ( DynamicBrakeType == dbrake_automatic ) - && ( true == DynamicBrakeFlag ) ) { + && ( true == DynamicBrakeFlag ) ) { RventRot += ( RVentnmax * motorcurrent / ImaxLo - RventRot ) * RVentSpeed * dt; } + else if( RVentForceOn ) { + RventRot += ( RVentnmax - RventRot ) * RVentSpeed * dt; + } else { RventRot *= std::max( 0.0, 1.0 - RVentSpeed * dt ); } diff --git a/Train.cpp b/Train.cpp index 85359348..b8abbfe2 100644 --- a/Train.cpp +++ b/Train.cpp @@ -170,6 +170,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::secondcontrollerdecreasefast, &TTrain::OnCommand_secondcontrollerdecreasefast }, { user_command::secondcontrollerset, &TTrain::OnCommand_secondcontrollerset }, { user_command::notchingrelaytoggle, &TTrain::OnCommand_notchingrelaytoggle }, + { user_command::tempomattoggle, &TTrain::OnCommand_tempomattoggle }, { user_command::mucurrentindicatorothersourceactivate, &TTrain::OnCommand_mucurrentindicatorothersourceactivate }, { user_command::independentbrakeincrease, &TTrain::OnCommand_independentbrakeincrease }, { user_command::independentbrakeincreasefast, &TTrain::OnCommand_independentbrakeincreasefast }, @@ -262,6 +263,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::motorblowerstogglefront, &TTrain::OnCommand_motorblowerstogglefront }, { user_command::motorblowerstogglerear, &TTrain::OnCommand_motorblowerstogglerear }, { user_command::motorblowersdisableall, &TTrain::OnCommand_motorblowersdisableall }, + { user_command::coolingfanstoggle, &TTrain::OnCommand_coolingfanstoggle }, { user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen }, { user_command::motorconnectorsclose, &TTrain::OnCommand_motorconnectorsclose }, { user_command::motordisconnect, &TTrain::OnCommand_motordisconnect }, @@ -931,6 +933,45 @@ void TTrain::OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &C } } +void TTrain::OnCommand_tempomattoggle( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_REPEAT ) { return; } + + if( Train->ggScndCtrlButton.type() == TGaugeType::push ) { + // impulse switch + if( Command.action == GLFW_RELEASE ) { + // just move the button back to default position + // visual feedback + Train->ggScndCtrlButton.UpdateValue( 0.0, Train->dsbSwitch ); + return; + } + // glfw_press + if( Train->mvControlled->ScndCtrlPos == 0 ) { + // turn on if needed + Train->mvControlled->IncScndCtrl( 1 ); + } + // visual feedback + Train->ggScndCtrlButton.UpdateValue( 1.0, Train->dsbSwitch ); + } + else { + // two-state switch + if( Command.action == GLFW_RELEASE ) { return; } + + if( Train->mvControlled->ScndCtrlPos == 0 ) { + // turn on + Train->mvControlled->IncScndCtrl( 1 ); + // visual feedback + Train->ggScndCtrlButton.UpdateValue( 1.0, Train->dsbSwitch ); + } + else { + //turn off + Train->mvControlled->DecScndCtrl( 2 ); + // visual feedback + Train->ggScndCtrlButton.UpdateValue( 0.0, Train->dsbSwitch ); + } + } +} + void TTrain::OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command ) { if( Train->ggNextCurrentButton.SubModel == nullptr ) { @@ -3059,6 +3100,13 @@ void TTrain::OnCommand_motorblowersdisableall( TTrain *Train, command_data const } } +void TTrain::OnCommand_coolingfanstoggle( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_PRESS ) { return; } + + Train->mvControlled->RVentForceOn = ( !Train->mvControlled->RVentForceOn ); +} + void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) { // TODO: don't rely on presense of 3d model to determine presence of the switch @@ -5189,10 +5237,10 @@ bool TTrain::Update( double const Deltatime ) fPress[i][0] = p->MoverParameters->BrakePress; fPress[i][1] = p->MoverParameters->PipePress; fPress[i][2] = p->MoverParameters->ScndPipePress; - bDoors[i][1] = ( false == p->MoverParameters->Doors.instances[ side::left ].is_closed ); - bDoors[i][2] = ( false == p->MoverParameters->Doors.instances[ side::right ].is_closed ); - bDoors[i][3] = ( p->MoverParameters->Doors.instances[ side::left ].step_position > 0.0 ); - bDoors[i][4] = ( p->MoverParameters->Doors.instances[ side::right ].step_position > 0.0 ); + bDoors[i][1] = ( p->MoverParameters->Doors.instances[ side::left ].position > 0.f ); + bDoors[i][2] = ( p->MoverParameters->Doors.instances[ side::right ].position > 0.f ); + bDoors[i][3] = ( p->MoverParameters->Doors.instances[ side::left ].step_position > 0.f ); + bDoors[i][4] = ( p->MoverParameters->Doors.instances[ side::right ].step_position > 0.f ); bDoors[i][0] = ( bDoors[i][1] || bDoors[i][2] ); iDoorNo[i] = p->iAnimType[ANIM_DOORS]; iUnits[i] = iUnitNo; @@ -5868,6 +5916,7 @@ bool TTrain::Update( double const Deltatime ) dsbNastawnikBocz ); ggScndCtrl.Update(); } + ggScndCtrlButton.Update(); if (ggDirKey.SubModel) { if (mvControlled->TrainType != dt_EZT) ggDirKey.UpdateValue( @@ -7193,6 +7242,7 @@ void TTrain::clear_cab_controls() ggMainCtrl.Clear(); ggMainCtrlAct.Clear(); ggScndCtrl.Clear(); + ggScndCtrlButton.Clear(); ggDirKey.Clear(); ggBrakeCtrl.Clear(); ggLocalBrake.Clear(); @@ -7661,6 +7711,13 @@ void TTrain::set_cab_controls( int const Cab ) { 1.f : 0.f ); } + // tempomat + if( ggScndCtrlButton.type() != TGaugeType::push ) { + ggScndCtrlButton.PutValue( + ( mvControlled->ScndCtrlPos > 0 ) ? + 1.f : + 0.f ); + } // we reset all indicators, as they're set during the update pass // TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it @@ -7919,6 +7976,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con { "cablight_sw:", ggCabLightButton }, { "cablightdim_sw:", ggCabLightDimButton }, { "battery_sw:", ggBatteryButton }, + { "tempomat_sw:", ggScndCtrlButton }, { "universal0:", ggUniversals[ 0 ] }, { "universal1:", ggUniversals[ 1 ] }, { "universal2:", ggUniversals[ 2 ] }, @@ -7940,7 +7998,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con } // TODO: move viable dedicated gauges to the automatic array std::unordered_map const autoboolgauges = { - { "doorstep_sw:", &mvOccupied->Doors.step_enabled } + { "doorstep_sw:", &mvOccupied->Doors.step_enabled }, + { "coolingfans_sw:", &mvControlled->RVentForceOn } }; { auto lookup = autoboolgauges.find( Label ); diff --git a/Train.h b/Train.h index 056bdd1b..837cdd22 100644 --- a/Train.h +++ b/Train.h @@ -169,6 +169,7 @@ class TTrain static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_secondcontrollerset( TTrain *Train, command_data const &Command ); static void OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_tempomattoggle( TTrain *Train, command_data const &Command ); static void OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command ); @@ -265,6 +266,7 @@ class TTrain static void OnCommand_motorblowersenablerear( TTrain *Train, command_data const &Command ); static void OnCommand_motorblowersdisablerear( TTrain *Train, command_data const &Command ); static void OnCommand_motorblowersdisableall( TTrain *Train, command_data const &Command ); + static void OnCommand_coolingfanstoggle( TTrain *Train, command_data const &Command ); static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ); static void OnCommand_motorconnectorsclose( TTrain *Train, command_data const &Command ); static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command ); @@ -379,7 +381,7 @@ public: // reszta może by?publiczna TGauge ggMainCtrl; TGauge ggMainCtrlAct; TGauge ggScndCtrl; - TGauge ggScndCtrlButton; // NOTE: not used? + TGauge ggScndCtrlButton; TGauge ggDirKey; TGauge ggBrakeCtrl; TGauge ggLocalBrake; diff --git a/command.cpp b/command.cpp index 6b49e343..25eeac6c 100644 --- a/command.cpp +++ b/command.cpp @@ -224,7 +224,9 @@ commanddescription_sequence Commands_descriptions = { { "batterydisable", command_target::vehicle }, { "motorblowerstogglefront", command_target::vehicle }, { "motorblowerstogglerear", command_target::vehicle }, - { "motorblowersdisableall", command_target::vehicle } + { "motorblowersdisableall", command_target::vehicle }, + { "coolingfanstoggle", command_target::vehicle }, + { "tempomattoggle", command_target::vehicle } }; diff --git a/command.h b/command.h index 3cdd6bd0..9e321ffe 100644 --- a/command.h +++ b/command.h @@ -218,6 +218,8 @@ enum class user_command { motorblowerstogglefront, motorblowerstogglerear, motorblowersdisableall, + coolingfanstoggle, + tempomattoggle, none = -1 }; diff --git a/driverkeyboardinput.cpp b/driverkeyboardinput.cpp index 0ece6a48..1b530384 100644 --- a/driverkeyboardinput.cpp +++ b/driverkeyboardinput.cpp @@ -227,7 +227,8 @@ driverkeyboard_input::default_bindings() { { user_command::motorblowerstogglefront, GLFW_KEY_N | keymodifier::shift }, { user_command::motorblowerstogglerear, GLFW_KEY_M | keymodifier::shift }, { user_command::motorblowersdisableall, GLFW_KEY_M | keymodifier::control } - + // coolingfanstoggle + // tempomattoggle }; } diff --git a/drivermouseinput.cpp b/drivermouseinput.cpp index a8e04c07..5792999b 100644 --- a/drivermouseinput.cpp +++ b/drivermouseinput.cpp @@ -494,6 +494,9 @@ drivermouse_input::default_bindings() { { "shuntmodepower:", { user_command::secondcontrollerincrease, user_command::secondcontrollerdecrease } }, + { "tempomat_sw:", { + user_command::tempomattoggle, + user_command::none } }, { "dirkey:", { user_command::reverserincrease, user_command::reverserdecrease } }, @@ -552,6 +555,9 @@ drivermouse_input::default_bindings() { { "motorblowersalloff_sw:", { user_command::motorblowersdisableall, user_command::none } }, + { "coolingfans_sw:", { + user_command::coolingfanstoggle, + user_command::none } }, { "main_off_bt:", { user_command::linebreakeropen, user_command::none } }, diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 62a89990..f10ae4c9 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -238,12 +238,14 @@ timetable_panel::update() { { // current time std::snprintf( m_buffer.data(), m_buffer.size(), - locale::strings[ locale::string::driver_timetable_time ].c_str(), + locale::strings[ locale::string::driver_timetable_header ].c_str(), + 40, 40, + locale::strings[ locale::string::driver_timetable_name ].c_str(), time.wHour, time.wMinute, time.wSecond ); - text_lines.emplace_back( m_buffer.data(), Global.UITextColor ); + title = m_buffer.data(); } auto *vehicle { ( diff --git a/translation.cpp b/translation.cpp index 8bfe7b1a..cd7d56bc 100644 --- a/translation.cpp +++ b/translation.cpp @@ -56,8 +56,8 @@ init() { "Drive according to signals and timetable", "Bank consist ahead", + "%-*.*s Time: %d:%02d:%02d", // HACK: some manual padding to account for longer 'time' equivalent in polish version "Timetable", - "Time: %d:%02d:%02d", "(no timetable)", "Consist weight: %d t (specified) %d t (actual)\nConsist length: %d m", @@ -84,6 +84,7 @@ init() { "master controller", "second controller", "shunt mode power", + "tempomat", "reverser", "train brake", "independent brake", @@ -104,6 +105,7 @@ init() { "motor blowers A", "motor blowers B", "all motor blowers", + "cooling fans", "line breaker", "line breaker", "alerter", @@ -219,8 +221,8 @@ init() { "Prowadzic sklad wedlug sygnalow i rozkladu", "Popychac sklad z przodu", + "%-*.*s Godzina: %d:%02d:%02d", "Rozklad jazdy", - "Godzina: %d:%02d:%02d", "(brak rozkladu)", "Brutto: %d t (rozkladowe) %d t (rzeczywiste)\nDlugosc pociagu: %d m", @@ -247,6 +249,7 @@ init() { "nastawnik jazdy", "nastawnik dodatkowy", "sterowanie analogowe", + "tempomat", "nastawnik kierunku", "hamulec zespolony", "hamulec pomocniczy", @@ -267,6 +270,7 @@ init() { "wentylatory silnikow trakcyjnych A", "wentylatory silnikow trakcyjnych B", "wszystkie wentylatory silnikow trakcyjnych", + "wentylatory oporow rozruchowych", "wylacznik szybki", "wylacznik szybki", "czuwak", @@ -363,6 +367,7 @@ init() { "jointctrl:", "scndctrl:", "shuntmodepower:", + "tempomat_sw:", "dirkey:", "brakectrl:", "localbrake:", @@ -383,6 +388,7 @@ init() { "motorblowersfront_sw:", "motorblowersrear_sw:", "motorblowersalloff_sw:", + "coolingfans_sw:", "main_off_bt:", "main_on_bt:", "security_reset_bt:", diff --git a/translation.h b/translation.h index ce6624c4..18edda94 100644 --- a/translation.h +++ b/translation.h @@ -46,7 +46,7 @@ enum string { driver_scenario_bank, driver_timetable_header, - driver_timetable_time, + driver_timetable_name, driver_timetable_notimetable, driver_timetable_consistdata, @@ -73,6 +73,7 @@ enum string { cab_jointctrl, cab_scndctrl, cab_shuntmodepower, + cab_tempomat, cab_dirkey, cab_brakectrl, cab_localbrake, @@ -93,6 +94,7 @@ enum string { cab_motorblowersfront_sw, cab_motorblowersrear_sw, cab_motorblowersalloff_sw, + cab_coolingfans_sw, cab_main_off_bt, cab_main_on_bt, cab_security_reset_bt, From 3de04fdb679fc474f96e3b2a4f362e5f7e4ea49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 14 Mar 2019 14:44:19 +0100 Subject: [PATCH 09/17] SpeedCntrl affects also first vehicle now --- DynObj.cpp | 1 + McZapkie/Mover.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/DynObj.cpp b/DynObj.cpp index a1c606bd..d6dad14b 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2705,6 +2705,7 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->CheckSpeedCtrl(); auto eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl); + MoverParameters->eimic = eimic; MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, eimic), MoverParameters->CabNo); auto LBR = Max0R(-eimic, 0); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 851f0aaa..daf5bc76 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5055,7 +5055,6 @@ double TMoverParameters::TractionForce( double dt ) { } else { - PosRatio = static_cast( MainCtrlPos ) / static_cast( MainCtrlPosNo ); PosRatio = Max0R(eimic, 0); eimv[eimv_Fzad] = PosRatio; if ((Flat) && (eimc[eimc_p_F0] * eimv[eimv_Fful] > 0)) From 8d6733895094473de4955abe8ccf28c0bb96c4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 14 Mar 2019 18:58:31 +0100 Subject: [PATCH 10/17] Small fix to eimic and speedcontrol interaction --- DynObj.cpp | 2 +- McZapkie/MOVER.h | 1 + McZapkie/Mover.cpp | 4 ++-- Train.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index d6dad14b..d17ec0bf 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2705,7 +2705,7 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->CheckSpeedCtrl(); auto eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl); - MoverParameters->eimic = eimic; + MoverParameters->eimic_real = eimic; MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, eimic), MoverParameters->CabNo); auto LBR = Max0R(-eimic, 0); diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index aa439b6f..ca040145 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1282,6 +1282,7 @@ public: /*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/ 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*/ double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/ double eimv[21]; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index daf5bc76..dbe39204 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5055,7 +5055,7 @@ double TMoverParameters::TractionForce( double dt ) { } else { - PosRatio = Max0R(eimic, 0); + PosRatio = Max0R(eimic_real, 0); eimv[eimv_Fzad] = PosRatio; if ((Flat) && (eimc[eimc_p_F0] * eimv[eimv_Fful] > 0)) PosRatio = Min0R(PosRatio * eimc[eimc_p_F0] / eimv[eimv_Fful], 1); @@ -9554,7 +9554,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C end */ else if (Command == "EIMIC") // ElectricInductionMotor Integrated Control - propulsion and brakes in relative values { - eimic = CValue1; + eimic_real = CValue1; OK = SendCtrlToNext(Command, CValue1, CValue2, Couplertype); } else if (Command == "Brake") // youBy - jak sie EP hamuje, to trza sygnal wyslac... diff --git a/Train.cpp b/Train.cpp index b8abbfe2..6977c69d 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5309,7 +5309,7 @@ bool TTrain::Update( double const Deltatime ) // else // fEIMParams[0][3] = // mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany - fEIMParams[0][3] = mvOccupied->eimic; + fEIMParams[0][3] = mvOccupied->eimic_real; fEIMParams[0][4] = Max0R(fEIMParams[0][3], 0); fEIMParams[0][5] = -Min0R(fEIMParams[0][3], 0); fEIMParams[0][1] = fEIMParams[0][4] * mvControlled->eimv[eimv_Fful]; From 04db86baa6ddf45ff348fc936bc72f40546f30ca Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 17 Mar 2019 19:08:53 +0100 Subject: [PATCH 11/17] 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 12/17] 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 13/17] 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 14/17] 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 15/17] 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 16/17] 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 17/17] 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 {