From 387f396ecb6c2d0abe616dedbf5cca2202fdca19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Mon, 16 Jul 2018 18:46:07 +0200 Subject: [PATCH 1/4] Fix for EP/MED brake after LBP changes --- DynObj.cpp | 10 +++++----- McZapkie/MOVER.h | 3 ++- McZapkie/Mover.cpp | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index 053c7943..ee5920b6 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3206,20 +3206,20 @@ bool TDynamicObject::Update(double dt, double dt1) p->MoverParameters->Hamulec->GetFC( Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA), VelC) * 1000; // sila hamowania pn - p->MoverParameters->LocalBrakePosA = (p->MoverParameters->SlippingWheels ? 0 : FzEP[i] / FmaxPoj); - if (p->MoverParameters->LocalBrakePosA>0.009) + p->MoverParameters->LocalBrakePosAEIM = (p->MoverParameters->SlippingWheels ? 0 : FzEP[i] / FmaxPoj); + if (p->MoverParameters->LocalBrakePosAEIM>0.009) if (p->MoverParameters->P2FTrans * p->MoverParameters->BrakeCylMult[0] * p->MoverParameters->MaxBrakePress[0] != 0) { float x = (p->MoverParameters->BrakeSlckAdj / p->MoverParameters->BrakeCylMult[0] + p->MoverParameters->BrakeCylSpring) / (p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0]); - p->MoverParameters->LocalBrakePosA = x + (1 - x) * p->MoverParameters->LocalBrakePosA; + p->MoverParameters->LocalBrakePosAEIM = x + (1 - x) * p->MoverParameters->LocalBrakePosAEIM; } else - p->MoverParameters->LocalBrakePosA = p->MoverParameters->LocalBrakePosA; + p->MoverParameters->LocalBrakePosAEIM = p->MoverParameters->LocalBrakePosAEIM; else - p->MoverParameters->LocalBrakePosA = 0; + p->MoverParameters->LocalBrakePosAEIM = 0; ++i; } diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 426d3f6f..69801a14 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1025,7 +1025,8 @@ public: double BrakeCtrlPosR = 0.0; /*nastawa hamulca zespolonego - plynna dla FV4a*/ double BrakeCtrlPos2 = 0.0; /*nastawa hamulca zespolonego - kapturek dla FV4a*/ int ManualBrakePos = 0; /*nastawa hamulca recznego*/ - double LocalBrakePosA = 0.0; + double LocalBrakePosA = 0.0; /*nastawa hamulca pomocniczego*/ + double LocalBrakePosAEIM = 0.0; /*pozycja hamulca pomocniczego ep dla asynchronicznych ezt*/ /* int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R */ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 72b32c95..8b1b5c17 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3462,8 +3462,10 @@ void TMoverParameters::UpdatePipePressure(double dt) if ((BrakeCtrlPosNo > 1) /*&& (ActiveCab != 0)*/) // with BrakePressureTable[BrakeCtrlPos] do { - dpLocalValve = LocHandle->GetPF(LocalBrakePosA, Hamulec->GetBCP(), ScndPipePress, dt, 0); - + if ((EngineType != TEngineType::ElectricInductionMotor)) + dpLocalValve = LocHandle->GetPF(std::max(LocalBrakePosA, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0); + else + dpLocalValve = LocHandle->GetPF(LocalBrakePosAEIM, Hamulec->GetBCP(), ScndPipePress, dt, 0); if( ( BrakeHandle == TBrakeHandle::FV4a ) && ( ( PipePress < 2.75 ) && ( ( Hamulec->GetStatus() & b_rls ) == 0 ) ) From cd10b72821d5bf3286e56e15e4ede1f6926d5dc5 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 19 Jul 2018 02:25:52 +0200 Subject: [PATCH 2/4] build 180718. ai slope logic tweaks, track grade ui indicator, minor bug fixes --- Driver.cpp | 125 +++++++++++++++++++++++++++++++--------------------- DynObj.h | 4 +- Train.cpp | 57 +++++++++++++----------- Train.h | 2 + uilayer.cpp | 11 +++-- utilities.h | 4 +- version.h | 2 +- 7 files changed, 121 insertions(+), 84 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 4a918991..26faab2f 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1410,16 +1410,24 @@ TController::braking_distance_multiplier( float const Targetvelocity ) const { if( Targetvelocity > 65.f ) { return 1.f; } if( Targetvelocity < 5.f ) { - + // HACK: engaged automatic transmission means extra/earlier braking effort is needed for the last leg before full stop if( ( mvOccupied->TrainType == dt_DMU ) && ( mvOccupied->Vel < 40.0 ) && ( Targetvelocity == 0.f ) ) { - // HACK: engaged automatic transmission means extra/earlier braking effort is needed for the last leg before full stop return interpolate( 2.f, 1.f, static_cast( mvOccupied->Vel / 40.0 ) ); } - else { - return 1.f; + // HACK: cargo trains or trains going downhill with high braking threshold need more distance to come to a full stop + if( ( fBrake_a0[ 0 ] > 0.2 ) + && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) + || ( fAccGravity > 0.025 ) ) { + return interpolate( + 1.f, 3.f, + clamp( + ( fBrake_a0[ 0 ] - 0.2 ) / 0.2, + 0.0, 1.0 ) ); } + + return 1.f; } // stretch the braking distance up to 3 times; the lower the speed, the greater the stretch return interpolate( 3.f, 1.f, ( Targetvelocity - 5.f ) / 60.f ); @@ -1546,7 +1554,7 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, // fAccThreshold może podlegać uczeniu się - hamowanie powinno być rejestrowane, a potem analizowane // próg opóźnienia dla zadziałania hamulca fAccThreshold = ( - mvOccupied->TrainType == dt_EZT ? -0.6 : + mvOccupied->TrainType == dt_EZT ? -0.55 : mvOccupied->TrainType == dt_DMU ? -0.45 : -0.2 ); } @@ -1868,7 +1876,7 @@ void TController::AutoRewident() fBrake_a1[i+1] /= (12*fMass); } if( mvOccupied->TrainType == dt_EZT ) { - fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.6); + fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.55); fBrakeReaction = 0.25; } else if( mvOccupied->TrainType == dt_DMU ) { @@ -2744,12 +2752,12 @@ bool TController::IncSpeed() // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) if (Ready || (iDrivigFlags & movePress)) { // use series mode: - // to build up speed to 30/40 km/h for passenger/cargo train, + // to build up speed to 30/40 km/h for passenger/cargo train (less if going uphill, more if downhill) // if high threshold is set for motor overload relay, // if the power station is heavily burdened auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV }; auto const useseriesmode = ( - ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) ) + ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) + ( fAccGravity * 100 ) ) || ( mvControlling->Imax > mvControlling->ImaxLo ) || ( fVoltage < useseriesmodevoltage ) ); // when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train @@ -3731,13 +3739,14 @@ TController::UpdateSituation(double dt) { if( ( dy = p->VectorFront().y ) != 0.0 ) { // istotne tylko dla pojazdów na pochyleniu // ciężar razy składowa styczna grawitacji - fAccGravity -= p->DirectionGet() * p->MoverParameters->TotalMassxg * dy; + fAccGravity -= p->MoverParameters->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 ); } p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła) } if( iDirection ) { // siłę generują pojazdy na pochyleniu ale działa ona całość składu, więc a=F/m - fAccGravity /= iDirection * fMass; + fAccGravity *= iDirection; + fAccGravity /= fMass; } if (!Ready) // v367: jeśli wg powyższych warunków skład nie jest odhamowany if (fAccGravity < -0.05) // jeśli ma pod górę na tyle, by się stoczyć @@ -4924,30 +4933,29 @@ TController::UpdateSituation(double dt) { // decisions based on current speed if( mvOccupied->CategoryFlag == 1 ) { - if( fAccGravity < 0.025 ) { - // on flats on uphill we can be less careful - if( vel > VelDesired ) { - // jesli jedzie za szybko do AKTUALNEGO - if( VelDesired == 0.0 ) { - // jesli stoj, to hamuj, ale i tak juz za pozno :) - AccDesired = std::min( AccDesired, -0.85 ); // hamuj solidnie + // on flats or uphill we can be less careful + if( vel > VelDesired ) { + // jesli jedzie za szybko do AKTUALNEGO + if( VelDesired == 0.0 ) { + // jesli stoj, to hamuj, ale i tak juz za pozno :) + AccDesired = std::min( AccDesired, -0.85 ); // hamuj solidnie + } + else { + // slow down, not full stop + if( vel > ( VelDesired + fVelPlus ) ) { + // hamuj tak średnio + AccDesired = std::min( AccDesired, -0.25 ); } else { - // slow down, not full stop - if( vel > ( VelDesired + fVelPlus ) ) { - // hamuj tak średnio - AccDesired = std::min( AccDesired, -0.25 ); - } - else { - // o 5 km/h to olej (zacznij luzować) - AccDesired = std::min( - AccDesired, // but don't override decceleration for VelNext - std::max( 0.0, AccPreferred ) ); - } + // o 5 km/h to olej (zacznij luzować) + AccDesired = std::min( + AccDesired, // but don't override decceleration for VelNext + std::max( 0.0, AccPreferred ) ); } } } - else { + + if( fAccGravity > 0.025 ) { // going sharply downhill we may need to start braking sooner than usual // try to estimate increase of current velocity before engaged brakes start working auto const speedestimate = vel + ( 1.0 - fBrake_a0[ 0 ] ) * 30.0 * AbsAccS; @@ -4958,20 +4966,39 @@ TController::UpdateSituation(double dt) { AccDesired = std::min( AccDesired, -0.85 ); // hamuj solidnie } else { - if( speedestimate > ( VelDesired + fVelPlus ) ) { - // if it looks like we'll exceed maximum allowed speed start thinking about slight slowing down - AccDesired = std::min( AccDesired, -0.25 ); - } - else { - // close enough to target to stop accelerating - AccDesired = std::min( - AccDesired, // but don't override decceleration for VelNext - interpolate( // ease off as you close to the target velocity - -0.06, AccPreferred, - clamp( speedestimate - vel, 0.0, fVelPlus ) / fVelPlus ) ); + // if it looks like we'll exceed maximum speed start thinking about slight slowing down + AccDesired = std::min( AccDesired, -0.25 ); + // HACK: for cargo trains with high braking threshold ensure we cross that threshold + if( ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) + && ( fBrake_a0[ 0 ] > 0.2 ) ) { + AccDesired -= clamp( fBrake_a0[ 0 ] - 0.2, 0.0, 0.15 ); } } } + else { + // stop accelerating when close enough to target speed + AccDesired = std::min( + AccDesired, // but don't override decceleration for VelNext + interpolate( // ease off as you close to the target velocity + -0.06, AccPreferred, + clamp( VelDesired - speedestimate, 0.0, fVelMinus ) / fVelMinus ) ); + } + // final tweaks + if( vel > 0.1 ) { + // going downhill also take into account impact of gravity + AccDesired -= fAccGravity; + // HACK: if the max allowed speed was exceeded something went wrong; brake harder + AccDesired -= 0.15 * clamp( vel - VelDesired, 0.0, 5.0 ); +/* + if( ( vel > VelDesired ) + && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) + && ( fBrake_a0[ 0 ] > 0.2 ) ) { + AccDesired = clamp( + AccDesired - clamp( fBrake_a0[ 0 ] - 0.2, 0.0, 0.15 ), + -0.9, 0.9 ); + } +*/ + } } } else { @@ -5001,14 +5028,7 @@ TController::UpdateSituation(double dt) { // last step sanity check, until the whole calculation is straightened out AccDesired = std::min( AccDesired, AccPreferred ); - - if( ( mvOccupied->CategoryFlag == 1 ) - && ( fAccGravity > 0.025 ) ) { - // going downhill also take into account impact of gravity - AccDesired = clamp( AccDesired - fAccGravity, -0.9, 0.9 ); - } - - + AccDesired = clamp( AccDesired, -0.9, 0.9 ); if (AIControllFlag) { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy @@ -5214,7 +5234,12 @@ TController::UpdateSituation(double dt) { if( mvOccupied->TrainType == dt_EZT ) { // właściwie, to warunek powinien być na działający EP // Ra: to dobrze hamuje EP w EZT - if( ( AccDesired <= fAccThreshold ) // jeśli hamować - u góry ustawia się hamowanie na fAccThreshold + // HACK: when going downhill be more responsive to desired deceleration + auto const accthreshold { ( + fAccGravity < 0.025 ? + fAccThreshold : + std::max( -0.2, fAccThreshold ) ) }; + if( ( AccDesired <= accthreshold ) // jeśli hamować - u góry ustawia się hamowanie na fAccThreshold && ( ( AbsAccS > AccDesired ) || ( mvOccupied->BrakeCtrlPos < 0 ) ) ) { // hamować bardziej, gdy aktualne opóźnienie hamowania mniejsze niż (AccDesired) @@ -5242,7 +5267,7 @@ TController::UpdateSituation(double dt) { } // type & dt_ezt else { // a stara wersja w miarę dobrze działa na składy wagonowe - if( ( ( fAccGravity < -0.05 ) && ( vel < 0.0 ) ) + if( ( ( fAccGravity < -0.05 ) && ( vel < -0.1 ) ) // brake if uphill and slipping back || ( ( AccDesired < fAccGravity - 0.1 ) && ( AbsAccS > AccDesired + fBrake_a1[ 0 ] ) ) ) { // u góry ustawia się hamowanie na fAccThreshold if( ( fBrakeTime < 0.0 ) diff --git a/DynObj.h b/DynObj.h index 15803796..8d5f75f4 100644 --- a/DynObj.h +++ b/DynObj.h @@ -564,12 +564,12 @@ private: inline double ABuGetDirection() const { // ABu. return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); }; // zwraca kierunek pojazdu na torze z aktywną osą - inline double RaDirectionGet() { + inline double RaDirectionGet() const { return iAxleFirst ? Axle1.GetDirection() : Axle0.GetDirection(); }; // zwraca przesunięcie wózka względem Point1 toru z aktywną osią - inline double RaTranslationGet() { + inline double RaTranslationGet() const { return iAxleFirst ? Axle1.GetTranslation() : Axle0.GetTranslation(); }; diff --git a/Train.cpp b/Train.cpp index 47d43099..22e13a9c 100644 --- a/Train.cpp +++ b/Train.cpp @@ -606,6 +606,28 @@ bool TTrain::is_eztoer() const { && ( mvControlled->ActiveDir != 0 ) ); // od yB } +// mover master controller to specified position +void TTrain::set_master_controller( double const Position ) { + + auto positionchange { + std::min( + Position, + ( mvControlled->CoupledCtrl ? + mvControlled->MainCtrlPosNo + mvControlled->ScndCtrlPosNo : + mvControlled->MainCtrlPosNo ) ) + - ( mvControlled->CoupledCtrl ? + mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos : + mvControlled->MainCtrlPos ) }; + while( ( positionchange < 0 ) + && ( true == mvControlled->DecMainCtrl( 1 ) ) ) { + ++positionchange; + } + while( ( positionchange > 0 ) + && ( true == mvControlled->IncMainCtrl( 1 ) ) ) { + --positionchange; + } +} + // moves train brake lever to specified position, potentially emits switch sound if conditions are met void TTrain::set_train_brake( double const Position ) { @@ -746,22 +768,9 @@ void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data void TTrain::OnCommand_mastercontrollerset( TTrain *Train, command_data const &Command ) { - auto positionchange { - std::min( - Command.param1, - ( Train->mvControlled->CoupledCtrl ? - Train->mvControlled->MainCtrlPosNo + Train->mvControlled->ScndCtrlPosNo : - Train->mvControlled->MainCtrlPosNo ) ) - - ( Train->mvControlled->CoupledCtrl ? - Train->mvControlled->MainCtrlPos + Train->mvControlled->ScndCtrlPos : - Train->mvControlled->MainCtrlPos ) }; - while( ( positionchange < 0 ) - && ( true == Train->mvControlled->DecMainCtrl( 1 ) ) ) { - ++positionchange; - } - while( ( positionchange > 0 ) - && ( true == Train->mvControlled->IncMainCtrl( 1 ) ) ) { - --positionchange; + if( Command.action != GLFW_RELEASE ) { + // on press or hold + Train->set_master_controller( Command.param1 ); } } @@ -5099,16 +5108,12 @@ bool TTrain::Update( double const Deltatime ) if (ggMainCtrl.SubModel) { #ifdef _WIN32 - if ((DynamicObject->Mechanik != nullptr) - && (false == DynamicObject->Mechanik->AIControllFlag) // nie blokujemy AI - && (Global.iFeedbackMode == 4) - && (Global.fCalibrateIn[2][1] != 0.0)) { - auto const b = clamp( - Console::AnalogCalibrateGet(2) * mvOccupied->MainCtrlPosNo, - 0.0, - mvOccupied->MainCtrlPosNo); - while (mvOccupied->MainCtrlPos < b) { mvOccupied->MainCtrlPos = b - 1; mvOccupied->IncMainCtrl(1); } - while (mvOccupied->MainCtrlPos > b) { mvOccupied->MainCtrlPos = b + 1; mvOccupied->DecMainCtrl(1); } + if( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI + && ( Global.iFeedbackMode == 4 ) + && ( Global.fCalibrateIn[ 2 ][ 1 ] != 0.0 ) ) { + + set_master_controller( Console::AnalogCalibrateGet( 2 ) * mvOccupied->MainCtrlPosNo ); } #endif diff --git a/Train.h b/Train.h index af61e8d4..14d1510f 100644 --- a/Train.h +++ b/Train.h @@ -132,6 +132,8 @@ class TTrain bool is_eztoer() const; // locates nearest vehicle belonging to the consist TDynamicObject *find_nearest_consist_vehicle() const; + // mover master controller to specified position + void set_master_controller( double const Position ); // moves train brake lever to specified position, potentially emits switch sound if conditions are met void set_train_brake( double const Position ); // sets specified brake acting speed for specified vehicle, potentially updating state of cab controls to match diff --git a/uilayer.cpp b/uilayer.cpp index a7fd6ce4..867a74ea 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -293,13 +293,18 @@ ui_layer::update() { uitextline2 += " Speed: " + std::to_string( static_cast( std::floor( mover->Vel ) ) ) + " km/h" + " (limit: " + std::to_string( speedlimit ) + " km/h"; - auto const nextspeedlimit { static_cast( std::floor( controlled->Mechanik->VelNext ) ) }; + auto const nextspeedlimit { static_cast( std::floor( driver->VelNext ) ) }; if( nextspeedlimit != speedlimit ) { uitextline2 += ", new limit: " + std::to_string( nextspeedlimit ) + " km/h" - + " in " + to_string( controlled->Mechanik->ActualProximityDist * 0.001, 1 ) + " km"; + + " in " + to_string( driver->ActualProximityDist * 0.001, 1 ) + " km"; } uitextline2 += ")"; + auto const reverser { ( mover->ActiveDir > 0 ? 1 : -1 ) }; + auto const grade { controlled->VectorFront().y * 100 * ( controlled->DirectionGet() == reverser ? 1 : -1 ) * reverser }; + if( std::abs( grade ) >= 0.25 ) { + uitextline2 += " Grade: " + to_string( grade, 1 ) + "%"; + } uitextline3 += " Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa" + " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)"; @@ -513,7 +518,7 @@ ui_layer::update() { + ( vehicle->MoverParameters->SlippingWheels ? " (!)" : "" ); if( vehicle->Mechanik ) { - uitextline2 += "; Ag: " + to_string( vehicle->Mechanik->fAccGravity, 2 ); + uitextline2 += "; Ag: " + to_string( vehicle->Mechanik->fAccGravity, 2 ) + " (" + ( vehicle->Mechanik->fAccGravity > 0.01 ? "\\" : ( vehicle->Mechanik->fAccGravity < -0.01 ? "/" : "-" ) ) + ")"; } uitextline2 += diff --git a/utilities.h b/utilities.h index ff94ba34..6c188c40 100644 --- a/utilities.h +++ b/utilities.h @@ -254,14 +254,14 @@ template Type_ interpolate( Type_ const &First, Type_ const &Second, float const Factor ) { - return ( First * ( 1.0f - Factor ) ) + ( Second * Factor ); + return static_cast( ( First * ( 1.0f - Factor ) ) + ( Second * Factor ) ); } template Type_ interpolate( Type_ const &First, Type_ const &Second, double const Factor ) { - return ( First * ( 1.0 - Factor ) ) + ( Second * Factor ); + return static_cast( ( First * ( 1.0 - Factor ) ) + ( Second * Factor ) ); } // tests whether provided points form a degenerate triangle diff --git a/version.h b/version.h index 13967e6c..3272ba5f 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 18 -#define VERSION_MINOR 708 +#define VERSION_MINOR 718 #define VERSION_REVISION 0 From 460bf6d382196c894e4f200e8f2e6d44bdeacf18 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 19 Jul 2018 22:11:22 +0200 Subject: [PATCH 3/4] ai braking logic tweaks and bug fixes --- Driver.cpp | 20 ++++++++++++++------ Train.cpp | 3 ++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 26faab2f..6d9c4430 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1421,7 +1421,7 @@ TController::braking_distance_multiplier( float const Targetvelocity ) const { && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) || ( fAccGravity > 0.025 ) ) { return interpolate( - 1.f, 3.f, + 1.f, 2.f, clamp( ( fBrake_a0[ 0 ] - 0.2 ) / 0.2, 0.0, 1.0 ) ); @@ -2680,7 +2680,7 @@ bool TController::DecBrake() } } if (!OK) - OK = mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); + OK = mvOccupied->DecLocalBrakeLevel(2); if (mvOccupied->PipePress < 3.0) Need_BrakeRelease = true; break; @@ -2704,7 +2704,7 @@ bool TController::DecBrake() else OK = false; if (!OK) - OK = mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); + OK = mvOccupied->DecLocalBrakeLevel(2); break; } return OK; @@ -2752,12 +2752,12 @@ bool TController::IncSpeed() // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) if (Ready || (iDrivigFlags & movePress)) { // use series mode: - // to build up speed to 30/40 km/h for passenger/cargo train (less if going uphill, more if downhill) + // to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill) // if high threshold is set for motor overload relay, // if the power station is heavily burdened auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV }; auto const useseriesmode = ( - ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) + ( fAccGravity * 100 ) ) + ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) || ( mvControlling->Imax > mvControlling->ImaxLo ) || ( fVoltage < useseriesmodevoltage ) ); // when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train @@ -4301,6 +4301,10 @@ TController::UpdateSituation(double dt) { // additional safety margin for cargo consists fMinProximityDist *= 2.0; fMaxProximityDist *= 2.0; + if( fBrake_a0[ 0 ] >= 0.35 ) { + // cargo trains with high braking threshold may require even larger safety margin + fMaxProximityDist += 20.0; + } } } fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania @@ -4335,7 +4339,11 @@ TController::UpdateSituation(double dt) { if( mvOccupied->BrakeDelayFlag == bdelay_G ) { // increase distances for cargo trains to take into account slower reaction to brakes fMinProximityDist += 10.0; - fMaxProximityDist += 10.0; + fMaxProximityDist += 15.0; + if( fBrake_a0[ 0 ] >= 0.35 ) { + // cargo trains with high braking threshold may require even larger safety margin + fMaxProximityDist += 20.0; + } } } else { diff --git a/Train.cpp b/Train.cpp index 22e13a9c..88b1bbb4 100644 --- a/Train.cpp +++ b/Train.cpp @@ -4365,7 +4365,8 @@ bool TTrain::Update( double const Deltatime ) // Odskakiwanie hamulce EP if( false == ( ( input::command == user_command::trainbrakeset ) - || ( input::command == user_command::trainbrakedecrease ) ) ) { + || ( input::command == user_command::trainbrakedecrease ) + || ( input::command == user_command::trainbrakecharging ) ) ) { set_train_brake( 0 ); } } From ed359d3b4e97d22e3b0b8bc18908ae38468d867f Mon Sep 17 00:00:00 2001 From: Kamil Lewan Date: Sun, 22 Jul 2018 16:46:54 +0200 Subject: [PATCH 4/4] Add conversion from `scenario_time` to `std::string`. --- simulationtime.cpp | 6 ++++++ simulationtime.h | 4 ++++ uilayer.cpp | 6 +----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/simulationtime.cpp b/simulationtime.cpp index 69ec910e..6ec42d08 100644 --- a/simulationtime.cpp +++ b/simulationtime.cpp @@ -194,4 +194,10 @@ scenario_time::julian_day() const { return JD; } +scenario_time::operator std::string(){ + + return to_string( m_time.wHour ) + ":" + + ( m_time.wMinute < 10 ? "0" : "" ) + to_string( m_time.wMinute ) + ":" + + ( m_time.wSecond < 10 ? "0" : "" ) + to_string( m_time.wSecond ); +}; //--------------------------------------------------------------------------- diff --git a/simulationtime.h b/simulationtime.h index 695a24cc..be5bdb86 100644 --- a/simulationtime.h +++ b/simulationtime.h @@ -9,6 +9,8 @@ http://mozilla.org/MPL/2.0/. #pragma once +#include + #include "winheaders.h" // wrapper for scenario time @@ -47,6 +49,8 @@ public: zone_bias() const { return m_timezonebias; } + /** Returns std::string in format: `"mm:ss"`. */ + operator std::string(); private: // calculates day and month from given day of year void diff --git a/uilayer.cpp b/uilayer.cpp index 71b1cd86..fc2442f3 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -279,12 +279,8 @@ ui_layer::update() { case( GLFW_KEY_F1 ) : { // f1, default mode: current time and timetable excerpt - auto const &time = simulation::Time.data(); uitextline1 = - "Time: " - + to_string( time.wHour ) + ":" - + ( time.wMinute < 10 ? "0" : "" ) + to_string( time.wMinute ) + ":" - + ( time.wSecond < 10 ? "0" : "" ) + to_string( time.wSecond ); + "Time: " + std::string( simulation::Time ); if( Global.iPause ) { uitextline1 += " (paused)"; }