vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RoadsState.h
Go to the documentation of this file.
1 #ifndef ROADS_STATE
2 #define ROADS_STATE
3 
4 #include <vrecko/Ability.h>
5 #include <vrecko/ReaderWriter.h>
6 #include <vrecko/IOPins.h>
7 #include <vrecko/Message.h>
8 
9 #include "Junction.h"
10 #include "PolygonPoint.h"
11 #include "Edge.h"
12 #include "RoadsEdges.h"
13 #include "CarControlUnit.h"
14 
15 #include <osg/Vec3>
16 #include <set>
17 #include <map>
18 #include <vector>
19 
20 namespace CarSim {
21 
22  using namespace vrecko;
23 
24  class RoadsState: public vrecko::Ability {
25  public:
26  // bude jenom 1 RoadsState, takze by nektere metody a atributy
27  // mohly byt static, pro jednoduchost ale zatim budou vsechny metody
28  // a atributy bez static, takze se budou vzdy vztahovat k instanci
29  // RoadsState a ne k samotne tride
30  RoadsState();
32  void preInitialize(void);
33  void processEvent(const std::string &input_name, void *value);
34  void *processRequest(const std::string &input_name, void *value);
35 
36  virtual void update(void);
37 
38  bool loadXMLParameters(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *pParametersNode);
39  protected:
40  // cesta k adresari, kde jsou ulozeny modely aut a textura silnice
41  std::string dataPath;
42  // jestlize je true, nektere krizovatky uvedene u from, to a fromPointRight,
43  // toPointRight u hran zadanych v XML souboru neexistuji.
44  // Tato promenna se kontroluje pri prijeti requestu a v pripade, ze je "true"
45  // -> posle se NULL CCU -> ktera pak zrusi sve aktualizovani,
46  // aby se uz neposilala zadosti roadsState
48 
49  // roads, junctions a polygonPoints jsou indexovany pomoci klicu,
50  // ktere se vyskytuji jako id ve vstupnim XML souboru - zacinaji tedy
51  // od 1 a v rozsahu pro klic se mohou vyskytovat diry;
52  // indexy pro edges jsou generovany az pri behu programu - jsou indexovany
53  // od 0 a v rozsahu pro index se nevyskytuji diry;
54  // graf silnic - implementovan pomoci seznamu (mnoziny) nasledniku;
55  // prvni unsigned int slouzi pro ID krizovatky (uzlu),
56  // druhe znaci ID nasledniku (krizovatek) a posledni je ID hran
57  // k temto naslednikum;
58  // budou zde pouze hrany, na kterych auta jezdi z bodu OUT do IN
59  // - tedy pouze normalni nebo kratke s aspon 1 pruhem (jestlize je hrana
60  // prilis uzka na to, aby na ni mohlo jezdit auto -> ma 0 pruhu)
61  std::map<unsigned int, std::map<unsigned int,unsigned int> > roads;
62  std::map<unsigned int,Junction> junctions;
63  // id krizovatky s nejvetsi hodnotou
64  unsigned int maxJuncId;
65  // id polygonPointu s nejvetsi hodnotou
66  unsigned int maxPolygonPointId;
67  std::map<unsigned int,PolygonPoint> polygonPoints;
68  std::vector<Edge> edges;
69 
70  // pocet neterminalnich hran v edges (ze zacatku jsou
71  // v edges neterminalni hrany, pak same terminalni)
72  unsigned int numOfNonTermEdges;
73 
74  // zde budou ulozeno, ktere hrany patri k jakym silnicim;
75  // klic je id silnice (budou zde vsechny silnice nactene
76  // z XML souboru
77  std::map<unsigned int,RoadsEdges> roadsEdges;
78 
79  // ukazatel na abilitu, ktera bude mazat auta
81 
82  // ukazatel na abilitu, ktera bude cachovat casti geometrie aut, aby
83  // se stejne soubory nemusely nacitat vicekrat
85 
86  // model sloupu semaforu,
87  osg::Node *pTLcolumnModel;
88  // model oranzoveho svetla semaforu,
89  osg::Node *pTLorangeModel;
90  // vzdalenost mezi stredy barevnych svetel na semaforu
92 
93 
94  // loaded from params, should be used when the roads will be loaded:
95  bool bDrawRoads;
98 
99  bool bAttemptToLoadRoadsFromArtificalWorld; // will be used when road are not specified in the Parameters node
100 
101 
102  // tato metoda nacte ze vstupniho XML souboru krizovatky (Junction),
103  // body urcujici tvary silnic (PolygonPoint) a silnice (Road) pomoci
104  // nasledujicich tri fci
105  void loadJuncPolyRoad(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode const *const pRoadNetNode);
106  // tato metoda nacte krizovatku z atributu uzlu Junction
107  void loadJunction(XERCES_CPP_NAMESPACE_QUALIFIER DOMNamedNodeMap const *const pAttributes);
108  // tato metoda nacte bod pro tvar silnice z atributu uzlu PolygonPoint
109  void loadPolygonPoint(XERCES_CPP_NAMESPACE_QUALIFIER DOMNamedNodeMap const *const pAttributes);
110  // tato metoda nacte silnici (Road) z atributu uzlu Road a ulozi ji pomoci
111  // dvou hran protichudnych smeru (po teto metode je tedy v edges vzdy hrana se
112  // sudym indexem komplementarni s hranou s tim indexem + 1)
113  void loadRoad(XERCES_CPP_NAMESPACE_QUALIFIER DOMNamedNodeMap const *const pAttributes);
114 
115  // tato metoda vytvori polygon pro kazdou hranu a ulozi je pod 1 EnvironmentObject
116  // do sceny (vykreslene polygony maji body from, fromPointRight, toPointRight, to)
117  void addEdgesAsEO() ;
118  // tato metoda overi, zda krizovatky uvedene u from, to a fromPointRight,
119  // toPointRight u hran zadanych v XML souboru skutecne existuji
120  void checkEdgesFromToAndTheirPolygonPoints();
121 
122  // metoda, ktera najde nejkratsi cestu ze startovni hrany s offsetem na ni
123  // do koncove hrany s prislusnym offsetem;
124  // vysledek bude ulozen do vektoru, na ktery ukazuje prvni ukazatel,
125  // cesta je ulozena v podobe indexu krizovatek na ceste do mapy junctions
126  void findShortestPath(std::vector<unsigned int> *const pResultPath,
127  const StartStopDestination *const pStartStopDestination);
128 
129  // metoda, ktera najde ze startovni hrany nahodne dlouhou cestu (rand(30)+1,
130  // delka cesty tu je v poctu hran na ni), ktera nemusi byt nejkratsi;
131  // bude se predpokladat, ze auto na hrane startEdge muze zacit (pro auto uz byla
132  // zavolana metoda regCarForEdge);
133  // posledni hrana bude normalni (pujde na ni zastavit);
134  // vysledek bude ulozen do vektoru, na ktery ukazuje ukazatel,
135  // cesta je ulozena v podobe indexu krizovatek na ceste do mapy junctions;
136  // slouzi pro rychlejsi nalezeni cest u generovanych aut;
137  // pozn.: pocita se s tim, ze byl inicializovan generator nahodnych cisel srand();
138  // pri generovani cesty se metoda bude snazit vybirat dalsi krizovatky po startovni hrane
139  // tak, aby se auto prilis casto neotacelo o 180
140  // (na krizovatkach to v realu neni prilis obvykle)
141  void findPath(std::vector<unsigned int> *const pResultPath,const unsigned int startEdge);
142 
143  // tato fce vypocita pomoci indexu hrany a relativni pozici na ni
144  // mezi body OUT a IN
145  // absolutni pozici ve svete, ta se ulozi to 1. parametru;
146  // offset je v procentech
147  void getAbsPos(osg::Vec3 &resultPos,const unsigned int edge,
148  const float offset);
149 
150  // tato metoda vypocita u vsech neterminalnich hran atributy: body IN a OUT,
151  // outInVec, widthTPR, widthFPR, type a dalsi
152  void computeEdgesAttributes();
153 
154  // tato metoda pred zapocetim simulace prida ke kazde krizovatce
155  // indexy na neterminalni hrany, ktere do ni vstupuji a vystupuji;
156  // budou slouzit k detekci prechodu auta pres hranice hran
157  // krizovatky u ktere je auto
158  void computeJunctionsEdges();
159 
160  /*// tato fce vypocte prusecik usecky a roviny, ktere jsou k sobe kolme;
161  // usecka je zadana pomoci bodu a vektoru (u usecky vektor definuje
162  // jeji delku), rovina je definovana pomoci bodu a vektorem usecky;
163  // jestlize prusecik puvodni primky a usecky neexistuje, vrati se NULL
164  const osg::Vec3 *const interPointOfAbscissaAndPerpendicularPlane
165  (const osg::Vec3 &abscissaPoint,const osg::Vec3 &abscissaVec,const osg::Vec3 &planePoint);*/
166 
167  // tato fce vypocte prusecik (1. parametr) primky a roviny, ktere jsou k sobe kolme;
168  // primka je zadana pomoci bodu a vektoru, rovina je definovana pomoci bodu a vektorem primky;
169  // jestlize je lineVec (0,0,0), bude vypsana chyba a vraceny prusecik bude (0,0,0)
170  void interPointOfLineAndPerpendicularPlane(osg::Vec3 &inter,const osg::Vec3 &linePoint,
171  const osg::Vec3 &lineVec,const osg::Vec3 &planePoint);
172 
173  // vypocita vzdalenost mezi primkou (zadana bodem a vektorem) a bodem v prostoru
174  const float distFromPointToLine(const osg::Vec3 &linePoint,
175  const osg::Vec3 &lineVec,const osg::Vec3 &point);
176 
177  void herFerDeriv(osg::Vec3 &result,const float d,const osg::Vec3 &P1,
178  const osg::Vec3 &P4,const osg::Vec3 &R1,const osg::Vec3 &R4);
179 
180  /*// tato metoda vypocita pozici Hermite/Fergussonovy kubiky (danou body
181  // P1, P4 a vektory R1 a R4) v bode d, vysledek ulozi do result
182  void herFer(osg::Vec3 &result,const float d,const osg::Vec3 &P1,
183  const osg::Vec3 &P4,const osg::Vec3 &R1,const osg::Vec3 &R4);*/
184 
185  // tato funkce zjisti, zda bod point lezi v poloprostoru zadanym vektorem
186  // halfSpacePoint a bodem halfSpaceVec
187  bool pointInHalfSpace(const osg::Vec3 &point,const osg::Vec3 &halfSpacePoint,
188  const osg::Vec3 &halfSpaceVec);
189 
190  // jestlize je auto v okoli stredu krizovatky, urci se na ktere hrane je,
191  // ta se pak vrati v prvnim parametru;
192  // 2. parametr je index hrany, na ktere bylo auto v minulem snimku
193  // 3. parametr je spodni pozice auta,
194  // 4. parametr je index krizovatky, u ktere je auto (sloucene, nikdy dilci)
195  // 5. parametr je id vystupni hrany u te krizovatky
196  void getCarEdgeId(unsigned int &carEdgeId,const unsigned int lastCarEdgeId,
197  const osg::Vec3 &bottomCarPosition,const unsigned int juncId,
198  const unsigned int outEdgeId);
199 
200  // v prvnim parametru vrati vzdalenost bodu point od roviny
201  // dane bodem (planePoint) a vektorem (planeNormal)
202  void distPointToPlane(float &dist,const osg::Vec3 &point,
203  const osg::Vec3 &planePoint,const osg::Vec3 &planeNormal);
204 
205  // tato metoda vypocte ve 2D prunik 2 ruznobeznych primek
206  // (jsou dany bodem a vektorem), vysledek je ulozen do result;
207  // jestlize jsou primky rovnobezne, zapise se chybova hlaska a vrati
208  // se (0,0,0)
209  void linesInter2D(osg::Vec2 &result,const osg::Vec2 &line1Point,
210  const osg::Vec2 &line1Vec,const osg::Vec2 &line2Point,
211  const osg::Vec2 &line2Vec);
212 
213  // metoda najde u krizovatek pary samostatnych polygonPointu
214  // (samostatnych ve smyslu jejich vyskytu u hran krizovatky), ktere jsou vedle
215  // sebe (1. je vzdy na vstupni, 2. na vystupni hrane) a zavola metodu, ktera
216  // z tech 2 polygonPointu a stredu krizovatky udela terminator;
217  // terminatory se pridavaji, aby auto pri prejeti kolem tech
218  // samostatnych polygonPointu nevyselo jenom tak ve vzduchu (aby se autu
219  // mohla snadno davat normala podle hrany pod nim, aby se jednoduse urcilo,
220  // kde auto je)
221  void findJuncsSinglePolyPoints();
222 
223  // tato metoda vytvori z 1. a 2. sam. polygonPointu a stredu kriz. juncId
224  // terminator (viz findJuncsSinglePolyPoints); terminator se take zacleni
225  // mezi hrany fstEdgeId (lezi na ni 1. polygonPoint, je to vzdy vstupni
226  // hrana) a sndEdgeId (lezi na ni 2. polygonPoint, je to vzdy vystupni hrana)
227  // v orderedEdges krizovatky juncId
228  void addTerminatorEdges(unsigned int fstSinglePolyPoint,
229  unsigned int sndSinglePolyPoint,unsigned int fstEdgeId,
230  unsigned int sndEdgeId,const unsigned int juncId);
231 
232  // mezi nekterymi krizovatkami se mohou vyskytnout hrany, ktere jsou
233  // ultrakratke (viz Edge.h);
234  // neni vhodne uvazovat prujezd pres tuto ultrakratkou hranu
235  // z bodu OUT a IN, protoze by pak auto muselo na takove hrane prudce zatacet;
236  // proto krizovatky, mezi nimiz jsou ultrakratke hrany,
237  // spojuji do jedne nove krizovatky;
238  // ta ma vstupni a vystupni hrany stejne jako neultrakratke vstupni a vystupni
239  // hrany dilcich krizovatek;
240  // v edges jsou odkazy na stare krizovatky; v roads se odstrani stare krizovatky
241  // a daji nove
242  void mergeCloseJunctions();
243 
244  // prida hranu s id edgeId jako EnvironmentObject do sceny (s geometrii ctyruhelnika)
245  void addEdgeAsEO(const unsigned int edgeId);
246 
247  // tato metoda usporada hrany u krizovatek ulozenych ve vektoru orderedEdgesIds
248  void orderJunctionsEdges();
249 
250  // tato metoda vypocita u krizovatek atributy pro dvojice vstupnich a vystupnich
251  // (ovsem vzdy kratkych nebo normalnich) hran, viz junction.h; predpoklada se,
252  // ze hrany u krizovatek jsou uz usporadane
253  void computeJuncInOutEdgesAttr();
254 
255  // jestlize auto skoncilo svoji cestu -> smaze se jeho id u koncove (normalni) hrany;
256  // tato metoda smaze id na auto u dane hrany; nemuze se stat, ze by
257  // se id auta u hrany nenaslo -> proto tuto moznost netestuji
258  void unregCarForEdge(const unsigned int carId,const unsigned int edgeId);
259 
260  // odregistuje posledni auto na zadane normalni hrane
261  void unregLastCarForEdge(const unsigned int edgeId);
262 
263  // zaregistruje auto u startovni (normalni) hrany
264  // (parametry jsou - id auta, id startovni hrany, offset pozice stredu auta na ni,
265  // delka auta a zda bylo auto vygenerovano);
266  // pridani auta do hrany, kde uz nejaka auta jsou, bude mit
267  // linearni slozitost - to ale nebude moc vadit, protoze to nebude moc caste
268  // (auto se zaregistuje u hrany pouze na zacatku sveho zivotniho cyklu);
269  // jestlize vse probehlo v poradku, vrati true;
270  // jestlize se vyskytla chyba (auto je moc blizko jinemu autu, ktere uz
271  // na hrane je; predni cast auta je za bodem stopBeforeJunc nebo je prilis blizko
272  // autu u from kriz. hrany), vrati false;
273  // jestlize je showErrors false, budou potlaceny chybove vystupy (napriklad pri
274  // generovani aut)
275  bool regCarForEdge(const unsigned int carId,const unsigned int startEdgeId,
276  const float startOffset,const float carLength,const bool showErrors);
277 
278  // zaregistruje auto s offsetem (urcujicim umisteni stredu auta na hrane), delkou
279  // a rychlosti u normalni hrany jako prvni
280  void regFstCarForEdge(const unsigned int carId,const unsigned int edgeId,
281  const float offset,const float carLength,const float vel);
282 
283  // zjisti, zda je auto zaregistrovano u hrany
284  bool isCarRegForEdge(const unsigned int carId,const unsigned int edgeId);
285 
286  // metoda, ktera aktualizuje informace o autu u normalni hrany
287  // (auto musi byt zaregistrovano u normalni hrany)
288  void updateCarForEdge(const unsigned int carId,const unsigned int edgeId,
289  const float headOffset,const float rearOffset,const float vel);
290 
291  // metoda, ktera vrati vzdalenost mezi autem, jehoz id je dano parametrem
292  // (auto musi byt zaregistrovano u hrany s id edgeId), a autem nasledujicim
293  // (smerem ke konci hrany) a rychlost tohoto nasledujiciho auta;
294  // pozadovane hodnoty jsou vraceny v prvnich dvou parametrech;
295  // Pozn.: Jestlize nasledujici auta neexistuje, jsou vracene hodnoty 0
296  void getNextCarDistAndVel(float &nextCarDist,float &nextCarVel,
297  const unsigned int carId,const unsigned int edgeId);
298 
299  // tato metoda overi, zda je cilova pozice na koncove (normalni) hrane pro auto
300  // povolena (vrati true) nebo zakazana (false);
301  // jestlize auto chce skoncit svou predni casti pred bodem stopBeforeJunc
302  // hrany a zaroven svou zadni casti za bodem, ktery urcuje lowBoundForStartStopPosOffset
303  // u hrany (auto by melo byt schopno po vyjezdu ze krizovatky zabrzdit tak, aby v cili
304  // melo temer nulovou rychlost), ma auto povoleni tu skoncit;
305 
306  // Pozn.: Auto bude moci skoncit tam, kde zacalo.
307 
308  // parametry jsou:
309  // stopEdgeId - id koncove hrany
310  // stopOffset - relativni pozice mezi Out a In (in (0,1))
311  // carLength - delka auta
312  bool isCarStopPositionRight(const unsigned int stopEdgeId,const float stopOffset,
313  const float carLength);
314 
315  // metoda, ktera vrati, zda je na zacatku normalni hrany edgeId dostatek
316  // mista pro skupinu aut (ktere na ni chteji vjet), kterych je carCount a ve ktere ma
317  // prvni auto (vzhledem ke smeru hrany) delku fstCarInGroupLength a vsechna ostatni
318  // v ni maximalni moznou delku
319  bool isFreeSpaceForCarGroupOnEdge(const unsigned int edgeId,const float fstCarInGroupLength,unsigned int carCount);
320 
321  // pokud krizovatka je
322  // bez pridavneho jmena velka, je mala - jedna se bud o krizovatku sloucenou z puvodnich
323  // krizovatek pres velmikratke hrany nebo puvodni krizovatku, ktera neni sloucena s jinymi
324  // pres velmi kratke hrany;
325  // ve starsim kodu muze znamenat krizovatka take proste puvodni krizovatku
326  // (TODO oprav starsi komentare, aby neplatilo?);
327  // velka krizovatka vznika spojenim krizovatek pres kratke hrany nebo se jedna o krizovatku,
328  // kolem ktere neni zadna kratka hrana;
329  // nijak se pred simulaci nevypocitavaji (narozdil od malych krizovatek sloucenych pres
330  // velmikratke (ultrakratke) hrany);
331  // pri prujezdu malymi krizovatkami bude auto porad zatacet;
332  // ve velke kriz. bude zatacet pouze v oblastech malych kriz.;
333 
334  // hrany k zamceni se oproti klasickym hranam lisi v nasledujicich bodech:
335  // a) normalni vstupni hranu do male nebo velke krizovatky tvori pouze cast za bodem In,
336  // obdobne normalni vystupni hranu z male ci velke krizovatky predstavuje cast pred
337  // bodem Out
338  // b) jestlize auto jede (pojede) po cele delce kratke hrany, pocita se dvakrat;
339  // je rozdelena na dve u bodu OUT, jedna cast patri ke krizovatce from (nebo te,
340  // do niz se sloucila), druha cast ke krizovatce to (nebo te, do niz se sloucila);
341  // c) pokud neni receno jinak, jsou hrany mezi pro auto vstupni a vystupni hranou do/z
342  // male krizovatky brany jako jedna hrana - sloucena hrana (sklada se z dilcich hran);
343  // pozn.: pokud se ve spojitosti s nejakou hranou budu zminovat o zamykani, odemykani
344  // a podobne, bude ta hrana hrana k zamceni
345  // pozn.: sloucena hrana se povazuje za odemcenou, jestlize jsou vsechny jeji dilci
346  // hrany odemcene
347 
348  // auto se rozhoduje, zda vjede do velke krizovatky
349  // u bodu stopOrGoDecision vstupni normalni hrany;
350  // auto pojede, jestlize:
351  // I. je posledni auto na vstupni hrane
352  // II. a) jsou vsechny hrany mezi hranou, na ktere auto je
353  // a nejblizsi normalni vystupni (pro auto) hranou (vcetne) odemcene nebo
354  // b) pokud je nejaka z vyse zminenych hran zamcena na nejake male krizovatce,
355  // musi jet na te male krizovatce stejnou cestou jako posledni auto,
356  // ktere si u ni zamklo nejake hrany (ta hrana u te male krizovatky muze
357  // byt zamcena, jelikoz uvedena auta v ni pojedou zhruba stejnou rychlosti, kdyz
358  // v ni pojedou stejnou cestou - takze si nebudou zavazet)
359  // III. jestlize je velka krizovatka rizena semafory (v tom pripade se velka krizovatka
360  // sklada pouze z jedne male) na vstupni normalni hrane sviti autu zelena; v opacnem
361  // pripade na vsech malych krizovatkach v te velke muze jet podle pravidla prave ruky
362  // IV. na te vystupni hrane je pro auto dostatek mista;
363  // jen pro velkou krizovatku nerizenou semafory:
364  // jestlize auto na nektere male krizovatce (ve velke krizovatce) muze jet
365  // podle pravidla prave ruky pouze diky deadlocku, musi byt na vystupni
366  // normalni hrane z te velke krizovatky dost mista pro auto s maximalni moznou
367  // delkou (+ rezerva). (dve auta chteji jet na stejnou vystupni normalni hranu; jedno by
368  // mohlo jet pouze diky uvaznuti, druhe by to zvladlo i bez nej; pak prvni auto
369  // musi vyrazit pozdeji nez druhe bez ohledu na jejich delky);
370  // pokud autu zatim nebyl zamitnut vjezd do velke krizovatky a v ceste auta pres
371  // velkou krizovatku je zamcena nejaka hrana, na zacatku vystupni normalni hrany
372  // musi byt za vyse pozadovanym mistem pro auto navic misto pro tolik aut
373  // s maximalni moznou delkou, kolikrat je ta vystupni normalni hrana zamcena
374  // V. jen pro velkou krizovatku nerizenou semafory:
375  // jestlize auto na nektere male krizovatce (ve velke krizovatce) muze jet
376  // podle pravidla prave ruky pouze diky deadlocku, nesmi byt v poslednim snimku
377  // nejakeho auta na zadne te male krizovatce byt odemcena hrana (ve snimku po
378  // odemceni hrany musi mit prednost auta, ktera mohou jet bez uvaznuti, pred
379  // vozidly, ktera to zvladnou jenom s nim)
380 
381  // jestlize auto muze jet (splnuje postupne vsechny predchozi podminky),
382  // zamcou se vsechny zminene hrany (jestlize auto pojede pres
383  // nejake hrany vicekrat, take se tim autem vicekrat zamcou; vicenasobne (2x a vic)
384  // zamceni hrany muze byt zpusobene take tim, ze nejaka hrana z tech hran, pres
385  // ktere auto pojede ve velke krizovatce, jiz byla zamcena),
386  // u malych krizovatek, pres ktere auto pojede, se nastavi cesta, kudy jelo posledni
387  // auto, ktere u nich zamcelo nejakou hranu a vrati se true, v opacnem pripade se
388  // vrati false
389 
390  // Pozn.: Jestlize by se zamykala treba jen pristi hrana (ne vsechny najednou),
391  // hrozilo by, ze se auto svym stredem v dolni podstave ocitne na jim
392  // nezamcene hrane.
393 
394  // parametry:
395  // pPath - ukazatel na vektor, kde jsou ulozeny vsechny krizovatky (jejich id)
396  // v ceste auta
397  // lastJuncInPath - mala krizovatka, ze ktere auto jede, je vyjadrena indexem
398  // v ceste path (na zacatku tedy index 0)
399  // isLastCar - rika, zda auto je posledni na vstupni hrane
400  // isStopedCar - rika, zda auto stoji pred velkou krizovatkou (bude se hodit pri
401  // reseni deadlocku v metode rightHandRule (slouzi pro zjisteni, zda auto muze
402  // jet na nejake male krizovatce v te velke podle PPR))
403  // carLength - delka auta (slouzi ke zjisteni, zda je na vystupni normalni
404  // hrane pro auto dostatek mista)
405  // carId - id auta (potrebne pro metodu rightHandRule)
406  bool lockJuncsEdgesForNewCar(const std::vector<unsigned int> *const pPath,
407  const unsigned int lastJuncInPath,const bool isLastCar,const bool isStopedCar,
408  const float carLength,const unsigned int carId);
409 
410  // najde pro auto (s id == carId) sekvenci kratkych hran (pres ktere auto pojede
411  // v pristi velke krizovatce z Out do In), ktera zacina pristi vystupni hranou
412  // (roads[(*pPath)[lastJuncInPath+1]][(*pPath)[lastJuncInPath+2]]);
413  // u vsech techto hran metoda zaznamena, ze pres ne auto pojede (z Out do In) ve
414  // sve pristi velke krizovatce, je na normalni hrane posledni a je blizko
415  // dalsi krizovatky (tak, ze ostatni auta, ktera pojedou pres casti tech kratkych
416  // hran za jejich body In, zvazuji, zda mu daji prednost)
417 
418  // parametry:
419  // pPath - ukazatel na vektor, kde jsou ulozeny vsechny krizovatky
420  // v ceste auta
421  // lastJuncInPath - mala krizovatka, ze ktere auto jede, je vyjadrena indexem
422  // v ceste path (na zacatku tedy index 0)
423  // carId - id auta
424  void regIncomingCarToShortEdges(const std::vector<unsigned int> *const pPath,
425  const unsigned int lastJuncInPath,const unsigned int carId);
426 
427  // najde pro auto (s id == carId) sekvenci kratkych hran (pres ktere
428  // auto pojede v pristi velke krizovatce z Out do In), ktera zacina
429  // pristi vystupni hranou
430  // (roads[(*pPath)[lastJuncInPath+1]][(*pPath)[lastJuncInPath+2]]);
431  // u vsech techto hran metoda zaznamena, ze auto je na normalni hrane
432  // posledni a stoji
433 
434  // parametry:
435  // pPath - ukazatel na vektor, kde jsou ulozeny vsechny krizovatky
436  // v ceste auta
437  // lastJuncInPath - mala krizovatka, ze ktere auto jede, je vyjadrena indexem
438  // v ceste path (na zacatku tedy index 0)
439  // carId - id auta
440  void setStopedIncomingCarToShortEdges(const std::vector<unsigned int> *const pPath,
441  const unsigned int lastJuncInPath,const unsigned int carId);
442 
443  // tato metoda resi pravidlo prave ruky, auto vjizdi do male krizovatky
444  // pres vstupni hranu inEdge;
445 
446  // auto ma povoleni jet podle pravidla prave ruky, jestlize:
447  // I. pro vsechny jeji normalni a kratke vstupni hrany, pres ktere auto chce jet a
448  // se kterymi svira hrana, pres kterou chce vjet vozidlo do krizovatky, uhel mensi
449  // nez 135°, plati:
450  // a) pro normalni hranu: posledni auto je pred bodem, ktery je vzdalenost d
451  // pred bodem stopOrGoDecision (tedy krome tohoto auta samotneho - auto si
452  // nebude davat prednost samo sobe - to by se mohlo stat, kdyz by auto jelo
453  // pres cyklus kratkych hran a nebylo by to osetrene - i s timto autem by se
454  // pocitalo);
455  // (d je vzdalenost toho auta potrebna ke zpomaleni na 0-ovou rychlost +
456  // 2*prumerna delka auta)
457  // b) pro kratkou hranu: neexistuje zadne auto, ktere pres ni pojede (z Out do In)
458  // ve sve pristi velke krizovatce, je posledni na normalni hrane a nachazi se tak
459  // blizko dalsi krizovatky, ze mu toto vozidlo musi dat prednost
460  // (toto auto se nepocita -> auto nebude davat prednost samo sobe - to by
461  // se mohlo stat, kdyz by auto jelo pres cyklus kratkych hran a i toto
462  // auto by se pocitalo)
463  // II. vozidlo stoji na hrane jako posledni a na krizovatce jsou uvazla auta
464  // (nastal deadlock)
465 
466  // jestlize auto to povoleni ma, vrati se true, v opacnem pripade false
467 
468  // parametry:
469  // withDeadlock - rika zda auto ma povoleni jet podle prave ruky pouze
470  // diky uvaznuti (deadlock)
471  // inEdge - vstupni hrana pro auto do male krizovatky
472  // outEdge - vystupni hrana pro auto z male krizovatky
473  // juncId - id male krizovatky
474  // isCarLastStoped - rika, zda auto, pro ktere se zjistuje PPR,
475  // stoji pred velkou krizovatkou jako posledni auto na hrane,
476  // bude se hodit pri reseni deadlocku
477  // carId - id auta
478  bool rightHandRule(bool &withDeadlock,const unsigned int inEdge,const unsigned int outEdge,
479  const unsigned int juncId,const bool isCarLastStoped,const unsigned int carId);
480 
481  // Tato metoda odemyka (ne vzdy uplne odemce) minulou hranu k zamceni -
482  // dekrementuje u ni lockCount, viz lockCount u JuncsEdge.
483 
484  // Jestlize je auto na vystupni hrane a doslo k preskoceni prilis uzke sloucene hrany
485  // (to se muze stavat pri nizkem fps), bude odemykana ta sloucena i vstupni hrana.
486 
487  // Pozn.: Auto muze byt poprve na sloucene hrane, i kdyz neni na jeji prvni dilci
488  // hrane po vstupni hrane.
489 
490  // Metoda predpoklada, ze je volana pouze tehdy, jestlize doslo k prechodu pres hranu k zamceni.
491 
492  // Sloucena hrana se povazuje za odemcenou, jestlize jsou vsechny jeji dilci hrany odemcene.
493 
494  // parametry:
495  // edgeId - aktualni hrana, na ktere je auto;
496  // lastJuncId - minula krizovatka, bude urcovat vstupni hranu do krizovatky,
497  // u ktere je auto
498  // nextJuncId - id male krizovatky, u ktere je auto
499  // nextNextJuncId - id male kriz. po ni
500  // mergedEdgeSkiped - rika, zda doslo k preskoceni prilis uzke sloucene hrany
501  // carId - id auta
502  void decreaseLockCountForPrevEdge(const unsigned int edgeId,
503  const unsigned int lastJuncId,const unsigned int nextJuncId,
504  const unsigned int nextNextJuncId,const bool mergedEdgeSkiped,
505  const unsigned int carId);
506 
507  // tato metoda vypocita doporucenou rychlost na krizovatce s id juncId
508  // pro auto, ktere jede ze vstupni hrany inEdge do vystupni hrany outEdge
509  void computeRecVelocityOnJunc(float &recVel,const unsigned int juncId,
510  const unsigned int inEdge,const unsigned int outEdge);
511 
512  // metoda urci typ zatoceni (doleva, doprava, rovne) na krizovatce juncId,
513  // na ktere auto jede ze vtupni hrany inEdge na vystupni hranu outEdge,
514  // vysledek vrati v prvnim parametru
515  void getTurnOnJunc(unsigned int &turnOnJunc,const unsigned int juncId,
516  const unsigned int inEdge,const unsigned int outEdge);
517 
518  // metoda, ktera na zacatku simulace nahodne vygeneruje auta,
519  // bude jich numOfGenCars; parametr genShortestPath urcuje, zda vygenerovane cesty
520  // maji byt nejkratsi (ze startovni do koncove hrany)
521  void generateCars(const unsigned int numOfGenCars,const bool genShortestPath);
522 
523  // pro debugovani umisti na bod malou zelenou krychlicku
524  void showPoint(const osg::Vec3 &point);
525 
526  // rika, zda u male krizovatky juncId vznikl deadlock (uvzaznuti), vznikl jestlize:
527  // a) jsou vsechny vstupni a vystupni hrany krizovatky odemcene
528  // b) na zadne vstupni normalni hrane neni auto, ktere je na ni posledni
529  // a ktere jede (nestoji)
530  // c) na zacatky vsech vystupnich normalnich hran se vejde auto
531  // s maximalni moznou delkou (ke ktere je pripoctena mala rezerva)
532  // (auto libovolne delky, ktere ceka pouze na to, az se pro nej na vystupni hrane
533  // uvolni misto, musi projet krizovatku drive nez vozidlo, ktere pres ni muze
534  // jet pouze diky uvaznuti) nebo na nich musi prvni auto stat
535  // d) pro zadnou kratkou vstupni hranu neexistuje auto, ktere pres ni pojede (z Out
536  // do In) ve sve pristi velke krizovatce, je na normalni hrane posledni, nachazi se
537  // blizko dalsi krizovatky (tak, ze auta u krizovatky juncId zvazuji, zda mu nedaji
538  // prednost) a ktere jede (nestoji)
539  // e) v poslednim snimku nedoslo k odemceni hrany u krizovatky (pokud se na
540  // krizovatce nebo v jeji tesne blizkosti neco deje, neni zablokovana)
541 
542  // Pozn.: ma vyznam pouze pro male krizovatky ve velkych krizovatkach, ktere nejsou
543  // rizeny semafory; jestlize je velka krizovatka rizena semafory, je vzdy tvorena pouze
544  // jednou malou krizovatkou, na ktere nemuze vzniknout deadlock
545  bool isDeadlock(const unsigned int juncId);
546 
547  // tato metoda nacte ze vstupniho XML souboru z elementu TLparameters
548  // cesty k souborum s geometriemi (modely) casti semaforu, ktere nasledne take nacte,
549  // dale take nacte vzdalenost mezi stredy barevnych svetel semaforu
550  void loadTLparameters(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *const pTLparametersNode);
551 
552  // metoda, ktera vytvori semafory na krizovatkach, ktere jsou rizeny semafory
553  void createTrafficLights(void);
554 
555  // zkontroluje, zda krizovatka (mala) s id juncId splnuje kriteria pro krizovatku se semafory
556  // (pro jednoduchost se mala krizovatka, ktera je rizena semafory, vyskytuje ve
557  // velke krizovatce vzdy sama a propojuje 3-4 silnice, v nichz jsou alespon 2 normalni
558  // hrany, ktere smeruji do krizovatky a alespon 1 normalni hrana, ktera smeruje ze krizovatky);
559  // kriteria jsou splnena -> vrati true, jinak false
560  bool isValidJuncWithTLs(unsigned int juncId);
561 
562  DECLARE_INPUT(InUnregCarForEdge, MessageCarEdge);
563  DECLARE_INPUT(InAddForEdgeRegisteredCarToPutAsideCars, MessageCarEdge);
564 
565  DECLARE_REQUEST_INPUT(InGetReady, MessageVoid, MessageBool);
568  DECLARE_REQUEST_INPUT(InGetEdgeOutInVec, MessageUnsignedInt, MessageVec3);
569  DECLARE_REQUEST_INPUT(InGetEdgeNormal, MessageUnsignedInt, MessageVec3);
571  DECLARE_REQUEST_INPUT(InCheckCarStopPosition, MessageCarEdgeData, MessageBool);
572  DECLARE_REQUEST_INPUT(InGetStartOrStopEdgeFromRoadAndDirection, MessageRoadAndDir, MessageUnsignedInt);
573  DECLARE_REQUEST_INPUT(InRegCarForEdge, MessageCarEdgeData, MessageBool);
574  DECLARE_REQUEST_INPUT(InGetRecVelOnJunc, MessageFirst3Juncs, MessageFloat);
575  DECLARE_REQUEST_INPUT(InGetTurnOnJunc, MessageFirst3Juncs, MessageUnsignedInt);
576  DECLARE_REQUEST_INPUT(InIsCarFstPutAsideOnEdge, MessageCarEdge, MessageBool);
577  DECLARE_REQUEST_INPUT(InRegisterPutAsideCarForEdge, MessageCarEdgeData, MessageBool);
579  };
580 
581 }
582 
583 #endif
584 
585 
586 
587