diff --git a/Driver.cpp b/Driver.cpp index 71a75786..0657d615 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -154,6 +154,7 @@ const double EasyAcceleration = 0.85; //[m/ss] const double HardAcceleration = 9.81; const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu bool WriteLogFlag = false; +double const deltalog = 0.05; // przyrost czasu std::string StopReasonTable[] = { // przyczyny zatrzymania ruchu AI @@ -1672,11 +1673,6 @@ void TController::CloseLog() if (WriteLogFlag) { LogFile.close(); - // if WriteLogFlag) - // CloseFile(AILogFile); - /* append(AIlogFile); - writeln(AILogFile,ElapsedTime5:2,": QUIT"); - close(AILogFile); */ } }; @@ -1739,11 +1735,8 @@ void TController::Activation() mvOccupied->DirectionForward(); // kierunek na 0 while (mvOccupied->ActiveDir > 0) mvOccupied->DirectionBackward(); - if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? 1 : 0].CouplingFlag, - ctrain_controll)) - { - mvControlling->MainSwitch( - false); // dezaktywacja czuwaka, jeśli przejście do innego członu + if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? 1 : 0].CouplingFlag, ctrain_controll)) { + mvControlling->MainSwitch( false); // dezaktywacja czuwaka, jeśli przejście do innego członu mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); // zwolnienie hamulca w opuszczanym pojeździe // mvOccupied->BrakeLevelSet((mvOccupied->BrakeHandle==FVel6)?4:-2); //odcięcie na // zaworze maszynisty, FVel6 po drugiej stronie nie luzuje @@ -1753,8 +1746,7 @@ void TController::Activation() mvOccupied->ActiveCab = mvOccupied->CabNo; // użytkownik moze zmienić ActiveCab wychodząc mvOccupied->CabDeactivisation(); // tak jest w Train.cpp // przejście AI na drugą stronę EN57, ET41 itp. - while (TestFlag(d->MoverParameters->Couplers[iDirection < 0 ? 1 : 0].CouplingFlag, - ctrain_controll)) + while (TestFlag(d->MoverParameters->Couplers[iDirection < 0 ? 1 : 0].CouplingFlag, ctrain_controll)) { // jeśli pojazd z przodu jest ukrotniony, to przechodzimy do niego d = iDirection * d->DirectionGet() < 0 ? d->Next() : d->Prev(); // przechodzimy do następnego członu @@ -1818,8 +1810,7 @@ void TController::AutoRewident() // · masa (jako suma) -> jest w (fMass) while (d) { // klasyfikacja pojazdów wg BrakeDelays i mocy (licznik) - if (d->MoverParameters->Power < - 1) // - lokomotywa - Power>1 - ale może być nieczynna na końcu... + if (d->MoverParameters->Power < 1) // - lokomotywa - Power>1 - ale może być nieczynna na końcu... if (TestFlag(d->MoverParameters->BrakeDelays, bdelay_R)) ++r; // - wagon pospieszny - jest R else if (TestFlag(d->MoverParameters->BrakeDelays, bdelay_G)) @@ -2085,13 +2076,11 @@ bool TController::CheckVehicles(TOrders user) if (AIControllFlag) // jeśli prowadzi komputer p->RaLightsSet(0, 0); // gasimy światła if (p->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector) - { // jeśli pojazd posiada pantograf, to przydzielamy mu maskę, którą będzie informował o - // jeździe bezprądowej + { // jeśli pojazd posiada pantograf, to przydzielamy mu maskę, którą będzie informował o jeździe bezprądowej p->iOverheadMask = pantmask; pantmask = pantmask << 1; // przesunięcie bitów, max. 32 pojazdy z pantografami w składzie } - d = p->DirectionSet(d ? 1 : -1); // zwraca położenie następnego (1=zgodny,0=odwrócony - - // względem czoła składu) + d = p->DirectionSet(d ? 1 : -1); // zwraca położenie następnego (1=zgodny,0=odwrócony - względem czoła składu) p->ctOwner = this; // dominator oznacza swoje terytorium p = p->Next(); // pojazd podłączony od tyłu (licząc od czoła) } @@ -2111,9 +2100,8 @@ bool TController::CheckVehicles(TOrders user) Lights( frontlights, rearlights ); -#if LOGPRESS == 0 - AutoRewident(); // nastawianie hamulca do jazdy pociągowej -#endif + // nastawianie hamulca do jazdy pociągowej + AutoRewident(); } else if (OrderCurrentGet() & (Shunt | Connect)) { @@ -2147,45 +2135,54 @@ bool TController::CheckVehicles(TOrders user) } } } - else // Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja - // o składzie - switch (user) // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie - { - case Change_direction: - while (OrderCurrentGet() & (Change_direction)) - JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek - // skanowania! + else { // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie + // Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja o składzie + switch (user) { + case Change_direction: { + while (OrderCurrentGet() & (Change_direction)) { + // zmianę kierunku też można olać, ale zmienić kierunek skanowania! + JumpToNextOrder(); + } break; - case Connect: - while (OrderCurrentGet() & (Change_direction)) - JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek - // skanowania! - if (OrderCurrentGet() & (Connect)) - { // jeśli miało być łączenie, zakładamy, że jest dobrze (sprawdzić?) + } + case Connect: { + while (OrderCurrentGet() & (Change_direction)) { + // zmianę kierunku też można olać, ale zmienić kierunek skanowania! + JumpToNextOrder(); + } + if (OrderCurrentGet() & (Connect)) { + // jeśli miało być łączenie, zakładamy, że jest dobrze (sprawdzić?) iCoupler = 0; // koniec z doczepianiem iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania JumpToNextOrder(); // wykonanie następnej komendy - if (OrderCurrentGet() & (Change_direction)) - JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek - // skanowania! + if (OrderCurrentGet() & (Change_direction)) { + // zmianę kierunku też można olać, ale zmienić kierunek skanowania! + JumpToNextOrder(); + } + } break; - case Disconnect: - while (OrderCurrentGet() & (Change_direction)) - JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek - // skanowania! - if (OrderCurrentGet() & (Disconnect)) - { // wypadało by sprawdzić, czy odczepiono wagony w odpowiednim miejscu - // (iVehicleCount) - JumpToNextOrder(); // wykonanie następnej komendy - if (OrderCurrentGet() & (Change_direction)) - JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek - // skanowania! - } - break; - default: - break; } + case Disconnect: { + while (OrderCurrentGet() & (Change_direction)) { + // zmianę kierunku też można olać, ale zmienić kierunek skanowania! + JumpToNextOrder(); + } + if (OrderCurrentGet() & (Disconnect)) { + // wypadało by sprawdzić, czy odczepiono wagony w odpowiednim miejscu (iVehicleCount) + JumpToNextOrder(); // wykonanie następnej komendy + if (OrderCurrentGet() & (Change_direction)) { + // zmianę kierunku też można olać, ale zmienić kierunek skanowania! + JumpToNextOrder(); + } + } + break; + } + default: { + break; + } + } // switch + } // Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61 if( ( mvOccupied->TrainType == dt_EZT ) || ( mvOccupied->TrainType == dt_DMU ) @@ -2443,24 +2440,6 @@ bool TController::PrepareEngine() || ( std::max( mvControlling->GetTrainsetVoltage(), std::abs( mvControlling->RunningTraction.TractionVoltage ) ) > mvControlling->EnginePowerSource.CollectorParameters.MinV ) ) { mvControlling->MainSwitch( true ); } -/* - if (mvControlling->EngineType == DieselEngine) { - // Ra 2014-06: dla SN61 trzeba wrzucić pierwszą pozycję - nie wiem, czy tutaj... - // kiedyś działało... - if (!mvControlling->MainCtrlPos) { - if( mvControlling->RList[ 0 ].R == 0.0 ) { - // gdy na pozycji 0 dawka paliwa jest zerowa, to zgaśnie dlatego trzeba zwiększyć pozycję - mvControlling->IncMainCtrl( 1 ); - } - if( ( !mvControlling->ScndCtrlPos ) // jeśli bieg nie został ustawiony - && ( !mvControlling->MotorParam[ 0 ].AutoSwitch ) // gdy biegi ręczne - && ( mvControlling->MotorParam[ 0 ].mIsat == 0.0 ) ) { // bl,mIsat,fi,mfi - // pierwszy bieg - mvControlling->IncScndCtrl( 1 ); - } - } - } -*/ } else { OK = ( OrderDirectionChange( iDirection, mvOccupied ) == -1 ); @@ -5796,7 +5775,7 @@ void TController::OrdersInit(double fVel) // Ale mozna by je zapodac ze scenerii }; -std::string TController::StopReasonText() +std::string TController::StopReasonText() const { // informacja tekstowa o przyczynie zatrzymania if (eStopReason != 7) // zawalidroga będzie inaczej return StopReasonTable[eStopReason]; diff --git a/Driver.h b/Driver.h index 0b52c95b..8ab06b2d 100644 --- a/Driver.h +++ b/Driver.h @@ -129,12 +129,7 @@ class TSpeedPos double fDist{ 0.0 }; // aktualna odległość (ujemna gdy minięte) double fVelNext{ -1.0 }; // prędkość obowiązująca od tego miejsca double fSectionVelocityDist{ 0.0 }; // długość ograniczenia prędkości - // double fAcc; int iFlags{ spNone }; // flagi typu wpisu do tabelki - // 1=istotny,2=tor,4=odwrotnie,8-zwrotnica (może się zmienić),16-stan - // zwrotnicy,32-minięty,64=koniec,128=łuk - // 0x100=event,0x200=manewrowa,0x400=przystanek,0x800=SBL,0x1000=wysłana komenda,0x2000=W5 - // 0x4000=semafor,0x10000=zatkanie bool bMoved{ false }; // czy przesunięty (dotyczy punktu zatrzymania w peronie) Math3D::vector3 vPos; // współrzędne XYZ do liczenia odległości struct @@ -174,89 +169,76 @@ static const int BrakeAccTableSize = 20; //---------------------------------------------------------------------------- class TController { + // TBD: few authorized inspectors, or bunch of public getters? + friend class TTrain; + friend class drivingaid_panel; + friend class timetable_panel; + friend class debug_panel; + friend class whois_event; - private: // obsługa tabelki prędkości (musi mieć możliwość odhaczania stacji w rozkładzie) - int iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli sSpeedTable; - double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze - TTrack *tLast = nullptr; // ostatni analizowany tor - basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu - std::size_t SemNextIndex{ std::size_t(-1) }; - std::size_t SemNextStopIndex{ std::size_t( -1 ) }; - double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki - // parametry aktualnego składu - double fLength = 0.0; // długość składu (do wyciągania z ograniczeń) - double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji public: - double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji - basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2] - std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu - int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu - // parametry sterowania pojazdem (stan, hamowanie) - private: - double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa - int iVehicles = 0; // ilość pojazdów w składzie - int iEngineActive = 0; // ABu: Czy silnik byl juz zalaczony; Ra: postęp w załączaniu - bool Psyche = false; - int iDrivigFlags = // flagi bitowe ruchu - moveStopPoint | // podjedź do W4 możliwie blisko - moveStopHere | // nie podjeżdżaj do semafora, jeśli droga nie jest wolna - moveStartHorn; // podaj sygnał po podaniu wolnej drogi - double fDriverBraking = 0.0; // po pomnożeniu przez v^2 [km/h] daje ~drogę hamowania [m] - double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody - double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd) - public: - double fBrakeDist = 0.0; // przybliżona droga hamowania - double BrakeAccFactor() const; - double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) - double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca - double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca - double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca - // dla fBrake_aX: - // indeks [0] - wartości odpowiednie dla aktualnej prędkości - // a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego - double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0 - double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji - double BrakingInitialLevel{ 1.0 }; - double BrakingLevelIncrease{ 0.25 }; - bool IsCargoTrain{ false }; - bool IsHeavyCargoTrain{ false }; - bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control - double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku - 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 fReady = 0.0; // poziom odhamowania wagonów - bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow -private: - double LastUpdatedTime = 0.0; // czas od ostatniego logu - double ElapsedTime = 0.0; // czas od poczatku logu - double deltalog = 0.05; // przyrost czasu - 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 - TAction eAction { TAction::actUnknown }; // aktualny stan - public: + TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true ); + ~TController(); + +// ai operations logic +// methods +public: + void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę + void MoveTo(TDynamicObject *to); + void TakeControl(bool yes); + inline + bool Primary() const { + return ( ( iDrivigFlags & movePrimary ) != 0 ); }; + inline + TMoverParameters const *Controlling() const { + return mvControlling; } + void DirectionInitial(); + inline + int Direction() const { + return iDirection; } inline TAction GetAction() { return eAction; } +private: + void Activation(); // umieszczenie obsady w odpowiednim członie + void ControllingSet(); // znajduje człon do sterowania + void SetDriverPsyche(); + bool IncBrake(); + bool DecBrake(); + bool IncSpeed(); + bool DecSpeed(bool force = false); + void SpeedSet(); + void SpeedCntrl(double DesiredSpeed); + double ESMVelocity(bool Main); + bool UpdateHeating(); + // uaktualnia informacje o prędkości + void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone); + int CheckDirection(); + void WaitingSet(double Seconds); + void DirectionForward(bool forward); + int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); + void Lights(int head, int rear); + std::string StopReasonText() const; + double BrakeAccFactor() const; + // modifies brake distance for low target speeds, to ease braking rate in such situations + float + braking_distance_multiplier( float const Targetvelocity ) const; + inline + int DrivigFlags() const { + return iDrivigFlags; }; +// members +public: bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista -/* - int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala migacz lub czeka na stan zwrotnicy -*/ - private: + int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami + int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami +private: + bool Psyche = false; + int HelperState = 0; //stan pomocnika maszynisty TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący - TDynamicObject *pVehicles[2]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane) TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT) TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje - Mtable::TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty - int iRadioChannel = 1; // numer aktualnego kanału radiowego - int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) - sound_source tsGuardSignal { sound_placement::internal }; + std::string VehicleName; std::array m_lighthints { -1 }; // suggested light patterns - public: - int HelperState = 0; //stan pomocnika maszynisty double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji) double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj) double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal @@ -270,18 +252,8 @@ private: double VelRoad = -1.0; // aktualna prędkość drogowa (ze znaku W27) (PutValues albo komendą) // prędkość drogowa bez ograniczenia double VelNext = 120.0; // prędkość, jaka ma być po przejechaniu długości ProximityDist double VelRestricted = -1.0; // speed of travel after passing a permissive signal at stop - private: double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora - public: double ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia - private: - Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego - // odnosi sie komenda - TOrders OrderList[maxorders]; // lista rozkazów - int OrderPos = 0, - OrderTop = 0; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych - std::ofstream LogFile; // zapis parametrow fizycznych - std::ofstream AILogFile; // log AI int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył) int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku) int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie) @@ -289,146 +261,186 @@ private: int iDriverFailCount = 0; // licznik błędów AI bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała bool Need_BrakeRelease = true; - - public: double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!) double fOverhead2 = -1.0; // informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i ograniczeniem prędkości) - int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami - int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami double fVoltage = 0.0; // uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas - private: double fMaxProximityDist = 50.0; // stawanie między 30 a 60 m przed przeszkodą // akceptowalna odległość stanięcia przed przeszkodą TStopReason eStopReason = stopSleep; // powód zatrzymania przy ustawieniu zerowej prędkości // na początku śpi - std::string VehicleName; double fVelPlus = 0.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania double fVelMinus = 0.0; // margines obniżenia prędkości, powodujący załączenie napędu double fWarningDuration = 0.0; // ile czasu jeszcze trąbić double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia double IdleTime {}; // keeps track of time spent at a stop - public: double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku) + double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa + int iDrivigFlags = // flagi bitowe ruchu + moveStopPoint | // podjedź do W4 możliwie blisko + moveStopHere | // nie podjeżdżaj do semafora, jeśli droga nie jest wolna + moveStartHorn; // podaj sygnał po podaniu wolnej drogi + double fDriverBraking = 0.0; // po pomnożeniu przez v^2 [km/h] daje ~drogę hamowania [m] + 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 + double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) + double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca + double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca + double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca + // dla fBrake_aX: + // indeks [0] - wartości odpowiednie dla aktualnej prędkości + // a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego + double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0 + double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji + double BrakingInitialLevel{ 1.0 }; + double BrakingLevelIncrease{ 0.25 }; + 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 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 + TAction eAction { TAction::actUnknown }; // aktualny stan - private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---// - void SetDriverPsyche(); - bool PrepareEngine(); - bool ReleaseEngine(); - bool IncBrake(); - bool DecBrake(); - bool IncSpeed(); - bool DecSpeed(bool force = false); - void SpeedSet(); - void SpeedCntrl(double DesiredSpeed); - void Doors(bool const Open, int const Side = 0); - // returns true if any vehicle in the consist has an open door - bool doors_open() const; - void RecognizeCommand(); // odczytuje komende przekazana lokomotywie - void Activation(); // umieszczenie obsady w odpowiednim członie - void ControllingSet(); // znajduje człon do sterowania - void AutoRewident(); // ustawia hamulce w składzie - double ESMVelocity(bool Main); - public: +// orders +// methods +public: void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm); bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm ); - void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę - bool UpdateHeating(); - // procedury dotyczace rozkazow dla maszynisty - // uaktualnia informacje o prędkości - void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone); - public: +private: + void RecognizeCommand(); // odczytuje komende przekazana lokomotywie void JumpToNextOrder(); void JumpToFirstOrder(); void OrderPush(TOrders NewOrder); void OrderNext(TOrders NewOrder); inline TOrders OrderCurrentGet(); inline TOrders OrderNextGet(); - bool CheckVehicles(TOrders user = Wait_for_orders); - int CheckDirection(); - - private: - void CloseLog(); void OrderCheck(); - - public: void OrdersInit(double fVel); void OrdersClear(); void OrdersDump(); - TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true ); std::string OrderCurrent() const; - void WaitingSet(double Seconds); - - private: std::string Order2Str(TOrders Order) const; - void DirectionForward(bool forward); - int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); - void Lights(int head, int rear); +// members + Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used + TOrders OrderList[ maxorders ]; // lista rozkazów + int OrderPos = 0, + OrderTop = 0; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych + +// scantable +// methods +public: + int CrossRoute(TTrack *tr); + inline void MoveDistanceAdd( double distance ) { + dMoveLen += distance * iDirection; } //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna +private: // Ra: metody obsługujące skanowanie toru - std::vector CheckTrackEvent(TTrack *Track, double const fDirection ) const; + std::vector CheckTrackEvent( TTrack *Track, double const fDirection ) const; bool TableAddNew(); - bool TableNotFound(basic_event const *Event) const; - void TableTraceRoute(double fDistance, TDynamicObject *pVehicle); - void TableCheck(double fDistance); - TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); - // modifies brake distance for low target speeds, to ease braking rate in such situations - float - braking_distance_multiplier( float const Targetvelocity ) const; + bool TableNotFound( basic_event const *Event ) const; + void TableTraceRoute( double fDistance, TDynamicObject *pVehicle ); + void TableCheck( double fDistance ); + TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc ); + // returns most recently calculated distance to potential obstacle ahead + double TrackBlock() const; void TablePurger(); void TableSort(); inline double MoveDistanceGet() const { - return dMoveLen; } + return dMoveLen; + } inline void MoveDistanceReset() { - dMoveLen = 0.0; } - public: - inline void MoveDistanceAdd(double distance) { - dMoveLen += distance * iDirection; //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna + dMoveLen = 0.0; } std::size_t TableSize() const { return sSpeedTable.size(); } void TableClear(); int TableDirection() { return iTableDirection; } - - private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu - bool BackwardTrackBusy(TTrack *Track); - basic_event *CheckTrackEventBackward(double fDirection, TTrack *Track); - TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event); + // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu + bool BackwardTrackBusy( TTrack *Track ); + basic_event *CheckTrackEventBackward( double fDirection, TTrack *Track ); + TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event ); void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos ); TCommandType BackwardScan(); - - public: - void PhysicsLog(); - std::string StopReasonText(); - ~TController(); - void TakeControl(bool yes); - Mtable::TTrainParameters const * TrainTimetable() const; - std::string TrainName() const; - std::string Relation() const; - int StationCount() const; - int StationIndex() const; - bool IsStop() const; - std::string NextStop() const; - inline - bool Primary() const { - return ( ( iDrivigFlags & movePrimary ) != 0 ); }; - inline - int DrivigFlags() const { - return iDrivigFlags; }; - // returns most recently calculated distance to potential obstacle ahead - double - TrackBlock() const; - void MoveTo(TDynamicObject *to); - void DirectionInitial(); std::string TableText(std::size_t const Index) const; - int CrossRoute(TTrack *tr); /* void RouteSwitch(int d); */ - std::string OwnerName() const; - TMoverParameters const *Controlling() const { - return mvControlling; } - int Direction() const { - return iDirection; } +// members + int iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli sSpeedTable; + double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze + TTrack *tLast = nullptr; // ostatni analizowany tor + basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu + std::size_t SemNextIndex{ std::size_t(-1) }; + std::size_t SemNextStopIndex{ std::size_t( -1 ) }; + double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki + basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2] + +// timetable +// methods +public: + std::string TrainName() const; +private: + std::string Relation() const; + Mtable::TTrainParameters const * TrainTimetable() const; + int StationIndex() const; + int StationCount() const; + bool IsStop() const; + std::string NextStop() const; +// members + Mtable::TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty + std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu + int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu + double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku + int iRadioChannel = 1; // numer aktualnego kanału radiowego + int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) + sound_source tsGuardSignal { sound_placement::internal }; + +// consist +// methods +public: +private: + bool CheckVehicles(TOrders user = Wait_for_orders); + bool PrepareEngine(); + bool ReleaseEngine(); + void Doors(bool const Open, int const Side = 0); + // returns true if any vehicle in the consist has an open door + bool doors_open() const; + void AutoRewident(); // ustawia hamulce w składzie +// members + double fLength = 0.0; // długość składu (do wyciągania z ograniczeń) + double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji + double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji + int iVehicles = 0; // ilość pojazdów w składzie + int iEngineActive = 0; // ABu: Czy silnik byl juz zalaczony; Ra: postęp w załączaniu + bool IsCargoTrain{ false }; + bool IsHeavyCargoTrain{ false }; + bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control + double fReady = 0.0; // poziom odhamowania wagonów + bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow + TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane) + +// logs +// methods + void PhysicsLog(); + void CloseLog(); +// members + std::ofstream LogFile; // zapis parametrow fizycznych + double LastUpdatedTime = 0.0; // czas od ostatniego logu + double ElapsedTime = 0.0; // czas od poczatku logu + +// getters +public: TDynamicObject const *Vehicle() const { return pVehicle; } TDynamicObject *Vehicle( side const Side ) const { return pVehicles[ Side ]; } +private: + std::string OwnerName() const; + +// leftovers +/* + int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala migacz lub czeka na stan zwrotnicy +*/ + }; diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 4c0d9384..da9e1ddb 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -526,37 +526,7 @@ debug_panel::update_section_vehicle( std::vector &Output ) { vehicle.GetPosition().z ); Output.emplace_back( m_buffer.data(), Global.UITextColor ); -/* - textline = " TC:" + to_string( mover.TotalCurrent, 0 ); -*/ -/* - if( mover.ManualBrakePos > 0 ) { - textline += "; manual brake on"; - } -*/ -/* - // McZapkie: warto wiedziec w jakim stanie sa przelaczniki - switch( - mover.ActiveDir * - ( mover.Imin == mover.IminLo ? - 1 : - 2 ) ) { - case 2: { textline += " >> "; break; } - case 1: { textline += " -> "; break; } - case 0: { textline += " -- "; break; } - case -1: { textline += " <- "; break; } - case -2: { textline += " << "; break; } - } - - // McZapkie: komenda i jej parametry - if( mover.CommandIn.Command != ( "" ) ) { - textline = - "C:" + mover.CommandIn.Command - + " V1=" + to_string( mover.CommandIn.Value1, 0 ) - + " V2=" + to_string( mover.CommandIn.Value2, 0 ); - } -*/ } std::string @@ -902,7 +872,10 @@ debug_panel::render_section( std::string const &Header, std::vector c if( false == ImGui::CollapsingHeader( Header.c_str() ) ) { return false; } for( auto const &line : Lines ) { - ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() ); + ImGui::PushStyleColor( ImGuiCol_Text, { line.color.r, line.color.g, line.color.b, line.color.a } ); + ImGui::TextUnformatted( line.data.c_str() ); + ImGui::PopStyleColor(); +// ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() ); } return true; }