Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 297949 : 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 297949 : MSJunctionLogic* logic) : MSLogicJunction(id, type, position, shape, name, incoming, internal),
49 297949 : myLogic(logic) {}
50 :
51 :
52 589926 : MSRightOfWayJunction::~MSRightOfWayJunction() {
53 294963 : delete myLogic;
54 589926 : }
55 :
56 :
57 : void
58 297109 : MSRightOfWayJunction::postloadInit() {
59 : // inform links where they have to report approaching vehicles to
60 297109 : int requestPos = 0;
61 : // going through the incoming lanes...
62 : int maxNo = 0;
63 : std::vector<std::pair<const MSLane*, MSLink*> > sortedLinks;
64 1179354 : for (MSLane* const lane : myIncomingLanes) {
65 : // ... set information for every link
66 2577734 : for (MSLink* const link : lane->getLinkCont()) {
67 3275572 : if (link->getLane()->isWalkingArea() ||
68 1614820 : (lane->isWalkingArea() && !link->getLane()->isCrossing())) {
69 132557 : continue;
70 : }
71 1562932 : sortedLinks.emplace_back(lane, link);
72 1562932 : ++maxNo;
73 : }
74 : }
75 :
76 297109 : const bool hasFoes = myLogic->hasFoes();
77 1179350 : for (const MSLane* const lane : myIncomingLanes) {
78 : // ... set information for every link
79 : const MSLane* walkingAreaFoe = nullptr;
80 2577730 : for (MSLink* const link : lane->getLinkCont()) {
81 1695489 : if (link->getLane()->isWalkingArea()) {
82 115406 : if (lane->getPermissions() != SVC_PEDESTRIAN) {
83 : // vehicular lane connects to a walkingarea
84 2222 : walkingAreaFoe = link->getLane();
85 : }
86 132557 : continue;
87 1580083 : } else if ((lane->isWalkingArea() && !link->getLane()->isCrossing())) {
88 17151 : continue;
89 : }
90 1562932 : 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 1562928 : const MSLogicJunction::LinkBits& linkResponse = myLogic->getResponseFor(requestPos); // SUMO_ATTR_RESPONSE
94 1562928 : const MSLogicJunction::LinkBits& linkFoes = myLogic->getFoesFor(requestPos); // SUMO_ATTR_FOES
95 1562928 : bool cont = myLogic->getIsCont(requestPos);
96 17873246 : for (int c = 0; c < maxNo; ++c) {
97 16310318 : if (linkResponse.test(c)) {
98 2590575 : MSLink* foe = sortedLinks[c].second;
99 2590575 : myLinkFoeLinks[link].push_back(foe);
100 2590575 : if (MSGlobals::gUsingInternalLanes && foe->getViaLane() != nullptr) {
101 : assert(foe->getViaLane()->getLinkCont().size() == 1);
102 1075965 : MSLink* foeExitLink = foe->getViaLane()->getLinkCont()[0];
103 : // add foe links after an internal junction
104 1075965 : if (foeExitLink->getViaLane() != nullptr) {
105 295266 : myLinkFoeLinks[link].push_back(foeExitLink);
106 : }
107 : }
108 : }
109 : }
110 : std::vector<MSLink*> foes;
111 17873246 : for (int c = 0; c < maxNo; ++c) {
112 16310318 : if (linkFoes.test(c)) {
113 5020763 : MSLink* foe = sortedLinks[c].second;
114 5020763 : foes.push_back(foe);
115 : MSLane* l = foe->getViaLane();
116 5020763 : if (l == nullptr) {
117 2923571 : continue;
118 : }
119 : // add foe links after an internal junction
120 4194384 : for (MSLink* const vLink : l->getLinkCont()) {
121 2097192 : if (vLink->getViaLane() != nullptr) {
122 668367 : foes.push_back(vLink);
123 : }
124 : }
125 : }
126 : }
127 :
128 1562928 : if (MSGlobals::gUsingInternalLanes && myInternalLanes.size() > 0) {
129 : int li = 0;
130 7648650 : for (int c = 0; c < (int)sortedLinks.size(); ++c) {
131 6974433 : if (sortedLinks[c].second->getLane() == nullptr) { // dead end
132 0 : continue;
133 : }
134 6974433 : 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 2198365 : myLinkFoeInternalLanes[link].push_back(myInternalLanes[li]);
141 3141587 : if (link->getLane()->isCrossing() || linkResponse.test(c) || sortedLinks[c].second->isIndirect() ||
142 943222 : link->getLane()->getBidiLane() == sortedLinks[c].second->getLaneBefore()) {
143 1258228 : const std::vector<MSLane::IncomingLaneInfo>& l = myInternalLanes[li]->getIncomingLanes();
144 1258228 : if (l.size() == 1 && l[0].lane->getEdge().isInternal()) {
145 331482 : myLinkFoeInternalLanes[link].push_back(l[0].lane);
146 : }
147 : }
148 : }
149 6974433 : ++li;
150 : }
151 : }
152 1562928 : 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 1562928 : if (MSGlobals::gUsingInternalLanes && link->getViaLane() != nullptr && !cont) {
156 : assert(link->getViaLane()->getLinkCont().size() == 1);
157 508365 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
158 508365 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
159 508365 : myLinkFoeInternalLanes[link], link->getViaLane());
160 1689672 : for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
161 1186438 : if (ili.lane->isWalkingArea()) {
162 5131 : exitLink->addWalkingAreaFoeExit(ili.lane);
163 : break;
164 : }
165 : }
166 : }
167 : // the exit link for a crossing is needed for the pedestrian model
168 1562928 : if (MSGlobals::gUsingInternalLanes && link->getLane()->isCrossing()) {
169 17586 : MSLink* exitLink = link->getLane()->getLinkCont()[0];
170 17586 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
171 17586 : myLinkFoeInternalLanes[link], link->getLane());
172 : }
173 1562928 : requestPos++;
174 1562928 : }
175 882241 : if (walkingAreaFoe != nullptr && lane->getLinkCont().size() > 1) {
176 10000 : for (const MSLink* const link : lane->getLinkCont()) {
177 7806 : if (!link->getLane()->isWalkingArea()) {
178 5612 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
179 : exitLink->addWalkingAreaFoe(walkingAreaFoe);
180 : }
181 : }
182 : }
183 : }
184 297109 : }
185 :
186 :
187 : /****************************************************************************/
|