/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef DriverH #define DriverH #include "Classes.h" #include "dumb3d.h" #include #include using namespace Math3D; using namespace Mtable; using namespace std; enum TOrders { // rozkazy dla AI Wait_for_orders = 0, // czekanie na dostarczenie następnych rozkazów // operacje tymczasowe Prepare_engine = 1, // włączenie silnika Release_engine = 2, // wyłączenie silnika Change_direction = 4, // zmiana kierunku (bez skanowania sygnalizacji) Connect = 8, // podłączanie wagonów (z częściowym skanowaniem sygnalizacji) Disconnect = 0x10, // odłączanie wagonów (bez skanowania sygnalizacji) // jazda Shunt = 0x20, // tryb manewrowy Obey_train = 0x40, // tryb pociągowy Jump_to_first_order = 0x60 // zapęlenie do pierwszej pozycji (po co?) }; enum TMovementStatus { // flagi bitowe ruchu (iDrivigFlags) moveStopCloser = 1, // podjechać blisko W4 (nie podjeżdżać na początku ani po zmianie czoła) moveStopPoint = 2, // stawać na W4 (wyłączone podczas zmiany czoła) moveActive = 4, // pojazd jest załączony i skanuje movePress = 8, // dociskanie przy odłączeniu (zamiast zmiennej Prepare2press) moveConnect = 0x10, // jest blisko innego pojazdu i można próbować podłączyć movePrimary = 0x20, // ma priorytet w składzie (master) moveLate = 0x40, // flaga spóźnienia, włączy bardziej moveStopHere = 0x80, // nie podjeżdżać do semafora, jeśli droga nie jest wolna moveStartHorn = 0x100, // podawaj sygnał po podaniu wolnej drogi moveStartHornNow = 0x200, // podaj sygnał po odhamowaniu moveStartHornDone = 0x400, // podano sygnał po podaniu wolnej drogi moveOerlikons = 0x800, // skład wyłącznie z zaworami? Oerlikona moveIncSpeed = 0x1000, // załączenie jazdy (np. dla EZT) moveTrackEnd = 0x2000, // dalsza jazda do przodu trwale ograniczona (W5, koniec toru) moveSwitchFound = 0x4000, // na drodze skanowania do przodu jest rozjazd moveGuardSignal = 0x8000, // sygnał od kierownika (minął czas postoju) moveVisibility = 0x10000, // jazda na widoczność po przejechaniu S1 na SBL moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku moveSemaphorFound = 0x80000, // na drodze skanowania został znaleziony semafor moveSemaphorWasElapsed = 0x100000, // minięty został semafor moveTrainInsideStation = 0x200000, // pociąg między semaforem a rozjazdami lub następnym semaforem moveSpeedLimitFound = 0x400000 // pociąg w ograniczeniu z podaną jego długością }; enum TStopReason { // powód zatrzymania, dodawany do SetVelocity 0 - w zasadzie do usunięcia stopNone, // nie ma powodu - powinien jechać stopSleep, // nie został odpalony, to nie pojedzie stopSem, // semafor zamknięty stopTime, // czekanie na godzinę odjazdu stopEnd, // brak dalszej części toru stopDir, // trzeba stanąć, by zmienić kierunek jazdy stopJoin, // stoi w celu połączenia wagonów stopBlock, // przeszkoda na drodze ruchu stopComm, // otrzymano taką komendę (niewiadomego pochodzenia) stopOut, // komenda wyjazdu poza stację (raczej nie powinna zatrzymywać!) stopRadio, // komunikat przekazany radiem (Radiostop) stopExt, // komenda z zewnątrz stopError // z powodu błędu w obliczeniu drogi hamowania }; enum TAction { // przechowanie aktualnego stanu AI od poprzedniego przebłysku świadomości actUnknown, // stan nieznany (domyślny na początku) actPantUp, // podnieś pantograf (info dla użytkownika) actConv, // załącz przetwornicę (info dla użytkownika) actCompr, // załącz sprężarkę (info dla użytkownika) actSleep, //śpi (wygaszony) actDrive, // jazda actGo, // ruszanie z miejsca actSlow, // przyhamowanie przed ograniczeniem sctStop, // hamowanie w celu precyzyjnego zatrzymania actIdle, // luzowanie składu przed odjazdem actRelease, // luzowanie składu po zmniejszeniu prędkości actConnect, // dojazd w celu podczepienia actWait, // czekanie na przystanku actReady, // zgłoszona gotowość do odjazdu od kierownika actEmergency, // hamowanie awaryjne actGoUphill, // ruszanie pod górę actTest, // hamowanie kontrolne (podczas jazdy) actTrial // próba hamulca (na postoju) }; enum TSpeedPosFlag { // wartości dla iFlag w TSpeedPos spEnabled = 0x1, // pozycja brana pod uwagę spTrack = 0x2, // to jest tor spReverse = 0x4, // odwrotnie spSwitch = 0x8, // to zwrotnica spSwitchStatus = 0x10, // stan zwrotnicy spElapsed = 0x20, // pozycja minięta przez pojazd spEnd = 0x40, // koniec spCurve = 0x80, // łuk spEvent = 0x100, // event spShuntSemaphor = 0x200, // tarcza manewrowa spPassengerStopPoint = 0x400, // przystanek osobowy (wskaźnik W4) spStopOnSBL = 0x800, // zatrzymanie na SBL spCommandSent = 0x1000, // komenda wysłana spOutsideStation = 0x2000, // wskaźnik końca manewrów spSemaphor = 0x4000, // semafor pociągowy spRoadVel = 0x8000, // zadanie prędkości drogowej spSectionVel = 0x20000, // odcinek z ograniczeniem spProximityVelocity = 0x40000, // odcinek z ograniczeniem i podaną jego długościa spEndOfTable = 0x10000 // zatkanie tabelki }; class TSpeedPos { // pozycja tabeli prędkości dla AI public: double fDist; // aktualna odległość (ujemna gdy minięte) double fVelNext; // prędkość obowiązująca od tego miejsca double fSectionVelocityDist; //długość ograniczenia prędkości // double fAcc; int iFlags; //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 vector3 vPos; // współrzędne XYZ do liczenia odległości struct { TTrack *trTrack; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica) TEvent *evEvent; // połączenie z eventem albo komórką pamięci }; void CommandCheck(); public: void Clear(); bool Update(vector3 *p, vector3 *dir, double &len); bool Set(TEvent *e, double d, TOrders order = Wait_for_orders); void Set(TTrack *t, double d, int f); std::string TableText(); std::string GetName(); bool IsProperSemaphor(TOrders order = Wait_for_orders); }; //---------------------------------------------------------------------------- static const bool Aggressive = true; static const bool Easyman = false; static const bool AIdriver = true; 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 //---------------------------------------------------------------------------- class TController { private: // obsługa tabelki prędkości (musi mieć możliwość odhaczania stacji w rozkładzie) TSpeedPos *sSpeedTable; // najbliższe zmiany prędkości int iSpeedTableSize; // wielkość tabelki int iFirst; // aktualna pozycja w tabeli (modulo iSpeedTableSize) int iLast; // ostatnia wypełniona pozycja w tabeli 0:przeliczać do // punktu, <0:podana wartość double FirstSemaphorDist; // odległość do pierwszego znalezionego semafora public: double ActualProximityDist; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia private: vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego // odnosi sie komenda TOrders OrderList[maxorders]; // lista rozkazów int OrderPos, OrderTop; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych std::ofstream LogFile; // zapis parametrow fizycznych std::ofstream AILogFile; // log AI bool MaxVelFlag; bool MinVelFlag; int iDirection; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył) int iDirectionOrder; //żadany kierunek jazdy (służy do zmiany kierunku) int iVehicleCount; // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie) int iCoupler; // maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 // gdy jazda bez łączenia int iDriverFailCount; // licznik błędów AI bool Need_TryAgain; // true, jeśli druga pozycja w elektryku nie załapała bool Need_BrakeRelease; public: double fMinProximityDist; // minimalna oległość do przeszkody, jaką należy zachować double fOverhead1; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!) double fOverhead2; // informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i // ograniczeniem prędkości) int iOverheadZero; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z // podniesionymi pantografami int iOverheadDown; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z // podniesionymi pantografami double fVoltage; // uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić // rozruch o losowy czas private: double fMaxProximityDist; // akceptowalna odległość stanięcia przed przeszkodą TStopReason eStopReason; // powód zatrzymania przy ustawieniu zerowej prędkości std::string VehicleName; double fVelPlus; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania double fVelMinus; // margines obniżenia prędkości, powodujący załączenie napędu double fWarningDuration; // ile czasu jeszcze trąbić double fStopTime; // czas postoju przed dalszą jazdą (np. na przystanku) double WaitingTime; // zliczany czas oczekiwania do samoistnego ruszenia double WaitingExpireTime; // maksymlany czas oczekiwania do samoistnego ruszenia // TEvent* eSignLast; //ostatnio znaleziony sygnał, o ile nie minięty 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 Doors(bool what); 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 public: Mtable::TTrainParameters * Timetable() { return TrainParams; }; void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm); bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const vector3 *NewLocation, TStopReason reason = stopComm); bool UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę // procedury dotyczace rozkazow dla maszynisty void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone); // uaktualnia informacje o prędkości bool SetProximityVelocity( double NewDist, double NewVelNext); // uaktualnia informacje o prędkości przy nastepnym semaforze public: 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); private: void CloseLog(); void OrderCheck(); public: void OrdersInit(double fVel); void OrdersClear(); void OrdersDump(); TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true // czy ma aktywnie prowadzić? ); std::string OrderCurrent(); void WaitingSet(double Seconds); private: std::string Order2Str(TOrders Order); void DirectionForward(bool forward); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); void Lights(int head, int rear); double Distance(vector3 &p1, vector3 &n, vector3 &p2); private: // Ra: metody obsługujące skanowanie toru TEvent * CheckTrackEvent(double fDirection, TTrack *Track); bool TableCheckEvent(TEvent *e); bool TableAddNew(); bool TableNotFound(TEvent *e); void TableClear(); TEvent * TableCheckTrackEvent(double fDirection, TTrack *Track); void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = NULL); void TableCheck(double fDistance); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); void TablePurger(); private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu bool BackwardTrackBusy(TTrack *Track); TEvent * CheckTrackEventBackward(double fDirection, TTrack *Track); TTrack * BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event); void SetProximityVelocity(double dist, double vel, const vector3 *pos); TCommandType BackwardScan(); public: void PhysicsLog(); string StopReasonText(); ~TController(); std::string NextStop(); void TakeControl(bool yes); std::string Relation(); std::string TrainName(); int StationCount(); int StationIndex(); bool IsStop(); bool Primary() { return this ? bool(iDrivigFlags & movePrimary) : false; }; int inline DrivigFlags() { return iDrivigFlags; }; void MoveTo(TDynamicObject *to); void DirectionInitial(); std::string TableText(int i); int CrossRoute(TTrack *tr); void RouteSwitch(int d); std::string OwnerName(); }; #endif