Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file MSRightOfWayJunction.cpp
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Michael Behrisch
18 : /// @author Jakob Erdmann
19 : /// @date Wed, 12 Dez 2001
20 : ///
21 : // junction.
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <algorithm>
26 : #include <cassert>
27 : #include <cmath>
28 : #include <utils/common/RandHelper.h>
29 : #include "MSEdge.h"
30 : #include "MSJunctionLogic.h"
31 : #include "MSGlobals.h"
32 : #include "MSLane.h"
33 : #include "MSLink.h"
34 : #include "MSRightOfWayJunction.h"
35 : #include <utils/common/MsgHandler.h>
36 :
37 :
38 : // ===========================================================================
39 : // method definitions
40 : // ===========================================================================
41 279287 : MSRightOfWayJunction::MSRightOfWayJunction(const std::string& id,
42 : SumoXMLNodeType type,
43 : const Position& position,
44 : const PositionVector& shape,
45 : const std::string& name,
46 : std::vector<MSLane*> incoming,
47 : std::vector<MSLane*> internal,
48 279287 : MSJunctionLogic* logic) : MSLogicJunction(id, type, position, shape, name, incoming, internal),
49 279287 : myLogic(logic) {}
50 :
51 :
52 552756 : MSRightOfWayJunction::~MSRightOfWayJunction() {
53 276378 : delete myLogic;
54 552756 : }
55 :
56 :
57 : void
58 278447 : MSRightOfWayJunction::postloadInit() {
59 : // inform links where they have to report approaching vehicles to
60 278447 : int requestPos = 0;
61 : // going through the incoming lanes...
62 : int maxNo = 0;
63 : std::vector<std::pair<const MSLane*, MSLink*> > sortedLinks;
64 1105096 : for (MSLane* const lane : myIncomingLanes) {
65 : // ... set information for every link
66 2444257 : for (MSLink* const link : lane->getLinkCont()) {
67 1617608 : if (link->getLane()->getEdge().isWalkingArea() ||
68 32208 : (lane->getEdge().isWalkingArea() && !link->getLane()->getEdge().isCrossing())) {
69 115903 : continue;
70 : }
71 1501705 : sortedLinks.emplace_back(lane, link);
72 1501705 : ++maxNo;
73 : }
74 : }
75 :
76 278447 : const bool hasFoes = myLogic->hasFoes();
77 1105092 : for (const MSLane* const lane : myIncomingLanes) {
78 : // ... set information for every link
79 : const MSLane* walkingAreaFoe = nullptr;
80 2444253 : for (MSLink* const link : lane->getLinkCont()) {
81 1617608 : if (link->getLane()->getEdge().isWalkingArea()) {
82 100055 : if (lane->getPermissions() != SVC_PEDESTRIAN) {
83 : // vehicular lane connects to a walkingarea
84 : walkingAreaFoe = link->getLane();
85 : }
86 115903 : continue;
87 1517553 : } else if ((lane->getEdge().isWalkingArea() && !link->getLane()->getEdge().isCrossing())) {
88 15848 : continue;
89 : }
90 1501705 : if (myLogic->getLogicSize() <= requestPos) {
91 12 : throw ProcessError(TLF("Found invalid logic position of a link for junction '%' (%, max %) -> (network error)", getID(), toString(requestPos), toString(myLogic->getLogicSize())));
92 : }
93 1501701 : const MSLogicJunction::LinkBits& linkResponse = myLogic->getResponseFor(requestPos); // SUMO_ATTR_RESPONSE
94 1501701 : const MSLogicJunction::LinkBits& linkFoes = myLogic->getFoesFor(requestPos); // SUMO_ATTR_FOES
95 1501701 : bool cont = myLogic->getIsCont(requestPos);
96 17357592 : for (int c = 0; c < maxNo; ++c) {
97 15855891 : if (linkResponse.test(c)) {
98 2516339 : MSLink* foe = sortedLinks[c].second;
99 2516339 : myLinkFoeLinks[link].push_back(foe);
100 2516339 : if (MSGlobals::gUsingInternalLanes && foe->getViaLane() != nullptr) {
101 : assert(foe->getViaLane()->getLinkCont().size() == 1);
102 1038223 : MSLink* foeExitLink = foe->getViaLane()->getLinkCont()[0];
103 : // add foe links after an internal junction
104 1038223 : if (foeExitLink->getViaLane() != nullptr) {
105 282517 : myLinkFoeLinks[link].push_back(foeExitLink);
106 : }
107 : }
108 : }
109 : }
110 : std::vector<MSLink*> foes;
111 17357592 : for (int c = 0; c < maxNo; ++c) {
112 15855891 : if (linkFoes.test(c)) {
113 4881802 : MSLink* foe = sortedLinks[c].second;
114 4881802 : foes.push_back(foe);
115 : MSLane* l = foe->getViaLane();
116 4881802 : if (l == nullptr) {
117 2860883 : continue;
118 : }
119 : // add foe links after an internal junction
120 4041838 : for (MSLink* const vLink : l->getLinkCont()) {
121 2020919 : if (vLink->getViaLane() != nullptr) {
122 639192 : foes.push_back(vLink);
123 : }
124 : }
125 : }
126 : }
127 :
128 1501701 : if (MSGlobals::gUsingInternalLanes && myInternalLanes.size() > 0) {
129 : int li = 0;
130 7334410 : for (int c = 0; c < (int)sortedLinks.size(); ++c) {
131 6700303 : if (sortedLinks[c].second->getLane() == nullptr) { // dead end
132 0 : continue;
133 : }
134 6700303 : if (linkFoes.test(c)) {
135 : // vehicles waiting at an internal junction can mostly be ignored. The main exceptions are:
136 : // - they are on the main road and the current link is from a side road
137 : // - its a tls and the current link is on a side road relative to the internal junction
138 : // both cases are encoded in a positive linkResponse
139 : // (case 2 only if netconvert option --tls.ignore-internal-junction-jam was not set)
140 2117126 : myLinkFoeInternalLanes[link].push_back(myInternalLanes[li]);
141 3113413 : if (linkResponse.test(c) || sortedLinks[c].second->isIndirect() ||
142 996287 : link->getLane()->getBidiLane() == sortedLinks[c].second->getLaneBefore()) {
143 1123924 : const std::vector<MSLane::IncomingLaneInfo>& l = myInternalLanes[li]->getIncomingLanes();
144 1123924 : if (l.size() == 1 && l[0].lane->getEdge().isInternal()) {
145 282792 : myLinkFoeInternalLanes[link].push_back(l[0].lane);
146 : }
147 : }
148 : }
149 6700303 : ++li;
150 : }
151 : }
152 1501701 : link->setRequestInformation((int)requestPos, hasFoes, cont, myLinkFoeLinks[link], myLinkFoeInternalLanes[link]);
153 : // the exit link for a link before an internal junction is handled in MSInternalJunction
154 : // so we need to skip if cont=true
155 1501701 : if (MSGlobals::gUsingInternalLanes && link->getViaLane() != nullptr && !cont) {
156 : assert(link->getViaLane()->getLinkCont().size() == 1);
157 476978 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
158 476978 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
159 476978 : myLinkFoeInternalLanes[link], link->getViaLane());
160 1601563 : for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
161 1130712 : if (ili.lane->getEdge().isWalkingArea()) {
162 : exitLink->addWalkingAreaFoeExit(ili.lane);
163 : break;
164 : }
165 : }
166 : }
167 : // the exit link for a crossing is needed for the pedestrian model
168 1501701 : if (MSGlobals::gUsingInternalLanes && link->getLane()->getEdge().isCrossing()) {
169 16360 : MSLink* exitLink = link->getLane()->getLinkCont()[0];
170 16360 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
171 16360 : myLinkFoeInternalLanes[link], link->getLane());
172 : }
173 1501701 : requestPos++;
174 1501701 : }
175 826645 : if (walkingAreaFoe != nullptr && lane->getLinkCont().size() > 1) {
176 12057 : for (const MSLink* const link : lane->getLinkCont()) {
177 9413 : if (!link->getLane()->getEdge().isWalkingArea()) {
178 6769 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
179 : exitLink->addWalkingAreaFoe(walkingAreaFoe);
180 : }
181 : }
182 : }
183 : }
184 278447 : }
185 :
186 :
187 : /****************************************************************************/
|