Eclipse SUMO - Simulation of Urban MObility
NBRequest.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // This class computes the logic of a junction
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <string>
27 #include <vector>
28 #include <set>
29 #include <algorithm>
30 #include <bitset>
31 #include <sstream>
32 #include <map>
33 #include <cassert>
35 #include <utils/common/ToString.h>
38 #include "NBEdge.h"
39 #include "NBContHelper.h"
40 #include "NBNode.h"
41 #include "NBRequest.h"
42 
43 //#define DEBUG_RESPONSE
44 //#define DEBUG_SETBLOCKING
45 #define DEBUGCOND (myJunction->getID() == "F")
46 
47 // ===========================================================================
48 // static member variables
49 // ===========================================================================
51 int NBRequest::myNotBuild = 0;
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
58  NBNode* junction,
59  const EdgeVector& all,
60  const EdgeVector& incoming,
61  const EdgeVector& outgoing,
62  const NBConnectionProhibits& loadedProhibits) :
63  myJunction(junction),
64  myAll(all),
65  myIncoming(incoming),
66  myOutgoing(outgoing) {
67  const int variations = numLinks();
68  // build maps with information which forbidding connection were
69  // computed and what's in there
70  myForbids.reserve(variations);
71  myDone.reserve(variations);
72  for (int i = 0; i < variations; i++) {
73  myForbids.push_back(LinkInfoCont(variations, false));
74  myDone.push_back(LinkInfoCont(variations, false));
75  }
76  // insert loaded prohibits
77  for (NBConnectionProhibits::const_iterator j = loadedProhibits.begin(); j != loadedProhibits.end(); j++) {
78  NBConnection prohibited = (*j).first;
79  bool ok1 = prohibited.check(ec);
80  if (find(myIncoming.begin(), myIncoming.end(), prohibited.getFrom()) == myIncoming.end()) {
81  ok1 = false;
82  }
83  if (find(myOutgoing.begin(), myOutgoing.end(), prohibited.getTo()) == myOutgoing.end()) {
84  ok1 = false;
85  }
86  int idx1 = 0;
87  if (ok1) {
88  idx1 = getIndex(prohibited.getFrom(), prohibited.getTo());
89  if (idx1 < 0) {
90  ok1 = false;
91  }
92  }
93  const NBConnectionVector& prohibiting = (*j).second;
94  for (NBConnectionVector::const_iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
95  NBConnection sprohibiting = *k;
96  bool ok2 = sprohibiting.check(ec);
97  if (find(myIncoming.begin(), myIncoming.end(), sprohibiting.getFrom()) == myIncoming.end()) {
98  ok2 = false;
99  }
100  if (find(myOutgoing.begin(), myOutgoing.end(), sprohibiting.getTo()) == myOutgoing.end()) {
101  ok2 = false;
102  }
103  if (ok1 && ok2) {
104  int idx2 = getIndex(sprohibiting.getFrom(), sprohibiting.getTo());
105  if (idx2 < 0) {
106  ok2 = false;
107  } else {
108  myForbids[idx2][idx1] = true;
109  myDone[idx2][idx1] = true;
110  myDone[idx1][idx2] = true;
111  myGoodBuilds++;
112  }
113  } else {
114  std::string pfID = prohibited.getFrom() != nullptr ? prohibited.getFrom()->getID() : "UNKNOWN";
115  std::string ptID = prohibited.getTo() != nullptr ? prohibited.getTo()->getID() : "UNKNOWN";
116  std::string bfID = sprohibiting.getFrom() != nullptr ? sprohibiting.getFrom()->getID() : "UNKNOWN";
117  std::string btID = sprohibiting.getTo() != nullptr ? sprohibiting.getTo()->getID() : "UNKNOWN";
118  WRITE_WARNING("could not prohibit " + pfID + "->" + ptID + " by " + bfID + "->" + btID);
119  myNotBuild++;
120  }
121  }
122  }
123  // ok, check whether someone has prohibited two links vice versa
124  // (this happens also in some Vissim-networks, when edges are joined)
125  for (int s1 = 0; s1 < variations; s1++) {
126  for (int s2 = s1 + 1; s2 < variations; s2++) {
127  // not set, yet
128  if (!myDone[s1][s2]) {
129  continue;
130  }
131  // check whether both prohibit vice versa
132  if (myForbids[s1][s2] && myForbids[s2][s1]) {
133  // mark unset - let our algorithm fix it later
134  myDone[s1][s2] = false;
135  myDone[s2][s1] = false;
136  }
137  }
138  }
139 }
140 
141 
143 
144 
145 void
147  EdgeVector::const_iterator i, j;
148  for (i = myIncoming.begin(); i != myIncoming.end(); i++) {
149  for (j = myOutgoing.begin(); j != myOutgoing.end(); j++) {
152  }
153  }
154  // reset signalised/non-signalised dependencies
155  resetSignalised();
156  // reset foes it the number of lanes matches (or exceeds) the number of incoming connections
158 }
159 
160 
161 void
163  EdgeVector::const_iterator pfrom = std::find(myAll.begin(), myAll.end(), from);
164  while (*pfrom != to) {
166  if ((*pfrom)->getToNode() == myJunction) {
167  EdgeVector::const_iterator pto = std::find(myAll.begin(), myAll.end(), to);
168  while (*pto != from) {
169  if (!((*pto)->getToNode() == myJunction)) {
170  setBlocking(from, to, *pfrom, *pto);
171  }
173  }
174  }
175  }
176 }
177 
178 
179 void
181  EdgeVector::const_iterator pfrom = std::find(myAll.begin(), myAll.end(), from);
182  while (*pfrom != to) {
183  NBContHelper::nextCW(myAll, pfrom);
184  if ((*pfrom)->getToNode() == myJunction) {
185  EdgeVector::const_iterator pto = std::find(myAll.begin(), myAll.end(), to);
186  while (*pto != from) {
187  if (!((*pto)->getToNode() == myJunction)) {
188  setBlocking(from, to, *pfrom, *pto);
189  }
191  }
192  }
193  }
194 }
195 
196 
197 void
199  NBEdge* from2, NBEdge* to2) {
200  // check whether one of the links has a dead end
201  if (to1 == nullptr || to2 == nullptr) {
202  return;
203  }
204  // get the indices of both links
205  int idx1 = getIndex(from1, to1);
206  int idx2 = getIndex(from2, to2);
207  if (idx1 < 0 || idx2 < 0) {
208  return; // !!! error output? did not happend, yet
209  }
210  // check whether the link crossing has already been checked
211  assert(idx1 < (int)(myIncoming.size() * myOutgoing.size()));
212  if (myDone[idx1][idx2]) {
213  return;
214  }
215  // mark the crossings as done
216  myDone[idx1][idx2] = true;
217  myDone[idx2][idx1] = true;
218  // special case all-way stop
220  // all ways forbid each other. Conflict resolution happens via arrival time
221  myForbids[idx1][idx2] = true;
222  myForbids[idx2][idx1] = true;
223  return;
224  }
225  // check if one of the links is a turn; this link is always not priorised
226  // true for right-before-left and priority
227  if (from1->isTurningDirectionAt(to1)) {
228  myForbids[idx2][idx1] = true;
229  return;
230  }
231  if (from2->isTurningDirectionAt(to2)) {
232  myForbids[idx1][idx2] = true;
233  return;
234  }
235  // if there are no connections, there are no prohibitions
236  if (from1->isConnectedTo(to1)) {
237  if (!from2->isConnectedTo(to2)) {
238  myForbids[idx1][idx2] = true;
239  myForbids[idx2][idx1] = false;
240  return;
241  }
242  } else {
243  if (!from2->isConnectedTo(to2)) {
244  myForbids[idx1][idx2] = false;
245  myForbids[idx2][idx1] = false;
246  return;
247  } else {
248  myForbids[idx1][idx2] = false;
249  myForbids[idx2][idx1] = true;
250  return;
251  }
252  }
253 #ifdef DEBUG_SETBLOCKING
254  if (DEBUGCOND) std::cout << "setBlocking"
255  << " 1:" << from1->getID() << "->" << to1->getID()
256  << " 2:" << from2->getID() << "->" << to2->getID() << "\n";
257 #endif
258  // check the priorities if required by node type
260  int from1p = from1->getJunctionPriority(myJunction);
261  int from2p = from2->getJunctionPriority(myJunction);
262 #ifdef DEBUG_SETBLOCKING
263  if (DEBUGCOND) std::cout << "setBlocking"
264  << " 1:" << from1->getID() << "->" << to1->getID()
265  << " 2:" << from2->getID() << "->" << to2->getID()
266  << " p1=" << from1p << " p2=" << from2p << "\n";
267 #endif
268  // check if one of the connections is higher priorised when incoming into
269  // the junction, the connection road will yield
270  if (from1p > from2p) {
271  myForbids[idx1][idx2] = true;
272  return;
273  }
274  if (from2p > from1p) {
275  myForbids[idx2][idx1] = true;
276  return;
277  }
278  }
279  // straight connections prohibit turning connections if the priorities are equal
280  // (unless the junction is a bent priority junction)
282  LinkDirection ld1 = myJunction->getDirection(from1, to1);
283  LinkDirection ld2 = myJunction->getDirection(from2, to2);
284 #ifdef DEBUG_SETBLOCKING
285  if (DEBUGCOND) std::cout << "setBlocking"
286  << " 1:" << from1->getID() << "->" << to1->getID()
287  << " 2:" << from2->getID() << "->" << to2->getID()
288  << " dir1=" << toString(ld1) << " dir2=" << toString(ld2) << "\n";
289 #endif
290  if (ld1 == LINKDIR_STRAIGHT) {
291  if (ld2 != LINKDIR_STRAIGHT) {
292  myForbids[idx1][idx2] = true;
293  myForbids[idx2][idx1] = false;
294  return;
295  }
296  } else {
297  if (ld2 == LINKDIR_STRAIGHT) {
298  myForbids[idx1][idx2] = false;
299  myForbids[idx2][idx1] = true;
300  return;
301  }
302  }
303  }
304 
305  // check whether one of the connections is higher priorised on
306  // the outgoing edge when both roads are high priorised
307  // the connection with the lower priorised outgoing edge will lead
308  // should be valid for priority junctions only
309  /*
310  if (from1p > 0 && from2p > 0) {
311  assert(myJunction->getType() != NODETYPE_RIGHT_BEFORE_LEFT);
312  int to1p = to1->getJunctionPriority(myJunction);
313  int to2p = to2->getJunctionPriority(myJunction);
314  if (to1p > to2p) {
315  myForbids[idx1][idx2] = true;
316  return;
317  }
318  if (to2p > to1p) {
319  myForbids[idx2][idx1] = true;
320  return;
321  }
322  }
323  */
324 
325  // compute the yielding due to the right-before-left rule
326  // get the position of the incoming lanes in the junction-wheel
327  EdgeVector::const_iterator c1 = std::find(myAll.begin(), myAll.end(), from1);
329  // go through next edges clockwise...
330  while (*c1 != from1 && *c1 != from2) {
331  if (*c1 == to2) {
332  // if we encounter to2 the second one prohibits the first
333  myForbids[idx2][idx1] = true;
334  return;
335  }
337  }
338  // get the position of the incoming lanes in the junction-wheel
339  EdgeVector::const_iterator c2 = std::find(myAll.begin(), myAll.end(), from2);
341  // go through next edges clockwise...
342  while (*c2 != from2 && *c2 != from1) {
343  if (*c2 == to1) {
344  // if we encounter to1 the second one prohibits the first
345  myForbids[idx1][idx2] = true;
346  return;
347  }
349  }
350 #ifdef DEBUG_SETBLOCKING
351  if (DEBUGCOND) std::cout << "setBlocking"
352  << " 1:" << from1->getID() << "->" << to1->getID()
353  << " 2:" << from2->getID() << "->" << to2->getID()
354  << " noDecision\n";
355 #endif
356 }
357 
358 
359 int
361  EdgeVector::const_iterator p = std::find(myAll.begin(), myAll.end(), from);
362  int ret = 0;
363  do {
364  ret++;
365  if (p == myAll.begin()) {
366  p = myAll.end();
367  }
368  p--;
369  } while (*p != to);
370  return ret;
371 }
372 
373 const std::string&
374 NBRequest::getFoes(int linkIndex) const {
375  assert(linkIndex >= 0);
376  assert(linkIndex < (int)myFoes.size());
377  return myFoes[linkIndex];
378 }
379 
380 
381 const std::string&
382 NBRequest::getResponse(int linkIndex) const {
383  assert(linkIndex >= 0);
384  assert(linkIndex < (int)myResponse.size());
385  return myResponse[linkIndex];
386 }
387 
388 
389 void
391  int numLinks = (int)myResponse.size();
392  assert((int)myFoes.size() == numLinks);
393  assert((int)myHaveVia.size() == numLinks);
394  const bool padding = numLinks > 10;
395  for (int i = 0; i < numLinks; i++) {
397  into.writeAttr(SUMO_ATTR_INDEX, i);
398  if (padding && i < 10) {
399  into.writePadding(" ");
400  }
402  into.writeAttr(SUMO_ATTR_FOES, myFoes[i]);
403  if (!OptionsCont::getOptions().getBool("no-internal-links")) {
405  }
406  into.closeTag();
407  }
408 }
409 
410 
411 void
412 NBRequest::computeLogic(const bool checkLaneFoes) {
413  myResponse.clear();
414  myFoes.clear();
415  myHaveVia.clear();
416  int pos = 0;
417  EdgeVector::const_iterator i;
418  // normal connections
419  for (i = myIncoming.begin(); i != myIncoming.end(); i++) {
420  int noLanes = (*i)->getNumLanes();
421  for (int k = 0; k < noLanes; k++) {
422  pos = computeLaneResponse(*i, k, pos, checkLaneFoes || myJunction->getType() == NODETYPE_ZIPPER);
423  }
424  }
425  // crossings
426  auto crossings = myJunction->getCrossings();
427  for (auto c : crossings) {
428  pos = computeCrossingResponse(*c, pos);
429  }
430 }
431 
432 void
434  // go through possible prohibitions
435  for (EdgeVector::const_iterator i11 = myIncoming.begin(); i11 != myIncoming.end(); i11++) {
436  int noLanesEdge1 = (*i11)->getNumLanes();
437  for (int j1 = 0; j1 < noLanesEdge1; j1++) {
438  std::vector<NBEdge::Connection> el1 = (*i11)->getConnectionsFromLane(j1);
439  for (std::vector<NBEdge::Connection>::iterator i12 = el1.begin(); i12 != el1.end(); ++i12) {
440  int idx1 = getIndex((*i11), (*i12).toEdge);
441  if (idx1 < 0) {
442  continue;
443  }
444  // go through possibly prohibited
445  for (EdgeVector::const_iterator i21 = myIncoming.begin(); i21 != myIncoming.end(); i21++) {
446  int noLanesEdge2 = (*i21)->getNumLanes();
447  for (int j2 = 0; j2 < noLanesEdge2; j2++) {
448  std::vector<NBEdge::Connection> el2 = (*i21)->getConnectionsFromLane(j2);
449  for (std::vector<NBEdge::Connection>::iterator i22 = el2.begin(); i22 != el2.end(); i22++) {
450  int idx2 = getIndex((*i21), (*i22).toEdge);
451  if (idx2 < 0) {
452  continue;
453  }
454  // check
455  // same incoming connections do not prohibit each other
456  if ((*i11) == (*i21)) {
457  myForbids[idx1][idx2] = false;
458  myForbids[idx2][idx1] = false;
459  continue;
460  }
461  // check other
462  // if both are non-signalised or both are signalised
463  if (((*i12).tlID == "" && (*i22).tlID == "")
464  ||
465  ((*i12).tlID != "" && (*i22).tlID != "")) {
466  // do nothing
467  continue;
468  }
469  // supposing, we don not have to
470  // brake if we are no foes
471  if (!foes(*i11, (*i12).toEdge, *i21, (*i22).toEdge)) {
472  continue;
473  }
474  // otherwise:
475  // the non-signalised must break
476  if ((*i12).tlID != "") {
477  myForbids[idx1][idx2] = true;
478  myForbids[idx2][idx1] = false;
479  } else {
480  myForbids[idx1][idx2] = false;
481  myForbids[idx2][idx1] = true;
482  }
483  }
484  }
485  }
486  }
487  }
488  }
489 }
490 
491 
492 std::pair<int, int>
494  int noLanes = 0;
495  int noLinks = 0;
496  for (EdgeVector::const_iterator i = myIncoming.begin();
497  i != myIncoming.end(); i++) {
498  int noLanesEdge = (*i)->getNumLanes();
499  for (int j = 0; j < noLanesEdge; j++) {
500  int numConnections = (int)(*i)->getConnectionsFromLane(j).size();
501  noLinks += numConnections;
502  if (numConnections > 0) {
503  noLanes++;
504  }
505  }
506  }
507  return std::make_pair(noLanes, noLinks);
508 }
509 
510 
511 bool
512 NBRequest::foes(const NBEdge* const from1, const NBEdge* const to1,
513  const NBEdge* const from2, const NBEdge* const to2) const {
514  // unconnected edges do not forbid other edges
515  if (to1 == nullptr || to2 == nullptr) {
516  return false;
517  }
518  // get the indices
519  int idx1 = getIndex(from1, to1);
520  int idx2 = getIndex(from2, to2);
521  if (idx1 < 0 || idx2 < 0) {
522  return false; // sure? (The connection does not exist within this junction)
523  }
524  assert(idx1 < (int)(myIncoming.size() * myOutgoing.size()));
525  assert(idx2 < (int)(myIncoming.size()*myOutgoing.size()));
526  return myForbids[idx1][idx2] || myForbids[idx2][idx1];
527 }
528 
529 
530 bool
531 NBRequest::forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
532  const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
533  bool regardNonSignalisedLowerPriority) const {
534  // unconnected edges do not forbid other edges
535  if (possProhibitorTo == nullptr || possProhibitedTo == nullptr) {
536  return false;
537  }
538  // get the indices
539  int possProhibitorIdx = getIndex(possProhibitorFrom, possProhibitorTo);
540  int possProhibitedIdx = getIndex(possProhibitedFrom, possProhibitedTo);
541  if (possProhibitorIdx < 0 || possProhibitedIdx < 0) {
542  return false; // sure? (The connection does not exist within this junction)
543  }
544  assert(possProhibitorIdx < (int)(myIncoming.size() * myOutgoing.size()));
545  assert(possProhibitedIdx < (int)(myIncoming.size() * myOutgoing.size()));
546  // check simple right-of-way-rules
547  if (!regardNonSignalisedLowerPriority) {
548  return myForbids[possProhibitorIdx][possProhibitedIdx];
549  }
550  // if its not forbidden, report
551  if (!myForbids[possProhibitorIdx][possProhibitedIdx]) {
552  return false;
553  }
554  // do not forbid a signalised stream by a non-signalised
555  if (!possProhibitorFrom->hasSignalisedConnectionTo(possProhibitorTo)) {
556  return false;
557  }
558  return true;
559 }
560 
561 int
562 NBRequest::computeLaneResponse(NBEdge* from, int fromLane, int pos, const bool checkLaneFoes) {
563  for (const NBEdge::Connection& c : from->getConnectionsFromLane(fromLane)) {
564  assert(c.toEdge != 0);
565  pos++;
566  const std::string foes = getFoesString(from, c.toEdge, fromLane, c.toLane, checkLaneFoes);
567  const std::string response = myJunction->getType() == NODETYPE_ZIPPER ? foes : getResponseString(from, c, checkLaneFoes);
568  myFoes.push_back(foes);
569  myResponse.push_back(response);
570  myHaveVia.push_back(c.haveVia);
571  }
572  return pos;
573 }
574 
575 
576 int
578  std::string foes(myJunction->getCrossings().size(), '0');
579  std::string response(myJunction->getCrossings().size(), '0');
580  // conflicts with normal connections
581  for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin(); i != myIncoming.rend(); i++) {
582  //const std::vector<NBEdge::Connection> &allConnections = (*i)->getConnections();
583  const NBEdge* from = *i;
584  int noLanes = from->getNumLanes();
585  for (int j = noLanes; j-- > 0;) {
586  std::vector<NBEdge::Connection> connected = from->getConnectionsFromLane(j);
587  int size = (int) connected.size();
588  for (int k = size; k-- > 0;) {
589  const NBEdge* to = connected[k].toEdge;
590  bool foe = false;
591  for (EdgeVector::const_iterator it_e = crossing.edges.begin(); it_e != crossing.edges.end(); ++it_e) {
592  if ((*it_e) == from || (*it_e) == to) {
593  foe = true;
594  break;
595  }
596  }
597  foes += foe ? '1' : '0';
598  response += mustBrakeForCrossing(myJunction, from, to, crossing) || !foe ? '0' : '1';
599  }
600  }
601  }
602  pos++;
603  myResponse.push_back(response);
604  myFoes.push_back(foes);
605  myHaveVia.push_back(false);
606  return pos;
607 }
608 
609 
610 std::string
611 NBRequest::getResponseString(const NBEdge* const from, const NBEdge::Connection& c, const bool checkLaneFoes) const {
612  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
613  const NBEdge* const to = c.toEdge;
614  const int fromLane = c.fromLane;
615  const int toLane = c.toLane;
616  int idx = 0;
617  if (to != nullptr) {
618  idx = getIndex(from, to);
619  }
620  std::string result;
621  // crossings
622  auto crossings = myJunction->getCrossings();
623  for (std::vector<NBNode::Crossing*>::const_reverse_iterator i = crossings.rbegin(); i != crossings.rend(); i++) {
624  result += mustBrakeForCrossing(myJunction, from, to, **i) ? '1' : '0';
625  }
626  NBEdge::Connection queryCon = from->getConnection(fromLane, to, toLane);
627  // normal connections
628  for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin(); i != myIncoming.rend(); i++) {
629  //const std::vector<NBEdge::Connection> &allConnections = (*i)->getConnections();
630  int noLanes = (*i)->getNumLanes();
631  for (int j = noLanes; j-- > 0;) {
632  std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
633  int size = (int) connected.size();
634  for (int k = size; k-- > 0;) {
635  if (c.mayDefinitelyPass) {
636  result += '0';
637  } else if ((*i) == from && fromLane == j) {
638  // do not prohibit a connection by others from same lane
639  result += '0';
640  } else {
641  assert(connected[k].toEdge != 0);
642  const int idx2 = getIndex(*i, connected[k].toEdge);
643  assert(k < (int) connected.size());
644  assert(idx < (int)(myIncoming.size() * myOutgoing.size()));
645  assert(idx2 < (int)(myIncoming.size() * myOutgoing.size()));
646  // check whether the connection is prohibited by another one
647 #ifdef DEBUG_RESPONSE
648  if (DEBUGCOND) {
649  std::cout << " c=" << queryCon.getDescription(from) << " prohibitC=" << connected[k].getDescription(*i)
650  << " f=" << myForbids[idx2][idx]
651  << " clf=" << checkLaneFoes
652  << " clfbc=" << checkLaneFoesByClass(queryCon, *i, connected[k])
653  << " clfbcoop=" << checkLaneFoesByCooperation(from, queryCon, *i, connected[k])
654  << " lc=" << laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane)
655  << " rtc=" << NBNode::rightTurnConflict(from, to, fromLane, *i, connected[k].toEdge, connected[k].fromLane, lefthand)
656  << " mc=" << mergeConflict(from, queryCon, *i, connected[k], false)
657  << " oltc=" << oppositeLeftTurnConflict(from, queryCon, *i, connected[k], false)
658  << " rorc=" << myJunction->rightOnRedConflict(c.tlLinkIndex, connected[k].tlLinkIndex)
659  << " tlscc=" << myJunction->tlsContConflict(from, c, *i, connected[k])
660  << "\n";
661  }
662 #endif
663  const bool hasLaneConflict = (!(checkLaneFoes || checkLaneFoesByClass(queryCon, *i, connected[k])
664  || checkLaneFoesByCooperation(from, queryCon, *i, connected[k]))
665  || laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane));
666  if ((myForbids[idx2][idx] && hasLaneConflict)
667  || NBNode::rightTurnConflict(from, to, fromLane, *i, connected[k].toEdge, connected[k].fromLane, lefthand)
668  || mergeConflict(from, queryCon, *i, connected[k], false)
669  || oppositeLeftTurnConflict(from, queryCon, *i, connected[k], false)
670  || myJunction->rightOnRedConflict(c.tlLinkIndex, connected[k].tlLinkIndex)
671  || (myJunction->tlsContConflict(from, c, *i, connected[k]) && hasLaneConflict
672  && !OptionsCont::getOptions().getBool("tls.ignore-internal-junction-jam"))
673  ) {
674  result += '1';
675  } else {
676  result += '0';
677  }
678  }
679  }
680  }
681  }
682  return result;
683 }
684 
685 
686 std::string
687 NBRequest::getFoesString(NBEdge* from, NBEdge* to, int fromLane, int toLane, const bool checkLaneFoes) const {
688  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
689  // remember the case when the lane is a "dead end" in the meaning that
690  // vehicles must choose another lane to move over the following
691  // junction
692  // !!! move to forbidden
693  std::string result;
694  // crossings
695  auto crossings = myJunction->getCrossings();
696  for (std::vector<NBNode::Crossing*>::const_reverse_iterator i = crossings.rbegin(); i != crossings.rend(); i++) {
697  bool foes = false;
698  for (EdgeVector::const_iterator it_e = (**i).edges.begin(); it_e != (**i).edges.end(); ++it_e) {
699  if ((*it_e) == from || (*it_e) == to) {
700  foes = true;
701  break;
702  }
703  }
704  result += foes ? '1' : '0';
705  }
706  NBEdge::Connection queryCon = from->getConnection(fromLane, to, toLane);
707  // normal connections
708  for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin();
709  i != myIncoming.rend(); i++) {
710 
711  for (int j = (int)(*i)->getNumLanes() - 1; j >= 0; --j) {
712  std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
713  int size = (int) connected.size();
714  for (int k = size; k-- > 0;) {
715  const bool hasLaneConflict = (!(checkLaneFoes || checkLaneFoesByClass(queryCon, *i, connected[k])
716  || checkLaneFoesByCooperation(from, queryCon, *i, connected[k]))
717  || laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane));
718  if ((foes(from, to, (*i), connected[k].toEdge) && hasLaneConflict)
719  || NBNode::rightTurnConflict(from, to, fromLane, *i, connected[k].toEdge, connected[k].fromLane, lefthand)
720  || myJunction->turnFoes(from, to, fromLane, *i, connected[k].toEdge, connected[k].fromLane, lefthand)
721  || mergeConflict(from, queryCon, *i, connected[k], true)
722  || oppositeLeftTurnConflict(from, queryCon, *i, connected[k], true)
723  ) {
724  result += '1';
725  } else {
726  result += '0';
727  }
728  }
729  }
730  }
731  return result;
732 }
733 
734 
735 bool
737  const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const {
738  if (from == prohibitorFrom
739  && con.toEdge == prohibitorCon.toEdge
740  && con.toLane == prohibitorCon.toLane
741  && con.fromLane != prohibitorCon.fromLane
743  if (foes) {
744  return true;
745  }
746  if (prohibitorCon.mayDefinitelyPass) {
747  return true;
748  }
749  if (con.mayDefinitelyPass) {
750  return false;
751  }
752  const bool bike = from->getPermissions(con.fromLane) == SVC_BICYCLE;
753  const bool prohibitorBike = prohibitorFrom->getPermissions(prohibitorCon.fromLane) == SVC_BICYCLE;
754  if (myOutgoing.size() == 1) {
755  // at on-ramp like situations, right lane should yield
756  return bike || (con.fromLane < prohibitorCon.fromLane && !prohibitorBike);
757  } else if (myIncoming.size() == 1) {
758  // at off-ramp like situations, right lane should pass unless it's a bicycle lane
759  return bike || (con.fromLane > prohibitorCon.fromLane && !prohibitorBike);
760  } else {
761  // priority depends on direction:
762  // for right turns the rightmost lane gets priority
763  // otherwise the left lane
764  LinkDirection dir = myJunction->getDirection(from, con.toEdge);
765  if (dir == LINKDIR_RIGHT || dir == LINKDIR_PARTRIGHT) {
766  return con.fromLane > prohibitorCon.fromLane;
767  } else {
768  return con.fromLane < prohibitorCon.fromLane;
769  }
770  }
771 
772  } else {
773  return false;
774  }
775 }
776 
777 
778 bool
780  const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const {
781  LinkDirection dir = myJunction->getDirection(from, con.toEdge);
782  // XXX lefthand issue (solve via #4256)
783  if (dir != LINKDIR_LEFT && dir != LINKDIR_PARTLEFT) {
784  return false;
785  }
786  dir = myJunction->getDirection(prohibitorFrom, prohibitorCon.toEdge);
787  if (dir != LINKDIR_LEFT && dir != LINKDIR_PARTLEFT) {
788  return false;
789  }
790  if (from == prohibitorFrom || NBRequest::foes(from, con.toEdge, prohibitorFrom, prohibitorCon.toEdge)) {
791  // not an opposite pair
792  return false;
793  };
794 
795  double width2 = prohibitorCon.toEdge->getLaneWidth(prohibitorCon.toLane) / 2;
796  PositionVector shape = con.shape;
797  shape.append(con.viaShape);
798  PositionVector otherShape = prohibitorCon.shape;
799  otherShape.append(prohibitorCon.viaShape);
800  if (shape.size() == 0 || otherShape.size() == 0) {
801  // no internal lanes built
802  return false;
803  }
804  const double minDV = NBEdge::firstIntersection(shape, otherShape, width2);
805  if (minDV < shape.length() - POSITION_EPS && minDV > POSITION_EPS) {
806  // break symmetry using edge id
807  return foes || from->getID() < prohibitorFrom->getID();
808  } else {
809  return false;
810  }
811 }
812 
813 bool
815  const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon) const {
816  if (con.toEdge != prohibitorCon.toEdge) {
817  return false;
818  }
819  SVCPermissions svc = con.toEdge->getPermissions(con.toLane);
820  SVCPermissions svc2 = prohibitorFrom->getPermissions(prohibitorCon.fromLane) & prohibitorCon.toEdge->getPermissions(prohibitorCon.toLane);
821  // check for lane level conflict if the only common classes are bicycles or pedestrians
822  return (svc & svc2 & ~(SVC_BICYCLE | SVC_PEDESTRIAN)) == 0;
823 }
824 
825 
826 bool
828  const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon) const {
829  if (con.toEdge != prohibitorCon.toEdge) {
830  return false;
831  }
832  // if from and prohibitorFrom target distinct lanes for all their
833  // connections to the common target edge, cooperation is possible
834  // (and should always happen unless the connections cross for some byzantine reason)
835 
836  std::set<int> fromTargetLanes;
837  for (const auto& c : from->getConnections()) {
838  if (c.toEdge == con.toEdge) {
839  fromTargetLanes.insert(c.toLane);
840  }
841  }
842  for (const auto& c : prohibitorFrom->getConnections()) {
843  if (c.toEdge == con.toEdge && fromTargetLanes.count(c.toLane) != 0) {
844  //std::cout << " con=" << con->getDescription(from) << " foe=" << prohibitorCon.getDescription(prohibitorFrom)
845  // << " no cooperation (targets=" << joinToString(fromTargetLanes, ' ') << " index=" << c.toLane << "\n";
846  return false;
847  }
848  }
849  return true;
850 }
851 
852 
853 bool
854 NBRequest::laneConflict(const NBEdge* from, const NBEdge* to, int toLane,
855  const NBEdge* prohibitorFrom, const NBEdge* prohibitorTo, int prohibitorToLane) const {
856  if (to != prohibitorTo) {
857  return true;
858  }
859  // since we know that the edge2edge connections are in conflict, the only
860  // situation in which the lane2lane connections can be conflict-free is, if
861  // they target the same edge but do not cross each other
862  double angle = NBHelpers::relAngle(
863  from->getAngleAtNode(from->getToNode()), to->getAngleAtNode(to->getFromNode()));
864  if (angle == 180) {
865  angle = -180; // turnarounds are left turns
866  }
867  const double prohibitorAngle = NBHelpers::relAngle(
868  prohibitorFrom->getAngleAtNode(prohibitorFrom->getToNode()), to->getAngleAtNode(to->getFromNode()));
869  const bool rightOfProhibitor = prohibitorFrom->isTurningDirectionAt(to)
870  || (angle > prohibitorAngle && !from->isTurningDirectionAt(to));
871  return rightOfProhibitor ? toLane >= prohibitorToLane : toLane <= prohibitorToLane;
872 }
873 
874 int
875 NBRequest::getIndex(const NBEdge* const from, const NBEdge* const to) const {
876  EdgeVector::const_iterator fp = std::find(myIncoming.begin(), myIncoming.end(), from);
877  EdgeVector::const_iterator tp = std::find(myOutgoing.begin(), myOutgoing.end(), to);
878  if (fp == myIncoming.end() || tp == myOutgoing.end()) {
879  return -1;
880  }
881  // compute the index
882  return (int)(distance(myIncoming.begin(), fp) * myOutgoing.size() + distance(myOutgoing.begin(), tp));
883 }
884 
885 
886 std::ostream&
887 operator<<(std::ostream& os, const NBRequest& r) {
888  int variations = r.numLinks();
889  for (int i = 0; i < variations; i++) {
890  os << i << ' ';
891  for (int j = 0; j < variations; j++) {
892  if (r.myForbids[i][j]) {
893  os << '1';
894  } else {
895  os << '0';
896  }
897  }
898  os << std::endl;
899  }
900  os << std::endl;
901  return os;
902 }
903 
904 
905 bool
906 NBRequest::mustBrake(const NBEdge* const from, const NBEdge* const to, int fromLane, int toLane, bool includePedCrossings) const {
907  NBEdge::Connection con(fromLane, const_cast<NBEdge*>(to), toLane);
908  const int linkIndex = myJunction->getConnectionIndex(from, con);
909  if (linkIndex >= 0 && (int)myResponse.size() > linkIndex) {
910  std::string response = getResponse(linkIndex);
911  if (!includePedCrossings) {
912  response = response.substr(0, response.size() - myJunction->getCrossings().size());
913  }
914  if (response.find_first_of("1") == std::string::npos) {
915  return false;
916  };
917  // if the link must respond it could also be due to a tlsConflict. This
918  // must not carry over the the off-state response so we continue with
919  // the regular check
920  }
921  // get the indices
922  int idx2 = getIndex(from, to);
923  if (idx2 == -1) {
924  return false;
925  }
926  // go through all (existing) connections;
927  // check whether any of these forbids the one to determine
928  assert(idx2 < (int)(myIncoming.size()*myOutgoing.size()));
929  for (int idx1 = 0; idx1 < numLinks(); idx1++) {
930  //assert(myDone[idx1][idx2]);
931  if (myDone[idx1][idx2] && myForbids[idx1][idx2]) {
932  return true;
933  }
934  }
935  // maybe we need to brake for a pedestrian crossing
936  if (includePedCrossings) {
937  auto crossings = myJunction->getCrossings();
938  for (std::vector<NBNode::Crossing*>::const_reverse_iterator i = crossings.rbegin(); i != crossings.rend(); i++) {
939  if (mustBrakeForCrossing(myJunction, from, to, **i)) {
940  return true;
941  }
942  }
943  }
944  // maybe we need to brake due to a right-turn conflict with straight-going
945  // bicycles
946  LinkDirection dir = myJunction->getDirection(from, to);
947  if (dir == LINKDIR_RIGHT || dir == LINKDIR_PARTRIGHT) {
948  const std::vector<NBEdge::Connection>& cons = from->getConnections();
949  for (std::vector<NBEdge::Connection>::const_iterator i = cons.begin(); i != cons.end(); i++) {
950  if (NBNode::rightTurnConflict(from, to, fromLane,
951  from, (*i).toEdge, (*i).fromLane)) {
952  return true;
953  }
954  }
955  }
956  // maybe we need to brake due to a merge conflict
957  NBEdge::Connection queryCon = from->getConnection(fromLane, to, toLane);
958  for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin(); i != myIncoming.rend(); i++) {
959  int noLanes = (*i)->getNumLanes();
960  for (int j = noLanes; j-- > 0;) {
961  std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
962  const int size = (int) connected.size();
963  for (int k = size; k-- > 0;) {
964  if ((*i) == from && fromLane != j
965  && mergeConflict(from, queryCon, *i, connected[k], myJunction->getType() == NODETYPE_ZIPPER)) {
966  return true;
967  }
968  }
969  }
970  }
971  // maybe we need to brake due to a zipper conflict
972  if (myJunction->getType() == NODETYPE_ZIPPER) {
973  for (int idx1 = 0; idx1 < numLinks(); idx1++) {
974  //assert(myDone[idx1][idx2]);
975  if (myDone[idx1][idx2] && myForbids[idx2][idx1]) {
976  return true;
977  }
978  }
979  }
980  return false;
981 }
982 
983 
984 bool
985 NBRequest::mustBrakeForCrossing(const NBNode* node, const NBEdge* const from, const NBEdge* const to, const NBNode::Crossing& crossing) {
986  const LinkDirection dir = node->getDirection(from, to);
987  const bool mustYield = dir == LINKDIR_LEFT || dir == LINKDIR_RIGHT;
988  if (crossing.priority || mustYield) {
989  for (EdgeVector::const_iterator it_e = crossing.edges.begin(); it_e != crossing.edges.end(); ++it_e) {
990  // left and right turns must yield to unprioritized crossings only on their destination edge
991  if (((*it_e) == from && crossing.priority) || (*it_e) == to) {
992  return true;
993  }
994  }
995  }
996  return false;
997 }
998 
999 
1000 bool
1001 NBRequest::mustBrake(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
1002  const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo) const {
1003  // get the indices
1004  int idx1 = getIndex(possProhibitorFrom, possProhibitorTo);
1005  int idx2 = getIndex(possProhibitedFrom, possProhibitedTo);
1006  return (myForbids[idx2][idx1]);
1007 }
1008 
1009 
1010 void
1012  // check if any errors occurred on build the link prohibitions
1013  if (myNotBuild != 0) {
1014  WRITE_WARNING(toString(myNotBuild) + " of " + toString(myNotBuild + myGoodBuilds) + " prohibitions were not build.");
1015  }
1016 }
1017 
1018 
1019 void
1021  // map from edge to number of incoming connections
1022  std::map<NBEdge*, int> incomingCount; // initialized to 0
1023  // map from edge to indices of approached lanes
1024  std::map<NBEdge*, std::set<int> > approachedLanes;
1025  // map from edge to list of incoming edges
1026  std::map<NBEdge*, EdgeVector> incomingEdges;
1027  for (EdgeVector::const_iterator it_e = myIncoming.begin(); it_e != myIncoming.end(); it_e++) {
1028  const std::vector<NBEdge::Connection> connections = (*it_e)->getConnections();
1029  for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); ++it_c) {
1030  incomingCount[it_c->toEdge]++;
1031  approachedLanes[it_c->toEdge].insert(it_c->toLane);
1032  incomingEdges[it_c->toEdge].push_back(*it_e);
1033  }
1034  }
1035  for (std::map<NBEdge*, int>::iterator it = incomingCount.begin(); it != incomingCount.end(); ++it) {
1036  NBEdge* to = it->first;
1037  // we cannot test against to->getNumLanes() since not all lanes may be used
1038  if ((int)approachedLanes[to].size() >= it->second) {
1039  EdgeVector& incoming = incomingEdges[to];
1040  // make these connections mutually unconflicting
1041  for (EdgeVector::iterator it_e1 = incoming.begin(); it_e1 != incoming.end(); ++it_e1) {
1042  for (EdgeVector::iterator it_e2 = incoming.begin(); it_e2 != incoming.end(); ++it_e2) {
1043  myForbids[getIndex(*it_e1, to)][getIndex(*it_e2, to)] = false;
1044  }
1045  }
1046  }
1047  }
1048 }
1049 
1050 int
1052  return (int)(myIncoming.size() * myOutgoing.size() + myJunction->getCrossings().size());
1053 }
1054 
1055 /****************************************************************************/
1056 
NBRequest::getSizes
std::pair< int, int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect.
Definition: NBRequest.cpp:493
SVC_PEDESTRIAN
pedestrian
Definition: SUMOVehicleClass.h:156
ToString.h
NBRequest::mustBrakeForCrossing
static bool mustBrakeForCrossing(const NBNode *node, const NBEdge *const from, const NBEdge *const to, const NBNode::Crossing &crossing)
Returns the information whether the described flow must brake for the given crossing.
Definition: NBRequest.cpp:985
NBEdge::Connection::toEdge
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:212
NBRequest::numLinks
int numLinks() const
return to total number of edge-to-edge connections of this request-logic
Definition: NBRequest.cpp:1051
NODETYPE_ZIPPER
Definition: SUMOXMLDefinitions.h:1065
NBEdge::isConnectedTo
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed)
Definition: NBEdge.cpp:1149
NBRequest::getIndex
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:875
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:275
NBRequest::mustBrake
bool mustBrake(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
Definition: NBRequest.cpp:1001
NBEdgeCont
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:60
OutputDevice
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:63
NBEdge::getConnection
Connection getConnection(int fromLane, const NBEdge *to, int toLane) const
Returns the specified connection This method goes through "myConnections" and returns the specified o...
Definition: NBEdge.cpp:1114
OptionsCont.h
NBRequest::getResponse
const std::string & getResponse(int linkIndex) const
Definition: NBRequest.cpp:382
NBRequest
Definition: NBRequest.h:58
MsgHandler.h
EdgeVector
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
LINKDIR_PARTRIGHT
The link is a partial right direction.
Definition: SUMOXMLDefinitions.h:1190
operator<<
std::ostream & operator<<(std::ostream &os, const NBRequest &r)
Definition: NBRequest.cpp:887
NBEdge::isTurningDirectionAt
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:2756
NBEdge::getConnectionsFromLane
std::vector< Connection > getConnectionsFromLane(int lane, NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
Definition: NBEdge.cpp:1100
NBRequest.h
NBConnection::getFrom
NBEdge * getFrom() const
returns the from-edge (start of the connection)
Definition: NBConnection.cpp:89
NBRequest::myResponse
std::vector< std::string > myResponse
Definition: NBRequest.h:266
NBConnection::getTo
NBEdge * getTo() const
returns the to-edge (end of the connection)
Definition: NBConnection.cpp:95
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:222
NBRequest::setBlocking
void setBlocking(NBEdge *from1, NBEdge *to1, NBEdge *from2, NBEdge *to2)
Definition: NBRequest.cpp:198
SVC_BICYCLE
vehicle is a bicycle
Definition: SUMOVehicleClass.h:179
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
NBNode::getType
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:272
NBRequest::computeLaneResponse
int computeLaneResponse(NBEdge *from, int lane, int pos, const bool checkLaneFoes)
computes the response of a certain lane Returns the next link index within the junction
Definition: NBRequest.cpp:562
PositionVector::length
double length() const
Returns the length.
Definition: PositionVector.cpp:484
NBNode::isBentPriority
bool isBentPriority() const
return whether a priority road turns at this node
Definition: NBNode.h:759
NBNode::rightOnRedConflict
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light
Definition: NBNode.cpp:3258
NBEdge::getPermissions
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:3404
LinkDirection
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
Definition: SUMOXMLDefinitions.h:1176
NBRequest::resetSignalised
void resetSignalised()
Definition: NBRequest.cpp:433
NBNode::isConstantWidthTransition
bool isConstantWidthTransition() const
detects whether a given junction splits or merges lanes while keeping constant road width
Definition: NBNode.cpp:780
NBEdge::Connection::tlLinkIndex
int tlLinkIndex
The index of this connection within the controlling traffic light.
Definition: NBEdge.h:221
NBRequest::buildBitfieldLogic
void buildBitfieldLogic()
builds the bitset-representation of the logic
Definition: NBRequest.cpp:146
PositionVector
A list of positions.
Definition: PositionVector.h:45
NBRequest::myIncoming
const EdgeVector & myIncoming
edges incoming to the junction
Definition: NBRequest.h:247
NBRequest::myFoes
std::vector< std::string > myFoes
precomputed right-of-way matrices for each lane-to-lane link
Definition: NBRequest.h:265
NBRequest::checkLaneFoesByClass
bool checkLaneFoesByClass(const NBEdge::Connection &con, const NBEdge *prohibitorFrom, const NBEdge::Connection &prohibitorCon) const
whether the given connections must be checked for lane conflicts due to the vClasses involved
Definition: NBRequest.cpp:814
NBRequest::computeCrossingResponse
int computeCrossingResponse(const NBNode::Crossing &crossing, int pos)
computes the response of a certain crossing Returns the next link index within the junction
Definition: NBRequest.cpp:577
NBRequest::oppositeLeftTurnConflict
bool oppositeLeftTurnConflict(const NBEdge *from, const NBEdge::Connection &con, const NBEdge *prohibitorFrom, const NBEdge::Connection &prohibitorCon, bool foes) const
whether opposite left turns intersect
Definition: NBRequest.cpp:779
NBRequest::foes
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:512
NBHelpers::relAngle
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
Definition: NBHelpers.cpp:46
NBNode::turnFoes
bool turnFoes(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *from2, const NBEdge *to2, int fromLane2, bool lefthand=false) const
return whether the given laneToLane connection originate from the same edge and are in conflict due t...
Definition: NBNode.cpp:1745
NBEdge::Connection::fromLane
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:209
NBEdge
The representation of a single edge during network building.
Definition: NBEdge.h:91
OutputDevice::closeTag
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Definition: OutputDevice.cpp:253
NBRequest::myHaveVia
std::vector< bool > myHaveVia
Definition: NBRequest.h:267
NBRequest::myNotBuild
static int myNotBuild
Definition: NBRequest.h:270
LINKDIR_RIGHT
The link is a (hard) right direction.
Definition: SUMOXMLDefinitions.h:1186
NBEdge::Connection::toLane
int toLane
The lane the connections yields in.
Definition: NBEdge.h:215
OutputDevice::writeAttr
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:255
NODETYPE_ALLWAY_STOP
Definition: SUMOXMLDefinitions.h:1064
NBRequest::NBRequest
NBRequest(const NBEdgeCont &ec, NBNode *junction, const EdgeVector &all, const EdgeVector &incoming, const EdgeVector &outgoing, const NBConnectionProhibits &loadedProhibits)
Definition: NBRequest.cpp:57
LINKDIR_STRAIGHT
The link is a straight direction.
Definition: SUMOXMLDefinitions.h:1178
NBEdge::getToNode
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:498
NBRequest::~NBRequest
~NBRequest()
destructor
Definition: NBRequest.cpp:142
NBEdge::Connection::viaShape
PositionVector viaShape
shape of via
Definition: NBEdge.h:263
NBEdge::getLaneWidth
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:587
NBEdge::Connection::mayDefinitelyPass
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:227
SVCPermissions
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
Definition: SUMOVehicleClass.h:218
NBRequest::LinkInfoCont
std::vector< bool > LinkInfoCont
definition of a container to store boolean informations about a link into
Definition: NBRequest.h:253
SUMO_ATTR_FOES
Definition: SUMOXMLDefinitions.h:742
SUMO_TAG_REQUEST
description of a logic request within the junction
Definition: SUMOXMLDefinitions.h:129
NBEdge::Connection::getDescription
std::string getDescription(const NBEdge *parent) const
get string describing this connection
Definition: NBEdge.cpp:87
NBNode::getConnectionIndex
int getConnectionIndex(const NBEdge *from, const NBEdge::Connection &con) const
return the index of the given connection
Definition: NBNode.cpp:3155
NBNode::getDirection
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
Definition: NBNode.cpp:1933
SUMO_ATTR_CONT
Definition: SUMOXMLDefinitions.h:748
NBEdge::Connection::shape
PositionVector shape
shape of Connection
Definition: NBEdge.h:251
NBRequest::computeRightOutgoingLinkCrossings
void computeRightOutgoingLinkCrossings(NBEdge *from, NBEdge *to)
computes the relationships between links outgoing right of the given link *‍/
Definition: NBRequest.cpp:162
NBNode::Crossing::priority
bool priority
whether the pedestrians have priority
Definition: NBNode.h:151
NBEdge::getNumLanes
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:477
NBRequest::getFoesString
std::string getFoesString(NBEdge *from, NBEdge *to, int fromLane, int toLane, const bool checkLaneFoes) const
Definition: NBRequest.cpp:687
OutputDevice.h
NBRequest::computeLeftOutgoingLinkCrossings
void computeLeftOutgoingLinkCrossings(NBEdge *from, NBEdge *to)
computes the relationships between links outgoing left of the given link
Definition: NBRequest.cpp:180
NBContHelper::nextCCW
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
Definition: NBContHelper.cpp:48
NBRequest::distanceCounterClockwise
int distanceCounterClockwise(NBEdge *from, NBEdge *to)
returns the distance between the incoming (from) and the outgoing (to) edge clockwise in edges
Definition: NBRequest.cpp:360
NBRequest::getFoes
const std::string & getFoes(int linkIndex) const
Definition: NBRequest.cpp:374
NBRequest::checkLaneFoesByCooperation
bool checkLaneFoesByCooperation(const NBEdge *from, const NBEdge::Connection &con, const NBEdge *prohibitorFrom, const NBEdge::Connection &prohibitorCon) const
whether the given connections must be checked for lane conflicts due to disjunct target lanes
Definition: NBRequest.cpp:827
NBRequest::myJunction
NBNode * myJunction
the node the request is assigned to
Definition: NBRequest.h:241
NBNode::rightTurnConflict
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane, bool lefthand=false)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
Definition: NBNode.cpp:1698
PositionVector::append
void append(const PositionVector &v, double sameThreshold=2.0)
Definition: PositionVector.cpp:696
NBContHelper.h
LINKDIR_LEFT
The link is a (hard) left direction.
Definition: SUMOXMLDefinitions.h:1184
NBConnection
Definition: NBConnection.h:43
NBRequest::myGoodBuilds
static int myGoodBuilds
Definition: NBRequest.h:270
NODETYPE_RIGHT_BEFORE_LEFT
Definition: SUMOXMLDefinitions.h:1063
NBNode::getCrossings
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.cpp:2439
NBRequest::forbids
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 "prohibited" flow must let "prohibitor" flow pass.
Definition: NBRequest.cpp:531
SUMO_ATTR_INDEX
Definition: SUMOXMLDefinitions.h:804
NBConnectionProhibits
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
Definition: NBConnectionDefs.h:39
OutputDevice::openTag
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Definition: OutputDevice.cpp:239
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
NBConnection::check
bool check(const NBEdgeCont &ec)
checks whether the edges are still valid
Definition: NBConnection.cpp:194
NBEdge::firstIntersection
static double firstIntersection(const PositionVector &v1, const PositionVector &v2, double width2, const std::string &error="")
compute the first intersection point between the given lane geometries considering their rspective wi...
Definition: NBEdge.cpp:1761
NBRequest::getResponseString
std::string getResponseString(const NBEdge *const from, const NBEdge::Connection &c, const bool checkLaneFoes) const
Writes the response of a certain link.
Definition: NBRequest.cpp:611
NBRequest::myOutgoing
const EdgeVector & myOutgoing
edges outgoing from the junction
Definition: NBRequest.h:250
NBRequest::writeLogic
void writeLogic(OutputDevice &into) const
Definition: NBRequest.cpp:390
NBEdge::getJunctionPriority
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
Definition: NBEdge.cpp:1816
SUMO_ATTR_RESPONSE
Definition: SUMOXMLDefinitions.h:411
DEBUGCOND
#define DEBUGCOND
Definition: NBRequest.cpp:45
NBConnectionVector
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
Definition: NBConnectionDefs.h:34
NBRequest::myDone
CombinationsCont myDone
the link X link is done-checks
Definition: NBRequest.h:262
NBRequest::myAll
const EdgeVector & myAll
all (icoming and outgoing) of the junctions edges
Definition: NBRequest.h:244
NBNode::Crossing::edges
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:137
NBRequest::computeLogic
void computeLogic(const bool checkLaneFoes)
writes the XML-representation of the logic as a bitset-logic XML representation
Definition: NBRequest.cpp:412
NBContHelper::nextCW
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
Definition: NBContHelper.cpp:39
config.h
NBNode::tlsContConflict
bool tlsContConflict(const NBEdge *from, const NBEdge::Connection &c, const NBEdge *foeFrom, const NBEdge::Connection &foe) const
whether the connection must yield if the foe remains on the intersection after its phase ends
Definition: NBNode.cpp:886
NBRequest::mergeConflict
bool mergeConflict(const NBEdge *from, const NBEdge::Connection &con, const NBEdge *prohibitorFrom, const NBEdge::Connection &prohibitorCon, bool foes) const
whether multple connections from the same edge target the same lane
Definition: NBRequest.cpp:736
NBNode
Represents a single node (junction) during network building.
Definition: NBNode.h:67
NBNode::Crossing
A definition of a pedestrian crossing.
Definition: NBNode.h:131
NBEdge::Connection
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:189
NBNode.h
NBEdge::hasSignalisedConnectionTo
bool hasSignalisedConnectionTo(const NBEdge *const e) const
Check if edge has signalised connections.
Definition: NBEdge.cpp:3073
LINKDIR_PARTLEFT
The link is a partial left direction.
Definition: SUMOXMLDefinitions.h:1188
NBEdge::getAngleAtNode
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
Definition: NBEdge.cpp:1836
NBRequest::reportWarnings
static void reportWarnings()
reports warnings if any occurred
Definition: NBRequest.cpp:1011
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
NBEdge::getConnections
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:934
NBEdge::getFromNode
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:491
NBRequest::laneConflict
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:854
NBRequest::resetCooperating
void resetCooperating()
reset foes it the number of lanes matches (or exceeds) the number of incoming connections for an edge
Definition: NBRequest.cpp:1020
NBRequest::myForbids
CombinationsCont myForbids
the link X link blockings
Definition: NBRequest.h:259
NBEdge.h
NBEdge::getID
const std::string & getID() const
Definition: NBEdge.h:1380
OutputDevice::writePadding
OutputDevice & writePadding(const std::string &val)
writes padding (ignored for binary output)
Definition: OutputDevice.h:307