56#define MAX_BLOCK_LENGTH 20000
57#define MAX_SIGNAL_WARNINGS 10
64#define DEBUG_SIGNALSTATE
65#define DEBUG_SIGNALSTATE_PRIORITY
66#define DEBUG_FIND_PROTECTION
70#define DEBUG_COND DEBUG_HELPER(this)
71#define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
72#define DEBUG_HELPER(obj) ((obj)->isSelected())
95 const std::string&
id,
const std::string& programID,
SUMOTime delay,
111 if (links.size() != 1) {
113 +
" links controlled by index " +
toString(links[0]->getTLIndex()));
147#ifdef DEBUG_SIGNALSTATE
151 std::string state(
myLinks.size(),
'G');
153 if (li.myLink->getApproaching().size() > 0) {
155 DriveWay& driveway = li.getDriveWay(closest.first);
160 if (mustWait || !driveway.
reserve(closest, occupied)) {
161 state[li.myLink->getTLIndex()] =
'r';
162 if (occupied.size() > 0) {
163 li.reroute(
const_cast<SUMOVehicle*
>(closest.first), occupied);
165#ifdef DEBUG_SIGNALSTATE
167 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" notReserved\n";
171 state[li.myLink->getTLIndex()] =
'G';
176#ifdef DEBUG_SIGNALSTATE
178 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" reserved\n";
183 DriveWay& driveway = li.myDriveways.front();
185#ifdef DEBUG_SIGNALSTATE
187 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" red for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
190 state[li.myLink->getTLIndex()] =
'r';
192#ifdef DEBUG_SIGNALSTATE
194 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" green for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
204#ifdef DEBUG_SIGNALSTATE
221#ifdef DEBUG_SIGNALSTATE
223 std::cout <<
" constraint '" << c->
getDescription() <<
"' not cleared\n";
248 auto it = std::find(constraints.begin(), constraints.end(), constraint);
249 if (it != constraints.end()) {
251 constraints.erase(it);
339 for (
MSLink* link : links) {
340 result += link->getDescription() +
" ";
347 std::vector<const MSLane*> lanes(visited.size(),
nullptr);
348 for (
auto item : visited) {
349 lanes[item.second] = item.first;
358 const int tmp = (int)map.size();
366 double minDist = std::numeric_limits<double>::max();
369 if (apprIt->second.dist < minDist) {
370 minDist = apprIt->second.
dist;
401 for (
const DriveWay& dw : li.myDriveways) {
414 bool hadOncoming =
false;
417 if (bidi ==
nullptr) {
418 brakeBeforeSignal =
false;
428#ifdef DEBUG_SIGNALSTATE
430 std::cout <<
" oncoming vehicle on bidi-lane " << lane->
getID() <<
"\n";
440#ifdef DEBUG_SIGNALSTATE
442 std::cout <<
" oncoming vehicle on flank-lane " << lane->
getID() <<
"\n";
450#ifdef DEBUG_SIGNALSTATE
462 const bool hasProtection = dw.
findProtection(approaching, switchLink);
464 if (!hasProtection) {
467 if (!brakeBeforeSignal || std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), bidi) != veh->getRoute().end()) {
468#ifdef DEBUG_SIGNALSTATE
470 std::cout <<
" no protection at bidi-switch " << switchLink->
getDescription() <<
" from veh=" << veh->getID() <<
"\n";
479 if (!brakeBeforeSignal || std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), bidi) != veh->getRoute().end()) {
480#ifdef DEBUG_SIGNALSTATE
482 std::cout <<
" no protection at bidi-switch " << switchLink->
getDescription() <<
" from linkRival veh=" << veh->getID() <<
"\n";
491#ifdef DEBUG_SIGNALSTATE
499 if (veh->
getSpeed() > 0 && closest.second.arrivalSpeedBraking > 0
501#ifdef DEBUG_SIGNALSTATE
503 std::cout <<
" oncoming vehicle approaching foe link " << foeLink->
getDescription() <<
"\n";
513 brakeBeforeSignal = hadOncoming;
527#ifdef DEBUG_SIGNALSTATE
529 std::cout <<
SIMTIME <<
" rsl=" << rs->
getID() <<
" insertion constraint '" << c->
getDescription() <<
"' for vehicle '" << veh->
getID() <<
"' not cleared\n";
533 isInsertionOrder = c->
getType() == MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
555 myUniqueDriveWay =
false;
556 myLastRerouteTime = -1;
557 myLastRerouteVehicle =
nullptr;
560 dummyRoute.push_back(&myLink->getLane()->getEdge());
561 DriveWay dw = buildDriveWay(dummyRoute.begin(), dummyRoute.end());
562 myDriveways.push_back(dw);
568 return myLink->getTLLogic()->getID() +
"_" +
toString(myLink->getTLIndex());
574 if (myUniqueDriveWay) {
575 return myDriveways.front();
577 MSEdge* first = &myLink->getLane()->getEdge();
586 while (lookBack > 0 && routeIndex > 0) {
588 if (prevEdge == first) {
599 return myDriveways.front();
604 auto itRoute = firstIt;
605 auto itDwRoute = dw.myRoute.begin();
607 while (itRoute != veh->
getRoute().
end() && itDwRoute != dw.myRoute.end()) {
608 if (*itRoute != *itDwRoute) {
622 myDriveways.push_back(dw);
623 return myDriveways.back();
654 std::vector<MSLane*> before;
657 if (fromBidi !=
nullptr) {
660 before.push_back(fromBidi);
662 dw.
buildRoute(myLink, 0., first, end, visited);
675#ifdef DEBUG_BUILD_DRIVEWAY
677 std::cout <<
" buildDriveWay railSignal=" <<
getID()
708 && (myLastRerouteVehicle != veh
712 myLastRerouteVehicle = veh;
713 myLastRerouteTime = now;
718 std::cout <<
SIMTIME <<
" reroute veh=" << veh->
getID() <<
" rs=" <<
getID() <<
" occupied=" <<
toString(occupied) <<
"\n";
726 std::cout <<
" rerouting successful\n";
740 std::string joinVehicle =
"";
743 if (stop !=
nullptr) {
744 joinVehicle = stop->
join;
747 if (conflictLaneOccupied(joinVehicle)) {
748 for (
MSLane* bidi : myBidi) {
749 if (!bidi->empty() && bidi->getBidiLane() !=
nullptr) {
750 occupied.push_back(&bidi->getBidiLane()->getEdge());
753#ifdef DEBUG_SIGNALSTATE
755 std::cout <<
" conflictLaneOccupied\n";
760 for (
MSLink* link : myProtectingSwitches) {
761 if (!findProtection(closest, link)) {
762#ifdef DEBUG_SIGNALSTATE
764 std::cout <<
" no protection at switch " << link->getDescription() <<
"\n";
770 for (
MSLink* foeLink : myConflictLinks) {
771 if (hasLinkConflict(closest, foeLink)) {
772#ifdef DEBUG_SIGNALSTATE
774 std::cout <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
780 if (deadlockLaneOccupied()) {
783 myActive = closest.first;
790 for (
MSLink* foeLink : myConflictLinks) {
791 if (foeLink->getApproaching().size() > 0) {
792#ifdef DEBUG_SIGNALSTATE
794 std::cout <<
SIMTIME <<
" foeLink=" << foeLink->getDescription() <<
" approachedBy=" << foeLink->getApproaching().begin()->first->getID() <<
"\n";
806#ifdef DEBUG_SIGNALSTATE_PRIORITY
808 std::cout <<
" checkLinkConflict foeLink=" <<
getTLLinkID(foeLink) <<
"\n";
813#ifdef DEBUG_SIGNALSTATE_PRIORITY
815 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
819 assert(foeTLL !=
nullptr);
822 if (foeRS !=
nullptr) {
827 !overlap(foeDriveWay)) {
828#ifdef DEBUG_SIGNALSTATE_PRIORITY
831 std::cout <<
" foe blocked\n";
833 std::cout <<
" foe constrained\n";
835 std::cout <<
" no overlap\n";
841#ifdef DEBUG_SIGNALSTATE_PRIORITY
844 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
845 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
846 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
847 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
848 <<
" aW=" << veh.first->getWaitingTime() <<
" foeW=" << foe.first->getWaitingTime()
849 <<
" aN=" << veh.first->getNumericalID() <<
" foeN=" << foe.first->getNumericalID()
853 const bool yield = mustYield(veh, foe);
869 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
870 if (foe.second.arrivalTime == veh.second.arrivalTime) {
871 if (foe.first->getSpeed() == veh.first->getSpeed()) {
872 if (foe.second.dist == veh.second.dist) {
873 if (foe.first->getWaitingTime() == veh.first->getWaitingTime()) {
874 return foe.first->getNumericalID() < veh.first->getNumericalID();
876 return foe.first->getWaitingTime() > veh.first->getWaitingTime();
879 return foe.second.dist < veh.second.dist;
882 return foe.first->getSpeed() > veh.first->getSpeed();
885 return foe.second.arrivalTime < veh.second.arrivalTime;
888 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
895 for (
const MSLane* lane : myConflictLanes) {
896 if (!lane->isEmpty()) {
897#ifdef DEBUG_SIGNALSTATE
899 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied\n";
900 if (joinVehicle !=
"") {
901 std::cout <<
" joinVehicle=" << joinVehicle <<
" occupant=" <<
toString(lane->getVehiclesSecure()) <<
"\n";
902 lane->releaseVehicles();
906 if (lane->getVehicleNumber() == 1 && joinVehicle !=
"") {
907 std::vector<MSVehicle*> vehs = lane->getVehiclesSecure();
908 const bool ignoreJoinTarget = vehs.front()->getID() == joinVehicle && vehs.front()->isStopped();
909 lane->releaseVehicles();
910 if (ignoreJoinTarget) {
911#ifdef DEBUG_SIGNALSTATE
913 std::cout <<
" ignore join-target '" << joinVehicle <<
";\n";
930 for (
MSLane* lane : myBidiExtended) {
931 if (!lane->empty()) {
932 assert(myBidi.size() != 0);
933 const MSEdge* lastBidi = myBidi.back()->getNextNormal();
934 MSVehicle* foe = lane->getVehiclesSecure().front();
935#ifdef DEBUG_SIGNALSTATE
937 std::cout <<
" check for deadlock with " << foe->
getID() <<
"\n";
942 const int minEdges = (int)myBidiExtended.size();
945 bool conflict =
false;
946 for (
int i = 0; i < minEdges && foeIt != foeEnd; i++) {
947 if ((*foeIt) == lastBidi) {
948#ifdef DEBUG_SIGNALSTATE
950 std::cout <<
" vehicle will enter " << lastBidi->
getID() <<
"\n";
958 lane->releaseVehicles();
973 double flankApproachingDist = std::numeric_limits<double>::max();
976 flankApproachingDist = closest.second.dist;
978#ifdef DEBUG_FIND_PROTECTION
980 std::cout <<
SIMTIME <<
" findProtection for link=" << link->
getDescription() <<
" flankApproachingDist=" << flankApproachingDist <<
"\n";
984 if (l2->getLane() != link->
getLane()) {
985#ifdef DEBUG_FIND_PROTECTION
987 std::cout <<
" protectionCandidate=" << l2->getDescription() <<
" l2Via=" <<
Named::getIDSecure(l2->getViaLane())
988 <<
" occupied=" << (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) <<
"\n";
991 if (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) {
992#ifdef DEBUG_FIND_PROTECTION
994 std::cout <<
" protection from internal=" << l2->getViaLane()->getID() <<
"\n";
999 if (l2->getApproaching().size() > 0) {
1001 if (closest2.second.dist < flankApproachingDist) {
1002#ifdef DEBUG_FIND_PROTECTION
1004 std::cout <<
" protection from veh=" << closest2.first->getID() <<
"\n";
1018 tmp.
myFlank.push_back(before);
1029 return tmp.
reserve(veh, occupied);
1036 for (
int i = 0; i < myCoreSize; i++) {
1038 const MSEdge* edge = myRoute[i];
1052 for (
const MSLane* lane : myForward) {
1054 if (lane == lane2) {
1059 if (lane == lane2) {
1071 if (myCoreSize != (
int)myRoute.size()) {
1079 if (myBidiExtended.size() > 0) {
1089 od.
openTag(
"protectingSwitches");
1090 std::vector<std::string> links;
1091 for (
MSLink* link : myProtectingSwitches) {
1098 std::vector<std::string> signals;
1099 for (
MSLink* link : myConflictLinks) {
1112 bool seekForwardSignal =
true;
1113 bool seekBidiSwitch =
true;
1114 bool foundUnsafeSwitch =
false;
1116#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1121 while ((seekForwardSignal || seekBidiSwitch)) {
1125 " exceeds maximum length (stopped searching after edge '" + toLane->
getEdge().
getID() +
"' (length=" +
toString(length) +
"m).");
1131#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1136 if (visited.count(toLane) != 0) {
1142 myRoute.push_back(&toLane->
getEdge());
1150 if (seekForwardSignal) {
1151 if (!foundUnsafeSwitch) {
1152 myForward.push_back(toLane);
1154 }
else if (bidi ==
nullptr) {
1155 seekBidiSwitch =
false;
1156#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1158 std::cout <<
" noBidi, abort search for bidiSwitch\n";
1162 if (bidi !=
nullptr) {
1163 if (foundUnsafeSwitch) {
1164 myBidiExtended.push_back(bidi);
1166 myBidi.push_back(bidi);
1169 if (!seekForwardSignal) {
1175 for (
const MSLink*
const link : ili.lane->getLinkCont()) {
1179 if (link->getViaLaneOrLane() != bidi) {
1183 myCoreSize = (int)myRoute.size();
1185#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1187 std::cout <<
" abort: found protecting switch " << ili.viaLink->getDescription() <<
"\n";
1192 myProtectedBidi = bidiNext;
1195#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1197 std::cout <<
" found unsafe switch " << ili.viaLink->getDescription() <<
" (used=" << bidiNext->
getID() <<
")\n";
1202 foundUnsafeSwitch =
true;
1206 myFlankSwitches.push_back(ili.viaLink);
1215 const std::vector<MSLink*>& links = toLane->
getLinkCont();
1218 for (
const MSLink*
const link : links) {
1219 if (((next != end && &link->getLane()->getEdge() == *next) ||
1221 &&
isRailway(link->getViaLaneOrLane()->getPermissions())) {
1222 toLane = link->getViaLaneOrLane();
1223 if (link->getLane()->getBidiLane() !=
nullptr && &link->getLane()->getEdge() == current->
getBidiEdge()) {
1225#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1227 std::cout <<
" abort: turn-around\n";
1232 if (link->getTLLogic() !=
nullptr) {
1233 if (link->getTLLogic() == origin->
getTLLogic()) {
1238 seekForwardSignal =
false;
1239 seekBidiSwitch = bidi !=
nullptr;
1240#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1242 std::cout <<
" found forwardSignal " << link->getTLLogic()->
getID() <<
" seekBidiSwitch=" << seekBidiSwitch <<
"\n";
1249 if (toLane ==
nullptr) {
1252 toLane = (*next)->getLanes()[0];
1254#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1256 std::cout <<
" abort: no next lane available\n";
1268#ifdef DEBUG_CHECK_FLANKS
1269 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
"\n visited=" <<
formatVisitedMap(visited) <<
" allFoes=" << allFoes <<
"\n";
1271 for (
MSLane* lane : lanes) {
1272 if (lane->isInternal()) {
1275 for (
auto ili : lane->getIncomingLanes()) {
1276 if (visited.count(ili.lane->getNormalPredecessorLane()) == 0) {
1277#ifdef DEBUG_CHECK_FLANKS
1278 std::cout <<
" add flankSwitch junction=" << ili.viaLink->getJunction()->getID() <<
" index=" << ili.viaLink->getIndex() <<
"\n";
1280 myFlankSwitches.push_back(ili.viaLink);
1281 }
else if (allFoes) {
1283 checkCrossingFlanks(ili.viaLink, visited);
1292#ifdef DEBUG_CHECK_FLANKS
1296 if (junction ==
nullptr) {
1300 if (logic ==
nullptr) {
1304 if (in->isInternal()) {
1307 for (
MSLane* inLane : in->getLanes()) {
1308 if (
isRailway(inLane->getPermissions()) && visited.count(inLane) == 0) {
1309 for (
MSLink* link : inLane->getLinkCont()) {
1310 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
1311 && visited.count(link->getLane()) == 0) {
1312#ifdef DEBUG_CHECK_FLANKS
1313 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
1315 if (link->getViaLane() ==
nullptr) {
1316 myFlankSwitches.push_back(link);
1318 myFlankSwitches.push_back(link->getViaLane()->getLinkCont().front());
1329#ifdef DEBUG_CHECK_FLANKS
1330 std::cout <<
" findFlankProtection link=" << link->
getDescription() <<
" length=" << length <<
" origLink=" << origLink->
getDescription() <<
"\n";
1334#ifdef DEBUG_CHECK_FLANKS
1335 std::cout <<
" flank guarded by " << link->
getTLLogic()->
getID() <<
"\n";
1337 myConflictLinks.push_back(link);
1347 const bool isNew = visited.count(lane) == 0;
1348 if (isNew || (visited[lane] > visited[origLink->
getLane()] && std::find(myForward.begin(), myForward.end(), lane) == myForward.end())) {
1354 myFlank.push_back(lane);
1355 findFlankProtection(lane->
getIncomingLanes().front().viaLink, length, visited, origLink);
1357 bool foundPSwitch =
false;
1359#ifdef DEBUG_CHECK_FLANKS
1360 std::cout <<
" lane=" << lane->
getID() <<
" visitedIndex=" << visited[lane] <<
" origIndex=" << visited[origLink->
getLane()] <<
" cand=" << l2->getDescription() <<
"\n";
1363 foundPSwitch =
true;
1365#ifdef DEBUG_CHECK_FLANKS
1366 std::cout <<
" protectingSwitch=" << l2->getDescription() <<
" for flank=" << link->
getDescription() <<
"\n";
1368 myProtectingSwitches.push_back(link);
1369 if (std::find(myBidi.begin(), myBidi.end(), origLink->
getLane()) != myBidi.end()) {
1370#ifdef DEBUG_CHECK_FLANKS
1371 std::cout <<
" (is bidi-switch)\n";
1373 myProtectingSwitchesBidi.push_back(link);
1377 if (!foundPSwitch) {
1378 myFlank.push_back(lane);
1382 findFlankProtection(ili.viaLink, length, visited, origLink);
1388#ifdef DEBUG_CHECK_FLANKS
1389 std::cout <<
" laneBefore=" << lane->
getID() <<
" already visited. index=" << visited[lane] <<
" origAfter=" << origLink->
getLane()->
getID() <<
" origIndex=" << visited[origLink->
getLane()] <<
"\n";
1393 myMaxFlankLength =
MAX2(myMaxFlankLength, length);
1409 driveway.
reserve(closest, occupied);
1444 for (
const DriveWay& dw : li.myDriveways) {
1459 if (item.second < item2.second) {
1460 bool conflict =
false;
1461 std::pair<int, int> code(item.second, item2.second);
1464 conflict = it->second;
1474#ifdef DEBUG_RECHECKGREEN
1485 state[item.first->getTLIndex()] =
'r';
1488#ifdef DEBUG_RECHECKGREEN
1490 <<
" (" << veh.first->getID() <<
" yields to " << veh2.first->getID() <<
"\n";
1492#ifdef DEBUG_SIGNALSTATE
1495 <<
" (" << veh.first->getID() <<
" yields to " << veh2.first->getID() <<
"\n";
1500 state[item2.first->getTLIndex()] =
'r';
1503#ifdef DEBUG_RECHECKGREEN
1505 <<
" (" << veh2.first->getID() <<
" yields to " << veh.first->getID() <<
"\n";
1507#ifdef DEBUG_SIGNALSTATE
1510 <<
" (" << veh2.first->getID() <<
" yields to " << veh.first->getID() <<
"\n";
1525 for (
auto it = li.myDriveways.begin(); it != li.myDriveways.end(); it++) {
1528#ifdef DEBUG_DRIVEWAY_UPDATE
1529 std::cout <<
SIMTIME <<
" rail signal junction '" <<
getID() <<
"' requires update for driveway " << numericalID <<
"\n";
1531 std::vector<const MSEdge*> route = dw.
myRoute;
1532 li.myDriveways.erase(it);
1533 if (li.myDriveways.size() == 0) {
1535 li.myDriveways.push_back(li.buildDriveWay(route.begin(), route.end()));
1550 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1563 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1576 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1589 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1599 if (key ==
"moving-block") {
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
#define DEBUG_COND_LINKINFO
#define DEBUG_HELPER(obj)
#define MAX_SIGNAL_WARNINGS
ConstMSEdgeVector::const_iterator MSRouteIterator
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
@ TURN
The link is a 180 degree turn.
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
const MSRoute & getRoute() const
Returns the current route.
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
A road/street connecting two junctions.
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
bool isNormal() const
return whether this edge is an internal edge
const MSJunction * getToJunction() const
double getLength() const
return the length of the edge
const MSJunction * getFromJunction() const
The base class for an intersection.
SumoXMLNodeType getType() const
return the type of this Junction
virtual const MSJunctionLogic * getLogic() const
const ConstMSEdgeVector & getIncoming() const
virtual const MSLogicJunction::LinkBits & getFoesFor(int linkIndex) const
Returns the foes for the given link.
Representation of a lane in the micro simulation.
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
const MSEdge * getNextNormal() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
double getLength() const
Returns the lane's length.
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
MSEdge & getEdge() const
Returns the lane's edge.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
MSJunction * getJunction() const
MSLane * getLane() const
Returns the connected lane.
int getIndex() const
Returns the respond index (for visualization)
int getTLIndex() const
Returns the TLS index.
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
ApproachingVehicleInformation getApproaching(const SUMOVehicle *veh) const
std::string getDescription() const
get string description for this link
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
void setState(const std::string &_state)
A base class for constraints.
virtual std::string getDescription() const
ConstraintType getType() const
bool isInsertionConstraint() const
virtual bool cleared() const =0
whether the constraint has been met
void addSignal(MSRailSignal *signal)
static MSRailSignalControl & getInstance()
const std::set< const MSEdge * > & getUsedEdges() const
void registerProtectedDriveway(MSRailSignal *rs, int driveWayID, const MSEdge *protectedBidi)
mark driveway that must receive additional checks if protectedBidi is ever used by a train route
bool constraintsAllow(const SUMOVehicle *veh) const
whether the given vehicle is free to drive
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
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 contraint for signal switching
static std::string getClickableTLLinkID(MSLink *link)
return logicID_linkIndex in a way that allows clicking in sumo-gui
std::vector< LinkInfo > myLinkInfos
data storage for every link at this node (more than one when directly guarding a switch)
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 ¶meters)
Constructor.
static void appendMapIndex(LaneVisitedMap &map, const MSLane *lane)
append to map by map index and avoid undefined behavior
VehicleVector getBlockingVehicles(int linkIndex) override
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
VehicleVector getRivalVehicles(int linkIndex) override
return vehicles that approach the intersection/rail signal and are in conflict with vehicles that wis...
static int myDriveWayIndex
static std::string describeLinks(std::vector< MSLink * > links)
print link descriptions
void writeBlocks(OutputDevice &od) const
write rail signal block output for all links and driveways
~MSRailSignal()
Destructor.
void adaptLinkInformationFrom(const MSTrafficLightLogic &logic) override
Applies information about controlled links and lanes from the given logic.
static VehicleVector myBlockingVehicles
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.
static Approaching getClosest(MSLink *link)
get the closest vehicle approaching the given link
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
static std::map< std::pair< int, int >, bool > myDriveWayCompatibility
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.
static void recheckGreen()
final check for driveway compatibility of signals that switched green in this step
static std::string getJunctionLinkID(MSLink *link)
return junctionID_junctionLinkIndex
SUMOTime trySwitch() override
Switches to the next phase.
const DriveWay & retrieveDriveWay(int numericalID) const
static bool myStoreVehicles
std::map< const MSLane *, int, ComparatorNumericalIdLess > LaneVisitedMap
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 contraint for signal switching
static bool hasOncomingRailTraffic(MSLink *link, const MSVehicle *ego, bool &brakeBeforeSignal)
static std::vector< std::pair< MSLink *, int > > mySwitchedGreenFlanks
list of signals that switched green along with driveway index
const Phases & getPhases() const override
Returns the phases of this tls program.
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns the definition of the current phase.
void updateDriveway(int numericalID)
update driveway for extended deadlock protection
std::string getConstraintInfo() const
static std::string formatVisitedMap(const LaneVisitedMap &visited)
print link descriptions
void updateCurrentPhase()
returns the state of the signal that actually required
void addLink(MSLink *link, MSLane *lane, int pos) override
Adds a link on building.
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 ...
static std::string getTLLinkID(MSLink *link)
return logicID_linkIndex
int getCurrentPhaseIndex() const override
Returns the current index within the program.
const ConstMSEdgeVector & getEdges() const
MSRouteIterator end() const
Returns the end of the list of edges to pass.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
static void reroute(SUMOVehicle &vehicle, const SUMOTime currentTime, const std::string &info, const bool onInit=false, const bool silent=false, const MSEdgeVector &prohibited=MSEdgeVector())
initiate the rerouting, create router / thread pool on first use
A class that stores and controls tls and switching of their programs.
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.
int myNumLinks
number of controlled links
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.
Builds detectors for microsim.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
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.
void lf()
writes a line feed if applicable
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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 double getSpeed() const =0
Returns the object's current speed.
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
Representation of a vehicle.
virtual MSVehicleDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
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.
Definition of vehicle stop (position and duration)
std::string join
the id of the vehicle (train portion) to which this vehicle shall be joined
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
void checkFlanks(const std::vector< MSLane * > &lanes, const LaneVisitedMap &visited, bool allFoes)
find switches that threaten this driveway
void writeBlocks(OutputDevice &od) const
Write block items for this driveway.
void buildRoute(MSLink *origin, double length, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap &visited)
std::vector< MSLink * > myFlankSwitches
int myCoreSize
number of edges in myRoute where overlap with other driveways is forbidden
bool deadlockLaneOccupied(bool store=true) const
whether any of myBidiExtended is occupied by a vehicle that targets myBidi
const MSEdge * myProtectedBidi
switch assumed safe from bidi-traffic
std::vector< MSLink * > myProtectingSwitchesBidi
subset of myProtectingSwitches that protects from oncoming trains
std::vector< const MSLane * > myConflictLanes
the lanes that must be clear of trains before this signal can switch to green
bool overlap(const DriveWay &other) const
Wether this driveway (route) overlaps with the given one.
int myNumericalID
global driveway index
std::vector< MSLink * > myConflictLinks
void checkCrossingFlanks(MSLink *dwLink, const LaneVisitedMap &visited)
find links that cross the driveway without entering it
std::vector< MSLane * > myBidi
void findFlankProtection(MSLink *link, double length, LaneVisitedMap &visited, MSLink *origLink)
find upstream protection from the given link
bool conflictLaneOccupied(const std::string &joinVehicle="", bool store=true) const
whether any of myConflictLanes is occupied (vehicles that are the target of a join must be ignored)
std::vector< const MSLane * > myFlank
std::vector< const MSEdge * > myRoute
list of edges for matching against train routes
bool hasLinkConflict(const Approaching &closest, MSLink *foeLink) const
Whether the approaching vehicle is prevent from driving by another vehicle approaching the given link...
bool findProtection(const Approaching &veh, MSLink *link) const
find protection for the given vehicle starting at a switch
std::vector< MSLink * > myProtectingSwitches
std::vector< MSLane * > myForward
bool conflictLinkApproached() const
Whether any of the conflict links have approaching vehicles.
bool reserve(const Approaching &closest, MSEdgeVector &occupied)
attempt reserve this driveway for the given vehicle
bool flankConflict(const DriveWay &other) const
Wether there is a flank conflict with the given driveway.
static bool mustYield(const Approaching &veh, const Approaching &foe)
Whether veh must yield to the foe train.
void reroute(SUMOVehicle *veh, const MSEdgeVector &occupied)
try rerouting vehicle if reservation failed
DriveWay buildDriveWay(MSRouteIterator first, MSRouteIterator end)
construct a new driveway by searching along the given route until all block structures are found
DriveWay & getDriveWay(const SUMOVehicle *)
retrieve an existing Driveway or construct a new driveway based on the vehicles route
void reset()
init LinkInfo
LinkInfo(MSLink *link)
constructor
std::vector< DriveWay > myDriveways
all driveways immediately following this link
std::string getID() const
return id for this railsignal-link