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] 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