56#define MAX_BLOCK_LENGTH 20000
57#define MAX_SIGNAL_WARNINGS 10
65#define DEBUG_SIGNALSTATE
66#define DEBUG_SIGNALSTATE_PRIORITY
67#define DEBUG_FIND_PROTECTION
71#define DEBUG_COND DEBUG_HELPER(this)
72#define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
73#define DEBUG_HELPER(obj) ((obj)->isSelected())
96 const std::string&
id,
const std::string& programID,
SUMOTime delay,
112 if (links.size() != 1) {
114 +
" links controlled by index " +
toString(links[0]->getTLIndex()));
148#ifdef DEBUG_SIGNALSTATE
152 std::string state(
myLinks.size(),
'G');
154 if (li.myLink->getApproaching().size() > 0) {
156 DriveWay& driveway = li.getDriveWay(closest.first);
161 if (mustWait || !driveway.
reserve(closest, occupied)) {
162 state[li.myLink->getTLIndex()] =
'r';
163 if (occupied.size() > 0) {
164 li.reroute(
const_cast<SUMOVehicle*
>(closest.first), occupied);
166#ifdef DEBUG_SIGNALSTATE
168 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" notReserved\n";
172 state[li.myLink->getTLIndex()] =
'G';
177#ifdef DEBUG_SIGNALSTATE
179 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" reserved\n";
184 if (li.myDriveways.empty()) {
185#ifdef DEBUG_SIGNALSTATE
187 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" red for unitialized signal (no driveways yet)\n";
190 state[li.myLink->getTLIndex()] =
'r';
192 DriveWay& driveway = li.myDriveways.front();
194#ifdef DEBUG_SIGNALSTATE
196 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" red for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
199 state[li.myLink->getTLIndex()] =
'r';
201#ifdef DEBUG_SIGNALSTATE
203 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" green for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
214#ifdef DEBUG_SIGNALSTATE
231#ifdef DEBUG_SIGNALSTATE
233 std::cout <<
" constraint '" << c->
getDescription() <<
"' not cleared\n";
258 auto it = std::find(constraints.begin(), constraints.end(), constraint);
259 if (it != constraints.end()) {
261 constraints.erase(it);
349 for (
MSLink* link : links) {
350 result += link->getDescription() +
" ";
357 std::vector<const MSLane*> lanes(visited.size(),
nullptr);
358 for (
auto item : visited) {
359 lanes[item.second] = item.first;
368 const int tmp = (int)map.size();
376 double minDist = std::numeric_limits<double>::max();
379 if (apprIt->second.dist < minDist) {
380 minDist = apprIt->second.
dist;
411 for (
const DriveWay& dw : li.myDriveways) {
425 endIndex = (int)edges.size() - 1;
428 const MSEdge* e = edges[i];
430 const MSEdge* e2 = edges[i + 1];
432 for (
MSLink* link : lane->getLinkCont()) {
433 if (&link->getLane()->getEdge() == e2) {
462 bool hadOncoming =
false;
465 if (bidi ==
nullptr) {
466 brakeBeforeSignal =
false;
478#ifdef DEBUG_SIGNALSTATE
480 std::cout <<
" oncoming vehicle on bidi-lane " << lane->
getID() <<
"\n";
491#ifdef DEBUG_SIGNALSTATE
493 std::cout <<
" oncoming vehicle on flank-lane " << lane->
getID() <<
"\n";
501#ifdef DEBUG_SIGNALSTATE
513 const bool hasProtection = dw.
findProtection(approaching, switchLink);
515 if (!hasProtection) {
518 if (!brakeBeforeSignal || std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), bidi) != veh->getRoute().end()) {
519#ifdef DEBUG_SIGNALSTATE
521 std::cout <<
" no protection at bidi-switch " << switchLink->
getDescription() <<
" from veh=" << veh->getID() <<
"\n";
530 if (!brakeBeforeSignal || std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), bidi) != veh->getRoute().end()) {
531#ifdef DEBUG_SIGNALSTATE
533 std::cout <<
" no protection at bidi-switch " << switchLink->
getDescription() <<
" from linkRival veh=" << veh->getID() <<
"\n";
542#ifdef DEBUG_SIGNALSTATE
550 if (veh->
getSpeed() > 0 && closest.second.arrivalSpeedBraking > 0
552#ifdef DEBUG_SIGNALSTATE
554 std::cout <<
" oncoming vehicle approaching foe link " << foeLink->
getDescription() <<
"\n";
564 brakeBeforeSignal = hadOncoming;
578#ifdef DEBUG_SIGNALSTATE
580 std::cout <<
SIMTIME <<
" rsl=" << rs->
getID() <<
" insertion constraint '" << c->
getDescription() <<
"' for vehicle '" << veh->
getID() <<
"' not cleared\n";
584 isInsertionOrder = c->
getType() == MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
606 myLastRerouteTime = -1;
607 myLastRerouteVehicle =
nullptr;
614 return myLink->getTLLogic()->getID() +
"_" +
toString(myLink->getTLIndex());
620 MSEdge* first = &myLink->getLane()->getEdge();
629 while (lookBack > 0 && routeIndex > 0) {
631 if (prevEdge == first) {
642 if (myDriveways.empty()) {
644 dummyRoute.push_back(&myLink->getLane()->getEdge());
645 DriveWay dw = buildDriveWay(dummyRoute.begin(), dummyRoute.end());
646 myDriveways.push_back(dw);
648 return myDriveways.front();
653 auto itRoute = firstIt;
654 auto itDwRoute = dw.myRoute.begin();
656 while (itRoute != veh->
getRoute().
end() && itDwRoute != dw.myRoute.end()) {
657 if (*itRoute != *itDwRoute) {
667 if (match && itDwRoute == dw.myRoute.end()
668 && (itRoute == veh->
getRoute().
end() || dw.myFoundSignal || dw.myFoundReversal)) {
672#ifdef DEBUG_SELECT_DRIVEWAY
677#ifdef DEBUG_SELECT_DRIVEWAY
680 myDriveways.push_back(dw);
681 return myDriveways.back();
712 std::vector<const MSLane*> before;
715 if (fromBidi !=
nullptr) {
718 before.push_back(fromBidi);
720 dw.
buildRoute(myLink, 0., first, end, visited);
731 std::vector<MSLink*> flankSwitchesBidiExtended;
733 for (
MSLink* link : flankSwitchesBidiExtended) {
738#ifdef DEBUG_BUILD_DRIVEWAY
740 std::cout <<
" buildDriveWay railSignal=" <<
getID()
771 && (myLastRerouteVehicle != veh
775 myLastRerouteVehicle = veh;
776 myLastRerouteTime = now;
781 std::cout <<
SIMTIME <<
" reroute veh=" << veh->
getID() <<
" rs=" <<
getID() <<
" occupied=" <<
toString(occupied) <<
"\n";
789 std::cout <<
" rerouting successful\n";
803 std::string joinVehicle =
"";
806 if (stop !=
nullptr) {
807 joinVehicle = stop->
join;
810 if (conflictLaneOccupied(joinVehicle,
true, closest.first)) {
811 for (
const MSLane* bidi : myBidi) {
812 if (!bidi->empty() && bidi->getBidiLane() !=
nullptr) {
813 occupied.push_back(&bidi->getBidiLane()->getEdge());
816#ifdef DEBUG_SIGNALSTATE
823 for (
MSLink* link : myProtectingSwitches) {
824 if (!findProtection(closest, link)) {
825#ifdef DEBUG_SIGNALSTATE
827 std::cout <<
" no protection at switch " << link->getDescription() <<
"\n";
833 for (
MSLink* foeLink : myConflictLinks) {
834 if (hasLinkConflict(closest, foeLink)) {
835#ifdef DEBUG_SIGNALSTATE
837 std::cout <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
843 if (deadlockLaneOccupied()) {
846 myActive = closest.first;
853 for (
MSLink* foeLink : myConflictLinks) {
854 if (foeLink->getApproaching().size() > 0) {
855#ifdef DEBUG_SIGNALSTATE
857 std::cout <<
SIMTIME <<
" foeLink=" << foeLink->getDescription() <<
" approachedBy=" << foeLink->getApproaching().begin()->first->getID() <<
"\n";
869#ifdef DEBUG_SIGNALSTATE_PRIORITY
871 std::cout <<
" checkLinkConflict foeLink=" <<
getTLLinkID(foeLink) <<
"\n";
876#ifdef DEBUG_SIGNALSTATE_PRIORITY
878 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
882 assert(foeTLL !=
nullptr);
885 if (foeRS !=
nullptr) {
890 !overlap(foeDriveWay)) {
891#ifdef DEBUG_SIGNALSTATE_PRIORITY
894 std::cout <<
" foe blocked\n";
896 std::cout <<
" foe constrained\n";
898 std::cout <<
" no overlap\n";
904#ifdef DEBUG_SIGNALSTATE_PRIORITY
907 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
908 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
909 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
910 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
911 <<
" aW=" << veh.first->getWaitingTime() <<
" foeW=" << foe.first->getWaitingTime()
912 <<
" aN=" << veh.first->getNumericalID() <<
" foeN=" << foe.first->getNumericalID()
916 const bool yield = mustYield(veh, foe);
932 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
933 if (foe.second.arrivalTime == veh.second.arrivalTime) {
934 if (foe.first->getSpeed() == veh.first->getSpeed()) {
935 if (foe.second.dist == veh.second.dist) {
936 if (foe.first->getWaitingTime() == veh.first->getWaitingTime()) {
937 return foe.first->getNumericalID() < veh.first->getNumericalID();
939 return foe.first->getWaitingTime() > veh.first->getWaitingTime();
942 return foe.second.dist < veh.second.dist;
945 return foe.first->getSpeed() > veh.first->getSpeed();
948 return foe.second.arrivalTime < veh.second.arrivalTime;
951 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
958 for (
const MSLane* lane : myConflictLanes) {
959 if (!lane->isEmpty()) {
960#ifdef DEBUG_SIGNALSTATE
962 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied ego=" <<
Named::getIDSecure(ego) <<
" vehNumber=" << lane->getVehicleNumber() <<
"\n";
963 if (joinVehicle !=
"") {
964 std::cout <<
" joinVehicle=" << joinVehicle <<
" occupant=" <<
toString(lane->getVehiclesSecure()) <<
"\n";
965 lane->releaseVehicles();
969 if (lane->getVehicleNumberWithPartials() == 1) {
970 MSVehicle* foe = lane->getLastAnyVehicle();
971 if (joinVehicle !=
"") {
973#ifdef DEBUG_SIGNALSTATE
975 std::cout <<
" ignore join-target '" << joinVehicle <<
"\n";
981 if (ego !=
nullptr) {
982 if (foe == ego && std::find(myBidi.begin(), myBidi.end(), lane) != myBidi.end()) {
983#ifdef DEBUG_SIGNALSTATE
985 std::cout <<
" ignore ego as oncoming '" << ego->
getID() <<
"\n";
1003 for (
const MSLane* lane : myBidiExtended) {
1004 if (!lane->empty()) {
1005 assert(myBidi.size() != 0);
1006 const MSEdge* lastBidi = myBidi.back()->getNextNormal();
1007 MSVehicle* foe = lane->getVehiclesSecure().front();
1008#ifdef DEBUG_SIGNALSTATE
1010 std::cout <<
" check for deadlock with " << foe->
getID() <<
"\n";
1015 const int minEdges = (int)myBidiExtended.size();
1018 bool conflict =
false;
1019 for (
int i = 0; i < minEdges && foeIt != foeEnd; i++) {
1020 if ((*foeIt) == lastBidi) {
1021#ifdef DEBUG_SIGNALSTATE
1023 std::cout <<
" vehicle will enter " << lastBidi->
getID() <<
"\n";
1031 lane->releaseVehicles();
1046 double flankApproachingDist = std::numeric_limits<double>::max();
1049 flankApproachingDist = closest.second.dist;
1051#ifdef DEBUG_FIND_PROTECTION
1053 std::cout <<
SIMTIME <<
" findProtection for link=" << link->
getDescription() <<
" flankApproachingDist=" << flankApproachingDist <<
"\n";
1057 if (l2->getLane() != link->
getLane()) {
1058#ifdef DEBUG_FIND_PROTECTION
1060 std::cout <<
" protectionCandidate=" << l2->getDescription() <<
" l2Via=" <<
Named::getIDSecure(l2->getViaLane())
1061 <<
" occupied=" << (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) <<
"\n";
1064 if (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) {
1065#ifdef DEBUG_FIND_PROTECTION
1067 std::cout <<
" protection from internal=" << l2->getViaLane()->getID() <<
"\n";
1072 if (l2->getApproaching().size() > 0) {
1074 if (closest2.second.dist < flankApproachingDist) {
1075#ifdef DEBUG_FIND_PROTECTION
1077 std::cout <<
" protection from veh=" << closest2.first->getID() <<
"\n";
1091 tmp.
myFlank.push_back(before);
1102 return tmp.
reserve(veh, occupied);
1109 for (
int i = 0; i < myCoreSize; i++) {
1111 const MSEdge* edge = myRoute[i];
1125 for (
const MSLane* lane : myForward) {
1127 if (lane == lane2) {
1132 if (lane == lane2) {
1144 if (myCoreSize != (
int)myRoute.size()) {
1152 if (myBidiExtended.size() > 0) {
1162 od.
openTag(
"protectingSwitches");
1163 std::vector<std::string> links;
1164 for (
MSLink* link : myProtectingSwitches) {
1171 std::vector<std::string> signals;
1172 for (
MSLink* link : myConflictLinks) {
1185 bool seekForwardSignal =
true;
1186 bool seekBidiSwitch =
true;
1187 bool foundUnsafeSwitch =
false;
1189#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1194 while ((seekForwardSignal || seekBidiSwitch)) {
1198 " exceeds maximum length (stopped searching after edge '" + toLane->
getEdge().
getID() +
"' (length=" +
toString(length) +
"m).");
1204#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1209 if (visited.count(toLane) != 0) {
1215 myRoute.push_back(&toLane->
getEdge());
1223 if (seekForwardSignal) {
1224 if (!foundUnsafeSwitch) {
1225 myForward.push_back(toLane);
1227 }
else if (bidi ==
nullptr) {
1228 seekBidiSwitch =
false;
1229#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1231 std::cout <<
" noBidi, abort search for bidiSwitch\n";
1235 if (bidi !=
nullptr) {
1236 if (foundUnsafeSwitch) {
1237 myBidiExtended.push_back(bidi);
1239 myBidi.push_back(bidi);
1242 if (!seekForwardSignal) {
1248 for (
const MSLink*
const link : ili.lane->getLinkCont()) {
1252 if (link->getViaLaneOrLane() != bidi) {
1256 myCoreSize = (int)myRoute.size();
1258#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1260 std::cout <<
" abort: found protecting switch " << ili.viaLink->getDescription() <<
"\n";
1265 myProtectedBidi = bidiNext;
1266 std::set<const MSEdge*> visitedEdges;
1267 for (
auto item : visited) {
1268 visitedEdges.insert(&item.first->getEdge());
1270 while (next != end && visitedEdges.count(*next) == 0) {
1272 visitedEdges.insert(*next);
1274 if (nextBidi !=
nullptr) {
1275 visitedEdges.insert(nextBidi);
1277 myRoute.push_back(*next);
1282#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1284 std::cout <<
" found unsafe switch " << ili.viaLink->getDescription() <<
" (used=" << bidiNext->
getID() <<
")\n";
1289 foundUnsafeSwitch =
true;
1293 myFlankSwitches.push_back(ili.viaLink);
1302 const std::vector<MSLink*>& links = toLane->
getLinkCont();
1305 for (
const MSLink*
const link : links) {
1306 if ((next != end && &link->getLane()->getEdge() == *next)
1307 &&
isRailway(link->getViaLaneOrLane()->getPermissions())) {
1308 toLane = link->getViaLaneOrLane();
1309 if (link->getLane()->getBidiLane() !=
nullptr && &link->getLane()->getEdge() == current->
getBidiEdge()) {
1311#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1313 std::cout <<
" abort: turn-around\n";
1316 myFoundReversal =
true;
1319 if (link->getTLLogic() !=
nullptr) {
1320 if (link->getTLLogic() == origin->
getTLLogic()) {
1325 seekForwardSignal =
false;
1326 myFoundSignal =
true;
1327 seekBidiSwitch = bidi !=
nullptr;
1328#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1330 std::cout <<
" found forwardSignal " << link->getTLLogic()->
getID() <<
" seekBidiSwitch=" << seekBidiSwitch <<
"\n";
1337 if (toLane ==
nullptr) {
1340 toLane = (*next)->getLanes()[0];
1342#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1344 std::cout <<
" abort: no next lane available\n";
1356#ifdef DEBUG_CHECK_FLANKS
1357 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
"\n visited=" <<
formatVisitedMap(visited) <<
" allFoes=" << allFoes <<
"\n";
1363 if (reverseOriginLink !=
nullptr) {
1367 for (
int i = 0; i < (int)lanes.size(); i++) {
1368 const MSLane* lane = lanes[i];
1369 const MSLane* prev = i > 0 ? lanes[i - 1] :
nullptr;
1370 const MSLane* next = i + 1 < (int)lanes.size() ? lanes[i + 1] :
nullptr;
1375 if (ili.viaLink == originLink
1376 || ili.viaLink == reverseOriginLink
1381 if (ili.lane != prev && ili.lane != next) {
1382#ifdef DEBUG_CHECK_FLANKS
1383 std::cout <<
" add flankSwitch junction=" << ili.viaLink->getJunction()->
getID() <<
" index=" << ili.viaLink->getIndex() <<
" iLane=" << ili.lane->getID() <<
" prev=" <<
Named::getIDSecure(prev) <<
" targetLane=" << lane->
getID() <<
" next=" <<
Named::getIDSecure(next) <<
"\n";
1385 flankSwitches.push_back(ili.viaLink);
1386 }
else if (allFoes) {
1388 checkCrossingFlanks(ili.viaLink, visited, flankSwitches);
1397#ifdef DEBUG_CHECK_FLANKS
1401 if (junction ==
nullptr) {
1405 if (logic ==
nullptr) {
1409 if (in->isInternal()) {
1412 for (
MSLane* inLane : in->getLanes()) {
1413 if (
isRailway(inLane->getPermissions()) && visited.count(inLane) == 0) {
1414 for (
MSLink* link : inLane->getLinkCont()) {
1415 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
1416 && visited.count(link->getLane()) == 0) {
1417#ifdef DEBUG_CHECK_FLANKS
1418 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
1420 if (link->getViaLane() ==
nullptr) {
1421 flankSwitches.push_back(link);
1423 flankSwitches.push_back(link->getViaLane()->getLinkCont().front());
1434#ifdef DEBUG_CHECK_FLANKS
1435 std::cout <<
" findFlankProtection link=" << link->
getDescription() <<
" length=" << length <<
" origLink=" << origLink->
getDescription() <<
"\n";
1439#ifdef DEBUG_CHECK_FLANKS
1440 std::cout <<
" flank guarded by " << link->
getTLLogic()->
getID() <<
"\n";
1442 myConflictLinks.push_back(link);
1452 const bool isNew = visited.count(lane) == 0;
1453 if (isNew || (visited[lane] > visited[origLink->
getLane()] && std::find(myForward.begin(), myForward.end(), lane) == myForward.end())) {
1459 flank.push_back(lane);
1460 findFlankProtection(lane->
getIncomingLanes().front().viaLink, length, visited, origLink, flank);
1462 bool foundPSwitch =
false;
1464#ifdef DEBUG_CHECK_FLANKS
1465 std::cout <<
" lane=" << lane->
getID() <<
" visitedIndex=" << visited[lane] <<
" origIndex=" << visited[origLink->
getLane()] <<
" cand=" << l2->getDescription() <<
"\n";
1468 foundPSwitch =
true;
1470#ifdef DEBUG_CHECK_FLANKS
1471 std::cout <<
" protectingSwitch=" << l2->getDescription() <<
" for flank=" << link->
getDescription() <<
"\n";
1473 myProtectingSwitches.push_back(link);
1474 if (std::find(myBidi.begin(), myBidi.end(), origLink->
getLane()) != myBidi.end()) {
1475#ifdef DEBUG_CHECK_FLANKS
1476 std::cout <<
" (is bidi-switch)\n";
1478 myProtectingSwitchesBidi.push_back(link);
1482 if (!foundPSwitch) {
1483 flank.push_back(lane);
1487 findFlankProtection(ili.viaLink, length, visited, origLink, flank);
1493#ifdef DEBUG_CHECK_FLANKS
1494 std::cout <<
" laneBefore=" << lane->
getID() <<
" already visited. index=" << visited[lane] <<
" origAfter=" << origLink->
getLane()->
getID() <<
" origIndex=" << visited[origLink->
getLane()] <<
"\n";
1498 myMaxFlankLength =
MAX2(myMaxFlankLength, length);
1514 driveway.
reserve(closest, occupied);
1550 for (
const DriveWay& dw : li.myDriveways) {
1565 if (item.second < item2.second) {
1566 bool conflict =
false;
1567 std::pair<int, int> code(item.second, item2.second);
1570 conflict = it->second;
1580#ifdef DEBUG_RECHECKGREEN
1591 state[item.first->getTLIndex()] =
'r';
1594#ifdef DEBUG_RECHECKGREEN
1596 <<
" (" << veh.first->getID() <<
" yields to " << veh2.first->getID() <<
"\n";
1598#ifdef DEBUG_SIGNALSTATE
1601 <<
" (" << veh.first->getID() <<
" yields to " << veh2.first->getID() <<
"\n";
1606 state[item2.first->getTLIndex()] =
'r';
1609#ifdef DEBUG_RECHECKGREEN
1611 <<
" (" << veh2.first->getID() <<
" yields to " << veh.first->getID() <<
"\n";
1613#ifdef DEBUG_SIGNALSTATE
1616 <<
" (" << veh2.first->getID() <<
" yields to " << veh.first->getID() <<
"\n";
1631 for (
auto it = li.myDriveways.begin(); it != li.myDriveways.end(); it++) {
1634#ifdef DEBUG_DRIVEWAY_UPDATE
1635 std::cout <<
SIMTIME <<
" rail signal junction '" <<
getID() <<
"' requires update for driveway " << numericalID <<
"\n";
1637 std::vector<const MSEdge*> route = dw.
myRoute;
1638 li.myDriveways.erase(it);
1639 if (li.myDriveways.size() == 0) {
1641 li.myDriveways.push_back(li.buildDriveWay(route.begin(), route.end()));
1656 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1669 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1682 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1695 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1705 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.
@ TURN_LEFTHAND
The link is a 180 degree turn (left-hand network)
@ 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.
bool isStopped() const
Returns whether the vehicle is at a stop.
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 std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
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 MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
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.
const MSLink * getCorrespondingExitLink() const
returns the corresponding exit link for entryLinks to a junction.
LinkDirection getDirection() const
Returns the direction the vehicle passing this link take.
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
static void initDriveWays(const SUMOVehicle *ego, bool update)
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 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.
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
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
std::vector< const MSLane * > myForward
void writeBlocks(OutputDevice &od) const
Write block items for this driveway.
void buildRoute(MSLink *origin, double length, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap &visited)
void checkFlanks(const MSLink *originLink, const std::vector< const MSLane * > &lanes, const LaneVisitedMap &visited, bool allFoes, std::vector< MSLink * > &flankSwitches) const
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
void findFlankProtection(MSLink *link, double length, LaneVisitedMap &visited, MSLink *origLink, std::vector< const MSLane * > &flank)
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
std::vector< const MSLane * > myBidi
std::vector< const MSLane * > myBidiExtended
bool conflictLaneOccupied(const std::string &joinVehicle="", bool store=true, const SUMOVehicle *ego=nullptr) 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
void checkCrossingFlanks(MSLink *dwLink, const LaneVisitedMap &visited, std::vector< MSLink * > &flankSwitches) const
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
bool myFoundSignal
whether this driveway ends its forward section with a rail signal (and thus comprises a full block)
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