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