From e88b85e72558337991879ce2a75164392ed3aee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Mon, 31 Jul 2017 17:31:29 +0200 Subject: [PATCH 1/3] AI z hamulcem co 0,25 pozycji --- Driver.cpp | 160 ++++++++++++++++++++++++++++++++----------- Driver.h | 6 ++ McZapkie/MOVER.h | 2 + McZapkie/Mover.cpp | 36 ++++++++++ World.cpp | 3 + maszyna.vcxproj.user | 2 +- 6 files changed, 169 insertions(+), 40 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 98709cc7..7e3fa07c 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1679,6 +1679,44 @@ void TController::AutoRewident() } d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) } + //teraz zerujemy tabelkę opóźnienia hamowania + for (int i = 0; i < BrakeAccTableSize; i++) + { + fBrake_a0[i+1] = 0; + fBrake_a1[i+1] = 0; + } + d = pVehicles[0]; // pojazd na czele składu + float velstep = (mvOccupied->Vmax*0.5) / BrakeAccTableSize; + while (d) + { // 4. Przeliczanie siły hamowania + for (int i = 0; i < BrakeAccTableSize; i++) + { + fBrake_a0[i+1] += d->MoverParameters->BrakeForceR(0.25, velstep*(1 + 2 * i)); + fBrake_a1[i+1] += d->MoverParameters->BrakeForceR(1.00, velstep*(1 + 2 * i)); + } + d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) + } + for (int i = 0; i < BrakeAccTableSize; i++) + { + fBrake_a1[i+1] -= fBrake_a0[i+1]; + fBrake_a0[i+1] /= fMass; + fBrake_a1[i+1] /= (12*fMass); + } + if (mvOccupied->TrainType == dt_EZT) + { + fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 10 * fBrake_a1[BrakeAccTableSize]; + fBrakeReaction = 0.25; + } + else if (ustaw > 16) + { + fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 6 * fBrake_a1[BrakeAccTableSize]; + fBrakeReaction = 0.5; + } + else + { + fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 2 * fBrake_a1[BrakeAccTableSize]; + fBrakeReaction = 2.0; + } }; int TController::CheckDirection() { @@ -1951,6 +1989,12 @@ bool TController::SetProximityVelocity(double NewDist,double NewVelNext) } */ +double TController::BrakeAccFactor() +{ + double Factor = 1 + fBrakeReaction*mvOccupied->Vel / (std::max(0.0, ActualProximityDist) + 1); + return Factor; +} + void TController::SetDriverPsyche() { // double maxdist=0.5; //skalowanie dystansu od innego pojazdu, zmienic to!!! @@ -2294,17 +2338,20 @@ bool TController::IncBrake() } else { if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) { - if( AccDesired < -1.5 ) // hamowanie nagle - OK = mvOccupied->IncBrakeLevel(); + if (AccDesired < -1.5) // hamowanie nagle + OK = mvOccupied->BrakeLevelAdd(1.0); else OK = false; } else { // dodane dla towarowego - if( mvOccupied->BrakeDelayFlag == bdelay_G ? - -AccDesired * 6.6 > std::min( 2, mvOccupied->BrakeCtrlPos ) : - true ) { - OK = mvOccupied->IncBrakeLevel(); + double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR - 1)*fBrake_a1[0]); + + if( deltaAcc > 0) + { + OK = mvOccupied->BrakeLevelAdd(mvOccupied->BrakeCtrlPosR>0?0.25:1.0); + if ((deltaAcc > 5 * fBrake_a1[0])&&(mvOccupied->BrakeCtrlPosR<=3.0)) + mvOccupied->BrakeLevelAdd(1.0); } else OK = false; @@ -2337,6 +2384,7 @@ bool TController::IncBrake() bool TController::DecBrake() { // zmniejszenie siły hamowania bool OK = false; + double deltaAcc = 0; switch (mvOccupied->BrakeSystem) { case Individual: @@ -2346,8 +2394,18 @@ bool TController::DecBrake() OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case Pneumatic: - if (mvOccupied->BrakeCtrlPos > 0) - OK = mvOccupied->DecBrakeLevel(); + deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR - 0.75)*fBrake_a1[0]); + if (deltaAcc < 0) + { + if (mvOccupied->BrakeCtrlPosR > 0) + { + 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 (!OK) OK = mvOccupied->DecLocalBrakeLevel(2); if (mvOccupied->PipePress < 3.0) @@ -3243,6 +3301,10 @@ bool TController::UpdateSituation(double dt) // ABu-160305 testowanie gotowości do jazdy // Ra: przeniesione z DynObj, skład użytkownika też jest testowany, żeby mu przekazać, że ma // odhamować + int index = double(BrakeAccTableSize) * (mvOccupied->Vel / mvOccupied->Vmax); + index = std::min(BrakeAccTableSize, std::max(1, index)); + fBrake_a0[0] = fBrake_a0[index]; + fBrake_a1[0] = fBrake_a1[index]; Ready = true; // wstępnie gotowy fReady = 0.0; // założenie, że odhamowany fAccGravity = 0.0; // przyspieszenie wynikające z pochylenia @@ -4226,8 +4288,18 @@ bool TController::UpdateSituation(double dt) if (mvOccupied->V == 0.0) AbsAccS = fAccGravity; // Ra 2014-03: jesli skład stoi, to działa na niego // składowa styczna grawitacji - else - AbsAccS = iDirection * mvOccupied->AccS; // przyspieszenie chwilowe, liczone + else + { + AbsAccS = 0; + TDynamicObject *d = pVehicles[0]; // pojazd na czele składu + while (d) + { + AbsAccS += d->MoverParameters->TotalMass * d->MoverParameters->AccS * iDirection; + d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) + } + AbsAccS /= fMass; + //AbsAccS = iDirection * mvOccupied->AccS; // przyspieszenie chwilowe, liczone + } // jako różnica skierowanej prędkości w // czasie // if (mvOccupied->V<0.0) AbsAccS=-AbsAccS; //Ra 2014-03: to trzeba przemyśleć @@ -4333,9 +4405,9 @@ bool TController::UpdateSituation(double dt) // krytycznym przedziale } } - else // przy dużej różnicy wysoki stopień (1,25 potrzebnego opoznienia) + else // przy dużej różnicy wysoki stopień (1,00 potrzebnego opoznienia) AccDesired = (VelNext * VelNext - vel * vel) / - (20.73 * ActualProximityDist + + (25.92 * ActualProximityDist + 0.1); // najpierw hamuje mocniej, potem zluzuje if (AccPreferred < AccDesired) AccDesired = AccPreferred; //(1+abs(AccDesired)) @@ -4389,17 +4461,20 @@ bool TController::UpdateSituation(double dt) else AccDesired = fAccThreshold; // hamuj tak średnio // koniec predkosci aktualnej - if (fAccThreshold > -0.3) // bez sensu, ale dla towarowych korzystnie - { // Ra 2014-03: to nie uwzględnia odległości i zaczyna hamować, jak tylko zobaczy - // W4 - if ((AccDesired > 0.0) && - (VelNext >= 0.0)) // wybieg bądź lekkie hamowanie, warunki byly zamienione - if (vel > VelNext + 100.0) // lepiej zaczac hamowac - AccDesired = fAccThreshold; - else if (vel > VelNext + 70.0) - AccDesired = 0.0; // nie spiesz się, bo będzie hamowanie - // koniec wybiegu i hamowania - } +#ifdef DEBUGFAC + if (fAccThreshold > -0.3) // bez sensu, ale dla towarowych korzystnie + { // Ra 2014-03: to nie uwzględnia odległości i zaczyna hamować, jak tylko zobaczy + // W4 + if ((AccDesired > 0.0) && + (VelNext >= 0.0)) // wybieg bądź lekkie hamowanie, warunki byly zamienione + if (vel > VelNext + 100.0) // lepiej zaczac hamowac + AccDesired = fAccThreshold; + else if (vel > VelNext + 70.0) + AccDesired = 0.0; // nie spiesz się, bo będzie hamowanie + // koniec wybiegu i hamowania + } +#endif // DEBUGFAC + if (AIControllFlag) { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy if (mvControlling->ConvOvldFlag || @@ -4434,6 +4509,8 @@ bool TController::UpdateSituation(double dt) SetDriverPsyche(); } } + if (-AccDesired * BrakeAccFactor() < (fReady > 0.4 ? fBrake_a0[0] : -fAccThreshold)) + AccDesired = std::max(-0.01, AccDesired); if (mvOccupied->BrakeSystem == Pneumatic) // napełnianie uderzeniowe if (mvOccupied->BrakeHandle == FV4a) { @@ -4464,12 +4541,12 @@ bool TController::UpdateSituation(double dt) } // if // ((mvOccupied->BrakeCtrlPos<0)&&(mvOccupied->BrakePress<0.3))//{(CntrlPipePress-(Volume/BrakeVVolume/10)<0.01)}) - if ((mvOccupied->BrakeCtrlPos < 0) && - (mvOccupied->EqvtPipePress > - (fReady < 0.25 ? - 5.1 : - 5.2))) //{(CntrlPipePress-(Volume/BrakeVVolume/10)<0.01)}) - mvOccupied->IncBrakeLevel(); + if ((mvOccupied->BrakeCtrlPos < 0) && + (mvOccupied->EqvtPipePress > + (fReady < 0.25 ? + 5.1 : + 5.2))) //{(CntrlPipePress-(Volume/BrakeVVolume/10)<0.01)}) + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); } #if LOGVELOCITY WriteLog("Dist=" + FloatToStrF(ActualProximityDist, ffFixed, 7, 1) + @@ -4503,9 +4580,11 @@ bool TController::UpdateSituation(double dt) { while (DecBrake()) ; // jeśli przyspieszamy, to nie hamujemy - if (mvOccupied->BrakePress > 0.4) - mvOccupied->BrakeReleaser( - 1); // wyluzuj lokomotywę, to szybciej ruszymy + if ((mvOccupied->BrakePress > 0.4) && (mvOccupied->Hamulec->GetCRP() > 4.9)) + mvOccupied->BrakeReleaser( + 1); // wyluzuj lokomotywę, to szybciej ruszymy + else + mvOccupied->BrakeReleaser(0); } // margines dla prędkości jest doliczany tylko jeśli oczekiwana prędkość jest // większa od 5km/h @@ -4585,7 +4664,7 @@ bool TController::UpdateSituation(double dt) if (((fAccGravity < -0.05) && (vel < 0)) || ((AccDesired < fAccGravity - 0.1) && (AbsAccS > - AccDesired + 0.05))) // u góry ustawia się hamowanie na fAccThreshold + AccDesired + fBrake_a1[0]))) // u góry ustawia się hamowanie na fAccThreshold // if not MinVelFlag) if (fBrakeTime < 0 ? true : (AccDesired < fAccGravity - 0.3) || (mvOccupied->BrakeCtrlPos <= 0)) @@ -4605,7 +4684,7 @@ bool TController::UpdateSituation(double dt) // zatrzymania jest mniejszy fBrakeTime *= 0.5; // Ra: tymczasowo, bo przeżyna S1 } - if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - 0.2)) + if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - fBrake_a1[0])) // if ((AccDesired<0.0)&&(AbsAccSDecMainCtrl(1); if (mvOccupied->BrakeCtrlPos == mvOccupied->BrakeCtrlPosNo) // jeśli ostatnia pozycja hamowania + //yB: ten warunek wyżej nie ma sensu mvOccupied->DecBrakeLevel(); // to cofnij hamulec else mvControlling->AntiSlippingButton(); @@ -4679,11 +4759,13 @@ bool TController::UpdateSituation(double dt) } if (AIControllFlag) { // odhamowywanie składu po zatrzymaniu i zabezpieczanie lokomotywy - if ((OrderList[OrderPos] & (Disconnect | Connect)) == - 0) // przy (p)odłączaniu nie zwalniamy tu hamulca - if ((mvOccupied->V == 0.0) && ((VelDesired == 0.0) || (AccDesired == 0.0))) - if ((mvOccupied->BrakeCtrlPos < 1) || !mvOccupied->DecBrakeLevel()) - mvOccupied->IncLocalBrakeLevel(1); // dodatkowy na pozycję 1 + if ((OrderList[OrderPos] & (Disconnect | Connect)) == + 0) // przy (p)odłączaniu nie zwalniamy tu hamulca + if ((mvOccupied->V == 0.0) && ((VelDesired == 0.0) || (AccDesired == 0.0))) + if (mvOccupied->BrakeCtrlPos == mvOccupied->Handle->GetPos(bh_RP)) + mvOccupied->IncLocalBrakeLevel(1); // dodatkowy na pozycję 1 + else + mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); } break; // rzeczy robione przy jezdzie } // switch (OrderList[OrderPos]) diff --git a/Driver.h b/Driver.h index 512e1d23..8866194b 100644 --- a/Driver.h +++ b/Driver.h @@ -162,6 +162,7 @@ static const bool Humandriver = false; static const int maxorders = 32; // 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; //---------------------------------------------------------------------------- class TController @@ -197,7 +198,12 @@ class TController double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd) double fBrakeDist = 0.0; // przybliżona droga hamowania + public: + double BrakeAccFactor(); + double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca + double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca + double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca public: double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index a21608ba..19e14c7d 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -1109,6 +1109,8 @@ public: double Adhesive(double staticfriction); double TractionForce(double dt); double FrictionForce(double R, int TDamage); + double BrakeForceR(double ratio, double velocity); + double BrakeForceP(double press, double velocity); double BrakeForce(const TTrackParam &Track); double CouplerForce(int CouplerN, double dt); void CollisionDetect(int CouplerN, double dt); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index b32c1e07..3d9f6416 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3766,6 +3766,39 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) //}; } +double TMoverParameters::BrakeForceR(double ratio, double velocity) +{ + double press = 0; + if (MBPM>2) + { + press = MaxBrakePress[1] + (MaxBrakePress[3] - MaxBrakePress[1]) * std::min(1.0, (TotalMass - Mass) / (MBPM - Mass)); + } + else + { + if (MaxBrakePress[1] > 0.1) + { + press = MaxBrakePress[LoadFlag]; + } + else + { + press = MaxBrakePress[3]; + if (DynamicBrakeType == dbrake_automatic) + ratio = ratio + (1.5 - ratio)*std::min(1.0, Vel*0.02); + } + + } + return BrakeForceP(press*ratio, velocity); +} + +double TMoverParameters::BrakeForceP(double press, double velocity) +{ + double BFP = 0; + double K = (((press * P2FTrans) - BrakeCylSpring) * BrakeCylMult[0] - BrakeSlckAdj) * BrakeRigEff; + K *= static_cast(BrakeCylNo) / (NAxles * std::max(1, NBpA)); + BFP = Hamulec->GetFC(velocity, K)*K*(NAxles * std::max(1, NBpA)) * 1000; + return BFP; +} + // ************************************************************************************************* // Q: 20160713 // oblicza siłę na styku koła i szyny @@ -3863,6 +3896,9 @@ double TMoverParameters::FrictionForce(double R, int TDamage) return FF; } + + + // ************************************************************************************************* // Q: 20160713 // Oblicza przyczepność diff --git a/World.cpp b/World.cpp index 198f4ed6..a7379ed0 100644 --- a/World.cpp +++ b/World.cpp @@ -1544,6 +1544,9 @@ TWorld::Update_UI() { uitextline4 += "Driver: Vd=" + to_string( tmp->Mechanik->VelDesired, 0 ) + " ad=" + to_string( tmp->Mechanik->AccDesired, 2 ) + + " ah=" + to_string(tmp->Mechanik->fAccThreshold, 2) + + "@" + to_string(tmp->Mechanik->fBrake_a0[0], 2) + + "+" + to_string(tmp->Mechanik->fBrake_a1[0], 2) + " Pd=" + to_string( tmp->Mechanik->ActualProximityDist, 0 ) + " Vn=" + to_string( tmp->Mechanik->VelNext, 0 ) + " VSm=" + to_string( tmp->Mechanik->VelSignalLast, 0 ) diff --git a/maszyna.vcxproj.user b/maszyna.vcxproj.user index 8c698752..7c32daec 100644 --- a/maszyna.vcxproj.user +++ b/maszyna.vcxproj.user @@ -1,7 +1,7 @@  - ..\..\..\development\maszyna + D:\MaSzyna WindowsLocalDebugger From 9cd20971f577160aa40abb2b5c152f8d08284d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Thu, 3 Aug 2017 22:55:46 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Korekta=20progu=20dzia=C5=82ania,=20wylicza?= =?UTF-8?q?nie=20op=C3=B3=C5=BAnienia=20hamowania=20z=20uwzgl=C4=99dnienie?= =?UTF-8?q?m=20wcze=C5=9Bniejszego=20luzowania,=20dodanie=20poprawki=20wym?= =?UTF-8?q?aganej=20pozycji=20zaworu=20maszynisty=20(si=C5=82y=20hamowania?= =?UTF-8?q?)=20w=20zale=C5=BCno=C5=9Bci=20od=20wyczerpania=20i=20prze?= =?UTF-8?q?=C5=82adowania=20hamulc=C3=B3w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Driver.cpp | 69 ++++++++++++++++++++++++++++++-------------- Driver.h | 1 + McZapkie/Mover.cpp | 4 ++- McZapkie/hamulce.cpp | 5 ++++ McZapkie/hamulce.h | 2 +- World.cpp | 6 +++- 6 files changed, 62 insertions(+), 25 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 7e3fa07c..58ea8e4d 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1680,13 +1680,13 @@ void TController::AutoRewident() d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) } //teraz zerujemy tabelkę opóźnienia hamowania + double velstep = (mvOccupied->Vmax*0.5) / BrakeAccTableSize; for (int i = 0; i < BrakeAccTableSize; i++) { fBrake_a0[i+1] = 0; fBrake_a1[i+1] = 0; } d = pVehicles[0]; // pojazd na czele składu - float velstep = (mvOccupied->Vmax*0.5) / BrakeAccTableSize; while (d) { // 4. Przeliczanie siły hamowania for (int i = 0; i < BrakeAccTableSize; i++) @@ -1700,21 +1700,22 @@ void TController::AutoRewident() { fBrake_a1[i+1] -= fBrake_a0[i+1]; fBrake_a0[i+1] /= fMass; + fBrake_a0[i + 1] += 0.001*velstep*(1 + 2 * i); fBrake_a1[i+1] /= (12*fMass); } if (mvOccupied->TrainType == dt_EZT) { - fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 10 * fBrake_a1[BrakeAccTableSize]; + fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize]; fBrakeReaction = 0.25; } else if (ustaw > 16) { - fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 6 * fBrake_a1[BrakeAccTableSize]; - fBrakeReaction = 0.5; + fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 4 * fBrake_a1[BrakeAccTableSize]; + fBrakeReaction = 0.75+fLength*0.001; } else { - fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 2 * fBrake_a1[BrakeAccTableSize]; + fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 1 * fBrake_a1[BrakeAccTableSize]; fBrakeReaction = 2.0; } }; @@ -1991,7 +1992,8 @@ bool TController::SetProximityVelocity(double NewDist,double NewVelNext) double TController::BrakeAccFactor() { - double Factor = 1 + fBrakeReaction*mvOccupied->Vel / (std::max(0.0, ActualProximityDist) + 1); +// double Factor = 1 + fBrakeReaction*mvOccupied->Vel / (std::max(0.0, ActualProximityDist) + 1); + double Factor = 1 + fBrakeReaction*mvOccupied->Vel / (std::max(0.0, ActualProximityDist) + 1) * ((AccDesired-AbsAccS_pub)/fAccThreshold); return Factor; } @@ -2345,13 +2347,34 @@ bool TController::IncBrake() } else { // dodane dla towarowego - double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR - 1)*fBrake_a1[0]); + float pos_corr = 0; - if( deltaAcc > 0) + TDynamicObject *d; + d = pVehicles[0]; // pojazd na czele składu + while (d) + { // przeliczanie dodatkowego potrzebnego spadku ciśnienia + pos_corr+=(d->MoverParameters->Hamulec->GetCRP() - 5.0)*d->MoverParameters->TotalMass; + d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) + } + pos_corr = pos_corr / fMass * 2.5; + + if (mvOccupied->BrakeHandle == FV4a) { - OK = mvOccupied->BrakeLevelAdd(mvOccupied->BrakeCtrlPosR>0?0.25:1.0); - if ((deltaAcc > 5 * fBrake_a1[0])&&(mvOccupied->BrakeCtrlPosR<=3.0)) - mvOccupied->BrakeLevelAdd(1.0); + pos_corr += mvOccupied->Handle->GetCP()*0.2; + + } + double deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4.0 * (mvOccupied->BrakeCtrlPosR - 1 - pos_corr)*fBrake_a1[0]); + + if( deltaAcc > fBrake_a1[0]) + { + if (mvOccupied->BrakeCtrlPosR<0.1) + OK = mvOccupied->BrakeLevelAdd(1.0); + else + { + OK = mvOccupied->BrakeLevelAdd(0.25); + if ((deltaAcc > 5 * fBrake_a1[0]) && (mvOccupied->BrakeCtrlPosR <= 3.0)) + mvOccupied->BrakeLevelAdd(0.75); + } } else OK = false; @@ -2394,7 +2417,7 @@ bool TController::DecBrake() OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case Pneumatic: - deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR - 0.75)*fBrake_a1[0]); + deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR)*fBrake_a1[0]); if (deltaAcc < 0) { if (mvOccupied->BrakeCtrlPosR > 0) @@ -3278,7 +3301,7 @@ bool TController::UpdateSituation(double dt) if ((iDrivigFlags & movePrimary) == 0) return true; // pasywny nic nie robi - double AbsAccS; + double AbsAccS = 0; // double VelReduced; //o ile km/h może przekroczyć dozwoloną prędkość bez hamowania bool UpdateOK = false; if (AIControllFlag) @@ -4300,6 +4323,7 @@ bool TController::UpdateSituation(double dt) AbsAccS /= fMass; //AbsAccS = iDirection * mvOccupied->AccS; // przyspieszenie chwilowe, liczone } + AbsAccS_pub = AbsAccS; // jako różnica skierowanej prędkości w // czasie // if (mvOccupied->V<0.0) AbsAccS=-AbsAccS; //Ra 2014-03: to trzeba przemyśleć @@ -4341,7 +4365,7 @@ bool TController::UpdateSituation(double dt) { // jedzie szybciej, niż trzeba na końcu ActualProximityDist, ale jeszcze // jest daleko if (vel < - VelNext + 40.0) // dwustopniowe hamowanie - niski przy małej różnicy + VelNext + 20.0) // dwustopniowe hamowanie - niski przy małej różnicy { // jeśli jedzie wolniej niż VelNext+35km/h //Ra: 40, żeby nie // kombinował na zwrotnicach if (VelNext == 0.0) @@ -4384,7 +4408,7 @@ bool TController::UpdateSituation(double dt) else AccDesired = -(vel * vel) / (25.92 * (ActualProximityDist + - 0.1)); //-fMinProximityDist));//-0.1; + 0.1-0.5*(fMinProximityDist+fMaxProximityDist))); //-fMinProximityDist));//-0.1; ////mniejsze opóźnienie przy // małej różnicy ReactionTime = 0.1; // i orientuj się szybciej, jak masz stanąć @@ -4405,10 +4429,12 @@ bool TController::UpdateSituation(double dt) // krytycznym przedziale } } - else // przy dużej różnicy wysoki stopień (1,00 potrzebnego opoznienia) - AccDesired = (VelNext * VelNext - vel * vel) / - (25.92 * ActualProximityDist + - 0.1); // najpierw hamuje mocniej, potem zluzuje + else { // przy dużej różnicy wysoki stopień (1,00 potrzebnego opoznienia) + double dist = (VelNext * VelNext - (VelNext + 20) * (VelNext + 20)) / (25.92)*(-1 / fBrake_a0[0] - 1 / fAccThreshold) + 1.5*VelNext; + AccDesired = (VelNext * VelNext - vel * vel) / + (25.92 * (std::max(ActualProximityDist - 2 * VelNext, std::min(ActualProximityDist, 2 * VelNext)) - dist) + + 0.1); // najpierw hamuje mocniej, potem zluzuje + } if (AccPreferred < AccDesired) AccDesired = AccPreferred; //(1+abs(AccDesired)) // ReactionTime=0.5*mvOccupied->BrakeDelay[2+2*mvOccupied->BrakeDelayFlag]; @@ -4459,7 +4485,7 @@ bool TController::UpdateSituation(double dt) AccDesired = 0.0; } else - AccDesired = fAccThreshold; // hamuj tak średnio + AccDesired = fBrake_a0[0]; // hamuj tak średnio // koniec predkosci aktualnej #ifdef DEBUGFAC if (fAccThreshold > -0.3) // bez sensu, ale dla towarowych korzystnie @@ -4684,7 +4710,7 @@ bool TController::UpdateSituation(double dt) // zatrzymania jest mniejszy fBrakeTime *= 0.5; // Ra: tymczasowo, bo przeżyna S1 } - if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - fBrake_a1[0])) + if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - fBrake_a1[0]*0.51)) // if ((AccDesired<0.0)&&(AbsAccSStationIndex; // zaktualizować wyświetlanie rozkładu fLastStopExpDist = -1.0f; // usunąć licznik } - if (AIControllFlag) { if (fWarningDuration > 0.0) // jeśli pozostało coś do wytrąbienia diff --git a/Driver.h b/Driver.h index 8866194b..c21eb050 100644 --- a/Driver.h +++ b/Driver.h @@ -202,6 +202,7 @@ class TController double BrakeAccFactor(); double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca + double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca public: diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 3d9f6416..3ad5ca42 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3784,6 +3784,8 @@ double TMoverParameters::BrakeForceR(double ratio, double velocity) press = MaxBrakePress[3]; if (DynamicBrakeType == dbrake_automatic) ratio = ratio + (1.5 - ratio)*std::min(1.0, Vel*0.02); + if ((BrakeDelayFlag&bdelay_R) && (BrakeMethod != bp_Cosid) && (BrakeMethod != bp_D1) && (BrakeMethod != bp_D2)&&(Power>1)) + ratio = ratio / 2; } } @@ -3842,7 +3844,7 @@ double TMoverParameters::BrakeForce(const TTrackParam &Track) Ntotal = u * BrakeRigEff; else { - u = (BrakePress * P2FTrans) * BrakeCylMult[0] - BrakeSlckAdj; + u = ((BrakePress * P2FTrans) - BrakeCylSpring) * BrakeCylMult[0] - BrakeSlckAdj; if (u * (2.0 - BrakeRigEff) < Ntotal) // histereza na nacisku klockow Ntotal = u * (2.0 - BrakeRigEff); } diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 2a1b300b..06e45445 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -2372,6 +2372,11 @@ double TFV4aM::GetPos(int i) return pos_table[i]; } +double TFV4aM::GetCP() +{ + return TP; +} + double TFV4aM::LPP_RP(double pos) // cisnienie z zaokraglonej pozycji; { int const i_pos = 2 + std::floor( pos ); // zaokraglone w dol diff --git a/McZapkie/hamulce.h b/McZapkie/hamulce.h index 25de35db..b23c6c06 100644 --- a/McZapkie/hamulce.h +++ b/McZapkie/hamulce.h @@ -551,7 +551,7 @@ class TFV4aM : public TDriverHandle { void SetReductor(double nAdj)/*override*/; double GetSound(int i)/*override*/; double GetPos(int i)/*override*/; - + double GetCP(); inline TFV4aM() : TDriverHandle() {} diff --git a/World.cpp b/World.cpp index 5c51f7b2..127a4aa6 100644 --- a/World.cpp +++ b/World.cpp @@ -1766,7 +1766,11 @@ TWorld::Update_UI() { && ( tmp->Mechanik->AIControllFlag == AIdriver ) ) { uitextline4 += "AI: Vd=" + to_string( tmp->Mechanik->VelDesired, 0 ) - + " ad=" + to_string( tmp->Mechanik->AccDesired, 2 ) + + " ad=" + to_string(tmp->Mechanik->AccDesired, 2) + + "/" + to_string(tmp->Mechanik->AccDesired*tmp->Mechanik->BrakeAccFactor(), 2) + + " atrain=" + to_string(tmp->Mechanik->fBrake_a0[0], 2) + + "+" + to_string(tmp->Mechanik->fBrake_a1[0], 2) + + " aS=" + to_string(tmp->Mechanik->AbsAccS_pub, 2) + " Pd=" + to_string( tmp->Mechanik->ActualProximityDist, 0 ) + " Vn=" + to_string( tmp->Mechanik->VelNext, 0 ); } From 2014494c2a8f43624af7348490007d652d8c03f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 11 Aug 2017 18:38:03 +0200 Subject: [PATCH 3/3] braking distance (fBrakeDist) calculation depends on train brakes performance, better braking - removed old conditions and phases --- Driver.cpp | 46 ++++++++++++++++++++++++++-------------------- McZapkie/Mover.cpp | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 58ea8e4d..d8f4df3a 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1711,12 +1711,12 @@ void TController::AutoRewident() else if (ustaw > 16) { fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 4 * fBrake_a1[BrakeAccTableSize]; - fBrakeReaction = 0.75+fLength*0.001; + fBrakeReaction = 0.75 + fLength*0.002; } else { fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 1 * fBrake_a1[BrakeAccTableSize]; - fBrakeReaction = 2.0; + fBrakeReaction = 1.5 + fLength*0.002; } }; @@ -2417,7 +2417,7 @@ bool TController::DecBrake() OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case Pneumatic: - deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR)*fBrake_a1[0]); + deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (mvOccupied->BrakeCtrlPosR-1.0)*fBrake_a1[0]); if (deltaAcc < 0) { if (mvOccupied->BrakeCtrlPosR > 0) @@ -3507,6 +3507,8 @@ bool TController::UpdateSituation(double dt) // zalecane ciśnienie if (fMass > 1000000.0) fBrakeDist *= 2.0; // korekta dla ciężkich, bo przeżynają - da to coś? + if ((fAccThreshold>0.05)&&(mvOccupied->CategoryFlag==1)) + fBrakeDist = mvOccupied->Vel * mvOccupied->Vel / 25.92 / fAccThreshold; if (mvOccupied->BrakeDelayFlag == bdelay_G) fBrakeDist = fBrakeDist + 2 * mvOccupied->Vel; // dla nastawienia G // koniecznie należy wydłużyć drogę na czas reakcji @@ -4364,21 +4366,24 @@ bool TController::UpdateSituation(double dt) else if (ActualProximityDist > fMinProximityDist) { // jedzie szybciej, niż trzeba na końcu ActualProximityDist, ale jeszcze // jest daleko - if (vel < - VelNext + 20.0) // dwustopniowe hamowanie - niski przy małej różnicy + if (ActualProximityDist < + fMaxProximityDist) // jak minął już maksymalny dystans + { // po prostu hamuj (niski stopień) //ma stanąć, a jest w + // drodze hamowania albo ma jechać + AccDesired = (VelNext * VelNext - vel * vel) / + (25.92 * (ActualProximityDist + + 0.1 - 0.5*fMinProximityDist)); // hamowanie tak, aby stanąć + AccDesired = std::min(AccDesired, fAccThreshold); + VelDesired = 0.0; // Min0R(VelDesired,VelNext); + } + else if ((vel < + VelNext + 20.0)&&(false)) // dwustopniowe hamowanie - niski przy małej różnicy { // jeśli jedzie wolniej niż VelNext+35km/h //Ra: 40, żeby nie // kombinował na zwrotnicach if (VelNext == 0.0) { // jeśli ma się zatrzymać, musi być to robione precyzyjnie i // skutecznie - if (ActualProximityDist < - fMaxProximityDist) // jak minął już maksymalny dystans - { // po prostu hamuj (niski stopień) //ma stanąć, a jest w - // drodze hamowania albo ma jechać - AccDesired = fAccThreshold; // hamowanie tak, aby stanąć - VelDesired = 0.0; // Min0R(VelDesired,VelNext); - } - else if (ActualProximityDist > fBrakeDist) + if (ActualProximityDist > fBrakeDist) { // jeśli ma stanąć, a mieści się w drodze hamowania if (vel < 10.0) // jeśli prędkość jest łatwa do zatrzymania { // tu jest trochę problem, bo do punktu zatrzymania dobija @@ -4430,9 +4435,9 @@ bool TController::UpdateSituation(double dt) } } else { // przy dużej różnicy wysoki stopień (1,00 potrzebnego opoznienia) - double dist = (VelNext * VelNext - (VelNext + 20) * (VelNext + 20)) / (25.92)*(-1 / fBrake_a0[0] - 1 / fAccThreshold) + 1.5*VelNext; + double dist = 0;// (VelNext * VelNext - (VelNext + 20) * (VelNext + 20)) / (25.92)*(-1 / fBrake_a0[0] - 1 / fAccThreshold); AccDesired = (VelNext * VelNext - vel * vel) / - (25.92 * (std::max(ActualProximityDist - 2 * VelNext, std::min(ActualProximityDist, 2 * VelNext)) - dist) + + (25.92 * std::max(ActualProximityDist - VelNext - dist, std::min(ActualProximityDist, VelNext+dist)) + 0.1); // najpierw hamuje mocniej, potem zluzuje } if (AccPreferred < AccDesired) @@ -4535,8 +4540,10 @@ bool TController::UpdateSituation(double dt) SetDriverPsyche(); } } - if (-AccDesired * BrakeAccFactor() < (fReady > 0.4 ? fBrake_a0[0] : -fAccThreshold)) - AccDesired = std::max(-0.01, AccDesired); + if (-AccDesired * BrakeAccFactor() < ((fReady > 0.4)||(VelDesiredBrakeSystem == Pneumatic) // napełnianie uderzeniowe if (mvOccupied->BrakeHandle == FV4a) { @@ -4600,9 +4607,8 @@ bool TController::UpdateSituation(double dt) mvOccupied->BrakeReleaser(1); // wyluzuj lokomotywę - może być więcej! else if (OrderList[OrderPos] != Disconnect) // przy odłączaniu nie zwalniamy tu hamulca - if ((AccDesired > 0.0) || - (fAccGravity * fAccGravity < - 0.001)) // luzuj tylko na plaskim lub przy ruszaniu + if (fAccGravity * fAccGravity < + 0.001) // luzuj tylko na plaskim lub przy ruszaniu { while (DecBrake()) ; // jeśli przyspieszamy, to nie hamujemy diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 3ad5ca42..1a371675 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3784,7 +3784,7 @@ double TMoverParameters::BrakeForceR(double ratio, double velocity) press = MaxBrakePress[3]; if (DynamicBrakeType == dbrake_automatic) ratio = ratio + (1.5 - ratio)*std::min(1.0, Vel*0.02); - if ((BrakeDelayFlag&bdelay_R) && (BrakeMethod != bp_Cosid) && (BrakeMethod != bp_D1) && (BrakeMethod != bp_D2)&&(Power>1)) + if ((BrakeDelayFlag&bdelay_R) && (BrakeMethod%128 != bp_Cosid) && (BrakeMethod % 128 != bp_D1) && (BrakeMethod % 128 != bp_D2) && (Power<1) && (velocity<40)) ratio = ratio / 2; }