Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/microsim/MSInternalJunction.cpp
185785 views
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 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
MSInternalJunction::MSInternalJunction(const std::string& id,
40
SumoXMLNodeType type,
41
const Position& position,
42
const PositionVector& shape,
43
std::vector<MSLane*> incoming,
44
std::vector<MSLane*> internal)
45
: MSLogicJunction(id, type, position, shape, "", incoming, internal) {}
46
47
48
49
MSInternalJunction::~MSInternalJunction() {}
50
51
52
void
53
MSInternalJunction::postloadInit() {
54
if (myIncomingLanes.size() == 0) {
55
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
const MSLane* specialLane = myIncomingLanes[0];
60
assert(specialLane->getLinkCont().size() == 1);
61
MSLink* thisLink = specialLane->getLinkCont()[0];
62
const MSRightOfWayJunction* parent = dynamic_cast<const MSRightOfWayJunction*>(specialLane->getEdge().getToJunction());
63
if (parent == nullptr) {
64
// parent has type traffic_light_unregulated
65
return;
66
}
67
const int ownLinkIndex = specialLane->getIncomingLanes()[0].viaLink->getIndex();
68
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
for (MSLane* const lane : myInternalLanes) {
72
for (MSLink* const link : lane->getLinkCont()) {
73
if (link->getViaLane() != nullptr) {
74
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
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 them has priority
83
myInternalLaneFoes.push_back(lane);
84
}
85
if (std::find(myInternalLaneFoes.begin(), myInternalLaneFoes.end(), link->getViaLane()) == myInternalLaneFoes.end()) {
86
myInternalLaneFoes.push_back(link->getViaLane());
87
}
88
} else {
89
if (std::find(myInternalLaneFoes.begin(), myInternalLaneFoes.end(), lane) == myInternalLaneFoes.end()) {
90
myInternalLaneFoes.push_back(lane);
91
if (lane->isCrossing()) {
92
// also add to myInternalLinkFoes (the origin
93
// walkingArea is not part of myIncomingLanes)
94
myInternalLinkFoes.push_back(lane->getIncomingLanes()[0].viaLink);
95
}
96
}
97
}
98
}
99
//std::cout << " intLane=" << lane->getID() << " foes=" << toString(myInternalLaneFoes) << "\n";
100
101
}
102
for (std::vector<MSLane*>::const_iterator i = myIncomingLanes.begin() + 1; i != myIncomingLanes.end(); ++i) {
103
for (MSLink* const link : (*i)->getLinkCont()) {
104
// link indices of internal junctions may not be initialized yet
105
int linkIndex = link->getCorrespondingEntryLink()->getIndex();
106
// links that target a shared walkingarea always have index -1
107
if (linkIndex != -1 && response.test(linkIndex)) {
108
myInternalLinkFoes.push_back(link);
109
const MSLane* via = link->getViaLane();
110
if (via != nullptr && via->getLinkCont().front()->getViaLane() != nullptr) {
111
// we added the entry link, also use the internalJunctionLink that follows
112
myInternalLinkFoes.push_back(via->getLinkCont().front());
113
}
114
}
115
}
116
}
117
// thisLinks is itself an exitLink of the preceding internal lane
118
thisLink->setRequestInformation(ownLinkIndex, true, false, myInternalLinkFoes, myInternalLaneFoes, thisLink->getViaLane()->getLogicalPredecessorLane());
119
assert(thisLink->getViaLane()->getLinkCont().size() == 1);
120
MSLink* exitLink = thisLink->getViaLane()->getLinkCont()[0];
121
exitLink->setRequestInformation(ownLinkIndex, false, false, std::vector<MSLink*>(),
122
myInternalLaneFoes, thisLink->getViaLane());
123
for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
124
if (ili.lane->isWalkingArea()) {
125
exitLink->addWalkingAreaFoeExit(ili.lane);
126
break;
127
}
128
}
129
}
130
131
132
bool
133
MSInternalJunction::indirectBicycleTurn(const MSLane* specialLane, const MSLink* thisLink, const MSLane* foeFirstPart, const MSLink* foeLink) const {
134
if (specialLane->getPermissions() == SVC_BICYCLE && foeFirstPart->getPermissions() == SVC_BICYCLE
135
&& thisLink->getDirection() == LinkDirection::LEFT && foeLink->getDirection() == LinkDirection::LEFT
136
&& thisLink->getViaLane() != nullptr
137
&& thisLink->getViaLane()->getShape().intersects(foeFirstPart->getShape())) {
138
return true;
139
} else {
140
return false;
141
}
142
}
143
144
145
/****************************************************************************/
146
147