SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NBRequest.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // This class computes the logic of a junction
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <vector>
36 #include <set>
37 #include <algorithm>
38 #include <bitset>
39 #include <sstream>
40 #include <map>
41 #include <cassert>
43 #include <utils/common/ToString.h>
46 #include "NBEdge.h"
47 #include "NBContHelper.h"
48 #include "NBTrafficLightLogic.h"
50 #include "NBNode.h"
51 #include "NBRequest.h"
52 
53 #ifdef CHECK_MEMORY_LEAKS
54 #include <foreign/nvwa/debug_new.h>
55 #endif // CHECK_MEMORY_LEAKS
56 
57 
58 // ===========================================================================
59 // static member variables
60 // ===========================================================================
61 size_t NBRequest::myGoodBuilds = 0;
62 size_t NBRequest::myNotBuild = 0;
63 
64 
65 // ===========================================================================
66 // method definitions
67 // ===========================================================================
69  NBNode* junction,
70  const EdgeVector& all,
71  const EdgeVector& incoming,
72  const EdgeVector& outgoing,
73  const NBConnectionProhibits& loadedProhibits)
74  : myJunction(junction),
75  myAll(all), myIncoming(incoming), myOutgoing(outgoing) {
76  size_t variations = myIncoming.size() * myOutgoing.size();
77  // build maps with information which forbidding connection were
78  // computed and what's in there
79  myForbids.reserve(variations);
80  myDone.reserve(variations);
81  for (size_t i = 0; i < variations; i++) {
82  myForbids.push_back(LinkInfoCont(variations, false));
83  myDone.push_back(LinkInfoCont(variations, false));
84  }
85  // insert loaded prohibits
86  for (NBConnectionProhibits::const_iterator j = loadedProhibits.begin(); j != loadedProhibits.end(); j++) {
87  NBConnection prohibited = (*j).first;
88  bool ok1 = prohibited.check(ec);
89  if (find(myIncoming.begin(), myIncoming.end(), prohibited.getFrom()) == myIncoming.end()) {
90  ok1 = false;
91  }
92  if (find(myOutgoing.begin(), myOutgoing.end(), prohibited.getTo()) == myOutgoing.end()) {
93  ok1 = false;
94  }
95  int idx1 = 0;
96  if (ok1) {
97  idx1 = getIndex(prohibited.getFrom(), prohibited.getTo());
98  if (idx1 < 0) {
99  ok1 = false;
100  }
101  }
102  const NBConnectionVector& prohibiting = (*j).second;
103  for (NBConnectionVector::const_iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
104  NBConnection sprohibiting = *k;
105  bool ok2 = sprohibiting.check(ec);
106  if (find(myIncoming.begin(), myIncoming.end(), sprohibiting.getFrom()) == myIncoming.end()) {
107  ok2 = false;
108  }
109  if (find(myOutgoing.begin(), myOutgoing.end(), sprohibiting.getTo()) == myOutgoing.end()) {
110  ok2 = false;
111  }
112  if (ok1 && ok2) {
113  int idx2 = getIndex(sprohibiting.getFrom(), sprohibiting.getTo());
114  if (idx2 < 0) {
115  ok2 = false;
116  } else {
117  myForbids[idx2][idx1] = true;
118  myDone[idx2][idx1] = true;
119  myDone[idx1][idx2] = true;
120  myGoodBuilds++;
121  }
122  } else {
123  std::string pfID = prohibited.getFrom() != 0 ? prohibited.getFrom()->getID() : "UNKNOWN";
124  std::string ptID = prohibited.getTo() != 0 ? prohibited.getTo()->getID() : "UNKNOWN";
125  std::string bfID = sprohibiting.getFrom() != 0 ? sprohibiting.getFrom()->getID() : "UNKNOWN";
126  std::string btID = sprohibiting.getTo() != 0 ? sprohibiting.getTo()->getID() : "UNKNOWN";
127  WRITE_WARNING("could not prohibit " + pfID + "->" + ptID + " by " + bfID + "->" + btID);
128  myNotBuild++;
129  }
130  }
131  }
132  // ok, check whether someone has prohibited two links vice versa
133  // (this happens also in some Vissim-networks, when edges are joined)
134  size_t no = myIncoming.size() * myOutgoing.size();
135  for (size_t s1 = 0; s1 < no; s1++) {
136  for (size_t s2 = s1 + 1; s2 < no; s2++) {
137  // not set, yet
138  if (!myDone[s1][s2]) {
139  continue;
140  }
141  // check whether both prohibit vice versa
142  if (myForbids[s1][s2] && myForbids[s2][s1]) {
143  // mark unset - let our algorithm fix it later
144  myDone[s1][s2] = false;
145  myDone[s2][s1] = false;
146  }
147  }
148  }
149 }
150 
151 
153 
154 
155 void
157  EdgeVector::const_iterator i, j;
158  for (i = myIncoming.begin(); i != myIncoming.end(); i++) {
159  for (j = myOutgoing.begin(); j != myOutgoing.end(); j++) {
160  computeRightOutgoingLinkCrossings(leftHanded, *i, *j);
161  computeLeftOutgoingLinkCrossings(leftHanded, *i, *j);
162  }
163  }
164  // reset signalised/non-signalised dependencies
165  resetSignalised();
166  // reset foes it the number of lanes matches (or exceeds) the number of incoming connections
168 }
169 
170 
171 void
173  EdgeVector::const_iterator pfrom = find(myAll.begin(), myAll.end(), from);
174  while (*pfrom != to) {
176  if ((*pfrom)->getToNode() == myJunction) {
177  EdgeVector::const_iterator pto = find(myAll.begin(), myAll.end(), to);
178  while (*pto != from) {
179  if (!((*pto)->getToNode() == myJunction)) {
180  setBlocking(leftHanded, from, to, *pfrom, *pto);
181  }
183  }
184  }
185  }
186 }
187 
188 
189 void
191  EdgeVector::const_iterator pfrom = find(myAll.begin(), myAll.end(), from);
192  while (*pfrom != to) {
193  NBContHelper::nextCW(myAll, pfrom);
194  if ((*pfrom)->getToNode() == myJunction) {
195  EdgeVector::const_iterator pto = find(myAll.begin(), myAll.end(), to);
196  while (*pto != from) {
197  if (!((*pto)->getToNode() == myJunction)) {
198  setBlocking(leftHanded, from, to, *pfrom, *pto);
199  }
201  }
202  }
203  }
204 }
205 
206 
207 void
208 NBRequest::setBlocking(bool leftHanded,
209  NBEdge* from1, NBEdge* to1,
210  NBEdge* from2, NBEdge* to2) {
211  // check whether one of the links has a dead end
212  if (to1 == 0 || to2 == 0) {
213  return;
214  }
215  // get the indices of both links
216  int idx1 = getIndex(from1, to1);
217  int idx2 = getIndex(from2, to2);
218  if (idx1 < 0 || idx2 < 0) {
219  return; // !!! error output? did not happend, yet
220  }
221  // check whether the link crossing has already been checked
222  assert((size_t) idx1 < myIncoming.size()*myOutgoing.size());
223  if (myDone[idx1][idx2]) {
224  return;
225  }
226  // mark the crossings as done
227  myDone[idx1][idx2] = true;
228  myDone[idx2][idx1] = true;
229  // special case all-way stop
231  // all ways forbid each other. Conflict resolution happens via arrival time
232  myForbids[idx1][idx2] = true;
233  myForbids[idx2][idx1] = true;
234  return;
235  }
236  // check if one of the links is a turn; this link is always not priorised
237  // true for right-before-left and priority
238  if (from1->isTurningDirectionAt(myJunction, to1)) {
239  myForbids[idx2][idx1] = true;
240  return;
241  }
242  if (from2->isTurningDirectionAt(myJunction, to2)) {
243  myForbids[idx1][idx2] = true;
244  return;
245  }
246  // check the priorities if required by node type
248  int from1p = from1->getJunctionPriority(myJunction);
249  int from2p = from2->getJunctionPriority(myJunction);
250  // check if one of the connections is higher priorised when incoming into
251  // the junction, the connection road will yield
252  if (from1p > from2p) {
253  myForbids[idx1][idx2] = true;
254  return;
255  }
256  if (from2p > from1p) {
257  myForbids[idx2][idx1] = true;
258  return;
259  }
260  }
261 
262  // check whether one of the connections is higher priorised on
263  // the outgoing edge when both roads are high priorised
264  // the connection with the lower priorised outgoing edge will lead
265  // should be valid for priority junctions only
266  /*
267  if (from1p > 0 && from2p > 0) {
268  assert(myJunction->getType() != NODETYPE_RIGHT_BEFORE_LEFT);
269  int to1p = to1->getJunctionPriority(myJunction);
270  int to2p = to2->getJunctionPriority(myJunction);
271  if (to1p > to2p) {
272  myForbids[idx1][idx2] = true;
273  return;
274  }
275  if (to2p > to1p) {
276  myForbids[idx2][idx1] = true;
277  return;
278  }
279  }
280  */
281 
282  // compute the yielding due to the right-before-left rule
283  // get the position of the incoming lanes in the junction-wheel
284  EdgeVector::const_iterator c1 = find(myAll.begin(), myAll.end(), from1);
286  // go through next edges clockwise...
287  while (*c1 != from1 && *c1 != from2) {
288  if (*c1 == to2) {
289  // if we encounter to2 the second one prohibits the first
290  if (!leftHanded) {
291  myForbids[idx2][idx1] = true;
292  } else {
293  myForbids[idx1][idx2] = true;
294  }
295  return;
296  }
298  }
299  // get the position of the incoming lanes in the junction-wheel
300  EdgeVector::const_iterator c2 = find(myAll.begin(), myAll.end(), from2);
302  // go through next edges clockwise...
303  while (*c2 != from2 && *c2 != from1) {
304  if (*c2 == to1) {
305  // if we encounter to1 the second one prohibits the first
306  if (!leftHanded) {
307  myForbids[idx1][idx2] = true;
308  } else {
309  myForbids[idx2][idx1] = true;
310  }
311  return;
312  }
314  }
315 }
316 
317 
318 size_t
320  EdgeVector::const_iterator p = find(myAll.begin(), myAll.end(), from);
321  size_t ret = 0;
322  do {
323  ret++;
324  if (p == myAll.begin()) {
325  p = myAll.end();
326  }
327  p--;
328  } while (*p != to);
329  return ret;
330 }
331 
332 
333 void
334 NBRequest::writeLogic(std::string /* key */, OutputDevice& into, const bool checkLaneFoes) const {
335  int pos = 0;
336  EdgeVector::const_iterator i;
337  for (i = myIncoming.begin(); i != myIncoming.end(); i++) {
338  unsigned int noLanes = (*i)->getNumLanes();
339  for (unsigned int k = 0; k < noLanes; k++) {
340  pos = writeLaneResponse(into, *i, k, pos, checkLaneFoes);
341  }
342  }
343 }
344 
345 
346 void
348  // go through possible prohibitions
349  for (EdgeVector::const_iterator i11 = myIncoming.begin(); i11 != myIncoming.end(); i11++) {
350  unsigned int noLanesEdge1 = (*i11)->getNumLanes();
351  for (unsigned int j1 = 0; j1 < noLanesEdge1; j1++) {
352  std::vector<NBEdge::Connection> el1 = (*i11)->getConnectionsFromLane(j1);
353  for (std::vector<NBEdge::Connection>::iterator i12 = el1.begin(); i12 != el1.end(); ++i12) {
354  int idx1 = getIndex((*i11), (*i12).toEdge);
355  if (idx1 < 0) {
356  continue;
357  }
358  // go through possibly prohibited
359  for (EdgeVector::const_iterator i21 = myIncoming.begin(); i21 != myIncoming.end(); i21++) {
360  unsigned int noLanesEdge2 = (*i21)->getNumLanes();
361  for (unsigned int j2 = 0; j2 < noLanesEdge2; j2++) {
362  std::vector<NBEdge::Connection> el2 = (*i21)->getConnectionsFromLane(j2);
363  for (std::vector<NBEdge::Connection>::iterator i22 = el2.begin(); i22 != el2.end(); i22++) {
364  int idx2 = getIndex((*i21), (*i22).toEdge);
365  if (idx2 < 0) {
366  continue;
367  }
368  // check
369  // same incoming connections do not prohibit each other
370  if ((*i11) == (*i21)) {
371  myForbids[idx1][idx2] = false;
372  myForbids[idx2][idx1] = false;
373  continue;
374  }
375  // check other
376  // if both are non-signalised or both are signalised
377  if (((*i12).tlID == "" && (*i22).tlID == "")
378  ||
379  ((*i12).tlID != "" && (*i22).tlID != "")) {
380  // do nothing
381  continue;
382  }
383  // supposing, we don not have to
384  // brake if we are no foes
385  if (!foes(*i11, (*i12).toEdge, *i21, (*i22).toEdge)) {
386  continue;
387  }
388  // otherwise:
389  // the non-signalised must break
390  if ((*i12).tlID != "") {
391  myForbids[idx1][idx2] = true;
392  myForbids[idx2][idx1] = false;
393  } else {
394  myForbids[idx1][idx2] = false;
395  myForbids[idx2][idx1] = true;
396  }
397  }
398  }
399  }
400  }
401  }
402  }
403 }
404 
405 
406 std::pair<unsigned int, unsigned int>
408  unsigned int noLanes = 0;
409  unsigned int noLinks = 0;
410  for (EdgeVector::const_iterator i = myIncoming.begin();
411  i != myIncoming.end(); i++) {
412  unsigned int noLanesEdge = (*i)->getNumLanes();
413  for (unsigned int j = 0; j < noLanesEdge; j++) {
414  unsigned int numConnections = (unsigned int)(*i)->getConnectionsFromLane(j).size();
415  noLinks += numConnections;
416  if (numConnections > 0) {
417  noLanes++;
418  }
419  }
420  }
421  return std::make_pair(noLanes, noLinks);
422 }
423 
424 
425 bool
426 NBRequest::foes(const NBEdge* const from1, const NBEdge* const to1,
427  const NBEdge* const from2, const NBEdge* const to2) const {
428  // unconnected edges do not forbid other edges
429  if (to1 == 0 || to2 == 0) {
430  return false;
431  }
432  // get the indices
433  int idx1 = getIndex(from1, to1);
434  int idx2 = getIndex(from2, to2);
435  if (idx1 < 0 || idx2 < 0) {
436  return false; // sure? (The connection does not exist within this junction)
437  }
438  assert((size_t) idx1 < myIncoming.size()*myOutgoing.size());
439  assert((size_t) idx2 < myIncoming.size()*myOutgoing.size());
440  return myForbids[idx1][idx2] || myForbids[idx2][idx1];
441 }
442 
443 
444 bool
445 NBRequest::forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
446  const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
447  bool regardNonSignalisedLowerPriority) const {
448  // unconnected edges do not forbid other edges
449  if (possProhibitorTo == 0 || possProhibitedTo == 0) {
450  return false;
451  }
452  // get the indices
453  int possProhibitorIdx = getIndex(possProhibitorFrom, possProhibitorTo);
454  int possProhibitedIdx = getIndex(possProhibitedFrom, possProhibitedTo);
455  if (possProhibitorIdx < 0 || possProhibitedIdx < 0) {
456  return false; // sure? (The connection does not exist within this junction)
457  }
458  assert((size_t) possProhibitorIdx < myIncoming.size()*myOutgoing.size());
459  assert((size_t) possProhibitedIdx < myIncoming.size()*myOutgoing.size());
460  // check simple right-of-way-rules
461  if (!regardNonSignalisedLowerPriority) {
462  return myForbids[possProhibitorIdx][possProhibitedIdx];
463  }
464  // if its not forbidden, report
465  if (!myForbids[possProhibitorIdx][possProhibitedIdx]) {
466  return false;
467  }
468  // do not forbid a signalised stream by a non-signalised
469  if (!possProhibitorFrom->hasSignalisedConnectionTo(possProhibitorTo)) {
470  return false;
471  }
472  return true;
473 }
474 
475 
476 int
478  int fromLane, int pos, const bool checkLaneFoes) const {
479  std::vector<NBEdge::Connection> connected = from->getConnectionsFromLane(fromLane);
480  for (std::vector<NBEdge::Connection>::iterator j = connected.begin(); j != connected.end(); j++) {
481  assert((*j).toEdge != 0);
483  od.writeAttr(SUMO_ATTR_INDEX, pos++);
484  od.writeAttr(SUMO_ATTR_RESPONSE, getResponseString(from, (*j).toEdge, fromLane, (*j).toLane, (*j).mayDefinitelyPass, checkLaneFoes));
485  od.writeAttr(SUMO_ATTR_FOES, getFoesString(from, (*j).toEdge, (*j).toLane, checkLaneFoes));
486  if (!OptionsCont::getOptions().getBool("no-internal-links")) {
487  od.writeAttr(SUMO_ATTR_CONT, j->haveVia);
488  }
489  od.closeTag();
490  }
491  return pos;
492 }
493 
494 
495 std::string
496 NBRequest::getResponseString(const NBEdge* const from, const NBEdge* const to,
497  int fromLane, int toLane, bool mayDefinitelyPass, const bool checkLaneFoes) const {
498  int idx = 0;
499  if (to != 0) {
500  idx = getIndex(from, to);
501  }
502  std::string result;
503  for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin(); i != myIncoming.rend(); i++) {
504  //const std::vector<NBEdge::Connection> &allConnections = (*i)->getConnections();
505  unsigned int noLanes = (*i)->getNumLanes();
506  for (int j = noLanes; j-- > 0;) {
507  std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
508  int size = (int) connected.size();
509  for (int k = size; k-- > 0;) {
510  if (mayDefinitelyPass) {
511  result += '0';
512  } else if ((*i) == from && fromLane == j) {
513  // do not prohibit a connection by others from same lane
514  result += '0';
515  } else {
516  assert(k < (int) connected.size());
517  assert((size_t) idx < myIncoming.size()*myOutgoing.size());
518  assert(connected[k].toEdge != 0);
519  assert((size_t) getIndex(*i, connected[k].toEdge) < myIncoming.size()*myOutgoing.size());
520  // check whether the connection is prohibited by another one
521  if (myForbids[getIndex(*i, connected[k].toEdge)][idx] &&
522  (!checkLaneFoes || laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane))) {
523  result += '1';
524  continue;
525  }
526  result += '0';
527  }
528  }
529  }
530  }
531  return result;
532 }
533 
534 
535 std::string
536 NBRequest::getFoesString(NBEdge* from, NBEdge* to, int toLane, const bool checkLaneFoes) const {
537  // remember the case when the lane is a "dead end" in the meaning that
538  // vehicles must choose another lane to move over the following
539  // junction
540  // !!! move to forbidden
541  std::string result;
542  for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin();
543  i != myIncoming.rend(); i++) {
544 
545  unsigned int noLanes = (*i)->getNumLanes();
546  for (unsigned int j = noLanes; j-- > 0;) {
547  std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
548  int size = (int) connected.size();
549  for (int k = size; k-- > 0;) {
550  if (foes(from, to, (*i), connected[k].toEdge) &&
551  (!checkLaneFoes || laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane))) {
552  result += '1';
553  } else {
554  result += '0';
555  }
556  }
557  }
558  }
559  return result;
560 }
561 
562 
563 bool
564 NBRequest::laneConflict(const NBEdge* from, const NBEdge* to, int toLane,
565  const NBEdge* prohibitorFrom, const NBEdge* prohibitorTo, int prohibitorToLane) const {
566  if (to != prohibitorTo) {
567  return true;
568  }
569  // since we know that the edge2edge connections are in conflict, the only
570  // situation in which the lane2lane connections can be conflict-free is, if
571  // they target the same edge but do not cross each other
573  from->getAngleAtNode(from->getToNode()), to->getAngleAtNode(to->getFromNode()));
574  if (angle == 180) {
575  angle = -180; // turnarounds are left turns
576  }
577  const SUMOReal prohibitorAngle = NBHelpers::relAngle(
578  prohibitorFrom->getAngleAtNode(prohibitorFrom->getToNode()), to->getAngleAtNode(to->getFromNode()));
579  const bool rightOfProhibitor = prohibitorFrom->isTurningDirectionAt(prohibitorFrom->getToNode(), to)
580  || (angle > prohibitorAngle && !from->isTurningDirectionAt(from->getToNode(), to));
581  return rightOfProhibitor ? toLane >= prohibitorToLane : toLane <= prohibitorToLane;
582 }
583 
584 
585 int
586 NBRequest::getIndex(const NBEdge* const from, const NBEdge* const to) const {
587  EdgeVector::const_iterator fp = find(myIncoming.begin(), myIncoming.end(), from);
588  EdgeVector::const_iterator tp = find(myOutgoing.begin(), myOutgoing.end(), to);
589  if (fp == myIncoming.end() || tp == myOutgoing.end()) {
590  return -1;
591  }
592  // compute the index
593  return (int)(distance(myIncoming.begin(), fp) * myOutgoing.size() + distance(myOutgoing.begin(), tp));
594 }
595 
596 
597 std::ostream&
598 operator<<(std::ostream& os, const NBRequest& r) {
599  size_t variations = r.myIncoming.size() * r.myOutgoing.size();
600  for (size_t i = 0; i < variations; i++) {
601  os << i << ' ';
602  for (size_t j = 0; j < variations; j++) {
603  if (r.myForbids[i][j]) {
604  os << '1';
605  } else {
606  os << '0';
607  }
608  }
609  os << std::endl;
610  }
611  os << std::endl;
612  return os;
613 }
614 
615 
616 bool
617 NBRequest::mustBrake(const NBEdge* const from, const NBEdge* const to) const {
618  // vehicles which do not have a following lane must always decelerate to the end
619  if (to == 0) {
620  return true;
621  }
622  // get the indices
623  int idx2 = getIndex(from, to);
624  if (idx2 == -1) {
625  return false;
626  }
627  // go through all (existing) connections;
628  // check whether any of these forbids the one to determine
629  assert((size_t) idx2 < myIncoming.size()*myOutgoing.size());
630  for (size_t idx1 = 0; idx1 < myIncoming.size()*myOutgoing.size(); idx1++) {
631  //assert(myDone[idx1][idx2]);
632  if (myDone[idx1][idx2] && myForbids[idx1][idx2]) {
633  return true;
634  }
635  }
636  return false;
637 }
638 
639 
640 bool
641 NBRequest::mustBrake(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
642  const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo) const {
643  // get the indices
644  int idx1 = getIndex(possProhibitorFrom, possProhibitorTo);
645  int idx2 = getIndex(possProhibitedFrom, possProhibitedTo);
646  return (myForbids[idx2][idx1]);
647 }
648 
649 
650 void
652  // check if any errors occured on build the link prohibitions
653  if (myNotBuild != 0) {
654  WRITE_WARNING(toString(myNotBuild) + " of " + toString(myNotBuild + myGoodBuilds) + " prohibitions were not build.");
655  }
656 }
657 
658 
659 void
661  // map from edge to number of incoming connections
662  std::map<NBEdge*, size_t> incomingCount; // initialized to 0
663  // map from edge to indices of approached lanes
664  std::map<NBEdge*, std::set<int> > approachedLanes;
665  // map from edge to list of incoming edges
666  std::map<NBEdge*, EdgeVector> incomingEdges;
667  for (EdgeVector::const_iterator it_e = myIncoming.begin(); it_e != myIncoming.end(); it_e++) {
668  const std::vector<NBEdge::Connection> connections = (*it_e)->getConnections();
669  for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); ++it_c) {
670  incomingCount[it_c->toEdge]++;
671  approachedLanes[it_c->toEdge].insert(it_c->toLane);
672  incomingEdges[it_c->toEdge].push_back(*it_e);
673  }
674  }
675  for (std::map<NBEdge*, size_t>::iterator it = incomingCount.begin(); it != incomingCount.end(); ++it) {
676  NBEdge* to = it->first;
677  // we cannot test against to->getNumLanes() since not all lanes may be used
678  if (approachedLanes[to].size() >= it->second) {
679  EdgeVector& incoming = incomingEdges[to];
680  // make these connections mutually unconflicting
681  for (EdgeVector::iterator it_e1 = incoming.begin(); it_e1 != incoming.end(); ++it_e1) {
682  for (EdgeVector::iterator it_e2 = incoming.begin(); it_e2 != incoming.end(); ++it_e2) {
683  myForbids[getIndex(*it_e1, to)][getIndex(*it_e2, to)] = false;
684  }
685  }
686  }
687  }
688 }
689 
690 /****************************************************************************/
691 
int getIndex(const NBEdge *const from, const NBEdge *const to) const
Returns the index to the internal combination container for the given edge combination.
Definition: NBRequest.cpp:586
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool check(const NBEdgeCont &ec)
checks whether the edges are still valid
void computeLeftOutgoingLinkCrossings(bool leftHanded, NBEdge *from, NBEdge *to)
Definition: NBRequest.cpp:190
std::vector< bool > LinkInfoCont
Definition: NBRequest.h:228
NBRequest(const NBEdgeCont &ec, NBNode *junction, const EdgeVector &all, const EdgeVector &incoming, const EdgeVector &outgoing, const NBConnectionProhibits &loadedProhibits)
Definition: NBRequest.cpp:68
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether &quot;prohibited&quot; flow must let &quot;prohibitor&quot; flow pass.
Definition: NBRequest.cpp:445
The representation of a single edge during network building.
Definition: NBEdge.h:71
NBNode * myJunction
the node the request is assigned to
Definition: NBRequest.h:215
const EdgeVector & myOutgoing
Definition: NBRequest.h:224
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isTurningDirectionAt(const NBNode *n, const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:1575
void writeLogic(std::string key, OutputDevice &into, const bool checkLaneFoes) const
Definition: NBRequest.cpp:334
std::vector< Connection > getConnectionsFromLane(unsigned int lane) const
Returns connections from a given lane.
Definition: NBEdge.cpp:706
NBEdge * getFrom() const
returns the from-edge (start of the connection)
std::string getResponseString(const NBEdge *const from, const NBEdge *const to, int fromLane, int toLane, bool mayDefinitelyPass, const bool checkLaneFoes) const
Writes the response of a certain link.
Definition: NBRequest.cpp:496
std::string getFoesString(NBEdge *from, NBEdge *to, int toLane, const bool checkLaneFoes) const
Definition: NBRequest.cpp:536
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
size_t distanceCounterClockwise(NBEdge *from, NBEdge *to)
Definition: NBRequest.cpp:319
const EdgeVector & myIncoming
Definition: NBRequest.h:221
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
CombinationsCont myDone
Definition: NBRequest.h:241
static void reportWarnings()
reports warnings if any occured
Definition: NBRequest.cpp:651
const std::string & getID() const
Returns the id.
Definition: Named.h:60
void buildBitfieldLogic(bool leftHanded)
Definition: NBRequest.cpp:156
bool mustBrake(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo) const
Returns the information whether &quot;prohibited&quot; flow must let &quot;prohibitor&quot; flow pass.
Definition: NBRequest.cpp:641
bool laneConflict(const NBEdge *from, const NBEdge *to, int toLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorToLane) const
return whether the given laneToLane connections prohibit each other under the assumption that the edg...
Definition: NBRequest.cpp:564
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:202
Information within the junction logic which internal lanes block external.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
const EdgeVector & myAll
Definition: NBRequest.h:218
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
Definition: NBEdge.cpp:1101
void setBlocking(bool leftHanded, NBEdge *from1, NBEdge *to1, NBEdge *from2, NBEdge *to2)
Definition: NBRequest.cpp:208
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:357
static size_t myNotBuild
Definition: NBRequest.h:244
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
int writeLaneResponse(OutputDevice &od, NBEdge *from, int lane, int pos, const bool checkLaneFoes) const
writes the response of a certain lane Returns the next link index within the junction ...
Definition: NBRequest.cpp:477
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:38
NBEdge * getTo() const
returns the to-edge (end of the connection)
Represents a single node (junction) during network building.
Definition: NBNode.h:74
bool hasSignalisedConnectionTo(const NBEdge *const e) const
Definition: NBEdge.cpp:1857
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
Definition: NBRequest.cpp:426
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:221
static size_t myGoodBuilds
Definition: NBRequest.h:244
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
Definition: NBHelpers.cpp:62
std::ostream & operator<<(std::ostream &os, const MTRand &mtrand)
Information whether the detector shall be continued on the folowing lanes.
void resetCooperating()
reset foes it the number of lanes matches (or exceeds) the number of incoming connections for an edge...
Definition: NBRequest.cpp:660
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
CombinationsCont myForbids
Definition: NBRequest.h:238
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
std::pair< unsigned int, unsigned int > getSizes() const
returns the number of the junction&#39;s lanes and the number of the junction&#39;s links in respect...
Definition: NBRequest.cpp:407
void computeRightOutgoingLinkCrossings(bool leftHanded, NBEdge *from, NBEdge *to)
Definition: NBRequest.cpp:172
SUMOReal getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge&#39;s geometry at the given node.
Definition: NBEdge.cpp:1121
void resetSignalised()
Definition: NBRequest.cpp:347
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:349