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 NBOwnTLDef.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Sascha Krieg
18 : /// @date Tue, 29.05.2005
19 : ///
20 : // A traffic light logics which must be computed (only nodes/edges are given)
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <vector>
26 : #include <set>
27 : #include <utils/xml/SUMOXMLDefinitions.h>
28 : #include "NBTrafficLightDefinition.h"
29 : #include "NBNode.h"
30 :
31 :
32 : // ===========================================================================
33 : // class declarations
34 : // ===========================================================================
35 :
36 :
37 : // ===========================================================================
38 : // class definitions
39 : // ===========================================================================
40 : /**
41 : * @class NBOwnTLDef
42 : * @brief A traffic light logics which must be computed (only nodes/edges are given)
43 : */
44 : class NBOwnTLDef : public NBTrafficLightDefinition {
45 : public:
46 : /** @brief Constructor
47 : * @param[in] id The id of the tls
48 : * @param[in] junctions Junctions controlled by this tls
49 : * @param[in] offset The offset of the plan
50 : * @param[in] type The algorithm type for the computed traffic light
51 : */
52 : NBOwnTLDef(const std::string& id,
53 : const std::vector<NBNode*>& junctions,
54 : SUMOTime offset,
55 : TrafficLightType type);
56 :
57 :
58 : /** @brief Constructor
59 : * @param[in] id The id of the tls
60 : * @param[in] junction The junction controlled by this tls
61 : * @param[in] offset The offset of the plan
62 : * @param[in] type The algorithm type for the computed traffic light
63 : */
64 : NBOwnTLDef(const std::string& id, NBNode* junction, SUMOTime offset,
65 : TrafficLightType type);
66 :
67 :
68 : /** @brief Constructor
69 : * @param[in] id The id of the tls
70 : * @param[in] offset The offset of the plan
71 : * @param[in] type The algorithm type for the computed traffic light
72 : */
73 : NBOwnTLDef(const std::string& id, SUMOTime offset, TrafficLightType type);
74 :
75 :
76 : /// @brief Destructor
77 : ~NBOwnTLDef();
78 :
79 :
80 : /// @name Public methods from NBTrafficLightDefinition-interface
81 : /// @{
82 :
83 : /** @brief Replaces occurrences of the removed edge in incoming/outgoing edges of all definitions
84 : * @param[in] removed The removed edge
85 : * @param[in] incoming The edges to use instead if an incoming edge was removed
86 : * @param[in] outgoing The edges to use instead if an outgoing edge was removed
87 : * @see NBTrafficLightDefinition::remapRemoved
88 : */
89 : void remapRemoved(NBEdge* removed,
90 : const EdgeVector& incoming, const EdgeVector& outgoing);
91 :
92 :
93 : /** @brief Informs edges about being controlled by a tls
94 : * @see NBTrafficLightDefinition::setTLControllingInformation
95 : */
96 : void setTLControllingInformation() const;
97 : /// @}
98 :
99 :
100 : /// @brief Forces the definition not to compute an additional phase for left-movers
101 : void setSinglePhase() {
102 : myHaveSinglePhase = true;
103 : }
104 :
105 : /// @brief ensure inner edges all get the green light eventually
106 : static void addGreenWithin(NBTrafficLightLogic* logic, const EdgeVector& fromEdges, EdgeVector& toProc);
107 :
108 : /// @brief add an additional pedestrian phase if there are crossings that did not get green yet
109 : static void addPedestrianScramble(NBTrafficLightLogic* logic, int totalNumLinks, SUMOTime greenTime, SUMOTime yellowTime,
110 : const std::vector<NBNode::Crossing*>& crossings, const EdgeVector& fromEdges, const EdgeVector& toEdges);
111 :
112 : /// @brief add 1 or 2 phases depending on the presence of pedestrian crossings
113 : static std::string addPedestrianPhases(NBTrafficLightLogic* logic, const SUMOTime greenTime, const SUMOTime minDur, const SUMOTime maxDur,
114 : const SUMOTime earliestEnd, const SUMOTime latestEnd,
115 : std::string state, const std::vector<NBNode::Crossing*>& crossings, const EdgeVector& fromEdges, const EdgeVector& toEdges);
116 :
117 : /// @brief compute phase state in regard to pedestrian crossings
118 : static std::string patchStateForCrossings(const std::string& state, const std::vector<NBNode::Crossing*>& crossings, const EdgeVector& fromEdges, const EdgeVector& toEdges);
119 :
120 : static std::string patchNEMAStateForCrossings(const std::string& state,
121 : const std::vector<NBNode::Crossing*>& crossings,
122 : const EdgeVector& fromEdges,
123 : const EdgeVector& toEdges,
124 : const NBEdge* greenEdge, NBEdge* otherChosen);
125 :
126 : /** @brief helper function for myCompute
127 : * @param[in] brakingTime Duration a vehicle needs for braking in front of the tls
128 : * @param[in] onlyConts whether the method is only called to compute myNeedsContRelation
129 : * @return The computed logic
130 : */
131 : NBTrafficLightLogic* computeLogicAndConts(int brakingTimeSeconds, bool onlyConts = false);
132 :
133 : /* initialize myNeedsContRelation and set myNeedsContRelationReady to true */
134 : void initNeedsContRelation() const;
135 :
136 : /* build optional all-red phase */
137 : void buildAllRedState(SUMOTime allRedTime, NBTrafficLightLogic* logic, const std::string& state);
138 :
139 : ///@brief Returns the maximum index controlled by this traffic light
140 : int getMaxIndex();
141 :
142 : /// @brief sets the layout for the generated signal plan
143 : void setLayout(TrafficLightLayout layout) {
144 518 : myLayout = layout;
145 10 : }
146 :
147 0 : TrafficLightLayout getLayout() const {
148 0 : return myLayout;
149 : }
150 :
151 : /// @brief minimum speed for computing time to cross intersection
152 : static const double MIN_SPEED_CROSSING_TIME;
153 :
154 : protected:
155 : /// @name Protected methods from NBTrafficLightDefinition-interface
156 : /// @{
157 :
158 : /** @brief Computes the traffic light logic finally in dependence to the type
159 : * @param[in] brakingTime Duration a vehicle needs for braking in front of the tls
160 : * @return The computed logic
161 : * @see NBTrafficLightDefinition::myCompute
162 : */
163 : NBTrafficLightLogic* myCompute(int brakingTimeSeconds);
164 :
165 :
166 : /** @brief Collects the links participating in this traffic light
167 : * @exception ProcessError If a link could not be found
168 : * @see NBTrafficLightDefinition::collectLinks
169 : */
170 : void collectLinks();
171 :
172 :
173 : /** @brief Replaces a removed edge/lane
174 : * @param[in] removed The edge to replace
175 : * @param[in] removedLane The lane of this edge to replace
176 : * @param[in] by The edge to insert instead
177 : * @param[in] byLane This edge's lane to insert instead
178 : * @see NBTrafficLightDefinition::replaceRemoved
179 : */
180 : void replaceRemoved(NBEdge* removed, int removedLane,
181 : NBEdge* by, int byLane, bool incoming);
182 : /// @}
183 :
184 :
185 : protected:
186 :
187 : /// @brief test whether a joined tls with layout 'opposites' would be built without dedicated left-turn phase
188 : bool corridorLike() const;
189 :
190 : NBTrafficLightLogic* buildNemaPhases(
191 : const EdgeVector& fromEdges,
192 : const EdgeVector& toEdges,
193 : const std::vector<NBNode::Crossing*>& crossings,
194 : const std::vector<std::pair<NBEdge*, NBEdge*> >& chosenList,
195 : const std::vector<std::string>& straightStates,
196 : const std::vector<std::string>& leftStates);
197 :
198 : /// @brief mask out all greens that do not originate at the given edge
199 : std::string filterState(std::string state, const EdgeVector& fromEdges, const NBEdge* e);
200 :
201 : /// @brief keep only valid NEMA phase names (for params)
202 : void filterMissingNames(std::vector<int>& vec, const std::map<int, int>& names, bool isBarrier, int barrierDefault = 0);
203 :
204 : /// @brief ensure that phase max durations before each barrier have the same sum in both rings
205 : void fixDurationSum(NBTrafficLightLogic* logic, const std::map<int, int>& names, int ring1a, int ring1b, int ring2a, int ring2b);
206 :
207 : /** @brief Returns the weight of a stream given its direction
208 : * @param[in] dir The direction of the stream
209 : * @return This stream's weight
210 : * @todo There are several magic numbers; describe
211 : */
212 : double getDirectionalWeight(LinkDirection dir);
213 :
214 :
215 : /** @brief Returns this edge's priority at the node it ends at
216 : * @param[in] e The edge to ask for his priority
217 : * @return The edge's priority at his destination node
218 : */
219 : int getToPrio(const NBEdge* const e);
220 :
221 :
222 : /** @brief Returns how many streams outgoing from the edges can pass the junction without being blocked
223 : * @param[in] e1 The first edge
224 : * @param[in] e2 The second edge
225 : * @todo There are several magic numbers; describe
226 : */
227 : double computeUnblockedWeightedStreamNumber(const NBEdge* const e1, const NBEdge* const e2);
228 :
229 :
230 : /** @brief Returns the combination of two edges from the given which has most unblocked streams
231 : * @param[in] edges The list of edges to include in the computation
232 : * @return The two edges for which the weighted number of unblocked streams is the highest
233 : */
234 : std::pair<NBEdge*, NBEdge*> getBestCombination(const EdgeVector& edges);
235 :
236 :
237 : /** @brief Returns the combination of two edges from the given which has most unblocked streams
238 : *
239 : * The chosen edges are removed from the given vector
240 : *
241 : * @param[in, changed] incoming The list of edges which are participating in the logic
242 : * @return The two edges for which the weighted number of unblocked streams is the highest
243 : */
244 : std::pair<NBEdge*, NBEdge*> getBestPair(EdgeVector& incoming);
245 :
246 :
247 : /// @brief compute whether the given connection is crossed by pedestrians
248 : static bool hasCrossing(const NBEdge* from, const NBEdge* to, const std::vector<NBNode::Crossing*>& crossings);
249 :
250 : /// @brief get edges that have connections
251 : static EdgeVector getConnectedOuterEdges(const EdgeVector& incoming);
252 :
253 :
254 : /// @brief allow connections that are compatible with the chosen edges
255 : std::string allowCompatible(std::string state, const EdgeVector& fromEdges, const EdgeVector& toEdges,
256 : const std::vector<int>& fromLanes, const std::vector<int>& toLanes);
257 :
258 : std::string allowSingleEdge(std::string state, const EdgeVector& fromEdges);
259 :
260 : std::string allowFollowers(std::string state, const EdgeVector& fromEdges, const EdgeVector& toEdges);
261 :
262 : std::string allowPredecessors(std::string state, const EdgeVector& fromEdges, const EdgeVector& toEdges,
263 : const std::vector<int>& fromLanes, const std::vector<int>& toLanes);
264 :
265 : std::string allowUnrelated(std::string state, const EdgeVector& fromEdges, const EdgeVector& toEdges,
266 : const std::vector<bool>& isTurnaround,
267 : const std::vector<NBNode::Crossing*>& crossings);
268 :
269 : std::string allowByVClass(std::string state, const EdgeVector& fromEdges, const EdgeVector& toEdges, SVCPermissions perm);
270 :
271 : /// @brief whether the given index is forbidden by a green link in the current state
272 : bool forbidden(const std::string& state, int index, const EdgeVector& fromEdges, const EdgeVector& toEdges, bool allowCont);
273 :
274 : /** @brief change 'G' to 'g' for conflicting connections
275 : * @param[in] state
276 : * @param[in] fromEdges
277 : * @param[in] toEdges
278 : * @param[in] isTurnaround
279 : * @param[in] fromLanes
280 : * @param[in] hadGreenMajor
281 : * @param[out] haveForbiddenLeftMover
282 : * @param[out] rightTurnConflicts
283 : * @param[out] mergeConflicts
284 : * @return The corrected state
285 : */
286 : std::string correctConflicting(std::string state, const EdgeVector& fromEdges, const EdgeVector& toEdges,
287 : const std::vector<bool>& isTurnaround,
288 : const std::vector<int>& fromLanes,
289 : const std::vector<int>& toLanes,
290 : const std::vector<bool>& hadGreenMajor,
291 : bool& haveForbiddenLeftMover,
292 : std::vector<bool>& rightTurnConflicts,
293 : std::vector<bool>& mergeConflicts);
294 :
295 : /// @brief prevent green and red from the same lane
296 : std::string correctMixed(std::string state, const EdgeVector& fromEdges,
297 : const std::vector<int>& fromLanes,
298 : bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen);
299 :
300 : /// @brief fix states in regard to custom crossing indices
301 : void checkCustomCrossingIndices(NBTrafficLightLogic* logic) const;
302 :
303 : /// @brief avoid yellow signal between successive green (major) phases
304 : void fixSuperfluousYellow(NBTrafficLightLogic* logic) const;
305 :
306 : /// @brief switch of signal for links that are always green
307 : void deactivateAlwaysGreen(NBTrafficLightLogic* logic) const;
308 :
309 : /// @brief switch of signal for links that are inside a joined tls
310 : void deactivateInsideEdges(NBTrafficLightLogic* logic, const EdgeVector& fromEdges) const;
311 :
312 : /// @brief compute time to clear all vehicles from within an alternateOneWay layout
313 : SUMOTime computeEscapeTime(const std::string& state, const EdgeVector& fromEdges, const EdgeVector& toEdges) const;
314 :
315 : /// @brief check whether there is a straight connection from this edge
316 : bool hasStraightConnection(const NBEdge* fromEdge);
317 :
318 : /** @class edge_by_incoming_priority_sorter
319 : * @brief Sorts edges by their priority within the node they end at
320 : */
321 : class edge_by_incoming_priority_sorter {
322 : public:
323 : /** @brief comparing operator
324 : * @param[in] e1 an edge
325 : * @param[in] e2 an edge
326 : */
327 15675 : int operator()(const NBEdge* const e1, const NBEdge* const e2) const {
328 15675 : if (e1->getJunctionPriority(e1->getToNode()) != e2->getJunctionPriority(e2->getToNode())) {
329 7058 : return e1->getJunctionPriority(e1->getToNode()) > e2->getJunctionPriority(e2->getToNode());
330 : }
331 8617 : return e1->getID() > e2->getID();
332 : }
333 : };
334 :
335 :
336 : private:
337 : /// @brief Whether left-mover should not have an additional phase
338 : bool myHaveSinglePhase;
339 :
340 : /// @brief the layout for generated signal plans
341 : TrafficLightLayout myLayout;
342 :
343 : };
|