46 #define DEBUGCOND (myJunction->getID() == "F") 67 myOutgoing(outgoing) {
72 myDone.reserve(variations);
73 for (
int i = 0; i < variations; i++) {
78 for (NBConnectionProhibits::const_iterator j = loadedProhibits.begin(); j != loadedProhibits.end(); j++) {
80 bool ok1 = prohibited.
check(ec);
95 for (NBConnectionVector::const_iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
97 bool ok2 = sprohibiting.
check(ec);
110 myDone[idx2][idx1] =
true;
111 myDone[idx1][idx2] =
true;
115 std::string pfID = prohibited.
getFrom() !=
nullptr ? prohibited.
getFrom()->
getID() :
"UNKNOWN";
116 std::string ptID = prohibited.
getTo() !=
nullptr ? prohibited.
getTo()->
getID() :
"UNKNOWN";
117 std::string bfID = sprohibiting.
getFrom() !=
nullptr ? sprohibiting.
getFrom()->
getID() :
"UNKNOWN";
118 std::string btID = sprohibiting.
getTo() !=
nullptr ? sprohibiting.
getTo()->
getID() :
"UNKNOWN";
119 WRITE_WARNING(
"could not prohibit " + pfID +
"->" + ptID +
" by " + bfID +
"->" + btID);
126 for (
int s1 = 0; s1 < variations; s1++) {
127 for (
int s2 = s1 + 1; s2 < variations; s2++) {
148 EdgeVector::const_iterator i, j;
164 EdgeVector::const_iterator pfrom = find(
myAll.begin(),
myAll.end(), from);
165 while (*pfrom != to) {
168 EdgeVector::const_iterator pto = find(
myAll.begin(),
myAll.end(), to);
169 while (*pto != from) {
182 EdgeVector::const_iterator pfrom = find(
myAll.begin(),
myAll.end(), from);
183 while (*pfrom != to) {
186 EdgeVector::const_iterator pto = find(
myAll.begin(),
myAll.end(), to);
187 while (*pto != from) {
202 if (to1 ==
nullptr || to2 ==
nullptr) {
208 if (idx1 < 0 || idx2 < 0) {
217 myDone[idx1][idx2] =
true;
218 myDone[idx2][idx1] =
true;
254 #ifdef DEBUG_SETBLOCKING 255 if (
DEBUGCOND) std::cout <<
"setBlocking" 256 <<
" 1:" << from1->
getID() <<
"->" << to1->
getID()
257 <<
" 2:" << from2->
getID() <<
"->" << to2->
getID() <<
"\n";
263 #ifdef DEBUG_SETBLOCKING 264 if (
DEBUGCOND) std::cout <<
"setBlocking" 265 <<
" 1:" << from1->
getID() <<
"->" << to1->
getID()
266 <<
" 2:" << from2->
getID() <<
"->" << to2->
getID()
267 <<
" p1=" << from1p <<
" p2=" << from2p <<
"\n";
271 if (from1p > from2p) {
275 if (from2p > from1p) {
285 #ifdef DEBUG_SETBLOCKING 286 if (
DEBUGCOND) std::cout <<
"setBlocking" 287 <<
" 1:" << from1->
getID() <<
"->" << to1->
getID()
288 <<
" 2:" << from2->
getID() <<
"->" << to2->
getID()
328 EdgeVector::const_iterator c1 = find(
myAll.begin(),
myAll.end(), from1);
331 while (*c1 != from1 && *c1 != from2) {
340 EdgeVector::const_iterator c2 = find(
myAll.begin(),
myAll.end(), from2);
343 while (*c2 != from2 && *c2 != from1) {
351 #ifdef DEBUG_SETBLOCKING 352 if (
DEBUGCOND) std::cout <<
"setBlocking" 353 <<
" 1:" << from1->
getID() <<
"->" << to1->
getID()
354 <<
" 2:" << from2->
getID() <<
"->" << to2->
getID()
362 EdgeVector::const_iterator p = find(
myAll.begin(),
myAll.end(), from);
366 if (p ==
myAll.begin()) {
376 assert(linkIndex >= 0);
377 assert(linkIndex < (
int)
myFoes.size());
384 assert(linkIndex >= 0);
395 const bool padding = numLinks > 10;
396 for (
int i = 0; i <
numLinks; i++) {
399 if (padding && i < 10) {
418 EdgeVector::const_iterator i;
421 int noLanes = (*i)->getNumLanes();
422 for (
int k = 0; k < noLanes; k++) {
428 for (
auto c : crossings) {
437 int noLanesEdge1 = (*i11)->getNumLanes();
438 for (
int j1 = 0; j1 < noLanesEdge1; j1++) {
439 std::vector<NBEdge::Connection> el1 = (*i11)->getConnectionsFromLane(j1);
440 for (std::vector<NBEdge::Connection>::iterator i12 = el1.begin(); i12 != el1.end(); ++i12) {
441 int idx1 =
getIndex((*i11), (*i12).toEdge);
447 int noLanesEdge2 = (*i21)->getNumLanes();
448 for (
int j2 = 0; j2 < noLanesEdge2; j2++) {
449 std::vector<NBEdge::Connection> el2 = (*i21)->getConnectionsFromLane(j2);
450 for (std::vector<NBEdge::Connection>::iterator i22 = el2.begin(); i22 != el2.end(); i22++) {
451 int idx2 =
getIndex((*i21), (*i22).toEdge);
457 if ((*i11) == (*i21)) {
464 if (((*i12).tlID ==
"" && (*i22).tlID ==
"")
466 ((*i12).tlID !=
"" && (*i22).tlID !=
"")) {
472 if (!
foes(*i11, (*i12).toEdge, *i21, (*i22).toEdge)) {
477 if ((*i12).tlID !=
"") {
497 for (EdgeVector::const_iterator i =
myIncoming.begin();
499 int noLanesEdge = (*i)->getNumLanes();
500 for (
int j = 0; j < noLanesEdge; j++) {
501 int numConnections = (int)(*i)->getConnectionsFromLane(j).size();
502 noLinks += numConnections;
503 if (numConnections > 0) {
508 return std::make_pair(noLanes, noLinks);
514 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
516 if (to1 ==
nullptr || to2 ==
nullptr) {
522 if (idx1 < 0 || idx2 < 0) {
533 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
534 bool regardNonSignalisedLowerPriority)
const {
536 if (possProhibitorTo ==
nullptr || possProhibitedTo ==
nullptr) {
540 int possProhibitorIdx =
getIndex(possProhibitorFrom, possProhibitorTo);
541 int possProhibitedIdx =
getIndex(possProhibitedFrom, possProhibitedTo);
542 if (possProhibitorIdx < 0 || possProhibitedIdx < 0) {
548 if (!regardNonSignalisedLowerPriority) {
549 return myForbids[possProhibitorIdx][possProhibitedIdx];
552 if (!
myForbids[possProhibitorIdx][possProhibitedIdx]) {
565 assert(c.toEdge != 0);
567 const std::string
foes =
getFoesString(from, c.toEdge, fromLane, c.toLane, checkLaneFoes);
586 for (
int j = noLanes; j-- > 0;) {
588 int size = (int) connected.size();
589 for (
int k = size; k-- > 0;) {
590 const NBEdge* to = connected[k].toEdge;
592 for (EdgeVector::const_iterator it_e = crossing.
edges.begin(); it_e != crossing.
edges.end(); ++it_e) {
593 if ((*it_e) == from || (*it_e) == to) {
598 foes += foe ?
'1' :
'0';
616 const int toLane = c.
toLane;
624 for (std::vector<NBNode::Crossing*>::const_reverse_iterator i = crossings.rbegin(); i != crossings.rend(); i++) {
631 int noLanes = (*i)->getNumLanes();
632 for (
int j = noLanes; j-- > 0;) {
633 std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
634 int size = (int) connected.size();
635 for (
int k = size; k-- > 0;) {
638 }
else if ((*i) == from && fromLane == j) {
642 assert(connected[k].toEdge != 0);
643 const int idx2 =
getIndex(*i, connected[k].toEdge);
644 assert(k < (
int) connected.size());
648 #ifdef DEBUG_RESPONSE 650 std::cout <<
" c=" << queryCon.
getDescription(from) <<
" prohibitC=" << connected[k].getDescription(*i)
652 <<
" clf=" << checkLaneFoes
655 <<
" lc=" <<
laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane)
657 <<
" mc=" <<
mergeConflict(from, queryCon, *i, connected[k],
false)
664 const bool hasLaneConflict = (!(checkLaneFoes ||
checkLaneFoesByClass(queryCon, *i, connected[k])
666 ||
laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane));
667 if ((
myForbids[idx2][idx] && hasLaneConflict)
696 for (std::vector<NBNode::Crossing*>::const_reverse_iterator i = crossings.rbegin(); i != crossings.rend(); i++) {
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) {
704 result += foes ?
'1' :
'0';
708 for (EdgeVector::const_reverse_iterator i =
myIncoming.rbegin();
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])
717 ||
laneConflict(from, to, toLane, *i, connected[k].toEdge, connected[k].toLane));
718 if ((
foes(from, to, (*i), connected[k].toEdge) && hasLaneConflict)
720 ||
myJunction->
turnFoes(from, to, fromLane, *i, connected[k].toEdge, connected[k].fromLane, lefthand)
738 if (from == prohibitorFrom
800 if (shape.size() == 0 || otherShape.size() == 0) {
807 return foes || from->
getID() < prohibitorFrom->
getID();
836 std::set<int> fromTargetLanes;
838 if (c.toEdge == con.
toEdge) {
839 fromTargetLanes.insert(c.toLane);
843 if (c.toEdge == con.
toEdge && fromTargetLanes.count(c.toLane) != 0) {
855 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorToLane)
const {
856 if (to != prohibitorTo) {
871 return rightOfProhibitor ? toLane >= prohibitorToLane : toLane <= prohibitorToLane;
889 for (
int i = 0; i < variations; i++) {
891 for (
int j = 0; j < variations; j++) {
909 if (linkIndex >= 0 && (
int)
myResponse.size() > linkIndex) {
911 if (!includePedCrossings) {
914 if (response.find_first_of(
"1") == std::string::npos) {
929 for (
int idx1 = 0; idx1 <
numLinks(); idx1++) {
936 if (includePedCrossings) {
938 for (std::vector<NBNode::Crossing*>::const_reverse_iterator i = crossings.rbegin(); i != crossings.rend(); i++) {
948 const std::vector<NBEdge::Connection>& cons = from->
getConnections();
949 for (std::vector<NBEdge::Connection>::const_iterator i = cons.begin(); i != cons.end(); i++) {
951 from, (*i).toEdge, (*i).fromLane)) {
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
979 if (crossing.
priority || mustYield) {
980 for (EdgeVector::const_iterator it_e = crossing.
edges.begin(); it_e != crossing.
edges.end(); ++it_e) {
982 if (((*it_e) == from && crossing.
priority) || (*it_e) == to) {
993 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo)
const {
995 int idx1 =
getIndex(possProhibitorFrom, possProhibitorTo);
996 int idx2 =
getIndex(possProhibitedFrom, possProhibitedTo);
1013 std::map<NBEdge*, int> incomingCount;
1015 std::map<NBEdge*, std::set<int> > approachedLanes;
1017 std::map<NBEdge*, EdgeVector> incomingEdges;
1019 const std::vector<NBEdge::Connection> connections = (*it_e)->getConnections();
1020 for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); ++it_c) {
1021 incomingCount[it_c->toEdge]++;
1022 approachedLanes[it_c->toEdge].insert(it_c->toLane);
1023 incomingEdges[it_c->toEdge].push_back(*it_e);
1026 for (std::map<NBEdge*, int>::iterator it = incomingCount.begin(); it != incomingCount.end(); ++it) {
1029 if ((
int)approachedLanes[to].size() >= it->second) {
1032 for (EdgeVector::iterator it_e1 = incoming.begin(); it_e1 != incoming.end(); ++it_e1) {
1033 for (EdgeVector::iterator it_e2 = incoming.begin(); it_e2 != incoming.end(); ++it_e2) {
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
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 ...
std::pair< int, int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect...
int getConnectionIndex(const NBEdge *from, const NBEdge::Connection &con) const
return the index of the given connection
The link is a partial left direction.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
void computeLeftOutgoingLinkCrossings(NBEdge *from, NBEdge *to)
computes the relationships between links outgoing left of the given link
bool check(const NBEdgeCont &ec)
checks whether the edges are still valid
A structure which describes a connection between edges or lanes.
int toLane
The lane the connections yields in.
std::vector< bool > LinkInfoCont
definition of a container to store boolean informations about a link into
void writeLogic(OutputDevice &into) const
void append(const PositionVector &v, double sameThreshold=2.0)
NBEdge * toEdge
The edge the connections yields in.
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed) ...
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
bool hasSignalisedConnectionTo(const NBEdge *const e) const
Check if edge has signalised connections.
NBRequest(const NBEdgeCont &ec, NBNode *junction, const EdgeVector &all, const EdgeVector &incoming, const EdgeVector &outgoing, const NBConnectionProhibits &loadedProhibits)
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
The representation of a single edge during network building.
NBNode * myJunction
the node the request is assigned to
std::string getResponseString(const NBEdge *const from, const NBEdge::Connection &c, const bool checkLaneFoes) const
Writes the response of a certain link.
void buildBitfieldLogic()
builds the bitset-representation of the logic
const EdgeVector & myOutgoing
edges outgoing from the junction
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light ...
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
NBEdge * getFrom() const
returns the from-edge (start of the connection)
void setBlocking(NBEdge *from1, NBEdge *to1, NBEdge *from2, NBEdge *to2)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
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 ...
const std::string & getFoes(int linkIndex) const
std::string getDescription(const NBEdge *parent) const
get string describing this connection
The link is a (hard) left direction.
#define WRITE_WARNING(msg)
const EdgeVector & myIncoming
edges incoming to the junction
static OptionsCont & getOptions()
Retrieves the options.
int numLinks() const
return to total number of edge-to-edge connections of this request-logic
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...
CombinationsCont myDone
the link X link is done-checks
bool priority
whether the pedestrians have priority
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
int getIndex(const NBEdge *const from, const NBEdge *const to) const
Returns the index to the internal combination container for the given edge combination.
The link is a straight direction.
PositionVector shape
shape of Connection
void computeLogic(const bool checkLaneFoes)
writes the XML-representation of the logic as a bitset-logic XML representation
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.
static void reportWarnings()
reports warnings if any occurred
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 ...
std::vector< Connection > getConnectionsFromLane(int lane) const
Returns connections from a given lane.
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.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
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.
int getNumLanes() const
Returns the number of lanes.
int fromLane
The lane the connections starts at.
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...
bool isConstantWidthTransition() const
detects whether a given junction splits or merges lanes while keeping constant road width ...
void computeRightOutgoingLinkCrossings(NBEdge *from, NBEdge *to)
computes the relationships between links outgoing right of the given link */
static double firstIntersection(const PositionVector &v1, const PositionVector &v2, double width2)
compute the first intersection point between the given lane geometries considering their rspective wi...
std::vector< bool > myHaveVia
Storage for edges, including some functionality operating on multiple edges.
The link is a (hard) right direction.
const std::string & getResponse(int linkIndex) const
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
The link is a partial right direction.
description of a logic request within the junction
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
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.
const EdgeVector & myAll
all (icoming and outgoing) of the junctions edges
int tlLinkIndex
The index of this connection within the controlling traffic light.
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
bool oppositeLeftTurnConflict(const NBEdge *from, const NBEdge::Connection &con, const NBEdge *prohibitorFrom, const NBEdge::Connection &prohibitorCon, bool foes) const
whether opposite left turns intersect
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
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 ...
NBEdge * getTo() const
returns the to-edge (end of the connection)
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...
Connection getConnection(int fromLane, const NBEdge *to, int toLane) const
Returns the specified connection This method goes through "myConnections" and returns the specified o...
double getLaneWidth() const
Returns the default width of lanes of this edge.
bool isBentPriority()
return whether a priority road turns at this node
double length() const
Returns the length.
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
PositionVector viaShape
shape of via
int computeCrossingResponse(const NBNode::Crossing &crossing, int pos)
computes the response of a certain crossing Returns the next link index within the junction ...
const std::vector< Connection > & getConnections() const
Returns the connections.
std::vector< std::string > myFoes
precomputed right-of-way matrices for each lane-to-lane link
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
friend std::ostream & operator<<(std::ostream &os, const NBRequest &r)
prints the request
SumoXMLNodeType getType() const
Returns the type of this node.
std::string getFoesString(NBEdge *from, NBEdge *to, int fromLane, int toLane, const bool checkLaneFoes) const
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
EdgeVector edges
The edges being crossed.
Represents a single node (junction) during network building.
A definition of a pedestrian crossing.
Static storage of an output device and its base (abstract) implementation.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
NBNode * getFromNode() const
Returns the origin node of the edge.
std::vector< std::string > myResponse
int distanceCounterClockwise(NBEdge *from, NBEdge *to)
returns the distance between the incoming (from) and the outgoing (to) edge clockwise in edges ...
OutputDevice & writePadding(const std::string &val)
writes padding (ignored for binary output)
NBNode * getToNode() const
Returns the destination node of the edge.
void resetCooperating()
reset foes it the number of lanes matches (or exceeds) the number of incoming connections for an edge...
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
CombinationsCont myForbids
the link X link blockings
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.