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 NBLoadedTLDef.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Sascha Krieg
18 : /// @author Michael Behrisch
19 : /// @date Tue, 29.05.2005
20 : ///
21 : // A loaded (complete) traffic light logic
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <vector>
26 : #include <set>
27 : #include <cassert>
28 : #include <iterator>
29 : #include <utils/common/MsgHandler.h>
30 : #include <utils/common/ToString.h>
31 : #include <utils/options/OptionsCont.h>
32 : #include "NBTrafficLightLogic.h"
33 : #include "NBTrafficLightDefinition.h"
34 : #include "NBLoadedTLDef.h"
35 : #include "NBNode.h"
36 :
37 :
38 : // ===========================================================================
39 : // method definitions
40 : // ===========================================================================
41 : /* -------------------------------------------------------------------------
42 : * NBLoadedTLDef::SignalGroup-methods
43 : * ----------------------------------------------------------------------- */
44 149 : NBLoadedTLDef::SignalGroup::SignalGroup(const std::string& id)
45 149 : : Named(id) {}
46 :
47 298 : NBLoadedTLDef::SignalGroup::~SignalGroup() {}
48 :
49 : void
50 345 : NBLoadedTLDef::SignalGroup::addConnection(const NBConnection& c) {
51 : assert(c.getFromLane() < 0 || c.getFrom()->getNumLanes() > c.getFromLane());
52 345 : myConnections.push_back(c);
53 345 : }
54 :
55 :
56 : void
57 301 : NBLoadedTLDef::SignalGroup::addPhaseBegin(SUMOTime time, TLColor color) {
58 301 : myPhases.push_back(PhaseDef(time, color));
59 301 : }
60 :
61 :
62 : void
63 149 : NBLoadedTLDef::SignalGroup::setYellowTimes(SUMOTime tRedYellow, SUMOTime tYellow) {
64 149 : myTRedYellow = tRedYellow;
65 149 : myTYellow = tYellow;
66 149 : }
67 :
68 :
69 : void
70 166 : NBLoadedTLDef::SignalGroup::sortPhases() {
71 166 : std::sort(myPhases.begin(), myPhases.end(), [](const PhaseDef & p1, const PhaseDef & p2) {
72 301 : return p1.myTime < p2.myTime;
73 : });
74 166 : }
75 :
76 :
77 : void
78 166 : NBLoadedTLDef::SignalGroup::patchTYellow(SUMOTime tyellow, bool forced) {
79 166 : if (myTYellow < 0) {
80 : // was not set before (was not loaded)
81 12 : myTYellow = tyellow;
82 154 : } else if (forced && myTYellow < tyellow) {
83 18 : WRITE_WARNINGF(TL("TYellow of signal group '%' was less than the computed one; patched (was:%, is:%)"), getID(), toString(myTYellow), time2string(tyellow));
84 6 : myTYellow = tyellow;
85 : }
86 166 : }
87 :
88 :
89 : std::vector<SUMOTime>
90 166 : NBLoadedTLDef::SignalGroup::getTimes(SUMOTime cycleDuration) const {
91 : // within the phase container, we should have the green and red phases add their times
92 : std::vector<SUMOTime> ret;
93 500 : for (const PhaseDef& p : myPhases) {
94 334 : ret.push_back(p.myTime);
95 : }
96 : // further, we possibly should set the yellow phases
97 166 : if (myTYellow > 0) {
98 480 : for (const PhaseDef& p : myPhases) {
99 320 : if (p.myColor == TLCOLOR_RED) {
100 161 : ret.push_back((p.myTime + myTYellow) % cycleDuration);
101 : }
102 : }
103 : }
104 166 : return ret;
105 0 : }
106 :
107 :
108 : int
109 10773 : NBLoadedTLDef::SignalGroup::getLinkNo() const {
110 10773 : return (int) myConnections.size();
111 : }
112 :
113 :
114 : bool
115 6540 : NBLoadedTLDef::SignalGroup::mayDrive(SUMOTime time) const {
116 : assert(myPhases.size() != 0);
117 12826 : for (std::vector<PhaseDef>::const_reverse_iterator i = myPhases.rbegin(); i != myPhases.rend(); i++) {
118 10996 : SUMOTime nextTime = (*i).myTime;
119 10996 : if (time >= nextTime) {
120 4710 : return (*i).myColor == TLCOLOR_GREEN;
121 : }
122 : }
123 1830 : return (*(myPhases.end() - 1)).myColor == TLCOLOR_GREEN;
124 : }
125 :
126 :
127 : bool
128 2180 : NBLoadedTLDef::SignalGroup::hasYellow(SUMOTime time) const {
129 2180 : bool has_red_now = !mayDrive(time);
130 2180 : bool had_green = mayDrive(time - myTYellow);
131 2180 : return has_red_now && had_green;
132 : }
133 :
134 :
135 : const NBConnection&
136 24335 : NBLoadedTLDef::SignalGroup::getConnection(int pos) const {
137 : assert(pos < (int)myConnections.size());
138 24335 : return myConnections[pos];
139 : }
140 :
141 :
142 : bool
143 238 : NBLoadedTLDef::SignalGroup::containsIncoming(NBEdge* from) const {
144 714 : for (NBConnectionVector::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
145 480 : if ((*i).getFrom() == from) {
146 : return true;
147 : }
148 : }
149 : return false;
150 : }
151 :
152 :
153 : void
154 0 : NBLoadedTLDef::SignalGroup::remapIncoming(NBEdge* which, const EdgeVector& by) {
155 : NBConnectionVector newConns;
156 0 : for (NBConnectionVector::iterator i = myConnections.begin(); i != myConnections.end();) {
157 0 : if ((*i).getFrom() == which) {
158 0 : NBConnection conn((*i).getFrom(), (*i).getTo());
159 0 : i = myConnections.erase(i);
160 0 : for (EdgeVector::const_iterator j = by.begin(); j != by.end(); j++) {
161 0 : NBConnection curr(conn);
162 0 : if (!curr.replaceFrom(which, *j)) {
163 0 : throw ProcessError("Could not replace edge '" + which->getID() + "' by '" + (*j)->getID() + "'.\nUndefined...");
164 : }
165 0 : newConns.push_back(curr);
166 0 : }
167 0 : } else {
168 : i++;
169 : }
170 : }
171 : copy(newConns.begin(), newConns.end(),
172 0 : back_inserter(myConnections));
173 0 : }
174 :
175 :
176 : bool
177 238 : NBLoadedTLDef::SignalGroup::containsOutgoing(NBEdge* to) const {
178 692 : for (NBConnectionVector::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
179 464 : if ((*i).getTo() == to) {
180 : return true;
181 : }
182 : }
183 : return false;
184 : }
185 :
186 :
187 : void
188 0 : NBLoadedTLDef::SignalGroup::remapOutgoing(NBEdge* which, const EdgeVector& by) {
189 : NBConnectionVector newConns;
190 0 : for (NBConnectionVector::iterator i = myConnections.begin(); i != myConnections.end();) {
191 0 : if ((*i).getTo() == which) {
192 0 : NBConnection conn((*i).getFrom(), (*i).getTo());
193 0 : i = myConnections.erase(i);
194 0 : for (EdgeVector::const_iterator j = by.begin(); j != by.end(); j++) {
195 0 : NBConnection curr(conn);
196 0 : if (!curr.replaceTo(which, *j)) {
197 0 : throw ProcessError("Could not replace edge '" + which->getID() + "' by '" + (*j)->getID() + "'.\nUndefined...");
198 : }
199 0 : newConns.push_back(curr);
200 0 : }
201 0 : } else {
202 : i++;
203 : }
204 : }
205 : copy(newConns.begin(), newConns.end(),
206 0 : back_inserter(myConnections));
207 0 : }
208 :
209 :
210 : void
211 14 : NBLoadedTLDef::SignalGroup::remap(NBEdge* removed, int removedLane,
212 : NBEdge* by, int byLane) {
213 66 : for (NBConnectionVector::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
214 52 : if ((*i).getTo() == removed
215 66 : &&
216 14 : ((*i).getToLane() == removedLane
217 0 : ||
218 0 : (*i).getToLane() == -1)) {
219 14 : (*i).replaceTo(removed, removedLane, by, byLane);
220 :
221 38 : } else if ((*i).getTo() == removed && removedLane == -1) {
222 0 : (*i).replaceTo(removed, by);
223 : }
224 :
225 52 : if ((*i).getFrom() == removed
226 60 : &&
227 8 : ((*i).getFromLane() == removedLane
228 8 : ||
229 8 : (*i).getFromLane() == -1)) {
230 8 : (*i).replaceFrom(removed, removedLane, by, byLane);
231 :
232 44 : } else if ((*i).getFrom() == removed && removedLane == -1) {
233 0 : (*i).replaceFrom(removed, by);
234 : }
235 : }
236 14 : }
237 :
238 :
239 : /* -------------------------------------------------------------------------
240 : * NBLoadedTLDef::Phase-methods
241 : * ----------------------------------------------------------------------- */
242 0 : NBLoadedTLDef::NBLoadedTLDef(const NBEdgeCont& ec, const std::string& id,
243 0 : const std::vector<NBNode*>& junctions, SUMOTime offset, TrafficLightType type) :
244 : NBTrafficLightDefinition(id, junctions, DefaultProgramID, offset, type),
245 0 : myEdgeCont(&ec) {
246 0 : }
247 :
248 :
249 17 : NBLoadedTLDef::NBLoadedTLDef(const NBEdgeCont& ec, const std::string& id, NBNode* junction, SUMOTime offset, TrafficLightType type) :
250 : NBTrafficLightDefinition(id, junction, DefaultProgramID, offset, type),
251 17 : myEdgeCont(&ec) {
252 17 : }
253 :
254 :
255 33 : NBLoadedTLDef::NBLoadedTLDef(const NBEdgeCont& ec, const std::string& id, SUMOTime offset, TrafficLightType type) :
256 : NBTrafficLightDefinition(id, DefaultProgramID, offset, type),
257 33 : myEdgeCont(&ec) {
258 33 : }
259 :
260 :
261 100 : NBLoadedTLDef::~NBLoadedTLDef() {
262 199 : for (SignalGroupCont::iterator i = mySignalGroups.begin(); i != mySignalGroups.end(); ++i) {
263 149 : delete (*i).second;
264 : }
265 100 : }
266 :
267 :
268 : NBTrafficLightLogic*
269 35 : NBLoadedTLDef::myCompute(int brakingTimeSeconds) {
270 35 : MsgHandler::getWarningInstance()->clear(); // !!!
271 : // compute the switching times and count the signals
272 : std::set<SUMOTime> switchTimes;
273 : int numSignals = 0;
274 201 : for (const auto& i : mySignalGroups) {
275 166 : NBLoadedTLDef::SignalGroup* const group = i.second;
276 : // needed later
277 166 : group->sortPhases();
278 : // patch the yellow time for this group
279 166 : group->patchTYellow(TIME2STEPS(brakingTimeSeconds), OptionsCont::getOptions().getBool("tls.yellow.patch-small"));
280 : // copy the now valid times into the container
281 : // both the given red and green phases are added and also the
282 : // yellow times
283 166 : const std::vector<SUMOTime> gtimes = group->getTimes(myCycleDuration);
284 : switchTimes.insert(gtimes.begin(), gtimes.end());
285 166 : numSignals += group->getLinkNo();
286 166 : }
287 :
288 : // build the phases
289 35 : NBTrafficLightLogic* logic = new NBTrafficLightLogic(getID(), getProgramID(), numSignals, myOffset, myType);
290 : SUMOTime prev = -1;
291 450 : for (const SUMOTime l : switchTimes) {
292 415 : if (prev != -1) {
293 760 : logic->addStep(l - prev, buildPhaseState(prev));
294 : }
295 : prev = l;
296 : }
297 70 : logic->addStep(myCycleDuration + (*switchTimes.begin()) - prev, buildPhaseState(prev));
298 : // check whether any warnings were printed
299 35 : if (MsgHandler::getWarningInstance()->wasInformed()) {
300 3 : WRITE_WARNINGF(TL("During computation of traffic light '%'."), getID());
301 : }
302 35 : logic->closeBuilding();
303 :
304 : // initialize myNeedsContRelation
305 : myNeedsContRelation.clear();
306 35 : const bool controlledWithin = !OptionsCont::getOptions().getBool("tls.uncontrolled-within");
307 35 : const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = logic->getPhases();
308 439 : for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) {
309 : const std::string state = (*it).state;
310 48630 : for (NBConnectionVector::const_iterator it1 = myControlledLinks.begin(); it1 != myControlledLinks.end(); it1++) {
311 : const NBConnection& c1 = *it1;
312 : const int i1 = c1.getTLIndex();
313 48226 : if (i1 == NBConnection::InvalidTlIndex || state[i1] != 'g' || c1.getFrom() == nullptr || c1.getTo() == nullptr) {
314 47022 : continue;
315 : }
316 233348 : for (NBConnectionVector::const_iterator it2 = myControlledLinks.begin(); it2 != myControlledLinks.end(); it2++) {
317 : const NBConnection& c2 = *it2;
318 : const int i2 = c2.getTLIndex();
319 : if (i2 != NBConnection::InvalidTlIndex
320 209600 : && i2 != i1
321 193448 : && (state[i2] == 'G' || state[i2] == 'g')
322 309672 : && c2.getFrom() != nullptr && c2.getTo() != nullptr) {
323 232584 : const bool rightTurnConflict = NBNode::rightTurnConflict(
324 155056 : c1.getFrom(), c1.getTo(), c1.getFromLane(), c2.getFrom(), c2.getTo(), c2.getFromLane());
325 77528 : if (forbids(c2.getFrom(), c2.getTo(), c1.getFrom(), c1.getTo(), true, controlledWithin) || rightTurnConflict) {
326 60432 : myNeedsContRelation.insert(StreamPair(c1.getFrom(), c1.getTo(), c2.getFrom(), c2.getTo()));
327 : }
328 : }
329 : }
330 : }
331 : }
332 35 : myNeedsContRelationReady = true;
333 :
334 35 : return logic;
335 35 : }
336 :
337 :
338 : void
339 44 : NBLoadedTLDef::setTLControllingInformation() const {
340 : // assign the tl-indices to the edge connections
341 2926 : for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
342 : const NBConnection& c = *it;
343 2882 : if (c.getTLIndex() != NBConnection::InvalidTlIndex) {
344 2658 : c.getFrom()->setControllingTLInformation(c, getID());
345 : }
346 : }
347 44 : }
348 :
349 :
350 : std::string
351 415 : NBLoadedTLDef::buildPhaseState(const SUMOTime time) const {
352 : int pos = 0;
353 : std::string state;
354 : // set the green and yellow information first;
355 : // the information whether other have to break needs those masks
356 : // completely filled
357 2595 : for (SignalGroupCont::const_iterator i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) {
358 2180 : SignalGroup* group = (*i).second;
359 2180 : int linkNo = group->getLinkNo();
360 2180 : bool mayDrive = group->mayDrive(time);
361 2180 : bool hasYellow = group->hasYellow(time);
362 : char c = 'r';
363 2180 : if (mayDrive) {
364 : c = 'g';
365 : }
366 2180 : if (hasYellow) {
367 : c = 'y';
368 : }
369 7204 : for (int j = 0; j < linkNo; j++) {
370 5024 : const NBConnection& conn = group->getConnection(j);
371 5024 : NBConnection assConn(conn);
372 : // assert that the connection really exists
373 5024 : if (assConn.check(*myEdgeCont)) {
374 10048 : state = state + c;
375 : ++pos;
376 : }
377 5024 : }
378 : }
379 : // set the braking mask
380 : pos = 0;
381 2595 : for (SignalGroupCont::const_iterator i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) {
382 2180 : SignalGroup* group = (*i).second;
383 2180 : int linkNo = group->getLinkNo();
384 7204 : for (int j = 0; j < linkNo; j++) {
385 5024 : const NBConnection& conn = group->getConnection(j);
386 5024 : NBConnection assConn(conn);
387 5024 : if (assConn.check(*myEdgeCont)) {
388 5024 : if (!mustBrake(assConn, state, pos)) {
389 928 : if (state[pos] == 'g') {
390 928 : state[pos] = 'G';
391 : }
392 928 : if (state[pos] == 'y') {
393 0 : state[pos] = 'Y';
394 : }
395 : }
396 5024 : pos++;
397 : }
398 5024 : }
399 : }
400 415 : return state;
401 : }
402 :
403 :
404 : bool
405 5024 : NBLoadedTLDef::mustBrake(const NBConnection& possProhibited,
406 : const std::string& state,
407 : int strmpos) const {
408 : // check whether the stream has red
409 5024 : if (state[strmpos] != 'g' && state[strmpos] != 'G') {
410 : return true;
411 : }
412 :
413 : // check whether another stream which has green is a higher
414 : // priorised foe to the given
415 : int pos = 0;
416 6939 : for (SignalGroupCont::const_iterator i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) {
417 6011 : SignalGroup* group = (*i).second;
418 : // get other links that have green
419 6011 : int linkNo = group->getLinkNo();
420 19610 : for (int j = 0; j < linkNo; j++) {
421 : // get the current connection (possible foe)
422 13739 : const NBConnection& other = group->getConnection(j);
423 13739 : NBConnection possProhibitor(other);
424 : // if the connection ist still valid ...
425 13739 : if (possProhibitor.check(*myEdgeCont)) {
426 : // ... do nothing if it starts at the same edge
427 13739 : if (possProhibited.getFrom() == possProhibitor.getFrom()) {
428 3949 : pos++;
429 : continue;
430 : }
431 9790 : if (state[pos] == 'g' || state[pos] == 'G') {
432 1778 : if (NBTrafficLightDefinition::mustBrake(possProhibited, possProhibitor, true)) {
433 : return true;
434 : }
435 : }
436 9650 : pos++;
437 : }
438 13739 : }
439 : }
440 : return false;
441 : }
442 :
443 :
444 : void
445 44 : NBLoadedTLDef::setParticipantsInformation() {
446 : // assign participating nodes to the request
447 44 : collectNodes();
448 : // collect the information about participating edges and links
449 44 : collectEdges();
450 44 : collectLinks();
451 44 : }
452 :
453 : void
454 44 : NBLoadedTLDef::collectNodes() {
455 : myControlledNodes.clear();
456 : SignalGroupCont::const_iterator m;
457 162 : for (m = mySignalGroups.begin(); m != mySignalGroups.end(); m++) {
458 118 : SignalGroup* group = (*m).second;
459 118 : int linkNo = group->getLinkNo();
460 392 : for (int j = 0; j < linkNo; j++) {
461 274 : const NBConnection& conn = group->getConnection(j);
462 274 : NBEdge* edge = conn.getFrom();
463 274 : NBNode* node = edge->getToNode();
464 274 : myControlledNodes.push_back(node);
465 : }
466 : }
467 44 : std::sort(myControlledNodes.begin(), myControlledNodes.end(), NBNode::nodes_by_id_sorter());
468 44 : }
469 :
470 :
471 : void
472 44 : NBLoadedTLDef::collectLinks() {
473 : myControlledLinks.clear();
474 : // build the list of links which are controlled by the traffic light
475 1128 : for (EdgeVector::iterator i = myIncomingEdges.begin(); i != myIncomingEdges.end(); i++) {
476 1084 : NBEdge* incoming = *i;
477 : int noLanes = incoming->getNumLanes();
478 3206 : for (int j = 0; j < noLanes; j++) {
479 2122 : std::vector<NBEdge::Connection> elv = incoming->getConnectionsFromLane(j);
480 5004 : for (std::vector<NBEdge::Connection>::iterator k = elv.begin(); k != elv.end(); k++) {
481 2882 : NBEdge::Connection el = *k;
482 2882 : if (el.toEdge != nullptr) {
483 5764 : myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane));
484 : }
485 2882 : }
486 2122 : }
487 : }
488 :
489 : // assign tl-indices to myControlledLinks
490 : int pos = 0;
491 162 : for (SignalGroupCont::const_iterator m = mySignalGroups.begin(); m != mySignalGroups.end(); m++) {
492 118 : SignalGroup* group = (*m).second;
493 118 : int linkNo = group->getLinkNo();
494 392 : for (int j = 0; j < linkNo; j++) {
495 274 : const NBConnection& conn = group->getConnection(j);
496 : assert(conn.getFromLane() < 0 || (int) conn.getFrom()->getNumLanes() > conn.getFromLane());
497 274 : NBConnection tst(conn);
498 : tst.setTLIndex(pos);
499 274 : if (tst.check(*myEdgeCont)) {
500 274 : if (tst.getFrom()->mayBeTLSControlled(tst.getFromLane(), tst.getTo(), tst.getToLane())) {
501 39820 : for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
502 : NBConnection& c = *it;
503 39546 : if (c.getTLIndex() == NBConnection::InvalidTlIndex
504 22104 : && tst.getFrom() == c.getFrom() && tst.getTo() == c.getTo()
505 2996 : && (tst.getFromLane() < 0 || tst.getFromLane() == c.getFromLane())
506 42292 : && (tst.getToLane() < 0 || tst.getToLane() == c.getToLane())) {
507 : c.setTLIndex(pos);
508 : }
509 : }
510 : //std::cout << getID() << " group=" << (*m).first << " tst=" << tst << "\n";
511 274 : pos++;
512 : }
513 : } else {
514 0 : WRITE_WARNINGF(TL("Could not set signal on connection (signal: %, group: %)"), getID(), group->getID());
515 : }
516 274 : }
517 : }
518 44 : }
519 :
520 :
521 : bool
522 345 : NBLoadedTLDef::addToSignalGroup(const std::string& groupid,
523 : const NBConnection& connection) {
524 345 : if (mySignalGroups.find(groupid) == mySignalGroups.end()) {
525 : return false;
526 : }
527 345 : mySignalGroups[groupid]->addConnection(connection);
528 345 : NBNode* n1 = connection.getFrom()->getToNode();
529 345 : if (n1 != nullptr) {
530 345 : addNode(n1);
531 345 : n1->addTrafficLight(this);
532 : }
533 345 : NBNode* n2 = connection.getTo()->getFromNode();
534 345 : if (n2 != nullptr) {
535 345 : addNode(n2);
536 345 : n2->addTrafficLight(this);
537 : }
538 : return true;
539 : }
540 :
541 :
542 : bool
543 215 : NBLoadedTLDef::addToSignalGroup(const std::string& groupid,
544 : const NBConnectionVector& connections) {
545 : bool ok = true;
546 560 : for (NBConnectionVector::const_iterator i = connections.begin(); i != connections.end(); i++) {
547 345 : ok &= addToSignalGroup(groupid, *i);
548 : }
549 215 : return ok;
550 : }
551 :
552 :
553 : void
554 149 : NBLoadedTLDef::addSignalGroup(const std::string& id) {
555 : assert(mySignalGroups.find(id) == mySignalGroups.end());
556 149 : mySignalGroups[id] = new SignalGroup(id);
557 149 : }
558 :
559 :
560 : void
561 301 : NBLoadedTLDef::addSignalGroupPhaseBegin(const std::string& groupid, SUMOTime time,
562 : TLColor color) {
563 : assert(mySignalGroups.find(groupid) != mySignalGroups.end());
564 301 : mySignalGroups[groupid]->addPhaseBegin(time, color);
565 301 : }
566 :
567 : void
568 149 : NBLoadedTLDef::setSignalYellowTimes(const std::string& groupid,
569 : SUMOTime myTRedYellow, SUMOTime myTYellow) {
570 : assert(mySignalGroups.find(groupid) != mySignalGroups.end());
571 149 : mySignalGroups[groupid]->setYellowTimes(myTRedYellow, myTYellow);
572 149 : }
573 :
574 :
575 : void
576 50 : NBLoadedTLDef::setCycleDuration(SUMOTime cycleDur) {
577 50 : myCycleDuration = cycleDur;
578 50 : }
579 :
580 :
581 : void
582 0 : NBLoadedTLDef::remapRemoved(NBEdge* removed,
583 : const EdgeVector& incoming,
584 : const EdgeVector& outgoing) {
585 0 : for (SignalGroupCont::const_iterator i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) {
586 0 : SignalGroup* group = (*i).second;
587 0 : if (group->containsIncoming(removed)) {
588 0 : group->remapIncoming(removed, incoming);
589 : }
590 0 : if (group->containsOutgoing(removed)) {
591 0 : group->remapOutgoing(removed, outgoing);
592 : }
593 : }
594 0 : }
595 :
596 :
597 : void
598 282 : NBLoadedTLDef::replaceRemoved(NBEdge* removed, int removedLane,
599 : NBEdge* by, int byLane, bool incoming) {
600 758 : for (SignalGroupCont::const_iterator i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) {
601 476 : SignalGroup* group = (*i).second;
602 476 : if ((incoming && group->containsIncoming(removed)) || (!incoming && group->containsOutgoing(removed))) {
603 14 : group->remap(removed, removedLane, by, byLane);
604 : }
605 : }
606 282 : }
607 :
608 :
609 : void
610 0 : NBLoadedTLDef::initNeedsContRelation() const {
611 0 : if (!myNeedsContRelationReady) {
612 0 : throw ProcessError(TL("myNeedsContRelation was not properly initialized\n"));
613 : }
614 0 : }
615 :
616 :
617 : int
618 0 : NBLoadedTLDef::getMaxIndex() {
619 0 : setParticipantsInformation();
620 0 : NBTrafficLightLogic* logic = compute(OptionsCont::getOptions());
621 0 : if (logic != nullptr) {
622 0 : return logic->getNumLinks() - 1;
623 : } else {
624 : return -1;
625 : }
626 : }
627 :
628 :
629 : /****************************************************************************/
|