From 72fa1c22a2676df122a0551defe2e72ac0eaece5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 09:50:40 +0100 Subject: [PATCH 1/9] Vehicles with EIMCtrlType>0 use integrated controller instead of localbrake handle --- Driver.cpp | 39 +++++++++++++++++++++++++++++++++++---- Driver.h | 2 ++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index f14e01ac..2fdb2f99 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2707,7 +2707,7 @@ bool TController::IncBrake() } } - standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); + //standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); if( true == standalone ) { if( mvControlling->EIMCtrlType > 0 ) { @@ -2855,9 +2855,11 @@ bool TController::DecBrake() } } if( !OK ) { - OK = DecBrakeEIM(); -// OK = mvOccupied->DecLocalBrakeLevel(2); + OK = mvOccupied->DecLocalBrakeLevel(2); } + if (!OK) { + OK = DecBrakeEIM(); + } if (mvOccupied->PipePress < 3.0) Need_BrakeRelease = true; break; @@ -3352,6 +3354,33 @@ void TController::SpeedCntrl(double DesiredSpeed) } }; +void TController::SetTimeControllers() +{ + +}; + +void TController::CheckTimeControllers() +{ + //1. Check the type of Main Brake Handle + + //2. Check the type of Secondary Brake Handle + + //3. Check the type od EIMCtrlType + if (mvOccupied->EIMCtrlType > 0) + { + if (mvOccupied->EIMCtrlType == 1) //traxx + { + if (mvOccupied->MainCtrlPos > 3) mvOccupied->MainCtrlPos = 5; + if (mvOccupied->MainCtrlPos < 3) mvOccupied->MainCtrlPos = 1; + } + else if (mvOccupied->EIMCtrlType == 2) //elf + { + if (mvOccupied->eimic > 0) mvOccupied->MainCtrlPos = 3; + if (mvOccupied->eimic < 0) mvOccupied->MainCtrlPos = 2; + } + } +}; + // otwieranie/zamykanie drzwi w składzie albo (tylko AI) EZT void TController::Doors( bool const Open, int const Side ) { @@ -4291,6 +4320,8 @@ TController::UpdateSituation(double dt) { auto const reactiontime = std::min( ReactionTime, 2.0 ); if( LastReactionTime < reactiontime ) { return; } + CheckTimeControllers(); + LastReactionTime -= reactiontime; // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ // yB: otóż jest to jedna trzecia czasu napełniania na towarowym; może się przydać przy @@ -5509,7 +5540,7 @@ TController::UpdateSituation(double dt) { } } if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P) { if( mvOccupied->BrakeCtrlPos == -2 ) { mvOccupied->BrakeLevelSet( 0 ); diff --git a/Driver.h b/Driver.h index 0c0188e4..1b7c32bd 100644 --- a/Driver.h +++ b/Driver.h @@ -218,6 +218,8 @@ private: bool DecSpeedEIM(); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); + void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ + void CheckTimeControllers(); /*checking state of time controllers to reset them to stable position*/ double ESMVelocity(bool Main); bool UpdateHeating(); // uaktualnia informacje o prędkości From ef1ccb448acec4bbf76a7570bc81db9eae85d3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 15:27:10 +0100 Subject: [PATCH 2/9] Preparation for rework of main brake handle usage by AI --- Driver.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- Driver.h | 3 +++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Driver.cpp b/Driver.cpp index 2fdb2f99..e61d9db7 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -3181,6 +3181,16 @@ bool TController::DecSpeedEIM() return OK; } +bool TController::BrakeLevelSet(double b) +{ + return false; +} + +bool TController::BrakeLevelAdd(double b) +{ + return false; +} + void TController::SpeedSet() { // Ra: regulacja prędkości, wykonywana w każdym przebłysku świadomości AI // ma dokręcać do bezoporowych i zdejmować pozycje w przypadku przekroczenia prądu @@ -3356,13 +3366,52 @@ void TController::SpeedCntrl(double DesiredSpeed) void TController::SetTimeControllers() { + //1. Check the type of Main Brake Handle + if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) + { + if (mvOccupied->Handle->Time) + { + if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); + else if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + else if (BrakeCtrlPosition == 0) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + else if (BrakeCtrlPosition == -1) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); + } + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); + } + //2. Check the type of Secondary Brake Handle + //3. Check the type od EIMCtrlType + if (mvOccupied->EIMCtrlType > 0) + { + if (mvOccupied->EIMCtrlType == 1) //traxx + { + if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 0; + } + else if (mvOccupied->EIMCtrlType == 2) //elf + { + if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 1; + } + } }; void TController::CheckTimeControllers() { //1. Check the type of Main Brake Handle - + if (mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP) + { + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN)); + } + if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic && mvOccupied->Handle->Time) + { + if (BrakeCtrlPosition > 0) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); + else + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); + } //2. Check the type of Secondary Brake Handle //3. Check the type od EIMCtrlType diff --git a/Driver.h b/Driver.h index 1b7c32bd..0b8156bc 100644 --- a/Driver.h +++ b/Driver.h @@ -216,6 +216,8 @@ private: bool DecBrakeEIM(); bool IncSpeedEIM(); bool DecSpeedEIM(); + bool BrakeLevelSet(double b); + bool BrakeLevelAdd(double b); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ @@ -310,6 +312,7 @@ private: double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently + double BrakeCtrlPosition = 0.0; // intermediate position of main brake controller double LastReactionTime = 0.0; double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations From 3fd408bd46759d38c4ea4fb9132d1f93c7d39f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 17:25:05 +0100 Subject: [PATCH 3/9] Reworked main brake handle usage by AI - it can use time-dependent handles now. --- Driver.cpp | 104 ++++++++++++++++++++++++++----------------- Driver.h | 8 +++- McZapkie/hamulce.cpp | 6 ++- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index e61d9db7..e9fdf7c9 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1776,6 +1776,7 @@ void TController::Activation() // zaworze maszynisty, FVel6 po drugiej stronie nie luzuje mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos(bh_NP)); // odcięcie na zaworze maszynisty + BrakeLevelSet(gbh_NP); //ustawienie zmiennej GBH } mvOccupied->ActiveCab = mvOccupied->CabNo; // użytkownik moze zmienić ActiveCab wychodząc mvOccupied->CabDeactivisation(); // tak jest w Train.cpp @@ -2354,7 +2355,7 @@ double TController::BrakeAccFactor() const double Factor = 1.0; if( ( ActualProximityDist > fMinProximityDist ) || ( mvOccupied->Vel > VelDesired + fVelPlus ) ) { - Factor += ( fBrakeReaction * ( mvOccupied->BrakeCtrlPosR < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); + Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); } return Factor; } @@ -2393,7 +2394,7 @@ void TController::SetDriverPsyche() { // with Controlling do if (mvControlling->MainCtrlPowerPos() < 3) ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime; - if (mvOccupied->BrakeCtrlPos > 1) + if (/* GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 1) ReactionTime = 0.5 * ReactionTime; } }; @@ -2518,6 +2519,7 @@ bool TController::PrepareEngine() // enable train brake if it's off if( mvOccupied->fBrakeCtrlPos == mvOccupied->Handle->GetPos( bh_NP ) ) { mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + BrakeLevelSet(gbh_RP); // GBH } } } @@ -2719,9 +2721,9 @@ bool TController::IncBrake() } } else { - if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == mvOccupied->BrakeCtrlPosNo ) { if (AccDesired < -1.5) // hamowanie nagle - OK = mvOccupied->BrakeLevelAdd(1.0); + OK = /*mvOccupied->*/BrakeLevelAdd(1.0); //GBH else OK = false; } @@ -2745,12 +2747,12 @@ bool TController::IncBrake() pos_corr += mvOccupied->Handle->GetCP()*0.2; } - double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (mvOccupied->BrakeCtrlPosR - 1 - pos_corr)*fBrake_a1[0]); + double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition - 1 - pos_corr)*fBrake_a1[0]); if( deltaAcc > fBrake_a1[0]) { - if( mvOccupied->BrakeCtrlPosR < 0.1 ) { - OK = mvOccupied->BrakeLevelAdd( BrakingInitialLevel ); + if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) { + OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH /* // HACK: stronger braking to overcome SA134 engine behaviour if( ( mvOccupied->TrainType == dt_DMU ) @@ -2765,19 +2767,23 @@ bool TController::IncBrake() } else { - OK = mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); + OK = /*mvOccupied->*/BrakeLevelAdd( BrakingLevelIncrease ); //GBH // brake harder if the acceleration is much higher than desired - if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) + /*if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) && ( mvOccupied->BrakeCtrlPosR + BrakingLevelIncrease <= 5.0 ) ) { mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); - } + } GBH */ + if ((deltaAcc > 2 * fBrake_a1[0]) + && (BrakeCtrlPosition + BrakingLevelIncrease <= 5.0)) { + /*mvOccupied->*/BrakeLevelAdd(BrakingLevelIncrease); + } } } else OK = false; } } - if( mvOccupied->BrakeCtrlPos > 0 ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 0 ) { mvOccupied->BrakeReleaser( 0 ); } break; @@ -2842,16 +2848,17 @@ bool TController::DecBrake() OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case TBrakeSystem::Pneumatic: - deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR-1.0)*fBrake_a1[0]); + deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition -1.0)*fBrake_a1[0]); if (deltaAcc < 0) { - if (mvOccupied->BrakeCtrlPosR > 0) + if (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition > 0) { - OK = mvOccupied->BrakeLevelAdd(-0.25); + OK = /*mvOccupied->*/BrakeLevelAdd(-0.25); //if ((deltaAcc < 5 * fBrake_a1[0]) && (mvOccupied->BrakeCtrlPosR >= 1.2)) // mvOccupied->BrakeLevelAdd(-1.0); - if (mvOccupied->BrakeCtrlPosR < 0.74) - mvOccupied->BrakeLevelSet(0.0); + /* if (mvOccupied->BrakeCtrlPosR < 0.74) GBH */ + if (BrakeCtrlPosition < 0.74) + /*mvOccupied->*/BrakeLevelSet(0.0); } } if( !OK ) { @@ -3181,14 +3188,20 @@ bool TController::DecSpeedEIM() return OK; } -bool TController::BrakeLevelSet(double b) -{ - return false; +void TController::BrakeLevelSet(double b) +{ // ustawienie pozycji hamulca na wartość (b) w zakresie od -2 do BrakeCtrlPosNo + // jedyny dopuszczalny sposób przestawienia hamulca zasadniczego + if (BrakeCtrlPosition == b) + return; // nie przeliczać, jak nie ma zmiany + BrakeCtrlPosition = clamp(b, (double)gbh_MIN, (double)gbh_MAX); } bool TController::BrakeLevelAdd(double b) -{ - return false; +{ // dodanie wartości (b) do pozycji hamulca (w tym ujemnej) + // zwraca false, gdy po dodaniu było by poza zakresem + BrakeLevelSet(BrakeCtrlPosition + b); + return b > 0.0 ? (BrakeCtrlPosition < gbh_MAX) : + (BrakeCtrlPosition > -1.0); // true, jeśli można kontynuować } void TController::SpeedSet() @@ -3371,14 +3384,16 @@ void TController::SetTimeControllers() { if (mvOccupied->Handle->Time) { - if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) - mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); - else if ((BrakeCtrlPosition > 0) && (mvOccupied->PipePress + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FB)); + else if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); else if (BrakeCtrlPosition == 0) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); else if (BrakeCtrlPosition == -1) mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); + else if (BrakeCtrlPosition == -2) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); } if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); } @@ -3389,11 +3404,11 @@ void TController::SetTimeControllers() { if (mvOccupied->EIMCtrlType == 1) //traxx { - if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 0; + if (mvOccupied->LocalBrakePosA > 0.95) mvOccupied->MainCtrlPos = 0; } else if (mvOccupied->EIMCtrlType == 2) //elf { - if (mvOccupied->LocalBrakePosA > 0.95 * LocalBrakePosNo) mvOccupied->MainCtrlPos = 1; + if (mvOccupied->LocalBrakePosA > 0.95) mvOccupied->MainCtrlPos = 1; } } }; @@ -4103,7 +4118,7 @@ TController::UpdateSituation(double dt) { // Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka... if (AIControllFlag) // skład jak dotąd był wyluzowany { - if( ( mvOccupied->BrakeCtrlPos == 0 ) // jest pozycja jazdy + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) // jest pozycja jazdy && ( ( vehicle->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken && ( vehicle->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy && ( vehicle->Hamulec->GetCRP() > vehicle->PipePress + 0.12 ) ) { // za dużo w zbiorniku @@ -4490,12 +4505,13 @@ TController::UpdateSituation(double dt) { if( mvOccupied->SecuritySystem.Status > 1 ) { // jak zadziałało CA/SHP if( !mvOccupied->SecuritySystemReset() ) { // to skasuj - if( ( mvOccupied->BrakeCtrlPos == 0 ) + if( ( /*mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) && ( AccDesired > 0.0 ) && ( ( TestFlag( mvOccupied->SecuritySystem.Status, s_SHPebrake ) ) || ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAebrake ) ) ) ) { //!!! hm, może po prostu normalnie sterować hamulcem? - mvOccupied->BrakeLevelSet( 0 ); + //mvOccupied->BrakeLevelSet( 0 ); GBH + BrakeLevelSet(gbh_RP); } } } @@ -4897,7 +4913,8 @@ TController::UpdateSituation(double dt) { // (ustalić po czym poznać taki tor) ++n; // to liczymy człony jako jeden p->MoverParameters->BrakeReleaser(1); // wyluzuj pojazd, aby dało się dopychać - p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował + // GBH p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował + BrakeLevelSet(gbh_RP); if (n) { // jeśli jeszcze nie koniec p = p->Prev(); // kolejny w stronę czoła składu (licząc od tyłu), bo dociskamy @@ -5589,17 +5606,18 @@ TController::UpdateSituation(double dt) { } } if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P) + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P + || mvOccupied->BrakeHandle == TBrakeHandle::M394) { - if( mvOccupied->BrakeCtrlPos == -2 ) { - mvOccupied->BrakeLevelSet( 0 ); + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == -2 ) { + /*mvOccupied->*/BrakeLevelSet( gbh_RP ); } if( ( mvOccupied->PipePress < 3.0 ) && ( AccDesired > -0.03 ) ) { mvOccupied->BrakeReleaser( 1 ); } - if( ( mvOccupied->BrakeCtrlPos == 0 ) + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 ) && ( AbsAccS < 0.03 ) && ( AccDesired > -0.03 ) && ( VelDesired - mvOccupied->Vel > 2.0 ) ) { @@ -5611,7 +5629,8 @@ TController::UpdateSituation(double dt) { if( ( iDrivigFlags & moveOerlikons ) || ( true == IsCargoTrain ) ) { // napełnianie w Oerlikonie - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); + /* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */ + BrakeLevelSet(gbh_FS); // don't charge the brakes too often, or we risk overcharging BrakeChargingCooldown = -120.0; } @@ -5622,9 +5641,10 @@ TController::UpdateSituation(double dt) { } } - if( ( mvOccupied->BrakeCtrlPos < 0 ) + if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) && ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) { - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + /* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */ + BrakeLevelSet(gbh_RP); } } #if LOGVELOCITY @@ -5727,7 +5747,7 @@ TController::UpdateSituation(double dt) { std::max( -0.2, fAccThreshold ) ) }; if( ( AccDesired <= accthreshold ) // jeśli hamować - u góry ustawia się hamowanie na fAccThreshold && ( ( AbsAccS > AccDesired ) - || ( mvOccupied->BrakeCtrlPos < 0 ) ) ) { + || ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) ) ) { // hamować bardziej, gdy aktualne opóźnienie hamowania mniejsze niż (AccDesired) IncBrake(); } @@ -5735,7 +5755,7 @@ TController::UpdateSituation(double dt) { // przy odłączaniu nie zwalniamy tu hamulca if( AbsAccS < AccDesired - 0.05 ) { // jeśli opóźnienie większe od wymaganego (z histerezą) luzowanie, gdy za dużo - if( mvOccupied->BrakeCtrlPos >= 0 ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition >= 0 ) { DecBrake(); // tutaj zmniejszało o 1 przy odczepianiu } } @@ -5758,7 +5778,7 @@ TController::UpdateSituation(double dt) { // u góry ustawia się hamowanie na fAccThreshold if( ( fBrakeTime < 0.0 ) || ( AccDesired < fAccGravity - 0.5 ) - || ( mvOccupied->BrakeCtrlPos <= 0 ) ) { + || ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition <= 0 ) ) { // jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował if( true == IncBrake() ) { fBrakeTime = @@ -5831,13 +5851,15 @@ TController::UpdateSituation(double dt) { mvOccupied->IncLocalBrakeLevel( 1 ); } else { - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); + mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); //GBH + BrakeLevelSet(gbh_RP); } } } } break; // rzeczy robione przy jezdzie } // switch (OrderList[OrderPos]) + if (AIControllFlag) SetTimeControllers(); } // configures vehicle heating given current situation; returns: true if vehicle can be operated normally, false otherwise diff --git a/Driver.h b/Driver.h index 0b8156bc..1c4034d1 100644 --- a/Driver.h +++ b/Driver.h @@ -169,6 +169,12 @@ static const int maxorders = 64; // ilość rozkazów w tabelce static const int maxdriverfails = 4; // ile błędów może zrobić AI zanim zmieni nastawienie extern bool WriteLogFlag; // logowanie parametrów fizycznych static const int BrakeAccTableSize = 20; + +static const int gbh_NP = -2; //odciecie w hamulcu ogolnym +static const int gbh_RP = 0; //jazda w hamulcu ogolnym +static const int gbh_FS = -1; //napelnianie uderzeniowe w hamulcu ogolnym +static const int gbh_MIN = -2; //minimalna pozycja w hamulcu ogolnym +static const int gbh_MAX = 6; //maksymalna pozycja w hamulcu ogolnym //---------------------------------------------------------------------------- class TController { @@ -216,7 +222,7 @@ private: bool DecBrakeEIM(); bool IncSpeedEIM(); bool DecSpeedEIM(); - bool BrakeLevelSet(double b); + void BrakeLevelSet(double b); bool BrakeLevelAdd(double b); void SpeedSet(); void SpeedCntrl(double DesiredSpeed); diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 47bbebe6..8916b2cd 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -2788,7 +2788,7 @@ double TMHZ_K5P::GetPos(int i) double TMHZ_K5P::GetCP() { - return RP; + return CP; } void TMHZ_K5P::SetParams(bool AO, bool MO, double, double) @@ -2890,6 +2890,8 @@ double TMHZ_6P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) void TMHZ_6P::Init(double Press) { CP = Press; + Time = true; + TimeEP = true; } void TMHZ_6P::SetReductor(double nAdj) @@ -2912,7 +2914,7 @@ double TMHZ_6P::GetPos(int i) double TMHZ_6P::GetCP() { - return RP; + return CP; } void TMHZ_6P::SetParams(bool AO, bool MO, double OverP, double) From 403c29746d01a187d52dec6d1a702f2fe961cf03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 17:47:16 +0100 Subject: [PATCH 4/9] AI does not fear accelerating a bit too fast --- Driver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Driver.cpp b/Driver.cpp index e9fdf7c9..8ac0229f 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5732,8 +5732,9 @@ TController::UpdateSituation(double dt) { else if( ( vel > VelDesired ) || ( fAccGravity < -0.01 ? AccDesired < 0.0 : - AbsAccS > AccDesired ) ) { + (AbsAccS > AccDesired && AccDesired < 0.75) ) ) { // jak za bardzo przyspiesza albo prędkość przekroczona + // dodany wyjatek na "pelna w przod" DecSpeed(); // pojedyncze cofnięcie pozycji, bo na zero to przesada } } From 91a7a94682ea8c3c7d8dc948878c2ff91446fc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 21:47:35 +0100 Subject: [PATCH 5/9] Fix for autoreturning controller --- Driver.cpp | 4 +++- McZapkie/MOVER.h | 19 +++++++++++++++ McZapkie/Mover.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 8ac0229f..120e1ef1 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4384,7 +4384,9 @@ TController::UpdateSituation(double dt) { auto const reactiontime = std::min( ReactionTime, 2.0 ); if( LastReactionTime < reactiontime ) { return; } - CheckTimeControllers(); + if (AIControllFlag) { + CheckTimeControllers(); + } LastReactionTime -= reactiontime; // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 782c9fd2..77ed3e3f 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -96,6 +96,7 @@ static int const maxcc = 4; /*max. ilosc odbierakow pradu*/ //static int const MainBrakeMaxPos = 10; /*max. ilosc nastaw hamulca zasadniczego*/ static int const ManualBrakePosNo = 20; /*ilosc nastaw hamulca recznego*/ static int const LightsSwitchPosNo = 16; +static int const UniversalCtrlArraySize = 32; /*max liczba pozycji uniwersalnego nastawnika*/ /*uszkodzenia toru*/ static int const dtrack_railwear = 2; @@ -572,6 +573,20 @@ struct TMotorParameters } }; +struct TUniversalCtrl +{ + int mode = 0; /*tryb pracy zadajnika - pomocnicze*/ + double MinCtrlVal = 0.0; /*minimalna wartosc nastawy*/ + double MaxCtrlVal = 0.0; /*maksymalna wartosc nastawy*/ + double SetCtrlVal = 0.0; /*docelowa wartosc nastawy*/ + double SpeedUp = 0.0; /*szybkosc zwiekszania nastawy*/ + double SpeedDown = 0.0; /*szybkosc zmniejszania nastawy*/ + int ReturnPosition = 0; /*pozycja na ktora odskakuje zadajnik*/ + int NextPosFastInc = 0; /*nastepna duza pozycja przy przechodzeniu szybkim*/ + int PrevPosFastDec = 0; /*poprzednia duza pozycja przy przechodzeniu szybkim*/ +}; +typedef TUniversalCtrl TUniversalCtrlTable[UniversalCtrlArraySize + 1]; /*tablica sterowania uniwersalnego nastawnika*/ + struct TSecuritySystem { int SystemType { 0 }; /*0: brak, 1: czuwak aktywny, 2: SHP/sygnalizacja kabinowa*/ @@ -940,6 +955,8 @@ public: bool MBrake = false; /*Czy jest hamulec reczny*/ double StopBrakeDecc = 0.0; TSecuritySystem SecuritySystem; + TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/ + int UniCtrlListSize = 0; /*wielkosc listy pozycji uniwersalnego nastawnika*/ /*-sekcja parametrow dla lokomotywy elektrycznej*/ TSchemeTable RList; /*lista rezystorow rozruchowych i polaczen silnikow, dla dizla: napelnienia*/ @@ -1563,6 +1580,7 @@ private: void LoadFIZ_MotorParamTable( std::string const &Input ); void LoadFIZ_Circuit( std::string const &Input ); void LoadFIZ_RList( std::string const &Input ); + void LoadFIZ_UCList(std::string const &Input); void LoadFIZ_DList( std::string const &Input ); void LoadFIZ_FFList( std::string const &Input ); void LoadFIZ_LightsList( std::string const &Input ); @@ -1577,6 +1595,7 @@ private: bool readMPTDieselEngine( std::string const &line ); bool readBPT(/*int const ln,*/ std::string const &line); //Q 20160721 bool readRList( std::string const &Input ); + bool readUCList(std::string const &Input); bool readDList( std::string const &line ); bool readFFList( std::string const &line ); bool readWWList( std::string const &line ); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index db89fbf7..acad6b49 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5994,6 +5994,10 @@ void TMoverParameters::CheckEIMIC(double dt) break; } break; + case 3: + eimic -= clamp(-UniCtrlList[MainCtrlPos].SetCtrlVal + eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedDown); //odejmuj do X + eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedUp); //dodawaj do X + eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal); } eimic = clamp(eimic, -1.0, 1.0); } @@ -7242,7 +7246,7 @@ bool TMoverParameters::switch_physics(bool const State) // DO PRZETLUMACZENIA NA // ************************************************************************************************* bool startBPT; bool startMPT, startMPT0; -bool startRLIST; +bool startRLIST, startUCLIST; bool startDLIST, startFFLIST, startWWLIST; bool startLIGHTSLIST; int LISTLINE; @@ -7437,6 +7441,31 @@ bool TMoverParameters::readRList( std::string const &Input ) { return true; } +bool TMoverParameters::readUCList(std::string const &line) { + + cParser parser(line); + parser.getTokens(10, false); + auto idx = LISTLINE++; + if (idx >= sizeof(UniCtrlList) / sizeof(TUniversalCtrl)) { + WriteLog("Read UCList: number of entries exceeded capacity of the data table"); + return false; + } + int i = 0; + parser + >> i + >> UniCtrlList[idx].mode + >> UniCtrlList[idx].MinCtrlVal + >> UniCtrlList[idx].MaxCtrlVal + >> UniCtrlList[idx].SetCtrlVal + >> UniCtrlList[idx].SpeedUp + >> UniCtrlList[idx].SpeedDown + >> UniCtrlList[idx].ReturnPosition + >> UniCtrlList[idx].NextPosFastInc + >> UniCtrlList[idx].PrevPosFastDec; + + return true; +} + bool TMoverParameters::readDList( std::string const &line ) { cParser parser( line ); @@ -7626,6 +7655,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) startMPT = false; startMPT0 = false; startRLIST = false; + startUCLIST = false; startDLIST = false; startFFLIST = false; startWWLIST = false; @@ -7677,6 +7707,11 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) startRLIST = false; continue; } + if (issection("END-RL", inputline)) { + startBPT = false; + startUCLIST = false; + continue; + } if( issection( "END-DL", inputline ) ) { startBPT = false; startDLIST = false; @@ -7880,6 +7915,15 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) continue; } + if (issection("UCList:", inputline)) + { + startBPT = false; + fizlines.emplace("UCList", inputline); + startUCLIST = true; LISTLINE = 0; + LoadFIZ_RList(inputline); + continue; + } + if( issection( "DList:", inputline ) ) { startBPT = false; @@ -7929,6 +7973,10 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) readRList( inputline ); continue; } + if (true == startUCLIST) { + readRList(inputline); + continue; + } if( true == startDLIST ) { readDList( inputline ); continue; @@ -8537,7 +8585,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { extract_value( CoupledCtrl, "CoupledCtrl", line, "" ); extract_value( EIMCtrlType, "EIMCtrlType", line, "" ); - clamp( EIMCtrlType, 0, 2 ); + clamp( EIMCtrlType, 0, 3 ); extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR @@ -8966,6 +9014,12 @@ void TMoverParameters::LoadFIZ_RList( std::string const &Input ) { extract_value( DynamicBrakeRes2, "DynBrakeRes2", Input, ""); } +void TMoverParameters::LoadFIZ_UCList(std::string const &Input) { + + extract_value(UniCtrlListSize, "Size", Input, ""); + +} + void TMoverParameters::LoadFIZ_DList( std::string const &Input ) { extract_value( dizel_Mmax, "Mmax", Input, "" ); From be63aa74524993518579146bee1ee3429ab7fc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 21 Mar 2019 23:17:41 +0100 Subject: [PATCH 6/9] Fix for Handle=H14K1 with BrakeValve=K --- Driver.cpp | 2 +- McZapkie/hamulce.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 120e1ef1..15c969e2 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2721,7 +2721,7 @@ bool TController::IncBrake() } } else { - if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == mvOccupied->BrakeCtrlPosNo ) { + if( /*GBH mvOccupied->BrakeCtrlPos*/ BrakeCtrlPosition + 1 == gbh_MAX ) { if (AccDesired < -1.5) // hamowanie nagle OK = /*mvOccupied->*/BrakeLevelAdd(1.0); //GBH else diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 8916b2cd..3544b002 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -346,7 +346,7 @@ double TBrake::GetVRP() // cisnienie zbiornika sterujacego double TBrake::GetCRP() { - return 0; + return GetBRP(); } // przeplyw z przewodu glowneg From 14e3a2702672e5cdd6a4e1f197638be176dc2e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 22 Mar 2019 20:26:59 +0100 Subject: [PATCH 7/9] AI does not fear SlippingWheels when driving ElectricInductionMotor vehicle + fix for adhesion calculation when slipping --- Driver.cpp | 2 +- McZapkie/Mover.cpp | 26 +++++++++++++------------- driveruipanels.cpp | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 15c969e2..9c82e860 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5542,7 +5542,7 @@ TController::UpdateSituation(double dt) { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy // zapobieganie poslizgowi u nas - if (mvControlling->SlippingWheels) { + if (mvControlling->SlippingWheels && mvControlling->EngineType != TEngineType::ElectricInductionMotor) { if( false == mvControlling->DecScndCtrl( 2 ) ) { // bocznik na zero diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index acad6b49..2dfc3537 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4001,12 +4001,18 @@ void TMoverParameters::ComputeTotalForce(double dt) { && ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) { SlippingWheels = true; } - if( true == SlippingWheels ) { + double temp_nrot = nrot; + if (true == SlippingWheels) { - double temp_nrot = ComputeRotatingWheel(Fwheels - - Sign(nrot * M_PI * WheelDiameter - V) * - Adhesive(RunningTrack.friction) * TotalMassxg, - dt, nrot); + temp_nrot = ComputeRotatingWheel(Fwheels - Sign(nrot * M_PI * WheelDiameter - V) * + Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); + if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) + { + SlippingWheels = false; + temp_nrot = V / M_PI / WheelDiameter; + } + } + if (true == SlippingWheels) { Fwheels = Sign(temp_nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction); if (Fwheels*Sign(V)>0) { @@ -4025,12 +4031,6 @@ void TMoverParameters::ComputeTotalForce(double dt) { { WheelFlat = sqrt(square(WheelFlat) + abs(Fwheels) / NAxles*Vel*0.000002); } - if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) - { - SlippingWheels = false; - temp_nrot = V / M_PI / WheelDiameter; - } - nrot = temp_nrot; } @@ -5368,9 +5368,9 @@ double TMoverParameters::v2n(void) n = V / (M_PI * WheelDiameter); // predkosc obrotowa wynikajaca z liniowej [obr/s] deltan = n - nrot; //"pochodna" prędkości obrotowej - if (SlippingWheels) + /* if (SlippingWheels) if (std::abs(deltan) < 0.001) - SlippingWheels = false; // wygaszenie poslizgu + SlippingWheels = false; // wygaszenie poslizgu */ //poslizg jest w innym miejscu wygaszany też if (SlippingWheels) // nie ma zwiazku z predkoscia liniowa V { // McZapkie-221103: uszkodzenia kol podczas poslizgu if (deltan > dmgn) diff --git a/driveruipanels.cpp b/driveruipanels.cpp index f10ae4c9..bcd5c623 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -820,7 +820,8 @@ debug_panel::update_section_ai( std::vector &Output ) { + ", slope: " + to_string( mechanik.fAccGravity + 0.001f, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")" + "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 ) + ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) - + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ); + + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ) + + "\n virtual brake position: " + to_string(mechanik.BrakeCtrlPosition, 2); Output.emplace_back( textline, Global.UITextColor ); From 8fddbadbafed9cf02d6f610b768e9b416ff494cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 23 Mar 2019 08:52:47 +0100 Subject: [PATCH 8/9] Fix for AI decoupling old Knorr/West locomotives --- Driver.cpp | 1 + McZapkie/hamulce.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Driver.cpp b/Driver.cpp index 39c1d15b..cb4397bb 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -5002,6 +5002,7 @@ TController::UpdateSituation(double dt) { TableClear(); // skanowanie od nowa iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie prędkości jazdy + mvOccupied->BrakeReleaser(0); // wyłączyć luzowanie } } diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 3544b002..6d258f8e 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -481,6 +481,12 @@ double TWest::GetPF( double const PP, double const dt, double const Vel ) dv = 0; BrakeCyl->Flow(-dv); + if ((BrakeStatus & b_rls) == b_rls) //odluzniacz + dv = PF(0, CVP, 0.1 * SizeBC) * dt; + else + dv = 0; + BrakeCyl->Flow(-dv); + // hamulec EP temp = BVP * int(EPS > 0); dv = PF(temp, LBP, 0.0015) * dt * EPS * EPS * int(LBP * EPS < MaxBP * LoadC); From 511d1c57d9245924646a16ea2b398eea0aeb7344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 23 Mar 2019 11:51:24 +0100 Subject: [PATCH 9/9] Added SpeedCtrl for TRAXX --- McZapkie/MOVER.h | 1 + McZapkie/Mover.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- Train.cpp | 1 + 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 77ed3e3f..f02bd64d 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1306,6 +1306,7 @@ public: double eimic = 0; /*aktualna pozycja zintegrowanego sterowania jazda i hamowaniem*/ double eimic_real = 0; /*faktycznie uzywana pozycja zintegrowanego sterowania jazda i hamowaniem*/ int EIMCtrlType = 0; /*rodzaj wariantu zadajnika jazdy*/ + bool SpeedCtrlTypeTime = false; /*czy tempomat sterowany czasowo*/ double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/ double eimv[21]; static std::vector const eimv_labels; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 2dfc3537..c3f0c534 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5011,7 +5011,44 @@ double TMoverParameters::TractionForce( double dt ) { { if( true == Mains ) { //tempomat - if (ScndCtrlPosNo > 1) + if (ScndCtrlPosNo == 4 && SpeedCtrlTypeTime) + { + switch (ScndCtrlPos) { + case 0: + NewSpeed = 0; + ScndCtrlActualPos = 0; + SpeedCtrlTimer = 10; + break; + case 1: + if (SpeedCtrlTimer > SpeedCtrlDelay) { + SpeedCtrlTimer = 0; + NewSpeed -= 10; + if (NewSpeed < 0) NewSpeed = 0; + } + else + SpeedCtrlTimer += dt; + break; + case 2: + SpeedCtrlTimer = 10; + ScndCtrlActualPos = NewSpeed; + break; + case 3: + if (SpeedCtrlTimer > SpeedCtrlDelay) { + SpeedCtrlTimer = 0; + NewSpeed += 10; + if (NewSpeed > Vmax) NewSpeed = Vmax; + } + else + SpeedCtrlTimer += dt; + break; + case 4: + NewSpeed = Vmax; + ScndCtrlActualPos = Vmax; + SpeedCtrlTimer = 10; + break; + } + } + else if (ScndCtrlPosNo > 1) { if (ScndCtrlPos != NewSpeed) { @@ -8604,6 +8641,10 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { // speed control extract_value( SpeedCtrlDelay, "SpeedCtrlDelay", line, "" ); + SpeedCtrlTypeTime = + (extract_value("SpeedCtrlType", line) == "Time") ? + true : + false; // converter { diff --git a/Train.cpp b/Train.cpp index 41c0416a..6c2da0f5 100644 --- a/Train.cpp +++ b/Train.cpp @@ -453,6 +453,7 @@ dictionary_source *TTrain::GetTrainState() { dict->insert( "main_ctrl_actual_pos", mover->MainCtrlActualPos ); dict->insert( "scndctrl_pos", mover->ScndCtrlPos ); dict->insert( "scnd_ctrl_actual_pos", mover->ScndCtrlActualPos ); + dict->insert( "new_speed", mover->NewSpeed); // brakes dict->insert( "manual_brake", ( mvOccupied->ManualBrakePos > 0 ) ); bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );