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