Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 :
36 :
37 : // ===========================================================================
38 : // method definitions
39 : // ===========================================================================
40 318910 : MSRightOfWayJunction::MSRightOfWayJunction(const std::string& id,
41 : SumoXMLNodeType type,
42 : const Position& position,
43 : const PositionVector& shape,
44 : const std::string& name,
45 : std::vector<MSLane*> incoming,
46 : std::vector<MSLane*> internal,
47 318910 : MSJunctionLogic* logic) : MSLogicJunction(id, type, position, shape, name, incoming, internal),
48 318910 : myLogic(logic) {}
49 :
50 :
51 587120 : MSRightOfWayJunction::~MSRightOfWayJunction() {
52 293560 : delete myLogic;
53 587120 : }
54 :
55 :
56 : void
57 318070 : MSRightOfWayJunction::postloadInit() {
58 : // inform links where they have to report approaching vehicles to
59 318070 : int requestPos = 0;
60 : // going through the incoming lanes...
61 : int maxNo = 0;
62 : std::vector<std::pair<const MSLane*, MSLink*> > sortedLinks;
63 1241634 : for (MSLane* const lane : myIncomingLanes) {
64 : // ... set information for every link
65 2645306 : for (MSLink* const link : lane->getLinkCont()) {
66 1721742 : if (link->getLane()->getEdge().isWalkingArea() ||
67 30652 : (lane->getEdge().isWalkingArea() && !link->getLane()->getEdge().isCrossing())) {
68 109608 : continue;
69 : }
70 1612134 : sortedLinks.emplace_back(lane, link);
71 1612134 : ++maxNo;
72 : }
73 : }
74 :
75 318070 : const bool hasFoes = myLogic->hasFoes();
76 1241630 : for (const MSLane* const lane : myIncomingLanes) {
77 : // ... set information for every link
78 : const MSLane* walkingAreaFoe = nullptr;
79 2645302 : for (MSLink* const link : lane->getLinkCont()) {
80 1721742 : if (link->getLane()->getEdge().isWalkingArea()) {
81 94537 : if (lane->getPermissions() != SVC_PEDESTRIAN) {
82 : // vehicular lane connects to a walkingarea
83 : walkingAreaFoe = link->getLane();
84 : }
85 109608 : continue;
86 1627205 : } else if ((lane->getEdge().isWalkingArea() && !link->getLane()->getEdge().isCrossing())) {
87 15071 : continue;
88 : }
89 1612134 : if (myLogic->getLogicSize() <= requestPos) {
90 16 : throw ProcessError("Found invalid logic position of a link for junction '" + getID() + "' (" + toString(requestPos) + ", max " + toString(myLogic->getLogicSize()) + ") -> (network error)");
91 : }
92 1612130 : const MSLogicJunction::LinkBits& linkResponse = myLogic->getResponseFor(requestPos); // SUMO_ATTR_RESPONSE
93 1612130 : const MSLogicJunction::LinkBits& linkFoes = myLogic->getFoesFor(requestPos); // SUMO_ATTR_FOES
94 1612130 : bool cont = myLogic->getIsCont(requestPos);
95 18318850 : for (int c = 0; c < maxNo; ++c) {
96 16706720 : if (linkResponse.test(c)) {
97 2603982 : MSLink* foe = sortedLinks[c].second;
98 2603982 : myLinkFoeLinks[link].push_back(foe);
99 2603982 : if (MSGlobals::gUsingInternalLanes && foe->getViaLane() != nullptr) {
100 : assert(foe->getViaLane()->getLinkCont().size() == 1);
101 1187745 : MSLink* foeExitLink = foe->getViaLane()->getLinkCont()[0];
102 : // add foe links after an internal junction
103 1187745 : if (foeExitLink->getViaLane() != nullptr) {
104 316756 : myLinkFoeLinks[link].push_back(foeExitLink);
105 : }
106 : }
107 : }
108 : }
109 : std::vector<MSLink*> foes;
110 18318850 : for (int c = 0; c < maxNo; ++c) {
111 16706720 : if (linkFoes.test(c)) {
112 5075746 : MSLink* foe = sortedLinks[c].second;
113 5075746 : foes.push_back(foe);
114 : MSLane* l = foe->getViaLane();
115 5075746 : if (l == nullptr) {
116 2745735 : continue;
117 : }
118 : // add foe links after an internal junction
119 4660022 : for (MSLink* const vLink : l->getLinkCont()) {
120 2330011 : if (vLink->getViaLane() != nullptr) {
121 704318 : foes.push_back(vLink);
122 : }
123 : }
124 : }
125 : }
126 :
127 1612130 : if (MSGlobals::gUsingInternalLanes && myInternalLanes.size() > 0) {
128 : int li = 0;
129 8695958 : for (int c = 0; c < (int)sortedLinks.size(); ++c) {
130 7917941 : if (sortedLinks[c].second->getLane() == nullptr) { // dead end
131 0 : continue;
132 : }
133 7917941 : if (linkFoes.test(c)) {
134 2421428 : myLinkFoeInternalLanes[link].push_back(myInternalLanes[li]);
135 3577163 : if (linkResponse.test(c) || sortedLinks[c].second->isIndirect() ||
136 1155735 : link->getLane()->getBidiLane() == sortedLinks[c].second->getLaneBefore()) {
137 1268692 : const std::vector<MSLane::IncomingLaneInfo>& l = myInternalLanes[li]->getIncomingLanes();
138 1268692 : if (l.size() == 1 && l[0].lane->getEdge().isInternal()) {
139 316973 : myLinkFoeInternalLanes[link].push_back(l[0].lane);
140 : }
141 : }
142 : }
143 7917941 : ++li;
144 : }
145 : }
146 1612130 : link->setRequestInformation((int)requestPos, hasFoes, cont, myLinkFoeLinks[link], myLinkFoeInternalLanes[link]);
147 : // the exit link for a link before an internal junction is handled in MSInternalJunction
148 : // so we need to skip if cont=true
149 1612130 : if (MSGlobals::gUsingInternalLanes && link->getViaLane() != nullptr && !cont) {
150 : assert(link->getViaLane()->getLinkCont().size() == 1);
151 609867 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
152 609867 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
153 609867 : myLinkFoeInternalLanes[link], link->getViaLane());
154 2027728 : for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
155 1423844 : if (ili.lane->getEdge().isWalkingArea()) {
156 : exitLink->addWalkingAreaFoeExit(ili.lane);
157 : break;
158 : }
159 : }
160 : }
161 : // the exit link for a crossing is needed for the pedestrian model
162 1612130 : if (MSGlobals::gUsingInternalLanes && link->getLane()->getEdge().isCrossing()) {
163 15581 : MSLink* exitLink = link->getLane()->getLinkCont()[0];
164 15581 : exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
165 15581 : myLinkFoeInternalLanes[link], link->getLane());
166 : }
167 1612130 : requestPos++;
168 1612130 : }
169 923560 : if (walkingAreaFoe != nullptr && lane->getLinkCont().size() > 1) {
170 11780 : for (const MSLink* const link : lane->getLinkCont()) {
171 9187 : if (!link->getLane()->getEdge().isWalkingArea()) {
172 6594 : MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
173 : exitLink->addWalkingAreaFoe(walkingAreaFoe);
174 : }
175 : }
176 : }
177 : }
178 318070 : }
179 :
180 :
181 : /****************************************************************************/
|