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 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
219std::vector<std::string>
220TrafficLight::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
234std::vector<std::string>
235TrafficLight::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
248std::vector<std::string>
249TrafficLight::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
262std::vector<TraCISignalConstraint>
263TrafficLight::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
281std::vector<TraCISignalConstraint>
282TrafficLight::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
305void
306TrafficLight::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
322std::vector<TraCISignalConstraint>
323TrafficLight::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
366std::vector<std::pair<std::string, std::string> >
367TrafficLight::getSwapParams(int constraintType) {
368 std::vector<std::pair<std::string, std::string> > result({
369 {"vehID", "foeID"},
370 {"line", "foeLine"},
371 {"arrival", "foeArrival"}});
372
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
384void
385TrafficLight::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
392void
393TrafficLight::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
408void
409TrafficLight::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
416void
417TrafficLight::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
435void
436TrafficLight::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
462void
463TrafficLight::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
547std::vector<TraCISignalConstraint>
548TrafficLight::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;
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()];
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
769TrafficLight::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
781std::vector<std::string>
782TrafficLight::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
800std::string
801TrafficLight::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
813void
814TrafficLight::setRedYellowGreenState(const std::string& tlsID, const std::string& state) {
815 Helper::getTLS(tlsID).setStateInstantiatingOnline(MSNet::getInstance()->getTLSControl(), state);
816}
817
818
819void
820TrafficLight::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
831void
832TrafficLight::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
838void
839TrafficLight::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
848void
849TrafficLight::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
856void
857TrafficLight::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);
921 }
922}
923
924
925void
926TrafficLight::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
936void
937TrafficLight::setNemaSplits(const std::string& tlsID, const std::vector<double>& splits) {
938 setParameter(tlsID, "NEMA.splits", toString(splits));
939}
940
941void
942TrafficLight::setNemaMaxGreens(const std::string& tlsID, const std::vector<double>& maxGreens) {
943 setParameter(tlsID, "NEMA.maxGreens", toString(maxGreens));
944}
945
946void
947TrafficLight::setNemaCycleLength(const std::string& tlsID, double cycleLength) {
948 setParameter(tlsID, "NEMA.cycleLength", toString(cycleLength));
949}
950
951void
952TrafficLight::setNemaOffset(const std::string& tlsID, double offset) {
953 setParameter(tlsID, "NEMA.offset", toString(offset));
954}
955
956
958TrafficLight::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
979std::shared_ptr<VariableWrapper>
980TrafficLight::makeWrapper() {
981 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
982}
983
984
985bool
986TrafficLight::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));
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: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
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