Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSRailSignal.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 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/****************************************************************************/
20// A rail signal logic
21/****************************************************************************/
22#include <config.h>
23
24#include <cassert>
25#include <utility>
26#include <vector>
27#include <bitset>
28#ifdef HAVE_FOX
30#endif
33#include <microsim/MSNet.h>
34#include <microsim/MSEdge.h>
36#include <microsim/MSLane.h>
37#include <microsim/MSLink.h>
38#include <microsim/MSVehicle.h>
41#include <microsim/MSLane.h>
42
43#include "MSTLLogicControl.h"
44#include "MSTrafficLightLogic.h"
45#include "MSPhaseDefinition.h"
46#include "MSTLLogicControl.h"
48#include "MSRailSignalControl.h"
49#include "MSDriveWay.h"
50#include "MSRailSignal.h"
51
52//#define DEBUG_SELECT_DRIVEWAY
53//#define DEBUG_DRIVEWAY_UPDATE
54//#define DEBUG_SIGNALSTATE
55//#define DEBUG_REROUTE
56
57#define DEBUG_COND DEBUG_HELPER(this)
58#define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
59#define DEBUG_HELPER(obj) ((obj)->isSelected())
60//#define DEBUG_HELPER(obj) ((obj)->getID() == "")
61//#define DEBUG_HELPER(obj) (true)
62
63// ===========================================================================
64// static value definitions
65// ===========================================================================
66
73std::vector<const MSDriveWay*> MSRailSignal::myBlockingDriveWays;
75
76// ===========================================================================
77// method definitions
78// ===========================================================================
80 const std::string& id, const std::string& programID, SUMOTime delay,
81 const Parameterised::Map& parameters) :
82 MSTrafficLightLogic(tlcontrol, id, programID, 0, TrafficLightType::RAIL_SIGNAL, delay, parameters),
83 myNumericalID(myRSIndex++),
84 myCurrentPhase(DELTA_T, std::string(SUMO_MAX_CONNECTIONS, 'X')), // dummy phase
85 myPhaseIndex(0),
86 myDriveWayIndex(0) {
88 myMovingBlock = OptionsCont::getOptions().getBool("railsignal-moving-block");
90}
91
92void
94 if (myLanes.size() == 0) {
95 WRITE_WARNINGF(TL("Rail signal at junction '%' does not control any links"), getID());
96 }
97 SVCPermissions outgoingPermissions = 0;
98 for (LinkVector& links : myLinks) { //for every link index
99 if (links.size() != 1) {
100 throw ProcessError("At railSignal '" + getID() + "' found " + toString(links.size())
101 + " links controlled by index " + toString(links[0]->getTLIndex()));
102 }
103 myLinkInfos.push_back(LinkInfo(links[0]));
104 outgoingPermissions |= links[0]->getPermissions();
105 }
107 setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
108 myNumLinks = (int)myLinks.size();
111}
112
113
117
118
119// ----------- Handling of controlled links
120void
125
126
127// ------------ Switching and setting current rows
130 // deschedule regular traffic light event,
131 // updateCurrentPhase is instead called from MSRailSignalControl::updateSignals
132 return SUMOTime_MAX;
133}
134
135
136
137bool
139#ifdef DEBUG_SIGNALSTATE
141#endif
142 bool keepActive = false;
143 // green by default so vehicles can be inserted at the borders of the network
144 std::string state(myLinks.size(), 'G');
145 for (LinkInfo& li : myLinkInfos) {
146 if (li.myLink->getApproaching().size() > 0 && li.myControlled) {
147 keepActive = true;
148 Approaching closest = li.myLink->getClosest();
149 MSDriveWay& driveway = li.getDriveWay(closest.first);
150 //std::cout << SIMTIME << " signal=" << getTLLinkID(li.myLink) << " veh=" << closest.first->getID() << " dw:\n";
151 //driveway.writeBlocks(*OutputDevice_COUT::getDevice());
152 const bool mustWait = !constraintsAllow(closest.first, true);
153 MSEdgeVector occupied;
154 if (mustWait || !driveway.reserve(closest, occupied)) {
155 state[li.myLink->getTLIndex()] = 'r';
156 if (occupied.size() > 0) {
157 li.reroute(const_cast<SUMOVehicle*>(closest.first), occupied);
158 }
159#ifdef DEBUG_SIGNALSTATE
160 if (gDebugFlag4) {
161 std::cout << SIMTIME << " rsl=" << li.getID() << " veh=" << closest.first->getID() << " notReserved\n";
162 }
163#endif
164 } else {
165 state[li.myLink->getTLIndex()] = 'G';
166#ifdef DEBUG_SIGNALSTATE
167 if (gDebugFlag4) {
168 std::cout << SIMTIME << " rsl=" << li.getID() << " veh=" << closest.first->getID() << " reserved\n";
169 }
170#endif
171 }
172 } else if (li.myControlled) {
173 if (li.myDriveways.empty()) {
174#ifdef DEBUG_SIGNALSTATE
175 if (gDebugFlag4) {
176 std::cout << SIMTIME << " rsl=" << li.getID() << " red for unitialized signal (no driveways yet)\n";
177 }
178#endif
179 state[li.myLink->getTLIndex()] = 'r';
180 } else {
181 const MSDriveWay& driveway = *li.myDriveways.front();
182 MSEdgeVector occupied;
183 if (driveway.foeDriveWayOccupied(true, nullptr, occupied) || driveway.foeDriveWayApproached()) {
184 keepActive = true;
185#ifdef DEBUG_SIGNALSTATE
186 if (gDebugFlag4) {
187 std::cout << SIMTIME << " rsl=" << li.getID() << " red for default driveway " << driveway.getID() << "\n";
188 }
189#endif
190 state[li.myLink->getTLIndex()] = 'r';
191 } else {
192#ifdef DEBUG_SIGNALSTATE
193 if (gDebugFlag4) {
194 std::cout << SIMTIME << " rsl=" << li.getID() << " green for default driveway " << driveway.getID() << "\n";
195 }
196#endif
197 }
198 }
199 } else {
200 state[li.myLink->getTLIndex()] = 'O';
201 }
202 }
203 if (myCurrentPhase.getState() != state) {
206 // set link priorities
208 // execute switch actions (3D-gui)
209 //const MSTLLogicControl::TLSLogicVariants& vars = myTLControl.get(myTLLogic->getID());
210 //vars.executeOnSwitchActions();
211 }
212#ifdef DEBUG_SIGNALSTATE
213 gDebugFlag4 = false;
214#endif
215 return keepActive;
216}
217
218
219bool
220MSRailSignal::constraintsAllow(const SUMOVehicle* veh, bool storeWaitRelation) const {
221 if (myConstraints.size() == 0) {
222 return true;
223 } else {
224 const std::string tripID = veh->getParameter().getParameter("tripId", veh->getID());
225 auto it = myConstraints.find(tripID);
226 if (it != myConstraints.end()) {
227 for (MSRailSignalConstraint* c : it->second) {
228 // ignore insertion constraints here
229 if (!c->isInsertionConstraint() && !c->cleared()) {
230#ifdef DEBUG_SIGNALSTATE
231 if (gDebugFlag4) {
232 std::cout << " constraint '" << c->getDescription() << "' not cleared\n";
233 }
234#endif
235 if (storeWaitRelation && MSGlobals::gTimeToTeleportRSDeadlock > 0
237 const SUMOVehicle* foe = c->getFoe();
238 if (foe != nullptr) {
240 }
241 }
242 if (myStoreVehicles) {
243 myConstraintInfo = c->getDescription();
244 }
245 return false;
246 }
247 }
248 }
249 return true;
250 }
251}
252
253
254void
255MSRailSignal::addConstraint(const std::string& tripId, MSRailSignalConstraint* constraint) {
256 myConstraints[tripId].push_back(constraint);
257}
258
259
260bool
261MSRailSignal::removeConstraint(const std::string& tripId, MSRailSignalConstraint* constraint) {
262 if (myConstraints.count(tripId) != 0) {
263 auto& constraints = myConstraints[tripId];
264 auto it = std::find(constraints.begin(), constraints.end(), constraint);
265 if (it != constraints.end()) {
266 delete *it;
267 constraints.erase(it);
268 return true;
269 }
270 }
271 return false;
272}
273
274void
276 for (auto item : myConstraints) {
277 for (MSRailSignalConstraint* c : item.second) {
278 delete c;
279 }
280 }
281 myConstraints.clear();
282}
283
284
285// ------------ Static Information Retrieval
286int
288 return 0;
289}
290
293 return myPhases;
294}
295
298 return myCurrentPhase;
299}
300
301// ------------ Dynamic Information Retrieval
302int
306
311
312
313void
317
318
319// ------------ Conversion between time and phase
322 return 0;
323}
324
327 return 0;
328}
329
330int
332 return 0;
333}
334
335
336void
337MSRailSignal::addLink(MSLink* link, MSLane* lane, int pos) {
338 if (pos >= 0) {
339 MSTrafficLightLogic::addLink(link, lane, pos);
340 } // ignore uncontrolled link
341}
342
343
344std::string
345MSRailSignal::describeLinks(std::vector<MSLink*> links) {
346 std::string result;
347 for (MSLink* link : links) {
348 result += link->getDescription() + " ";
349 }
350 return result;
351}
352
353
354void
355MSRailSignal::writeBlocks(OutputDevice& od, bool writeVehicles) const {
356 od.openTag("railSignal");
358 for (const LinkInfo& li : myLinkInfos) {
359 MSLink* link = li.myLink;
360 od.openTag("link");
364 for (const MSDriveWay* dw : li.myDriveways) {
365 if (writeVehicles) {
366 dw->writeBlockVehicles(od);
367 } else {
368 dw->writeBlocks(od);
369 }
370 }
371 od.closeTag(); // link
372 }
373 od.closeTag(); // railSignal
374}
375
376
377void
379 const ConstMSEdgeVector& edges = ego->getRoute().getEdges();
380 int endIndex = ego->getParameter().arrivalEdge;
381 if (endIndex < 0) {
382 endIndex = (int)edges.size() - 1;
383 }
384 int departIndex = ego->getParameter().departEdge;
385 MSDriveWay* prev = nullptr;
386 if (update && ego->hasDeparted()) {
387 // find last rail signal on the route and obtain the driveway
388 const MSEdge* next = ego->getEdge();
389 for (int i = ego->getRoutePosition() - 1; i > departIndex; i--) {
390 const MSEdge* e = ego->getRoute().getEdges()[i];
392 const MSLink* link = e->getLanes().front()->getLinkTo(next->getLanes().front());
393 //std::cout << SIMTIME << " veh=" << ego->getID() << " rp=" << ego->getRoutePosition()
394 // << " i=" << i << " e=" << e->getID() << " next=" << next->getID() << " link=" << (link == nullptr ? "NUL" : link->getDescription()) << "\n";
395 if (link != nullptr && link->isTLSControlled()) {
396 MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(link->getTLLogic()));
397 LinkInfo& li = rs->myLinkInfos[link->getTLIndex()];
398 prev = &li.getDriveWay(ego, i);
399 departIndex = ego->getRoutePosition();
400 break;
401 }
402 }
403 next = e;
404 }
405 }
406 if (prev == nullptr) {
407 prev = const_cast<MSDriveWay*>(MSDriveWay::getDepartureDriveway(ego, true));
408 }
409 if (update && ego->hasDeparted()) {
410 MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(const_cast<SUMOVehicle*>(ego));
411 if (!prev->hasTrain(veh) && prev->notifyEnter(*veh, prev->NOTIFICATION_REROUTE, nullptr) && !veh->hasReminder(prev)) {
412 veh->addReminder(prev, 1);
413 }
414 }
415 for (int i = departIndex; i <= endIndex - 1; i++) {
416 const MSEdge* e = edges[i];
418 const MSEdge* e2 = edges[i + 1];
419 for (MSLane* lane : e->getLanes()) {
420 for (MSLink* link : lane->getLinkCont()) {
421 if (&link->getLane()->getEdge() == e2) {
422 MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(link->getTLLogic()));
423 if (rs != nullptr) {
424 LinkInfo& li = rs->myLinkInfos[link->getTLIndex()];
425 // init driveway
426 MSDriveWay* dw = &li.getDriveWay(ego, i);
430 prev = dw;
431 if (update && rs->isActive()) {
432 // vehicle may have rerouted its intial trip
433 // after the states have been set
434 // @note: This is a hack because it could lead to invalid tls-output
435 // (it's still an improvement over switching based on default driveways)
436 if (!ego->hasDeparted()) {
437 rs->updateCurrentPhase();
439 } else if (ego->hasDeparted() && i <= ego->getRoutePosition()) {
440 MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(const_cast<SUMOVehicle*>(ego));
441 if (!dw->hasTrain(veh) && dw->notifyEnter(*veh, dw->NOTIFICATION_REROUTE, nullptr) && !veh->hasReminder(dw)) {
442 veh->addReminder(dw, 1);
443 for (MSDriveWay* sub : dw->getSubDriveWays()) {
444 if (!sub->hasTrain(veh) && sub->notifyEnter(*veh, dw->NOTIFICATION_REROUTE, nullptr) && !veh->hasReminder(sub)) {
445 veh->addReminder(sub, 1);
446 }
447 }
448 }
449 }
450 }
451 }
452 }
453 }
454 }
455 }
456 }
457}
458
459
460bool
461MSRailSignal::hasInsertionConstraint(MSLink* link, const MSVehicle* veh, std::string& info, bool& isInsertionOrder) {
462 if (link->getJunction() != nullptr && link->getJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL) {
463 const MSRailSignal* rs = dynamic_cast<const MSRailSignal*>(link->getTLLogic());
464 if (rs != nullptr && rs->myConstraints.size() > 0) {
465 const std::string tripID = veh->getParameter().getParameter("tripId", veh->getID());
466 auto it = rs->myConstraints.find(tripID);
467 if (it != rs->myConstraints.end()) {
468 for (MSRailSignalConstraint* c : it->second) {
469 if (c->isInsertionConstraint() && !c->cleared()) {
470#ifdef DEBUG_SIGNALSTATE
471 if (DEBUG_HELPER(rs)) {
472 std::cout << SIMTIME << " rsl=" << rs->getID() << " insertion constraint '" << c->getDescription() << "' for vehicle '" << veh->getID() << "' not cleared\n";
473 }
474#endif
475 info = c->getDescription();
476 isInsertionOrder = c->getType() == MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
478 const SUMOVehicle* foe = c->getFoe();
479 if (foe != nullptr) {
481 }
482 }
483 return true;
484 }
485 }
486 }
487 }
488 }
489 return false;
490}
491
492// ===========================================================================
493// LinkInfo method definitions
494// ===========================================================================
495
497 myLink(link) {
498 reset();
499}
500
502 for (MSDriveWay* dw : myDriveways) {
503 delete dw;
504 }
505 myDriveways.clear();
506}
507
508void
510 myLastRerouteTime = -1;
511 myLastRerouteVehicle = nullptr;
512 myDriveways.clear();
513 myControlled = (myLink->getViaLaneOrLane()->getPermissions() & myLink->getLane()->getPermissions() & SVC_RAIL_CLASSES) != 0;
514}
515
516
517std::string
519 return myLink->getTLLogic()->getID() + "_" + toString(myLink->getTLIndex());
520}
521
522
525 MSEdge* first = &myLink->getLane()->getEdge();
526 auto searchStartIt = searchStart < 0 ? veh->getCurrentRouteEdge() : veh->getRoute().begin() + searchStart;
527 MSRouteIterator firstIt = std::find(searchStartIt, veh->getRoute().end(), first);
528 if (firstIt == veh->getRoute().end()) {
529 // possibly the vehicle has already gone past the first edge (i.e.
530 // because first is short or the step-length is high)
531 // lets look backward along the route
532 // give some slack because the vehicle might have been braking from a higher speed and using ballistic integration
533 double lookBack = SPEED2DIST(veh->getSpeed() + 10) + veh->getLength();
534 int routeIndex = veh->getRoutePosition() - 1;
535 while (lookBack > 0 && routeIndex > 0) {
536 const MSEdge* prevEdge = veh->getRoute().getEdges()[routeIndex];
537 if (prevEdge == first) {
538 firstIt = veh->getRoute().begin() + routeIndex;
539 break;
540 }
541 lookBack -= prevEdge->getLength();
542 routeIndex--;
543 }
544 }
545 MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(myLink->getTLLogic()));
546 if (firstIt == veh->getRoute().end()) {
547 WRITE_WARNING("Invalid approach information to rail signal " + MSDriveWay::getClickableTLLinkID(myLink) + " after rerouting for vehicle '" + veh->getID()
548 + "' first driveway edge '" + first->getID() + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
549 if (myDriveways.empty()) {
550 ConstMSEdgeVector dummyRoute;
551 dummyRoute.push_back(&myLink->getLane()->getEdge());
552 MSDriveWay* dw = MSDriveWay::buildDriveWay(rs->getNewDrivewayID(), myLink, dummyRoute.begin(), dummyRoute.end());
553 myDriveways.push_back(dw);
554 }
555 return *myDriveways.front();
556 }
557 //std::cout << SIMTIME << " veh=" << veh->getID() << " rsl=" << getID() << " dws=" << myDriveways.size() << "\n";
558 return getDriveWay(firstIt, veh->getRoute().end(), veh->getID());
559}
560
561
564 for (MSDriveWay* dw : myDriveways) {
565 if (dw->match(firstIt, endIt)) {
566 return *dw;
567 }
568#ifdef DEBUG_SELECT_DRIVEWAY
569 std::cout << SIMTIME << " rs=" << getID() << " veh=" << info << " other dwSignal=" << dw->foundSignal() << " dwRoute=" << toString(dw->getRoute()) << "\n";
570#else
571 UNUSED_PARAMETER(info);
572#endif
573 }
574 MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(myLink->getTLLogic()));
575 MSDriveWay* dw = MSDriveWay::buildDriveWay(rs->getNewDrivewayID(), myLink, firstIt, endIt);
576 dw->setVehicle(info);
577#ifdef DEBUG_SELECT_DRIVEWAY
578 std::cout << SIMTIME << " rs=" << getID() << " veh=" << info << " new dwSignal=" << dw->foundSignal() << " dwRoute=" << toString(dw->getRoute()) << "\n";
579#endif
580 myDriveways.push_back(dw);
581 return *myDriveways.back();
582}
583
584
585void
587 MSDevice_Routing* rDev = static_cast<MSDevice_Routing*>(veh->getDevice(typeid(MSDevice_Routing)));
589 if (rDev != nullptr
590 && rDev->mayRerouteRailSignal()
591 && (myLastRerouteVehicle != veh
592 // reroute each vehicle only once if no periodic routing is allowed,
593 // otherwise with the specified period
594 || (rDev->getPeriod() > 0 && myLastRerouteTime + rDev->getPeriod() <= now))) {
595 myLastRerouteVehicle = veh;
596 myLastRerouteTime = now;
597
598#ifdef DEBUG_REROUTE
599 ConstMSEdgeVector oldRoute = veh->getRoute().getEdges();
601 std::cout << SIMTIME << " reroute veh=" << veh->getID() << " rs=" << getID() << " occupied=" << toString(occupied) << "\n";
602 }
603#endif
605 for (MSEdge* e : occupied) {
606 // indefinite occupation because vehicles might be in deadlock on their current routes
607 prohibited[e].end = std::numeric_limits<double>::max();
608 }
609 MSRoutingEngine::reroute(*veh, now, "railSignal:" + getID(), false, true, prohibited);
610#ifdef DEBUG_REROUTE
611 // attention this works only if we are not parallel!
613 if (veh->getRoute().getEdges() != oldRoute) {
614 std::cout << " rerouting successful\n";
615 }
616 }
617#endif
618 }
619}
620
621
622const MSDriveWay&
624 LinkInfo& li = myLinkInfos[link->getTLIndex()];
625 const MSDriveWay& cand = li.getDriveWay(firstIt, endIt, "_tmp_");
626 // an existing driveway should be found
627 assert(cand.getFirstVehicle() != "_tmp_");
628 return cand;
629}
630
631
632void
641
642
643void
645 resetStored();
646 myStoreVehicles = true;
647 MSEdgeVector occupied;
648 // call for side effects
649 dw->foeDriveWayOccupied(true, nullptr, occupied);
650 myStoreVehicles = false;
651}
652
653void
655 resetStored();
656 myStoreVehicles = true;
657 LinkInfo& li = myLinkInfos[linkIndex];
658 if (li.myLink->getApproaching().size() > 0) {
659 Approaching closest = li.myLink->getClosest();
660 MSDriveWay& driveway = li.getDriveWay(closest.first);
661 MSEdgeVector occupied;
662 myRequestedDriveWay = driveway.getID();
663 // call for side effects
664 driveway.reserve(closest, occupied);
665 constraintsAllow(closest.first);
666 } else if (li.myDriveways.size() > 0) {
667 li.myDriveways.front()->conflictLaneOccupied();
668 li.myDriveways.front()->foeDriveWayApproached();
669 }
670 myStoreVehicles = false;
671}
672
675 storeTraCIVehicles(linkIndex);
676 return myBlockingVehicles;
677}
678
681 storeTraCIVehicles(linkIndex);
682 return myRivalVehicles;
683}
684
687 storeTraCIVehicles(linkIndex);
688 return myPriorityVehicles;
689}
690
691std::string
693 storeTraCIVehicles(linkIndex);
694 return myConstraintInfo;
695}
696
697
698std::string
700 storeTraCIVehicles(linkIndex);
701 return myRequestedDriveWay;
702}
703
704
705std::vector<const MSDriveWay*>
707 storeTraCIVehicles(linkIndex);
708 return myBlockingDriveWays;
709}
710
711
717
718
719std::vector<const MSDriveWay*>
724
725const MSDriveWay&
726MSRailSignal::retrieveDriveWay(int numericalID) const {
727 for (const LinkInfo& li : myLinkInfos) {
728 for (const MSDriveWay* dw : li.myDriveways) {
729 if (dw->getNumericalID() == numericalID) {
730 return *dw;
731 }
732 }
733 }
734 throw ProcessError("Invalid driveway id " + toString(numericalID) + " at railSignal '" + getID() + "'");
735}
736
737const MSDriveWay&
739 return myLinkInfos[tlIndex].getDriveWay(veh);
740}
741
742const MSDriveWay&
744 return myLinkInfos[tlIndex].getDriveWay(first, end);
745}
746
747
748const std::vector<MSDriveWay*>
750 return myLinkInfos[tlIndex].myDriveways;
751}
752
753
754const MSJunction*
756 return myLinkInfos.front().myLink->getJunction();
757}
758
759
760std::string
762 MSRailSignal* rs = const_cast<MSRailSignal*>(this);
763 if (myLinkInfos.size() == 1) {
764 return toString(rs->getBlockingVehicles(0));
765 } else {
766 std::string result;
767 for (int i = 0; i < (int)myLinkInfos.size(); i++) {
768 result += toString(i) + ": " + toString(rs->getBlockingVehicles(i)) + ";";
769 }
770 return result;
771 }
772}
773std::string
775 MSRailSignal* rs = const_cast<MSRailSignal*>(this);
776 if (myLinkInfos.size() == 1) {
777 return toString(rs->getRivalVehicles(0));
778 } else {
779 std::string result;
780 for (int i = 0; i < (int)myLinkInfos.size(); i++) {
781 result += toString(i) + ": " + toString(rs->getRivalVehicles(i)) + ";";
782 }
783 return result;
784 }
785}
786std::string
788 MSRailSignal* rs = const_cast<MSRailSignal*>(this);
789 if (myLinkInfos.size() == 1) {
790 return toString(rs->getPriorityVehicles(0));
791 } else {
792 std::string result;
793 for (int i = 0; i < (int)myLinkInfos.size(); i++) {
794 result += toString(i) + ": " + toString(rs->getPriorityVehicles(i)) + ";";
795 }
796 return result;
797 }
798}
799std::string
801 MSRailSignal* rs = const_cast<MSRailSignal*>(this);
802 if (myLinkInfos.size() == 1) {
803 return rs->getConstraintInfo(0);
804 } else {
805 std::string result;
806 for (int i = 0; i < (int)myLinkInfos.size(); i++) {
807 result += toString(i) + ": " + rs->getConstraintInfo(i);
808 }
809 return result;
810 }
811}
812std::string
814 MSRailSignal* rs = const_cast<MSRailSignal*>(this);
815 if (myLinkInfos.size() == 1) {
816 return toString(rs->getRequestedDriveWay(0));
817 } else {
818 std::string result;
819 for (int i = 0; i < (int)myLinkInfos.size(); i++) {
820 result += toString(i) + ": " + toString(rs->getRequestedDriveWay(i)) + ";";
821 }
822 return result;
823 }
824}
825std::string
827 MSRailSignal* rs = const_cast<MSRailSignal*>(this);
828 if (myLinkInfos.size() == 1) {
829 return toString(rs->getBlockingDriveWays(0));
830 } else {
831 std::string result;
832 for (int i = 0; i < (int)myLinkInfos.size(); i++) {
833 result += toString(i) + ": " + toString(rs->getBlockingDriveWays(i)) + ";";
834 }
835 return result;
836 }
837}
838
839void
840MSRailSignal::setParameter(const std::string& key, const std::string& value) {
841 // some pre-defined parameters can be updated at runtime
842 if (key == "moving-block") {
843 bool movingBlock = StringUtils::toBool(value);
844 if (movingBlock != myMovingBlock) {
845 // recompute driveways
846 myMovingBlock = movingBlock;
847 for (LinkInfo& li : myLinkInfos) {
848 li.reset();
849 }
851 setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
852 }
853 }
854 Parameterised::setParameter(key, value);
855}
856
857
858std::string
862/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define DEBUG_HELPER(obj)
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:75
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:74
#define DEBUG_COND_LINKINFO
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition MSRoute.h:57
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
SUMOTime DELTA_T
Definition SUMOTime.cpp:39
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:107
#define SPEED2DIST(x)
Definition SUMOTime.h:48
#define SIMSTEP
Definition SUMOTime.h:69
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:70
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ID
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
bool gDebugFlag4
Definition StdDefs.cpp:47
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
Definition StdDefs.h:45
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:57
The base class for microscopic and mesoscopic vehicles.
bool hasReminder(MSMoveReminder *rem) const
Checks whether the vehicle has the given MoveReminder.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
void addReminder(MSMoveReminder *rem, double pos=0)
Adds a MoveReminder dynamically.
SUMOTime getStartupDelay() const
Get the vehicle type's startupDelay.
Definition MSCFModel.h:309
A device that performs vehicle rerouting based on current edge speeds.
SUMOTime getPeriod() const
bool mayRerouteRailSignal() const
return whether the equipped vehicle may receive dispatch information at a rail signal
static std::string getClickableTLLinkID(const MSLink *link)
return logicID_linkIndex in a way that allows clicking in sumo-gui
const std::string & getFirstVehicle() const
Definition MSDriveWay.h:149
const std::vector< MSDriveWay * > & getSubDriveWays() const
Definition MSDriveWay.h:177
bool foundSignal() const
Definition MSDriveWay.h:181
bool hasTrain(SUMOVehicle *veh) const
whether the given train is on this driveway
void setVehicle(const std::string &vehID)
Definition MSDriveWay.h:145
const std::vector< const MSEdge * > & getRoute() const
Definition MSDriveWay.h:117
static MSDriveWay * buildDriveWay(const std::string &id, const MSLink *link, MSRouteIterator first, MSRouteIterator end)
construct a new driveway by searching along the given route until all block structures are found
bool foeDriveWayApproached() const
whether any of my Foes is being approached
static const MSDriveWay * getDepartureDriveway(const SUMOVehicle *veh, bool init=false)
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering the lane.
bool reserve(const Approaching &closest, MSEdgeVector &occupied)
attempt reserve this driveway for the given vehicle
bool foeDriveWayOccupied(bool store, const SUMOVehicle *ego, MSEdgeVector &occupied) const
whether any of myFoes is occupied (vehicles that are the target of a join must be ignored)
A road/street connecting two junctions.
Definition MSEdge.h:78
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:169
bool isNormal() const
return whether this edge is an internal edge
Definition MSEdge.h:265
const MSJunction * getToJunction() const
Definition MSEdge.h:428
double getLength() const
return the length of the edge
Definition MSEdge.h:695
static SUMOTime gTimeToTeleportRSDeadlock
Definition MSGlobals.h:72
The base class for an intersection.
Definition MSJunction.h:58
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
@ NOTIFICATION_REROUTE
The vehicle changed it's route.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:201
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
The definition of a single phase of a tls logic.
SUMOTime myLastSwitch
Stores the timestep of the last on-switched of the phase.
const std::string & getState() const
Returns the state within this phase.
void setState(const std::string &_state)
A base class for constraints.
void notifyApproach(const MSLink *link)
switch rail signal to active
void addSignal(MSRailSignal *signal)
void addDrivewayFollower(const MSDriveWay *dw, const MSDriveWay *dw2)
void addWaitRelation(const SUMOVehicle *waits, const MSRailSignal *rs, const SUMOVehicle *reason, MSRailSignalConstraint *constraint=nullptr)
void addDWDeadlockChecks(const MSRailSignal *rs, MSDriveWay *dw)
check whether the given signal and driveway are part of a deadlock circle
static MSRailSignalControl & getInstance()
static bool isMovingBlock(SVCPermissions svc)
A signal for rails.
static VehicleVector myRivalVehicles
std::string getBlockingVehicleIDs() const
Phases myPhases
The list of phases this logic uses.
std::string getConstraintInfo(int linkIndex)
return information regarding active rail signal constraints for the closest approaching vehicle
static VehicleVector myPriorityVehicles
std::string getRequestedDriveWay() const
int myPhaseIndex
MSTrafficLightLogic requires that the phase index changes whenever signals change their state.
SUMOTime getOffsetFromIndex(int index) const override
Returns the position (start of a phase during a cycle) from of a given step.
void setParameter(const std::string &key, const std::string &value) override
Sets a parameter and updates internal constants.
static std::string myConstraintInfo
MSPhaseDefinition myCurrentPhase
The current phase.
void addConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
register constraint for signal switching
const MSDriveWay & getExistingDriveWay(const MSLink *link, MSRouteIterator firstIt, MSRouteIterator endIt)
std::vector< LinkInfo > myLinkInfos
data storage for every link at this node (more than one when directly guarding a switch)
const MSDriveWay & retrieveDriveWayForVeh(int tlIndex, const SUMOVehicle *veh)
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const override
Returns the index of the logic at the given simulation step.
std::string getPriorityVehicleIDs() const
MSRailSignal(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, SUMOTime delay, const Parameterised::Map &parameters)
Constructor.
static std::string myRequestedDriveWay
void resetLastSwitch(SUMOTime t) override
VehicleVector getBlockingVehicles(int linkIndex) override
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
const MSJunction * getJunction() const
get the unique junction controlled by this signal
void writeBlocks(OutputDevice &od, bool writeVehicles) const
write rail signal block output for all links and driveways
VehicleVector getRivalVehicles(int linkIndex) override
return vehicles that approach the intersection/rail signal and are in conflict with vehicles that wis...
int myDriveWayIndex
running number of driveways created for this signal
static std::string describeLinks(std::vector< MSLink * > links)
print link descriptions
~MSRailSignal()
Destructor.
static void resetStored()
reset temporary storage for injected conflict output
void adaptLinkInformationFrom(const MSTrafficLightLogic &logic) override
Applies information about controlled links and lanes from the given logic.
static int myRSIndex
static VehicleVector myBlockingVehicles
bool constraintsAllow(const SUMOVehicle *veh, bool storeWaitRelation=false) const
whether the given vehicle is free to drive
void removeConstraints()
void storeTraCIVehicles(int linkIndex)
update vehicle lists for traci calls
int getIndexFromOffset(SUMOTime offset) const override
Returns the step (the phasenumber) of a given position of the cycle.
void init(NLDetectorBuilder &nb) override
Initialises the rail signal with information about adjacent rail signals.
std::map< std::string, std::vector< MSRailSignalConstraint * > > myConstraints
map from tripId to constraint list
std::pair< const SUMOVehicle *const, const MSLink::ApproachingVehicleInformation > Approaching
int getPhaseNumber() const override
Returns the number of phases.
const MSPhaseDefinition & getPhase(int givenstep) const override
Returns the definition of the phase from the given position within the plan.
SUMOTime trySwitch() override
Switches to the next phase.
std::string getBlockingDriveWayIDs() const
const std::vector< MSDriveWay * > retrieveDriveWays(int tlIndex) const
const MSDriveWay & retrieveDriveWay(int numericalID) const
static bool myStoreVehicles
std::string getRequestedDriveWay(int linkIndex) override
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
bool myMovingBlock
whether the signal is in moving block mode (only protects from oncoming and flanking trains)
bool removeConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
remove constraint for signal switching
static std::vector< const MSDriveWay * > myBlockingDriveWays
bool updateCurrentPhase()
returns the state of the signal that actually required
const Phases & getPhases() const override
Returns the phases of this tls program.
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns the definition of the current phase.
std::string getConstraintInfo() const
std::string getNewDrivewayID()
static void initDriveWays(const SUMOVehicle *ego, bool update)
void addLink(MSLink *link, MSLane *lane, int pos) override
Adds a link on building.
const MSDriveWay & retrieveDriveWayForRoute(int tlIndex, MSRouteIterator first, MSRouteIterator end)
std::string getRivalVehicleIDs() const
static bool hasInsertionConstraint(MSLink *link, const MSVehicle *veh, std::string &info, bool &isInsertionOrder)
VehicleVector getPriorityVehicles(int linkIndex) override
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
std::vector< const MSDriveWay * > getBlockingDriveWays(int linkIndex) override
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
int getCurrentPhaseIndex() const override
Returns the current index within the program.
const ConstMSEdgeVector & getEdges() const
Definition MSRoute.h:128
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition MSRoute.cpp:79
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition MSRoute.cpp:73
SUMOAbstractRouter< MSEdge, SUMOVehicle >::Prohibitions Prohibitions
static void reroute(SUMOVehicle &vehicle, const SUMOTime currentTime, const std::string &info, const bool onInit=false, const bool silent=false, const Prohibitions &prohibited={})
initiate the rerouting, create router / thread pool on first use
A class that stores and controls tls and switching of their programs.
void deschedule(MSTrafficLightLogic *tlLogic)
Marks this swicth as invalid (if the phase duration has changed, f.e.)
The parent class for traffic light logics.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
std::vector< const SUMOVehicle * > VehicleVector
list of vehicles
SUMOTime myDefaultCycleTime
The cycle time (without changes)
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
SwitchCommand * mySwitchCommand
The current switch command.
int myNumLinks
number of controlled links
bool isActive() const
whether this logic is the active program
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
Builds detectors for microsim.
const std::string & getID() const
Returns the id.
Definition Named.h:73
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false, const bool escape=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
std::map< std::string, std::string > Map
parameters map
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual MSDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or nullptr if not.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual SUMOTime getWaitingTime(const bool accumulated=false) const =0
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSEdge * getEdge() const =0
Returns the (normal) route edge the object is currently at.
Representation of a vehicle.
Definition SUMOVehicle.h:63
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual double getLength() const =0
Returns the vehicles's length.
virtual int getRoutePosition() const =0
return index of edge within route
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual const MSRoute & getRoute() const =0
Returns the current route.
int departEdge
(optional) The initial edge within the route of the vehicle
int arrivalEdge
(optional) The final edge within the route of the vehicle
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
#define UNUSED_PARAMETER(x)
#define DEBUG_COND
Definition json.hpp:5639