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 281251 : 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 281251 : MSJunctionLogic* logic) : MSLogicJunction(id, type, position, shape, name, incoming, internal),
49 281251 : myLogic(logic) {}
50 :
51 :
52 556578 : MSRightOfWayJunction::~MSRightOfWayJunction() {
53 278289 : delete myLogic;
54 556578 : }
55 :
56 :
57 : void
58 280411 : MSRightOfWayJunction::postloadInit() {
59 : // inform links where they have to report approaching vehicles to
60 280411 : int requestPos = 0;
61 : // going through the incoming lanes...
62 : int maxNo = 0;
63 : std::vector<std::pair<const MSLane*, MSLink*> > sortedLinks;
64 1113324 : for (MSLane* const lane : myIncomingLanes) {
65 : // ... set information for every link
66 2462422 : for (MSLink* const link : lane->getLinkCont()) {
67 3158827 : if (link->getLane()->isWalkingArea() ||
68 1561638 : (lane->isWalkingArea() && !link->getLane()->isCrossing())) {
69 116087 : continue;
70 : }
71 1513422 : sortedLinks.emplace_back(lane, link);
72 1513422 : ++maxNo;
73 : }
74 : }
75 :
76 280411 : const bool hasFoes = myLogic->hasFoes();
77 1113320 : for (const MSLane* const lane : myIncomingLanes) {
78 : // ... set information for every link
79 : const MSLane* walkingAreaFoe = nullptr;
80 2462418 : for (MSLink* const link : lane->getLinkCont()) {
81 1629509 : if (link->getLane()->isWalkingArea()) {
82 100191 : if (lane->getPermissions() != SVC_PEDESTRIAN) {
83 : // vehicular lane connects to a walkingarea
84 2672 : walkingAreaFoe = link->getLane();
85 : }
86 116087 : continue;
87 1529318 : } else if ((lane->isWalkingArea() && !link->getLane()->isCrossing())) {
88 15896 : continue;
89 : }
90 1513422 : 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 1513418 : const MSLogicJunction::LinkBits& linkResponse = myLogic->getResponseFor(requestPos); // SUMO_ATTR_RESPONSE
94 1513418 : const MSLogicJunction::LinkBits& linkFoes = myLogic->getFoesFor(requestPos); // SUMO_ATTR_FOES
95 1513418 : bool cont = myLogic->getIsCont(requestPos);
96 17465310 : for (int c = 0; c < maxNo; ++c) {
97 15951892 : if (linkResponse.test(c)) {
98 2532652 : MSLink* foe = sortedLinks[c].second;
99 2532652 : myLinkFoeLinks[link].push_back(foe);
100 2532652 : if (MSGlobals::gUsingInternalLanes && foe->getViaLane() != nullptr) {
101 : assert(foe->getViaLane()->getLinkCont().size() == 1);
102 1044240 : MSLink* foeExitLink = foe->getViaLane()->getLinkCont()[0];
103 : // add foe links after an internal junction
104 1044240 : if (foeExitLink->getViaLane() != nullptr) {
105 284099 : myLinkFoeLinks[link].push_back(foeExitLink);
106 : }
107 : }
108 : }
109 : }
110 : std::vector<MSLink*> foes;
111 17465310 : for (int c = 0; c < maxNo; ++c) {
112 15951892 : if (linkFoes.test(c)) {
113 4913728 : MSLink* foe = sortedLinks[c].second;
114 4913728 : foes.push_back(foe);
115 : MSLane* l = foe->getViaLane();
116 4913728 : if (l == nullptr) {
117 2881187 : continue;
118 : }
119 : // add foe links after an internal junction
120 4065082 : for (MSLink* const vLink : l->getLinkCont()) {
121 2032541 : if (vLink->getViaLane() != nullptr) {
122 642989 : foes.push_back(vLink);
123 : }
124 : }
125 : }
126 : }
127 :
128 1513418 : if (MSGlobals::gUsingInternalLanes && myInternalLanes.size() > 0) {
129 : int li = 0;
130 7378092 : for (int c = 0; c < (int)sortedLinks.size(); ++c) {
131 6740209 : if (sortedLinks[c].second->getLane() == nullptr) { // dead end
132 0 : continue;
133 : }
134 6740209 : 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 2129000 : myLinkFoeInternalLanes[link].push_back(myInternalLanes[li]);
141 3048773 : if (link->getLane()->isCrossing() || linkResponse.test(c) || sortedLinks[c].second->isIndirect() ||
142 919773 : link->getLane()->getBidiLane() == sortedLinks[c].second->getLaneBefore()) {
143 1212312 : const std::vector<MSLane::IncomingLaneInfo>& l = myInternalLanes[li]->getIncomingLanes();
144 1212312 : if (l.size() == 1 && l[0].lane->getEdge().isInternal()) {
145 318394 : myLinkFoeInternalLanes[link].push_back(l[0].lane);
146 : }
147 : }
148 : }
149 6740209 : ++li;
150 : }
151 : }
152 1513418 : 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 1513418 : if (MSGlobals::gUsingInternalLanes && link->getViaLane() != nullptr && !cont) {
156 : assert(link->getViaLane()->getLinkCont().size() == 1);
157 479826 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
158 479826 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
159 479826 : myLinkFoeInternalLanes[link], link->getViaLane());
160 1611048 : for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
161 1137349 : if (ili.lane->isWalkingArea()) {
162 6127 : exitLink->addWalkingAreaFoeExit(ili.lane);
163 : break;
164 : }
165 : }
166 : }
167 : // the exit link for a crossing is needed for the pedestrian model
168 1513418 : if (MSGlobals::gUsingInternalLanes && link->getLane()->isCrossing()) {
169 16424 : MSLink* exitLink = link->getLane()->getLinkCont()[0];
170 16424 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
171 16424 : myLinkFoeInternalLanes[link], link->getLane());
172 : }
173 1513418 : requestPos++;
174 1513418 : }
175 832909 : if (walkingAreaFoe != nullptr && lane->getLinkCont().size() > 1) {
176 12057 : for (const MSLink* const link : lane->getLinkCont()) {
177 9413 : if (!link->getLane()->isWalkingArea()) {
178 6769 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
179 : exitLink->addWalkingAreaFoe(walkingAreaFoe);
180 : }
181 : }
182 : }
183 : }
184 280411 : }
185 :
186 :
187 : /****************************************************************************/
|