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 MSInternalJunction.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 "MSRightOfWayJunction.h"
29 : #include "MSLane.h"
30 : #include "MSLink.h"
31 : #include "MSEdge.h"
32 : #include "MSJunctionLogic.h"
33 : #include "MSInternalJunction.h"
34 :
35 :
36 : // ===========================================================================
37 : // method definitions
38 : // ===========================================================================
39 152632 : MSInternalJunction::MSInternalJunction(const std::string& id,
40 : SumoXMLNodeType type,
41 : const Position& position,
42 : const PositionVector& shape,
43 : std::vector<MSLane*> incoming,
44 152632 : std::vector<MSLane*> internal)
45 305264 : : MSLogicJunction(id, type, position, shape, "", incoming, internal) {}
46 :
47 :
48 :
49 282790 : MSInternalJunction::~MSInternalJunction() {}
50 :
51 :
52 : void
53 152616 : MSInternalJunction::postloadInit() {
54 152616 : if (myIncomingLanes.size() == 0) {
55 0 : throw ProcessError(TLF("Internal junction % has no incoming lanes", getID()));
56 : }
57 : // the first lane in the list of incoming lanes is special. It defines the
58 : // link that needs to do all the checking for this internal junction
59 152616 : const MSLane* specialLane = myIncomingLanes[0];
60 : assert(specialLane->getLinkCont().size() == 1);
61 152616 : MSLink* thisLink = specialLane->getLinkCont()[0];
62 152616 : const MSRightOfWayJunction* parent = dynamic_cast<const MSRightOfWayJunction*>(specialLane->getEdge().getToJunction());
63 152616 : if (parent == nullptr) {
64 : // parent has type traffic_light_unregulated
65 : return;
66 : }
67 152569 : const int ownLinkIndex = specialLane->getIncomingLanes()[0].viaLink->getIndex();
68 152569 : const MSLogicJunction::LinkBits& response = parent->getLogic()->getResponseFor(ownLinkIndex);
69 : // inform links where they have to report approaching vehicles to
70 : //std::cout << " special=" << specialLane->getID() << " incoming=" << toString(myIncomingLanes) << " internal=" << toString(myInternalLanes) << "\n";
71 867741 : for (MSLane* const lane : myInternalLanes) {
72 1430344 : for (MSLink* const link : lane->getLinkCont()) {
73 715172 : if (link->getViaLane() != nullptr) {
74 95119 : const int foeIndex = lane->getIncomingLanes()[0].viaLink->getIndex();
75 : //std::cout << " response=" << response << " index=" << ownLinkIndex << " foeIndex=" << foeIndex << " ibct=" << indirectBicycleTurn(specialLane, thisLink, *i, *q) << "\n";
76 95119 : if (response.test(foeIndex) || indirectBicycleTurn(specialLane, thisLink, lane, link)) {
77 : // only respect vehicles before internal junctions if they
78 : // have priority (see the analogous foeLinks.test() when
79 : // initializing myLinkFoeInternalLanes in MSRightOfWayJunction
80 : // Indirect left turns for bicycles are a special case
81 : // because they both intersect on their second part with the first part of the other one
82 : // and only one of the has priority
83 61275 : myInternalLaneFoes.push_back(lane);
84 : }
85 95119 : if (std::find(myInternalLaneFoes.begin(), myInternalLaneFoes.end(), link->getViaLane()) == myInternalLaneFoes.end()) {
86 94782 : myInternalLaneFoes.push_back(link->getViaLane());
87 : }
88 : } else {
89 620053 : if (std::find(myInternalLaneFoes.begin(), myInternalLaneFoes.end(), lane) == myInternalLaneFoes.end()) {
90 618571 : myInternalLaneFoes.push_back(lane);
91 618571 : if (lane->isCrossing()) {
92 : // also add to myInternalLinkFoes (the origin
93 : // walkingArea is not part of myIncomingLanes)
94 34957 : myInternalLinkFoes.push_back(lane->getIncomingLanes()[0].viaLink);
95 : }
96 : }
97 : }
98 : }
99 : //std::cout << " intLane=" << lane->getID() << " foes=" << toString(myInternalLaneFoes) << "\n";
100 :
101 : }
102 437636 : for (std::vector<MSLane*>::const_iterator i = myIncomingLanes.begin() + 1; i != myIncomingLanes.end(); ++i) {
103 1033707 : for (MSLink* const link : (*i)->getLinkCont()) {
104 : // link indices of internal junctions may not be initialized yet
105 748640 : int linkIndex = link->getCorrespondingEntryLink()->getIndex();
106 : // links that target a shared walkingarea always have index -1
107 748640 : if (linkIndex != -1 && response.test(linkIndex)) {
108 336109 : myInternalLinkFoes.push_back(link);
109 : const MSLane* via = link->getViaLane();
110 336109 : if (via != nullptr && via->getLinkCont().front()->getViaLane() != nullptr) {
111 : // we added the entry link, also use the internalJunctionLink that follows
112 25607 : myInternalLinkFoes.push_back(via->getLinkCont().front());
113 : }
114 : }
115 : }
116 : }
117 : // thisLinks is itself an exitLink of the preceding internal lane
118 152569 : thisLink->setRequestInformation(ownLinkIndex, true, false, myInternalLinkFoes, myInternalLaneFoes, thisLink->getViaLane()->getLogicalPredecessorLane());
119 : assert(thisLink->getViaLane()->getLinkCont().size() == 1);
120 152569 : MSLink* exitLink = thisLink->getViaLane()->getLinkCont()[0];
121 152569 : exitLink->setRequestInformation(ownLinkIndex, false, false, std::vector<MSLink*>(),
122 : myInternalLaneFoes, thisLink->getViaLane());
123 641486 : for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
124 489601 : if (ili.lane->getEdge().isWalkingArea()) {
125 : exitLink->addWalkingAreaFoeExit(ili.lane);
126 : break;
127 : }
128 : }
129 : }
130 :
131 :
132 : bool
133 33880 : MSInternalJunction::indirectBicycleTurn(const MSLane* specialLane, const MSLink* thisLink, const MSLane* foeFirstPart, const MSLink* foeLink) const {
134 3975 : if (specialLane->getPermissions() == SVC_BICYCLE && foeFirstPart->getPermissions() == SVC_BICYCLE
135 484 : && thisLink->getDirection() == LinkDirection::LEFT && foeLink->getDirection() == LinkDirection::LEFT
136 208 : && thisLink->getViaLane() != nullptr
137 34088 : && thisLink->getViaLane()->getShape().intersects(foeFirstPart->getShape())) {
138 : return true;
139 : } else {
140 33844 : return false;
141 : }
142 : }
143 :
144 :
145 : /****************************************************************************/
|