Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
libsumo/TrafficLight.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2017-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/****************************************************************************/
21// C++ TraCI client API implementation
22/****************************************************************************/
23#include <config.h>
24
26#include <microsim/MSLane.h>
27#include <microsim/MSEdge.h>
28#include <microsim/MSNet.h>
30#include <microsim/MSStop.h>
44#include "Helper.h"
45#include "TrafficLight.h"
46
47//#define DEBUG_CONSTRAINT_DEADLOCK
48
49namespace libsumo {
50// ===========================================================================
51// static member initializations
52// ===========================================================================
53SubscriptionResults TrafficLight::mySubscriptionResults;
54ContextSubscriptionResults TrafficLight::myContextSubscriptionResults;
55
56// ===========================================================================
57// static member definitions
58// ===========================================================================
59std::vector<std::string>
60TrafficLight::getIDList() {
62}
63
64
65int
66TrafficLight::getIDCount() {
67 return (int)getIDList().size();
68}
69
70
71std::string
72TrafficLight::getRedYellowGreenState(const std::string& tlsID) {
74}
75
76
77std::vector<TraCILogic>
78TrafficLight::getAllProgramLogics(const std::string& tlsID) {
79 std::vector<TraCILogic> result;
80 const std::vector<MSTrafficLightLogic*> logics = Helper::getTLS(tlsID).getAllLogics();
81 for (MSTrafficLightLogic* logic : logics) {
82 TraCILogic l(logic->getProgramID(), (int)logic->getLogicType(), logic->getCurrentPhaseIndex());
83 l.subParameter = logic->getParametersMap();
84 for (const MSPhaseDefinition* const phase : logic->getPhases()) {
85 l.phases.emplace_back(new TraCIPhase(STEPS2TIME(phase->duration), phase->getState(),
86 STEPS2TIME(phase->minDuration), STEPS2TIME(phase->maxDuration),
87 phase->getNextPhases(), phase->getName()));
88 }
89 result.emplace_back(l);
90 }
91 return result;
92}
93
94
95std::vector<std::string>
96TrafficLight::getControlledJunctions(const std::string& tlsID) {
97 std::set<std::string> junctionIDs;
99 for (const MSTrafficLightLogic::LinkVector& llinks : links) {
100 for (const MSLink* l : llinks) {
101 junctionIDs.insert(l->getJunction()->getID());
102 }
103 }
104 return std::vector<std::string>(junctionIDs.begin(), junctionIDs.end());
105}
106
107
108std::vector<std::string>
109TrafficLight::getControlledLanes(const std::string& tlsID) {
110 std::vector<std::string> laneIDs;
112 for (const MSTrafficLightLogic::LaneVector& llanes : lanes) {
113 for (const MSLane* l : llanes) {
114 laneIDs.push_back(l->getID());
115 }
116 }
117 return laneIDs;
118}
119
120
121std::vector<std::vector<TraCILink> >
122TrafficLight::getControlledLinks(const std::string& tlsID) {
123 std::vector<std::vector<TraCILink> > result;
126 for (int i = 0; i < (int)lanes.size(); ++i) {
127 std::vector<TraCILink> subList;
128 const MSTrafficLightLogic::LaneVector& llanes = lanes[i];
129 const MSTrafficLightLogic::LinkVector& llinks = links[i];
130 // number of links controlled by this signal (signal i)
131 for (int j = 0; j < (int)llanes.size(); ++j) {
132 MSLink* link = llinks[j];
133 // approached non-internal lane (if any)
134 const std::string to = link->getLane() != nullptr ? link->getLane()->getID() : "";
135 // approached "via", internal lane (if any)
136 const std::string via = link->getViaLane() != nullptr ? link->getViaLane()->getID() : "";
137 subList.emplace_back(TraCILink(llanes[j]->getID(), via, to));
138 }
139 result.emplace_back(subList);
140 }
141 return result;
142}
143
144
145std::string
146TrafficLight::getProgram(const std::string& tlsID) {
147 return Helper::getTLS(tlsID).getActive()->getProgramID();
148}
149
150
151int
152TrafficLight::getPhase(const std::string& tlsID) {
154}
155
156
157std::string
158TrafficLight::getPhaseName(const std::string& tlsID) {
160}
161
162
163double
164TrafficLight::getPhaseDuration(const std::string& tlsID) {
165 return STEPS2TIME(Helper::getTLS(tlsID).getActive()->getCurrentPhaseDef().duration);
166}
167
168
169double
170TrafficLight::getNextSwitch(const std::string& tlsID) {
171 return STEPS2TIME(Helper::getTLS(tlsID).getActive()->getNextSwitchTime());
172}
173
174
175double
176TrafficLight::getSpentDuration(const std::string& tlsID) {
177 return STEPS2TIME(Helper::getTLS(tlsID).getActive()->getSpentDuration());
178}
179
180int
181TrafficLight::getServedPersonCount(const std::string& tlsID, int index) {
182 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getActive();
183 if (index < 0 || active->getPhaseNumber() <= index) {
184 throw TraCIException("The phase index " + toString(index) + " is not in the allowed range [0,"
185 + toString(active->getPhaseNumber() - 1) + "].");
186 }
187 // find all crossings which have a green light in that phas
188 int result = 0;
189
190 const std::string& state = active->getPhases()[index]->getState();
191 for (int i = 0; i < (int)state.size(); i++) {
192 if (state[i] == LINKSTATE_TL_GREEN_MAJOR) {
193 for (MSLink* link : active->getLinksAt(i)) {
194 if (link->getLane()->getEdge().isCrossing()) {
195 // walking forwards across
196 for (MSTransportable* person : link->getLaneBefore()->getEdge().getPersons()) {
197 if (static_cast<MSPerson*>(person)->getNextEdge() == link->getLane()->getEdge().getID()) {
198 result += 1;
199 }
200 }
201 // walking backwards across
202 MSLane* walkingAreaAcross = link->getLane()->getLinkCont().front()->getLane();
203 for (MSTransportable* person : walkingAreaAcross->getEdge().getPersons()) {
204 if (static_cast<MSPerson*>(person)->getNextEdge() == link->getLane()->getEdge().getID()) {
205 result += 1;
206 }
207 }
208 } else if (link->getLaneBefore()->getEdge().isCrossing()) {
209 // walking backwards across (in case both sides are separately controlled)
210 for (MSTransportable* person : link->getLane()->getEdge().getPersons()) {
211 if (static_cast<MSPerson*>(person)->getNextEdge() == link->getLaneBefore()->getEdge().getID()) {
212 result += 1;
213 }
214 }
215 }
216 }
217 }
218 }
219 return result;
220}
221
222std::vector<std::string>
223TrafficLight::getBlockingVehicles(const std::string& tlsID, int linkIndex) {
224 std::vector<std::string> result;
225 // for railsignals we cannot use the "online" program
226 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
227 if (linkIndex < 0 || linkIndex >= active->getNumLinks()) {
228 throw TraCIException("The link index " + toString(linkIndex) + " is not in the allowed range [0,"
229 + toString(active->getNumLinks() - 1) + "].");
230 }
231 for (const SUMOVehicle* veh : active->getBlockingVehicles(linkIndex)) {
232 result.push_back(veh->getID());
233 }
234 return result;
235}
236
237std::vector<std::string>
238TrafficLight::getRivalVehicles(const std::string& tlsID, int linkIndex) {
239 std::vector<std::string> result;
240 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
241 if (linkIndex < 0 || linkIndex >= active->getNumLinks()) {
242 throw TraCIException("The link index " + toString(linkIndex) + " is not in the allowed range [0,"
243 + toString(active->getNumLinks() - 1) + "].");
244 }
245 for (const SUMOVehicle* veh : active->getRivalVehicles(linkIndex)) {
246 result.push_back(veh->getID());
247 }
248 return result;
249}
250
251std::vector<std::string>
252TrafficLight::getPriorityVehicles(const std::string& tlsID, int linkIndex) {
253 std::vector<std::string> result;
254 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
255 if (linkIndex < 0 || linkIndex >= active->getNumLinks()) {
256 throw TraCIException("The link index " + toString(linkIndex) + " is not in the allowed range [0,"
257 + toString(active->getNumLinks() - 1) + "].");
258 }
259 for (const SUMOVehicle* veh : active->getPriorityVehicles(linkIndex)) {
260 result.push_back(veh->getID());
261 }
262 return result;
263}
264
265std::vector<TraCISignalConstraint>
266TrafficLight::getConstraints(const std::string& tlsID, const std::string& tripId) {
267 std::vector<TraCISignalConstraint> result;
268 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
269 MSRailSignal* s = dynamic_cast<MSRailSignal*>(active);
270 if (s == nullptr) {
271 throw TraCIException("'" + tlsID + "' is not a rail signal");
272 }
273 for (auto item : s->getConstraints()) {
274 if (tripId != "" && tripId != item.first) {
275 continue;
276 }
277 for (MSRailSignalConstraint* c : item.second) {
278 result.push_back(buildConstraint(tlsID, item.first, c));
279 }
280 }
281 return result;
282}
283
284std::vector<TraCISignalConstraint>
285TrafficLight::getConstraintsByFoe(const std::string& foeSignal, const std::string& foeId) {
286 // retrieve all constraints that have the given foeSignal (optionally filtered by foeId)
287 // @note could improve efficiency by storing a map of rail signals in MSRailSignalControl
288 std::vector<TraCISignalConstraint> result;
289 for (const std::string& tlsID : getIDList()) {
290 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
291 MSRailSignal* s = dynamic_cast<MSRailSignal*>(active);
292 if (s != nullptr) {
293 for (auto item : s->getConstraints()) {
294 for (MSRailSignalConstraint* cand : item.second) {
296 if (pc != nullptr && pc->myFoeSignal->getID() == foeSignal
297 && (foeId == "" || pc->myTripId == foeId)) {
298 result.push_back(buildConstraint(s->getID(), item.first, pc));
299 }
300 }
301 }
302 }
303 }
304 return result;
305}
306
307
308void
309TrafficLight::addConstraint(const std::string& tlsID, const std::string& tripId, const std::string& foeSignal, const std::string& foeId, const int type, const int limit) {
310 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
311 MSTrafficLightLogic* const active2 = Helper::getTLS(foeSignal).getDefault();
312 MSRailSignal* s = dynamic_cast<MSRailSignal*>(active);
313 MSRailSignal* s2 = dynamic_cast<MSRailSignal*>(active2);
314 if (s == nullptr) {
315 throw TraCIException("'" + tlsID + "' is not a rail signal");
316 }
317 if (s2 == nullptr) {
318 throw TraCIException("'" + foeSignal + "' is not a rail signal");
319 }
321 s->addConstraint(tripId, c);
322}
323
324
325std::vector<TraCISignalConstraint>
326TrafficLight::swapConstraints(const std::string& tlsID, const std::string& tripId, const std::string& foeSignal, const std::string& foeId) {
327#ifdef DEBUG_CONSTRAINT_DEADLOCK
328 std::cout << "swapConstraints tlsId=" << tlsID << " tripId=" << tripId << " foeSignal=" << foeSignal << " foeId=" << foeId << "\n";
329#endif
330 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getDefault();
331 MSTrafficLightLogic* const active2 = Helper::getTLS(foeSignal).getDefault();
332 MSRailSignal* s = dynamic_cast<MSRailSignal*>(active);
333 MSRailSignal* s2 = dynamic_cast<MSRailSignal*>(active2);
334 if (s == nullptr) {
335 throw TraCIException("'" + tlsID + "' is not a rail signal");
336 }
337 if (s2 == nullptr) {
338 throw TraCIException("'" + foeSignal + "' is not a rail signal");
339 }
341 for (auto item : s->getConstraints()) {
342 if (tripId == item.first) {
343 for (MSRailSignalConstraint* cand : item.second) {
345 if (pc != nullptr && pc->myFoeSignal->getID() == foeSignal && pc->myTripId == foeId) {
346 c = pc;
347 break;
348 }
349 }
350 break;
351 }
352 }
353 if (c != nullptr) {
354 const int limit = c->myLimit;
355 // the two constraints are complementary so we actually remove rather than deactivate to avoid redundant conflict information
357 MSRailSignalConstraint* swapped = new MSRailSignalConstraint_Predecessor(type, s, tripId, limit, true);
358 swapped->updateParameters(c->getParametersMap());
359 swapParameters(swapped);
360 s->removeConstraint(tripId, c);
361 s2->addConstraint(foeId, swapped);
362 return findConstraintsDeadLocks(foeId, tripId, foeSignal, tlsID);
363 } else {
364 throw TraCIException("Rail signal '" + tlsID + "' does not have a constraint for tripId '" + tripId + "' with foeSignal '" + foeSignal + "' and foeId '" + foeId + "'");
365 }
366}
367
368
369std::vector<std::pair<std::string, std::string> >
370TrafficLight::getSwapParams(int constraintType) {
371 std::vector<std::pair<std::string, std::string> > result({
372 {"vehID", "foeID"},
373 {"line", "foeLine"},
374 {"arrival", "foeArrival"}});
375
377 std::vector<std::pair<std::string, std::string> > special({
378 {"busStop", "busStop2"},
379 {"priorStop", "priorStop2"},
380 {"stopArrival", "foeStopArrival"}});
381 result.insert(result.end(), special.begin(), special.end());
382 }
383 return result;
384}
385
386
387void
388TrafficLight::swapParameters(MSRailSignalConstraint* c) {
389 // swap parameters that were assigned by generateRailSignalConstraints.py
390 for (auto keys : getSwapParams(c->getType())) {
391 swapParameters(c, keys.first, keys.second);
392 }
393}
394
395void
396TrafficLight::swapParameters(MSRailSignalConstraint* c, const std::string& key1, const std::string& key2) {
397 const std::string value1 = c->getParameter(key1);
398 const std::string value2 = c->getParameter(key2);
399 if (value1 != "") {
400 c->setParameter(key2, value1);
401 } else {
402 c->unsetParameter(key2);
403 }
404 if (value2 != "") {
405 c->setParameter(key1, value2);
406 } else {
407 c->unsetParameter(key1);
408 }
409}
410
411void
412TrafficLight::swapParameters(TraCISignalConstraint& c) {
413 // swap parameters that were assigned by generateRailSignalConstraints.py
414 for (auto keys : getSwapParams(c.type)) {
415 swapParameters(c, keys.first, keys.second);
416 }
417}
418
419void
420TrafficLight::swapParameters(TraCISignalConstraint& c, const std::string& key1, const std::string& key2) {
421 auto it1 = c.param.find(key1);
422 auto it2 = c.param.find(key2);
423 const std::string value1 = it1 != c.param.end() ? it1->second : "";
424 const std::string value2 = it2 != c.param.end() ? it2->second : "";
425 if (value1 != "") {
426 c.param[key2] = value1;
427 } else {
428 c.param.erase(key2);
429 }
430 if (value2 != "") {
431 c.param[key1] = value2;
432 } else {
433 c.param.erase(key1);
434 }
435}
436
437
438void
439TrafficLight::removeConstraints(const std::string& tlsID, const std::string& tripId, const std::string& foeSignal, const std::string& foeId) {
440 // remove all constraints that have the given foeId
441 // @note could improve efficiency by storing a map of rail signals in MSRailSignalControl
442 for (const std::string& tlsCand : getIDList()) {
443 if (tlsID == "" || tlsCand == tlsID) {
444 MSTrafficLightLogic* const active = Helper::getTLS(tlsCand).getDefault();
445 MSRailSignal* s = dynamic_cast<MSRailSignal*>(active);
446 if (s != nullptr) {
447 for (auto item : s->getConstraints()) {
448 if (tripId == "" || item.first == tripId) {
449 for (MSRailSignalConstraint* cand : item.second) {
451 if (pc != nullptr
452 && (foeId == "" || pc->myTripId == foeId)
453 && (foeSignal == "" || pc->myFoeSignal->getID() == foeSignal)) {
454 cand->setActive(false);
455 }
456 }
457 }
458 }
459 }
460 }
461 }
462}
463
464
465void
466TrafficLight::updateConstraints(const std::string& vehID, std::string tripId) {
467 // Removes all constraints that can no longer be met because the route of
468 // vehID does not pass the signal involved in the constraint with the given tripId.
469 // This includes constraints on tripId as well as constraints where tripId is the foeId.
470
471 MSBaseVehicle* veh = Helper::getVehicle(vehID);
472 std::string curTripId = veh->getParameter().getParameter("tripId", veh->getID());
473 tripId = tripId == "" ? curTripId : tripId;
474
475 // find signals and tripId along the route of veh
476 std::map<const MSRailSignal*, std::set<std::string> > onRoute;
477 const ConstMSEdgeVector& route = veh->getRoute().getEdges();
478 auto routeIt = veh->getCurrentRouteEdge();
479 for (const MSStop& stop : veh->getStops()) {
480 for (auto it = routeIt; it < stop.edge; it++) {
481 const MSEdge* edge = *it;
483 if (it + 1 != route.end()) {
484 const MSEdge* next = *(it + 1);
485 const MSLink* link = edge->getLanes()[0]->getLinkTo(next->getLanes()[0]);
486 if (link != nullptr && link->getTLLogic() != nullptr) {
487 const MSRailSignal* s = dynamic_cast<const MSRailSignal*>(link->getTLLogic());
488 onRoute[s].insert(curTripId);
489 }
490 }
491 }
492 }
493 if (stop.pars.tripId != "") {
494 curTripId = stop.pars.tripId;
495 }
496 routeIt = stop.edge;
497 }
498 for (auto it = routeIt; it < route.end(); it++) {
499 const MSEdge* edge = *it;
501 if (it + 1 != route.end()) {
502 const MSEdge* next = *(it + 1);
503 const MSLink* link = edge->getLanes()[0]->getLinkTo(next->getLanes()[0]);
504 if (link != nullptr && link->getTLLogic() != nullptr) {
505 const MSRailSignal* s = dynamic_cast<const MSRailSignal*>(link->getTLLogic());
506 onRoute[s].insert(curTripId);
507 }
508 }
509 }
510 }
511 //for (auto item : onRoute) {
512 // std::cout << " s=" << item.first->getID() << " @" << item.first << " ids=" << toString(item.second) << "\n";
513 //}
514
515 // check relevance for all active contraints
517
518 // record outdated constraints on and by the vehicle
519 std::vector<MSRailSignalConstraint*> onVeh;
520 std::vector<std::pair<std::string, MSRailSignalConstraint*> > byVeh;
521
522 for (auto item : s->getConstraints()) {
523 for (MSRailSignalConstraint* cand : item.second) {
525 if (pc != nullptr && !pc->cleared() && pc->isActive()) {
526 if (item.first == tripId) {
527 if (onRoute[s].count(tripId) == 0) {
528 // constraint on our veh no longer relevant
529 onVeh.push_back(cand);
530 }
531 } else if (pc->myTripId == tripId) {
532 if (onRoute[pc->myFoeSignal].count(tripId) == 0) {
533 // constraint by our veh no longer relevant
534 byVeh.push_back(std::make_pair(item.first, cand));
535 }
536 }
537 }
538 }
539 }
540 for (MSRailSignalConstraint* c : onVeh) {
541 s->removeConstraint(tripId, c);
542 }
543 for (auto item : byVeh) {
544 s->removeConstraint(item.first, item.second);
545 }
546 }
547}
548
549
550std::vector<TraCISignalConstraint>
551TrafficLight::findConstraintsDeadLocks(const std::string& foeId, const std::string& tripId, const std::string& foeSignal, const std::string& tlsID) {
552 std::vector<TraCISignalConstraint> result;
553 // find circular constraints (deadlock)
554 // foeId is now constrainted by tripId and assumed to follow tripId on the
555 // same track without possibility of overtaking
556 // we look for a third vehicle foeId2 where
557 // tripId waits for foeId2 and foeId2 waits on foeId
558 std::map<std::string, TraCISignalConstraint> constraintsOnTripId;
559 std::map<std::string, TraCISignalConstraint> constrainedByFoeId;
560 std::set<std::string> foeId2Cands1;
561 std::set<std::string> foeId2Cands2;
563 for (auto item : s->getConstraints()) {
564 for (MSRailSignalConstraint* cand : item.second) {
566 if (pc != nullptr && !pc->cleared() && pc->isActive()) {
567 if (item.first == tripId) {
568 // tripId waits for foe2
569 // @could there by more than one constraint on tripId by this foe2?
570 libsumo::TraCISignalConstraint tsc = buildConstraint(s->getID(), item.first, pc);
571 constraintsOnTripId[pc->myTripId] = tsc;
572 foeId2Cands1.insert(pc->myTripId);
573 for (std::string& futureFoe2Id : getFutureTripIds(pc->myTripId)) {
574 foeId2Cands1.insert(futureFoe2Id);
575 //tsc.foeId = futureFoe2Id; // if we do this, the constraint to swap will not be found
576 constraintsOnTripId[futureFoe2Id] = tsc;
577 }
578 } else if (pc->myTripId == foeId) {
579 // foeId2 waits for foe
580 libsumo::TraCISignalConstraint tsc = buildConstraint(s->getID(), item.first, pc);
581 constrainedByFoeId[item.first] = tsc;
582 foeId2Cands2.insert(item.first);
583 for (std::string& futureTripId : getFutureTripIds(item.first)) {
584 foeId2Cands2.insert(futureTripId);
585 //tsc.tripId = futureTripId; // if we do this, the constraint to swap will not be found
586 constrainedByFoeId[futureTripId] = tsc;
587 }
588 }
589 }
590 }
591 }
592 }
593#ifdef DEBUG_CONSTRAINT_DEADLOCK
594 std::cout << "findConstraintsDeadLocks foeId=" << foeId << " tripId=" << tripId << " foeSignal=" << foeSignal << " tlsID=" << tlsID << "\n";
595 std::cout << " foeId2Cands1=" << toString(foeId2Cands1) << "\n";
596 std::cout << " foeId2Cands2=" << toString(foeId2Cands2) << "\n";
597#endif
598 if (foeId2Cands1.size() > 0) {
599 // foe2 might be constrained implicitly by foe due to following on the same track
600 // in this case foe must be on the route of foe2 between its current position and foeSignal
601
602 // we have to check this first because it also affects foeInsertion
603 // constraints if the foe is already inserted but hasn't yet passed the
604 // signal (cleared == false).
605 SUMOVehicle* foe = getVehicleByTripId(foeId);
606 if (foe != nullptr) {
607 const MSEdge* foeEdge = foe->getEdge();
608 const double foePos = foe->getPositionOnLane();
609 for (const std::string& foeId2 : foeId2Cands1) {
610 // tripId waits for foeId2
611 SUMOVehicle* foe2 = getVehicleByTripId(foeId2);
612 if (foe2 != nullptr) {
613 const ConstMSEdgeVector& foe2Route = foe2->getRoute().getEdges();
614 const TraCISignalConstraint& c = constraintsOnTripId[foeId2];
615 bool foeAhead = false;
616 for (int i = foe2->getRoutePosition(); i < (int)foe2Route.size(); i++) {
617 const MSEdge* e = foe2Route[i];
618 if (e == foeEdge &&
619 ((e != foe2->getEdge() || foe2->getPositionOnLane() < foePos)
620 || (foe->hasDeparted() && !foe2->hasDeparted())
621 || (!foe->hasDeparted() && !foe2->hasDeparted() &&
622 (foe->getParameter().depart < foe2->getParameter().depart
623 || (foe->getParameter().depart == foe2->getParameter().depart && foe->getNumericalID() < foe2->getNumericalID())))
624 )) {
625 foeAhead = true;
626#ifdef DEBUG_CONSTRAINT_DEADLOCK
627 std::cout << "findConstraintsDeadLocks foeId=" << foeId << " tripId=" << tripId << " foeSignal=" << foeSignal << "\n";
628 std::cout << " foeLeaderDeadlock foeEdge=" << foeEdge->getID() << " foe2=" << foe2->getParameter().getParameter("tripId", foe2->getID())
629 << " routePos=" << foe2->getRoutePosition() << " futureRPos=" << i << " e=" << e->getID()
630 //<< " foePos=" << foePos << " foe2Pos=" << foe2->getPositionOnLane()
631 << " " << constraintsOnTripId[foeId2].getString() << "\n";
632#endif
633 break;
634 }
635 if (e->getToJunction()->getID() == foeSignal
636 || e->getToJunction()->getID() == c.foeSignal) {
637 break;
638 }
639 }
640 if (foeAhead) {
641 // foe cannot wait for foe2 (since it's behind). Instead foe2 must wait for tripId
642 TraCISignalConstraint nc; // constraint after swap
643 nc.tripId = c.foeId;
644 nc.foeId = c.tripId;
645 nc.signalId = c.foeSignal;
646 nc.foeSignal = c.signalId;
647 nc.limit = c.limit;
648 nc.type = c.type;
649 nc.mustWait = true; // ???
650 nc.active = true;
651 nc.param = c.param;
652 swapParameters(nc);
653 result.push_back(nc);
654 // let foe wait for foe2
655 std::vector<TraCISignalConstraint> result2 = swapConstraints(c.signalId, c.tripId, c.foeSignal, c.foeId);
656 result.insert(result.end(), result2.begin(), result2.end());
657
658 // Other deadlocks might not be valid anymore so we need a fresh recheck for remaining implicit or explicit deadlocks
659 const std::vector<TraCISignalConstraint>& result4 = findConstraintsDeadLocks(foeId, tripId, foeSignal, tlsID);
660 result.insert(result.end(), result4.begin(), result4.end());
661 return result;
662 }
663 }
664 }
665 }
666 }
667
668 if (foeId2Cands2.size() > 0) {
669 // tripId might be constrained implicitly by foe2 due to following on the same track
670 // in this case foe2 must be on the route of tripId between its current position and tlsID
671 // if foe2 then waits for foe, deadlock occurs
672
673 SUMOVehicle* ego = getVehicleByTripId(tripId);
674 if (ego != nullptr && (ego->hasDeparted() || !ego->getParameter().wasSet(VEHPARS_FORCE_REROUTE))) {
675 std::set<const MSEdge*> egoToSignal;
676 const double egoPos = ego->getPositionOnLane();
677 const ConstMSEdgeVector& egoRoute = ego->getRoute().getEdges();
678 for (int i = ego->getRoutePosition(); i < (int)egoRoute.size(); i++) {
679 const MSEdge* e = egoRoute[i];
680 egoToSignal.insert(e);
681 if (e->getToJunction()->getID() == tlsID) {
682 break;
683 }
684 }
685
686 for (const std::string& foeId2 : foeId2Cands2) {
687 // foeId2 waits for foe
688 SUMOVehicle* foe2 = getVehicleByTripId(foeId2);
689 //std::cout << " foe2=" << foe2->getID() << " edge=" << foe2->getEdge()->getID() << " egoToSignal=" << toString(egoToSignal) << "\n";
690 if (foe2 != nullptr) {
691 if (egoToSignal.count(foe2->getEdge()) != 0
692 && (foe2->getEdge() != ego->getEdge() || foe2->getPositionOnLane() > egoPos)) {
693 const TraCISignalConstraint& c = constrainedByFoeId[foeId2];
694#ifdef DEBUG_CONSTRAINT_DEADLOCK
695 std::cout << "findConstraintsDeadLocks foeId=" << foeId << " tripId=" << tripId << " foeSignal=" << foeSignal << "\n";
696 std::cout << " egoLeaderDeadlock foe2Edge=" << foe2->getEdge()->getID() << " foe2=" << foe2->getParameter().getParameter("tripId", foe2->getID())
697 << " " << c.getString() << "\n";
698#endif
699 // foe is already waiting for tripId (ego) and should also wait for foeId2
700 TraCISignalConstraint nc; // constraint after swap
701 nc.tripId = c.foeId;
702 nc.foeId = c.tripId;
703 nc.signalId = c.foeSignal;
704 nc.foeSignal = c.signalId;
705 nc.limit = c.limit;
706 nc.type = c.type;
707 nc.mustWait = true; // ???
708 nc.active = true;
709 nc.param = c.param;
710 swapParameters(nc);
711 result.push_back(nc);
712 // let foe wait for foe2
713 std::vector<TraCISignalConstraint> result2 = swapConstraints(c.signalId, c.tripId, c.foeSignal, c.foeId);
714 result.insert(result.end(), result2.begin(), result2.end());
715
716 // Other deadlocks might not be valid anymore so we need a fresh recheck for remaining implicit or explicit deadlocks
717 const std::vector<TraCISignalConstraint>& result4 = findConstraintsDeadLocks(foeId, tripId, foeSignal, tlsID);
718 result.insert(result.end(), result4.begin(), result4.end());
719 return result;
720 }
721 }
722 }
723 } else if (ego != nullptr) {
724 WRITE_WARNINGF(TL("Cannot check for all deadlocks on swapConstraints because the route for vehicle '%' is not computed yet"), ego->getID());
725 }
726 }
727
728 // find deadlock in explicit constraints
729 std::vector<std::string> foeIds2;
730 std::set_intersection(
731 foeId2Cands1.begin(), foeId2Cands1.end(),
732 foeId2Cands2.begin(), foeId2Cands2.end(),
733 std::back_inserter(foeIds2));
734#ifdef DEBUG_CONSTRAINT_DEADLOCK
735 std::cout << "findConstraintsDeadLocks foeId=" << foeId << " tripId=" << tripId << " foeSignal=" << foeSignal << "\n";
736 for (const std::string& foeId2 : foeIds2) {
737 std::cout << " deadlockId=" << foeId2 << " " << constraintsOnTripId[foeId2].getString() << " " << constrainedByFoeId[foeId2].getString() << "\n";
738 }
739#endif
740 if (foeIds2.size() > 0) {
741 TraCISignalConstraint c = constrainedByFoeId[foeIds2.front()];
743 // avoid swapping insertion constraint
744 c = constraintsOnTripId[foeIds2.front()];
745 }
746 TraCISignalConstraint nc; // constraint after swap
747 nc.tripId = c.foeId;
748 nc.foeId = c.tripId;
749 nc.signalId = c.foeSignal;
750 nc.foeSignal = c.signalId;
751 nc.limit = c.limit;
752 nc.type = c.type;
753 nc.mustWait = true; // ???
754 nc.active = true;
755 nc.param = c.param;
756 swapParameters(nc);
757 result.push_back(nc);
758 // let foe wait for foe2
759 const std::vector<TraCISignalConstraint>& result2 = swapConstraints(c.signalId, c.tripId, c.foeSignal, c.foeId);
760 result.insert(result.end(), result2.begin(), result2.end());
761 if (foeIds2.size() > 1) {
762 // calling swapConstraints once may result in further swaps so we have to recheck for remaining deadlocks anew
763 const std::vector<TraCISignalConstraint>& result3 = findConstraintsDeadLocks(foeId, tripId, foeSignal, tlsID);
764 result.insert(result.end(), result3.begin(), result3.end());
765 }
766 }
767 return result;
768}
769
770
772TrafficLight::getVehicleByTripId(const std::string tripOrVehID) {
774 for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
775 SUMOVehicle* veh = i->second;
776 if (veh->getParameter().getParameter("tripId", veh->getID()) == tripOrVehID) {
777 return veh;
778 }
779 }
780 return nullptr;
781}
782
783
784std::vector<std::string>
785TrafficLight::getFutureTripIds(const std::string vehID) {
786 std::vector<std::string> result;
788 if (veh) {
789 std::string tripId = veh->getParameter().getParameter("tripId");
790 if (tripId != "") {
791 result.push_back(tripId);
792 }
793 for (const MSStop& stop : veh->getStops()) {
794 if (stop.pars.tripId != "") {
795 result.push_back(stop.pars.tripId);
796 }
797 }
798 }
799 return result;
800}
801
802
803std::string
804TrafficLight::getParameter(const std::string& tlsID, const std::string& paramName) {
806 if (StringUtils::startsWith(paramName, "NEMA.") && tll->getLogicType() != TrafficLightType::NEMA) {
807 throw TraCIException("'" + tlsID + "' is not a NEMA controller");
808 }
809 return tll->getParameter(paramName, "");
810}
811
812
814
815
816void
817TrafficLight::setRedYellowGreenState(const std::string& tlsID, const std::string& state) {
818 Helper::getTLS(tlsID).setStateInstantiatingOnline(MSNet::getInstance()->getTLSControl(), state);
819}
820
821
822void
823TrafficLight::setPhase(const std::string& tlsID, const int index) {
824 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getActive();
825 if (index < 0 || active->getPhaseNumber() <= index) {
826 throw TraCIException("The phase index " + toString(index) + " is not in the allowed range [0,"
827 + toString(active->getPhaseNumber() - 1) + "].");
828 }
830 const SUMOTime duration = active->getPhase(index).duration;
831 active->changeStepAndDuration(MSNet::getInstance()->getTLSControl(), cTime, index, duration);
832}
833
834void
835TrafficLight::setPhaseName(const std::string& tlsID, const std::string& name) {
836 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getActive();
837 const_cast<MSPhaseDefinition&>(active->getCurrentPhaseDef()).setName(name);
838}
839
840
841void
842TrafficLight::setProgram(const std::string& tlsID, const std::string& programID) {
843 try {
844 Helper::getTLS(tlsID).switchTo(MSNet::getInstance()->getTLSControl(), programID);
845 } catch (ProcessError& e) {
846 throw TraCIException(e.what());
847 }
848}
849
850
851void
852TrafficLight::setPhaseDuration(const std::string& tlsID, const double phaseDuration) {
853 MSTrafficLightLogic* const active = Helper::getTLS(tlsID).getActive();
855 active->changeStepAndDuration(MSNet::getInstance()->getTLSControl(), cTime, -1, TIME2STEPS(phaseDuration));
856}
857
858
859void
860TrafficLight::setProgramLogic(const std::string& tlsID, const TraCILogic& logic) {
862 // make sure index and phaseNo are consistent
863 if (logic.currentPhaseIndex >= (int)logic.phases.size()) {
864 throw TraCIException("set program: parameter index must be less than parameter phase number.");
865 }
866 std::vector<MSPhaseDefinition*> phases;
867 for (const std::shared_ptr<libsumo::TraCIPhase>& phase : logic.phases) {
868 MSPhaseDefinition* sumoPhase = new MSPhaseDefinition(TIME2STEPS(phase->duration), phase->state, phase->name);
869 sumoPhase->minDuration = TIME2STEPS(phase->minDur);
870 sumoPhase->maxDuration = TIME2STEPS(phase->maxDur);
871 sumoPhase->nextPhases = phase->next;
872 phases.push_back(sumoPhase);
873 }
874 if (vars.getLogic(logic.programID) == nullptr) {
876 int step = logic.currentPhaseIndex;
877 const std::string basePath = "";
878 MSTrafficLightLogic* tlLogic = nullptr;
879 SUMOTime nextSwitch = MSNet::getInstance()->getCurrentTimeStep() + phases[0]->duration;
880 switch ((TrafficLightType)logic.type) {
882 tlLogic = new MSActuatedTrafficLightLogic(tlc,
883 tlsID, logic.programID, 0,
884 phases, step, nextSwitch,
885 logic.subParameter, basePath);
886 break;
888 tlLogic = new NEMALogic(tlc,
889 tlsID, logic.programID, 0,
890 phases, step, nextSwitch,
891 logic.subParameter, basePath);
892 break;
894 tlLogic = new MSDelayBasedTrafficLightLogic(tlc,
895 tlsID, logic.programID, 0,
896 phases, step, nextSwitch,
897 logic.subParameter, basePath);
898 break;
900 tlLogic = new MSSimpleTrafficLightLogic(tlc,
901 tlsID, logic.programID, 0, TrafficLightType::STATIC,
902 phases, step, nextSwitch,
903 logic.subParameter);
904 break;
905 default:
906 throw TraCIException("Unsupported traffic light type '" + toString(logic.type) + "'");
907 }
908 try {
909 if (!vars.addLogic(logic.programID, tlLogic, true, true)) {
910 throw TraCIException("Could not add traffic light logic '" + logic.programID + "'");
911 }
912 } catch (const ProcessError& e) {
913 throw TraCIException(e.what());
914 }
915 // XXX pass GUIDetectorBuilder when running with gui
917 tlLogic->init(db);
919 } else {
920 MSSimpleTrafficLightLogic* tlLogic = static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic(logic.programID));
921 tlLogic->setPhases(phases, logic.currentPhaseIndex);
924 }
925}
926
927
928void
929TrafficLight::setParameter(const std::string& tlsID, const std::string& paramName, const std::string& value) {
931 if (StringUtils::startsWith(paramName, "NEMA.") && tll->getLogicType() != TrafficLightType::NEMA) {
932 throw TraCIException("'" + tlsID + "' is not a NEMA controller");
933 }
934 tll->setParameter(paramName, value);
935}
936
938
939void
940TrafficLight::setNemaSplits(const std::string& tlsID, const std::vector<double>& splits) {
941 setParameter(tlsID, "NEMA.splits", toString(splits));
942}
943
944void
945TrafficLight::setNemaMaxGreens(const std::string& tlsID, const std::vector<double>& maxGreens) {
946 setParameter(tlsID, "NEMA.maxGreens", toString(maxGreens));
947}
948
949void
950TrafficLight::setNemaCycleLength(const std::string& tlsID, double cycleLength) {
951 setParameter(tlsID, "NEMA.cycleLength", toString(cycleLength));
952}
953
954void
955TrafficLight::setNemaOffset(const std::string& tlsID, double offset) {
956 setParameter(tlsID, "NEMA.offset", toString(offset));
957}
958
959
961TrafficLight::buildConstraint(const std::string& tlsID, const std::string& tripId, MSRailSignalConstraint* constraint) {
962 TraCISignalConstraint c;
963 c.tripId = tripId;
965 if (pc == nullptr) {
966 // unsupported constraint
967 c.type = -1;
968 } else {
969 c.signalId = tlsID;
970 c.foeId = pc->myTripId;
971 c.foeSignal = pc->myFoeSignal->getID();
972 c.limit = pc->myLimit;
973 c.type = pc->getType();
974 c.mustWait = !pc->cleared() && pc->isActive();
975 c.active = pc->isActive();
976 c.param = constraint->getParametersMap();
977 }
978 return c;
979}
980
981
982std::shared_ptr<VariableWrapper>
983TrafficLight::makeWrapper() {
984 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
985}
986
987
988bool
989TrafficLight::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
990 switch (variable) {
991 case TRACI_ID_LIST:
992 return wrapper->wrapStringList(objID, variable, getIDList());
993 case ID_COUNT:
994 return wrapper->wrapInt(objID, variable, getIDCount());
996 return wrapper->wrapString(objID, variable, getRedYellowGreenState(objID));
998 return wrapper->wrapLogicVector(objID, variable, getAllProgramLogics(objID));
1000 return wrapper->wrapStringList(objID, variable, getControlledLanes(objID));
1002 return wrapper->wrapLinkVectorVector(objID, variable, getControlledLinks(objID));
1003 case TL_CURRENT_PHASE:
1004 return wrapper->wrapInt(objID, variable, getPhase(objID));
1005 case VAR_NAME:
1006 return wrapper->wrapString(objID, variable, getPhaseName(objID));
1007 case TL_CURRENT_PROGRAM:
1008 return wrapper->wrapString(objID, variable, getProgram(objID));
1009 case TL_PHASE_DURATION:
1010 return wrapper->wrapDouble(objID, variable, getPhaseDuration(objID));
1011 case TL_NEXT_SWITCH:
1012 return wrapper->wrapDouble(objID, variable, getNextSwitch(objID));
1013 case TL_SPENT_DURATION:
1014 return wrapper->wrapDouble(objID, variable, getSpentDuration(objID));
1015 case VAR_PERSON_NUMBER:
1016 return wrapper->wrapInt(objID, variable, getServedPersonCount(objID, StoHelp::readTypedInt(*paramData)));
1018 return wrapper->wrapStringList(objID, variable, getBlockingVehicles(objID, StoHelp::readTypedInt(*paramData)));
1019 case TL_RIVAL_VEHICLES:
1020 return wrapper->wrapStringList(objID, variable, getRivalVehicles(objID, StoHelp::readTypedInt(*paramData)));
1022 return wrapper->wrapStringList(objID, variable, getPriorityVehicles(objID, StoHelp::readTypedInt(*paramData)));
1023 case TL_CONSTRAINT:
1024 return wrapper->wrapSignalConstraintVector(objID, variable, getConstraints(objID, StoHelp::readTypedString(*paramData)));
1026 return wrapper->wrapSignalConstraintVector(objID, variable, getConstraintsByFoe(objID, StoHelp::readTypedString(*paramData)));
1028 return wrapper->wrapStringList(objID, variable, getControlledJunctions(objID));
1029 case VAR_PARAMETER:
1030 return wrapper->wrapString(objID, variable, getParameter(objID, StoHelp::readTypedString(*paramData)));
1032 return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, StoHelp::readTypedString(*paramData)));
1033 default:
1034 return false;
1035 }
1036}
1037}
1038
1039
1040/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:74
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:304
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define TIME2STEPS(x)
Definition SUMOTime.h:57
const long long int VEHPARS_FORCE_REROUTE
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOM)
Definition TraCIDefs.h:77
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition TraCIDefs.h:124
An actuated (adaptive) traffic light logic.
The base class for microscopic and mesoscopic vehicles.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
const std::list< MSStop > & getStops() const
const MSRoute & getRoute() const
Returns the current route.
An actuated traffic light logic based on time delay of approaching vehicles.
A road/street connecting two junctions.
Definition MSEdge.h:77
const std::set< MSTransportable *, ComparatorNumericalIdLess > & getPersons() const
Returns this edge's persons set.
Definition MSEdge.h:204
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
const MSJunction * getToJunction() const
Definition MSEdge.h:426
SumoXMLNodeType getType() const
return the type of this Junction
Definition MSJunction.h:133
Representation of a lane in the micro simulation.
Definition MSLane.h:84
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:769
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:729
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition MSNet.h:465
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
virtual void createTLWrapper(MSTrafficLightLogic *)
creates a wrapper for the given logic (see GUINet)
Definition MSNet.h:597
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:392
const std::string & getNextEdge() const
return the list of internal edges if this person is walking and the pedestrian model allows it
Definition MSPerson.cpp:234
The definition of a single phase of a tls logic.
SUMOTime maxDuration
The maximum duration of the phase.
SUMOTime minDuration
The minimum duration of the phase.
const std::string & getName() const
const std::string & getState() const
Returns the state within this phase.
SUMOTime duration
The duration of the phase.
std::vector< int > nextPhases
The index of the phase that suceeds this one (or -1)
const MSRailSignal * myFoeSignal
store the foe signal (for TraCI access)
bool cleared() const
whether the constraint has been met
const std::string myTripId
id of the predecessor that must already have passed
const int myLimit
the number of passed vehicles within which tripId must have occurred
A base class for constraints.
ConstraintType getType() const
ConstraintType getSwappedType() const
static MSRailSignalControl & getInstance()
const std::vector< MSRailSignal * > & getSignals() const
A signal for rails.
void addConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
register constraint for signal switching
const std::map< std::string, std::vector< MSRailSignalConstraint * > > & getConstraints() const
bool removeConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
remove constraint for signal switching
const ConstMSEdgeVector & getEdges() const
Definition MSRoute.h:125
A fixed traffic light logic.
void setPhases(const Phases &phases, int index)
Replaces the phases and set the phase index.
Storage for all programs of a single tls.
void switchTo(MSTLLogicControl &tlc, const std::string &programID)
void setStateInstantiatingOnline(MSTLLogicControl &tlc, const std::string &state)
std::vector< MSTrafficLightLogic * > getAllLogics() const
MSTrafficLightLogic * getLogic(const std::string &programID) const
bool addLogic(const std::string &programID, MSTrafficLightLogic *logic, bool netWasLoaded, bool isNewDefault=true)
Adds a logic (program). In case of an error the logic gets deleted.
MSTrafficLightLogic * getActive() const
MSTrafficLightLogic * getDefault() const
return the default program (that last used program except TRACI_PROGRAM)
A class that stores and controls tls and switching of their programs.
std::vector< std::string > getAllTLIds() const
The parent class for traffic light logics.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
std::vector< LaneVector > LaneVectorVector
Definition of a list that holds lists of lanes that do have the same attribute.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
virtual int getPhaseNumber() const =0
Returns the number of phases.
virtual int getCurrentPhaseIndex() const =0
Returns the current index within the program.
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
virtual VehicleVector getPriorityVehicles(int linkIndex)
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
virtual VehicleVector getBlockingVehicles(int linkIndex)
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
virtual const MSPhaseDefinition & getPhase(int givenstep) const =0
Returns the definition of the phase from the given position within the plan.
virtual VehicleVector getRivalVehicles(int linkIndex)
return vehicles that approach the intersection/rail signal and are in conflict with vehicles that wis...
const std::string & getProgramID() const
Returns this tl-logic's id.
TrafficLightType getLogicType() const
Returns the type of the logic.
int getNumLinks() const
return the number of controlled link indices
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
std::vector< LinkVector > LinkVectorVector
Definition of a list that holds lists of links that do have the same attribute.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
The class responsible for building and deletion of vehicles.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
A NEMA (adaptive) traffic light logic based on E2Detector.
Builds detectors for microsim.
const std::string & getID() const
Returns the id.
Definition Named.h:74
void unsetParameter(const std::string &key)
Removes a parameter.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
virtual NumericalID getNumericalID() const =0
return the numerical ID which is only for internal usage
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual int getRoutePosition() const =0
return index of edge within route
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition SUMOVehicle.h:62
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual const MSRoute & getRoute() const =0
Returns the current route.
bool wasSet(long long int what) const
Returns whether the given parameter was set.
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
C++ TraCI client API implementation.
static MSBaseVehicle * getVehicle(const std::string &id)
Definition Helper.cpp:494
static MSTLLogicControl::TLSLogicVariants & getTLS(const std::string &id)
Definition Helper.cpp:535
static int readTypedInt(tcpip::Storage &ret, const std::string &error="")
static std::string readTypedString(tcpip::Storage &ret, const std::string &error="")
TRACI_CONST int VAR_NAME
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int TL_BLOCKING_VEHICLES
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition TraCIDefs.h:379
TRACI_CONST int TL_PRIORITY_VEHICLES
TRACI_CONST int TL_CONTROLLED_LANES
TRACI_CONST int TL_SPENT_DURATION
TRACI_CONST int TL_COMPLETE_DEFINITION_RYG
TRACI_CONST int VAR_PERSON_NUMBER
TRACI_CONST int TL_CONTROLLED_JUNCTIONS
TRACI_CONST int TL_CONTROLLED_LINKS
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition TraCIDefs.h:378
TRACI_CONST int ID_COUNT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int TL_CONSTRAINT_BYFOE
TRACI_CONST int TL_CONSTRAINT
TRACI_CONST int TL_NEXT_SWITCH
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int TL_PHASE_DURATION
TRACI_CONST int TL_CURRENT_PHASE
TRACI_CONST int TL_RED_YELLOW_GREEN_STATE
TRACI_CONST int TL_CURRENT_PROGRAM
TRACI_CONST int TL_RIVAL_VEHICLES
std::string tripId
the tripId or vehicle id of the train that is constrained
Definition TraCIDefs.h:871