Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-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 NBTrafficLightDefinition.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Sept 2002
19 : ///
20 : // The base class for traffic light logic definitions
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <vector>
26 : #include <string>
27 : #include <bitset>
28 : #include <utility>
29 : #include <set>
30 : #include <utils/common/StdDefs.h>
31 : #include <utils/common/Named.h>
32 : #include <utils/common/VectorHelper.h>
33 : #include <utils/common/SUMOTime.h>
34 : #include <utils/common/UtilExceptions.h>
35 : #include <utils/common/Parameterised.h>
36 : #include "NBCont.h"
37 : #include "NBConnection.h"
38 : #include "NBConnectionDefs.h"
39 : #include "NBLinkPossibilityMatrix.h"
40 :
41 :
42 : // ===========================================================================
43 : // class declarations
44 : // ===========================================================================
45 : class NBNode;
46 : class OptionsCont;
47 : class NBTrafficLightLogic;
48 :
49 :
50 : // ===========================================================================
51 : // class definitions
52 : // ===========================================================================
53 : /**
54 : * @class NBTrafficLightDefinition
55 : * @brief The base class for traffic light logic definitions
56 : *
57 : * A base class is necessary, as we have two cases: a) the logic is given by
58 : * the imported network, or b) the logic is not given and we have to compute
59 : * it by ourselves. In the first case, NBLoadedTLDef should be used, in the
60 : * second NBOwnTLDef.
61 : *
62 : * @see NBLoadedTLDef
63 : * @see NBOwnTLDef
64 : */
65 : class NBTrafficLightDefinition : public Named, public Parameterised {
66 : public:
67 :
68 : static const std::string DefaultProgramID;
69 : static const SUMOTime UNSPECIFIED_DURATION;
70 : static const int MIN_YELLOW_SECONDS;
71 :
72 : /**
73 : * @enum TLColor
74 : * @brief An enumeration of possible tl-signal states
75 : */
76 : enum TLColor {
77 : /// @brief Signal shows red
78 : TLCOLOR_RED,
79 : /// @brief Signal shows yellow
80 : TLCOLOR_YELLOW,
81 : /// @brief Signal shows red/yellow (unused)
82 : TLCOLOR_REDYELLOW,
83 : /// @brief Signal shows green
84 : TLCOLOR_GREEN,
85 : /// @brief Signal is blinking yellow
86 : TLCOLOR_BLINK
87 : };
88 :
89 :
90 : /** @brief Constructor
91 : * @param[in] id The id of the tls
92 : * @param[in] junctions List of junctions controlled by this tls
93 : * @param[in] programID The id of the added program ("subID")
94 : * @param[in] offset The offset of the plan
95 : * @param[in] type The algorithm type for the computed traffic light
96 : */
97 : NBTrafficLightDefinition(const std::string& id,
98 : const std::vector<NBNode*>& junctions,
99 : const std::string& programID,
100 : SUMOTime offset,
101 : TrafficLightType type);
102 :
103 :
104 : /** @brief Constructor
105 : * @param[in] id The id of the tls
106 : * @param[in] junction The (single) junction controlled by this tls
107 : * @param[in] programID The id of the added program ("subID")
108 : * @param[in] offset The offset of the plan
109 : * @param[in] type The algorithm type for the computed traffic light
110 : */
111 : NBTrafficLightDefinition(const std::string& id,
112 : NBNode* junction,
113 : const std::string& programID,
114 : SUMOTime offset,
115 : TrafficLightType type);
116 :
117 :
118 : /** @brief Constructor
119 : * @param[in] id The id of the tls
120 : * @param[in] programID The id of the added program ("subID")
121 : * @param[in] offset The offset of the plan
122 : * @param[in] type The algorithm type for the computed traffic light
123 : */
124 : NBTrafficLightDefinition(const std::string& id, const std::string& programID,
125 : SUMOTime offset,
126 : TrafficLightType type);
127 :
128 :
129 : /// @brief Destructor
130 : virtual ~NBTrafficLightDefinition();
131 :
132 : /** @brief Computes the traffic light logic
133 : *
134 : * Does some initialisation at first, then calls myCompute to finally
135 : * build the tl-logic
136 : *
137 : * @param[in] oc The options container holding options needed during the building
138 : * @return The built logic (may be 0)
139 : */
140 : NBTrafficLightLogic* compute(const OptionsCont& oc);
141 :
142 : /// @name Access to controlled nodes
143 : /// @{
144 :
145 : /** @brief Adds a node to the traffic light logic
146 : * @param[in] node A further node that shall be controlled by the tls
147 : */
148 : virtual void addNode(NBNode* node);
149 :
150 :
151 : /** @brief Removes the given node from the list of controlled nodes
152 : * @param[in] node The node that shall not be controlled by the tls any more
153 : */
154 : virtual void removeNode(NBNode* node);
155 :
156 : /** @brief removes the given connection from the traffic light
157 : * if recontruct=true, reconstructs the logic and informs the edges for immediate use in netedit
158 : * @note: tlIndex is not necessarily unique. we need the whole connection data here
159 : */
160 68 : virtual void removeConnection(const NBConnection& conn, bool reconstruct = true) {
161 : UNUSED_PARAMETER(conn);
162 : UNUSED_PARAMETER(reconstruct);
163 68 : }
164 :
165 : /** @brief Returns the list of controlled nodes
166 : * @return Controlled nodes
167 : */
168 : const std::vector<NBNode*>& getNodes() const {
169 57 : return myControlledNodes;
170 : }
171 : /// @}
172 :
173 :
174 : /** @brief Returns the information whether the described flow must let any other flow pass
175 : *
176 : * If the from/to connection passes only one junction (from is incoming into
177 : * same node as to outgoes from) the node is asked whether the flow must brake-
178 : * Otherwise true is returned (recheck!)
179 : * "from" must be an incoming edge into one of the participating nodes!
180 : * @param[in] from The connection's start edge
181 : * @param[in] to The connection's end edge
182 : * @return Whether the described connection must brake (has higher priorised foes)
183 : */
184 : bool mustBrake(const NBEdge* const from, const NBEdge* const to) const;
185 :
186 :
187 : /** @brief Returns the information whether the described flow must let the other flow pass
188 : * @param[in] possProhibited The maybe prohibited connection
189 : * @param[in] possProhibitor The maybe prohibiting connection
190 : * @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
191 : * @return Whether the second flow prohibits the first one
192 : * @see forbids
193 : */
194 : bool mustBrake(const NBConnection& possProhibited,
195 : const NBConnection& possProhibitor,
196 : bool regardNonSignalisedLowerPriority) const;
197 :
198 : /** @brief Returns the information whether the described flow must let any other flow pass
199 : * @param[in] possProhibitedFrom The maybe prohibited connection's begin
200 : * @param[in] possProhibitedTo The maybe prohibited connection's end
201 : * @param[in] possProhibitorFrom The maybe prohibiting connection's begin
202 : * @param[in] possProhibitorTo The maybe prohibiting connection's end
203 : * @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
204 : * @return Whether the second flow prohibits the first one
205 : * @see forbids
206 : */
207 : bool mustBrake(const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
208 : const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
209 : bool regardNonSignalisedLowerPriority) const;
210 :
211 :
212 : /** @brief Returns the information whether "prohibited" flow must let "prohibitor" flow pass
213 : * @param[in] possProhibitedFrom The maybe prohibited connection's begin
214 : * @param[in] possProhibitedTo The maybe prohibited connection's end
215 : * @param[in] possProhibitorFrom The maybe prohibiting connection's begin
216 : * @param[in] possProhibitorTo The maybe prohibiting connection's end
217 : * @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
218 : * @param[in] sameNodeOnly Whether the check shall only be performed if both edges are incoming to the same node
219 : * @return Whether the second flow prohibits the first one
220 : * @see forbids
221 : */
222 : bool forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
223 : const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
224 : bool regardNonSignalisedLowerPriority,
225 : bool sameNodeOnly = false) const;
226 :
227 :
228 : /** @brief Returns the information whether the given flows cross
229 : * @param[in] from1 The starting edge of the first stream
230 : * @param[in] to1 The ending edge of the first stream
231 : * @param[in] from2 The starting edge of the second stream
232 : * @param[in] to2 The ending edge of the second stream
233 : * @return Whether both stream are foes (cross)
234 : */
235 : bool foes(const NBEdge* const from1, const NBEdge* const to1,
236 : const NBEdge* const from2, const NBEdge* const to2) const;
237 :
238 :
239 : /** @brief Informs edges about being controlled by a tls
240 : */
241 : virtual void setTLControllingInformation() const = 0;
242 :
243 :
244 : /** @brief Builds the list of participating nodes/edges/links
245 : */
246 : virtual void setParticipantsInformation();
247 :
248 :
249 : /** @brief Adds the given ids into the list of inner edges controlled by the tls
250 : * @param[in] edges The list of edge ids which shall be controlled despite lying with the jointly controlled node cluster
251 : */
252 : void addControlledInnerEdges(const std::vector<std::string>& edges);
253 :
254 : /** @brief Retrieve the ids of edges explicitly controlled by the tls
255 : */
256 : std::vector<std::string> getControlledInnerEdges() const;
257 :
258 : /** @brief Replaces occurrences of the removed edge in incoming/outgoing edges of all definitions
259 : * @param[in] removed The removed edge
260 : * @param[in] incoming The edges to use instead if an incoming edge was removed
261 : * @param[in] outgoing The edges to use instead if an outgoing edge was removed
262 : */
263 : virtual void remapRemoved(NBEdge* removed,
264 : const EdgeVector& incoming, const EdgeVector& outgoing) = 0;
265 :
266 :
267 : /** @brief Replaces a removed edge/lane
268 : * @param[in] removed The edge to replace
269 : * @param[in] removedLane The lane of this edge to replace
270 : * @param[in] by The edge to insert instead
271 : * @param[in] byLane This edge's lane to insert instead
272 : * @param[in] incoming Whether the removed edge is incoming or outgoing
273 : */
274 : virtual void replaceRemoved(NBEdge* removed, int removedLane,
275 : NBEdge* by, int byLane, bool incoming) = 0;
276 :
277 : /// @brief patches (loaded) signal plans by modifying lane indices
278 1717 : virtual void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold = -1) {
279 : UNUSED_PARAMETER(edge);
280 : UNUSED_PARAMETER(offset);
281 : UNUSED_PARAMETER(threshold);
282 1717 : }
283 :
284 : /** @brief Returns the list of incoming edges (must be build first)
285 : * @return The edges which are incoming into the tls
286 : */
287 : const EdgeVector& getIncomingEdges() const;
288 :
289 :
290 : /// @brief returns the controlled links (depends on previous call to collectLinks)
291 : const NBConnectionVector& getControlledLinks() const {
292 13 : return myControlledLinks;
293 : }
294 :
295 :
296 : /// @brief returns the controlled links (non const version)
297 : NBConnectionVector& getControlledLinks() {
298 : return myControlledLinks;
299 : }
300 :
301 :
302 : /** @brief Returns the ProgramID
303 : * @return The ID of the program (subID)
304 : */
305 : const std::string& getProgramID() const {
306 9848 : return mySubID;
307 : };
308 :
309 :
310 : /** @brief Sets the programID
311 : * @param[in] programID The new ID of the program (subID)
312 : */
313 11 : virtual void setProgramID(const std::string& programID) {
314 11 : mySubID = programID;
315 14 : }
316 :
317 0 : virtual TrafficLightLayout getLayout() const {
318 0 : return TrafficLightLayout::DEFAULT;
319 : }
320 :
321 : /** @brief Returns the offset
322 : * @return Offset
323 : */
324 : SUMOTime getOffset() {
325 14 : return myOffset;
326 : }
327 :
328 :
329 : /// @brief get the algorithm type (static etc..)
330 : TrafficLightType getType() const {
331 3665 : return myType;
332 : }
333 :
334 : /// @brief set the algorithm type (static etc..)
335 2 : virtual void setType(TrafficLightType type) {
336 2 : myType = type;
337 2 : }
338 :
339 : /* @brief computes whether the given stream may have green minor while the
340 : * other stream has green major in the same phase
341 : */
342 : bool needsCont(const NBEdge* fromE, const NBEdge* toE, const NBEdge* otherFromE, const NBEdge* otherToE) const;
343 :
344 : /// @brief whether the given index must yield to the foeIndex while turning right on a red light
345 : virtual bool rightOnRedConflict(int index, int foeIndex) const;
346 :
347 : /* initialize myNeedsContRelation and set myNeedsContRelationReady to true
348 : * This information is a byproduct of NBOwnTLDef::myCompute. All other
349 : * subclasses instantiate a private instance of NBOwnTLDef to answer this query */
350 : virtual void initNeedsContRelation() const;
351 :
352 : virtual void initRightOnRedConflicts() const;
353 :
354 : ///@brief Returns the maximum index controlled by this traffic light and assigned to a connection
355 : virtual int getMaxIndex() = 0;
356 :
357 : ///@brief Returns the maximum index controlled by this traffic light
358 0 : virtual int getMaxValidIndex() {
359 0 : return getMaxIndex();
360 : }
361 :
362 : /** @brief Computes the time vehicles may need to brake
363 : *
364 : * This time depends on the maximum speed allowed on incoming junctions.
365 : * It is computed as max_speed_allowed / minimum_vehicle_decleration
366 : */
367 : int computeBrakingTime(double minDecel) const;
368 :
369 : /// @brief whether this definition uses signal group (multiple connections with the same link index)
370 0 : virtual bool usingSignalGroups() const {
371 0 : return false;
372 : };
373 :
374 : /// @brief get ID and programID together (for convenient debugging)
375 : std::string getDescription() const;
376 :
377 : /// @brief perform optional final checks
378 1581 : virtual void finalChecks() const {}
379 :
380 : /// @brief processing parameter for rail signal edges and nodes
381 : static const std::string OSM_DIRECTION;
382 : static const std::string OSM_SIGNAL_DIRECTION;
383 :
384 : protected:
385 : /// @brief id for temporary definitions
386 : static const std::string DummyID;
387 :
388 : /** @brief Computes the traffic light logic finally in dependence to the type
389 : * @param[in] brakingTime Duration a vehicle needs for braking in front of the tls
390 : * @return The computed logic
391 : */
392 : virtual NBTrafficLightLogic* myCompute(int brakingTime) = 0;
393 :
394 :
395 : /** @brief Collects the links participating in this traffic light
396 : * @exception ProcessError If a link could not be found
397 : */
398 : virtual void collectLinks() = 0;
399 :
400 :
401 : /** @brief Build the list of participating edges
402 : */
403 : virtual void collectEdges();
404 :
405 :
406 : // @return whether this traffic light is invalid and should be computed
407 : virtual bool amInvalid() const;
408 :
409 : /// @brief helper method for use in NBOwnTLDef and NBLoadedSUMOTLDef
410 : void collectAllLinks(NBConnectionVector& into);
411 :
412 : protected:
413 : /// @brief The container with participating nodes
414 : std::vector<NBNode*> myControlledNodes;
415 :
416 : /// @brief The list of incoming edges
417 : EdgeVector myIncomingEdges;
418 :
419 : /// @brief The list of edges within the area controlled by the tls
420 : EdgeVector myEdgesWithin;
421 :
422 : /// @brief The list of controlled links
423 : NBConnectionVector myControlledLinks;
424 :
425 : /// @brief Set of inner edges that shall be controlled, though
426 : std::set<std::string> myControlledInnerEdges;
427 :
428 : /// @brief The tls program's subid
429 : std::string mySubID;
430 :
431 : /// @brief The offset in the program
432 : SUMOTime myOffset;
433 :
434 : /// @brief The algorithm type for the traffic light
435 : TrafficLightType myType;
436 :
437 : /// @brief data structure for caching needsCont information
438 : struct StreamPair {
439 127760 : StreamPair(const NBEdge* _from1, const NBEdge* _to1, const NBEdge* _from2, const NBEdge* _to2):
440 127760 : from1(_from1),
441 127760 : to1(_to1),
442 127760 : from2(_from2),
443 127760 : to2(_to2) {}
444 :
445 : bool operator==(const StreamPair& o) const {
446 249305 : return (from1 == o.from1 && to1 == o.to1
447 1391043 : && from2 == o.from2 && to2 == o.to2);
448 : }
449 :
450 : bool operator<(const StreamPair& o) const {
451 247920 : if (from1 != o.from1) {
452 79882 : return from1 < o.from1;
453 : }
454 168038 : if (to1 != o.to1) {
455 29879 : return to1 < o.to1;
456 : }
457 138159 : if (from2 != o.from2) {
458 9039 : return from2 < o.from2;
459 : }
460 129120 : return to2 < o.to2;
461 : }
462 :
463 : const NBEdge* from1;
464 : const NBEdge* to1;
465 : const NBEdge* from2;
466 : const NBEdge* to2;
467 : };
468 : typedef std::set<StreamPair> NeedsContRelation;
469 : mutable NeedsContRelation myNeedsContRelation;
470 : mutable bool myNeedsContRelationReady;
471 :
472 : typedef std::set<std::pair<int, int> > RightOnRedConflicts;
473 : mutable RightOnRedConflicts myRightOnRedConflicts;
474 : mutable bool myRightOnRedConflictsReady;
475 :
476 : private:
477 : static std::set<NBEdge*> collectReachable(EdgeVector outer, const EdgeVector& within, bool checkControlled);
478 :
479 : static bool railSignalUncontrolled(const NBEdge* in, const NBEdge* out);
480 :
481 : };
|