56 #define MAX_BLOCK_LENGTH 20000
57 #define MAX_SIGNAL_WARNINGS 10
70 #define DEBUG_COND DEBUG_HELPER(this)
71 #define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
72 #define DEBUG_HELPER(obj) ((obj)->isSelected())
93 const std::string&
id,
const std::string& programID,
SUMOTime delay,
109 if (links.size() != 1) {
111 +
" links controlled by index " +
toString(links[0]->getTLIndex()));
145 #ifdef DEBUG_SIGNALSTATE
149 std::string state(
myLinks.size(),
'G');
151 if (li.myLink->getApproaching().size() > 0) {
153 DriveWay& driveway = li.getDriveWay(closest.first);
158 if (mustWait || !driveway.
reserve(closest, occupied)) {
159 state[li.myLink->getTLIndex()] =
'r';
160 if (occupied.size() > 0) {
161 li.reroute(
const_cast<SUMOVehicle*
>(closest.first), occupied);
163 #ifdef DEBUG_SIGNALSTATE
165 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" notReserved\n";
169 state[li.myLink->getTLIndex()] =
'G';
174 #ifdef DEBUG_SIGNALSTATE
176 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" reserved\n";
181 if (li.myDriveways.empty()) {
182 #ifdef DEBUG_SIGNALSTATE
184 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" red for unitialized signal (no driveways yet)\n";
187 state[li.myLink->getTLIndex()] =
'r';
189 DriveWay& driveway = li.myDriveways.front();
191 #ifdef DEBUG_SIGNALSTATE
193 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" red for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
196 state[li.myLink->getTLIndex()] =
'r';
198 #ifdef DEBUG_SIGNALSTATE
200 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" green for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
211 #ifdef DEBUG_SIGNALSTATE
228 #ifdef DEBUG_SIGNALSTATE
230 std::cout <<
" constraint '" << c->
getDescription() <<
"' not cleared\n";
255 auto it = std::find(constraints.begin(), constraints.end(), constraint);
256 if (it != constraints.end()) {
258 constraints.erase(it);
346 for (
MSLink* link : links) {
347 result += link->getDescription() +
" ";
354 std::vector<const MSLane*> lanes(visited.size(),
nullptr);
355 for (
auto item : visited) {
356 lanes[item.second] = item.first;
365 const int tmp = (int)map.size();
373 double minDist = std::numeric_limits<double>::max();
376 if (apprIt->second.dist < minDist) {
377 minDist = apprIt->second.
dist;
408 for (
const DriveWay& dw : li.myDriveways) {
422 endIndex = (int)edges.size() - 1;
425 const MSEdge* e = edges[i];
427 const MSEdge* e2 = edges[i + 1];
429 for (
MSLink* link : lane->getLinkCont()) {
430 if (&link->getLane()->getEdge() == e2) {
459 bool hadOncoming =
false;
462 if (bidi ==
nullptr) {
463 brakeBeforeSignal =
false;
475 #ifdef DEBUG_SIGNALSTATE
477 std::cout <<
" oncoming vehicle on bidi-lane " << lane->
getID() <<
"\n";
488 #ifdef DEBUG_SIGNALSTATE
490 std::cout <<
" oncoming vehicle on flank-lane " << lane->
getID() <<
"\n";
498 #ifdef DEBUG_SIGNALSTATE
510 const bool hasProtection = dw.
findProtection(approaching, switchLink);
512 if (!hasProtection) {
515 if (!brakeBeforeSignal || std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), bidi) != veh->getRoute().end()) {
516 #ifdef DEBUG_SIGNALSTATE
518 std::cout <<
" no protection at bidi-switch " << switchLink->
getDescription() <<
" from veh=" << veh->getID() <<
"\n";
527 if (!brakeBeforeSignal || std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), bidi) != veh->getRoute().end()) {
528 #ifdef DEBUG_SIGNALSTATE
530 std::cout <<
" no protection at bidi-switch " << switchLink->
getDescription() <<
" from linkRival veh=" << veh->getID() <<
"\n";
539 #ifdef DEBUG_SIGNALSTATE
547 if (veh->
getSpeed() > 0 && closest.second.arrivalSpeedBraking > 0
549 #ifdef DEBUG_SIGNALSTATE
551 std::cout <<
" oncoming vehicle approaching foe link " << foeLink->
getDescription() <<
"\n";
561 brakeBeforeSignal = hadOncoming;
575 #ifdef DEBUG_SIGNALSTATE
577 std::cout <<
SIMTIME <<
" rsl=" << rs->
getID() <<
" insertion constraint '" << c->
getDescription() <<
"' for vehicle '" << veh->
getID() <<
"' not cleared\n";
581 isInsertionOrder = c->
getType() == MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
603 myLastRerouteTime = -1;
604 myLastRerouteVehicle =
nullptr;
611 return myLink->getTLLogic()->getID() +
"_" +
toString(myLink->getTLIndex());
617 MSEdge* first = &myLink->getLane()->getEdge();
626 while (lookBack > 0 && routeIndex > 0) {
628 if (prevEdge == first) {
639 if (myDriveways.empty()) {
641 dummyRoute.push_back(&myLink->getLane()->getEdge());
642 DriveWay dw = buildDriveWay(dummyRoute.begin(), dummyRoute.end());
643 myDriveways.push_back(dw);
645 return myDriveways.front();
650 auto itRoute = firstIt;
651 auto itDwRoute = dw.myRoute.begin();
653 while (itRoute != veh->
getRoute().
end() && itDwRoute != dw.myRoute.end()) {
654 if (*itRoute != *itDwRoute) {
664 if (match && itDwRoute == dw.myRoute.end()
665 && (itRoute == veh->
getRoute().
end() || dw.myFoundSignal || dw.myFoundReversal)) {
669 #ifdef DEBUG_SELECT_DRIVEWAY
674 #ifdef DEBUG_SELECT_DRIVEWAY
677 myDriveways.push_back(dw);
678 return myDriveways.back();
709 std::vector<const MSLane*> before;
712 if (fromBidi !=
nullptr) {
715 before.push_back(fromBidi);
717 dw.
buildRoute(myLink, 0., first, end, visited);
728 std::vector<MSLink*> flankSwitchesBidiExtended;
730 for (
MSLink* link : flankSwitchesBidiExtended) {
735 #ifdef DEBUG_BUILD_DRIVEWAY
737 std::cout <<
" buildDriveWay railSignal=" <<
getID()
768 && (myLastRerouteVehicle != veh
772 myLastRerouteVehicle = veh;
773 myLastRerouteTime = now;
778 std::cout <<
SIMTIME <<
" reroute veh=" << veh->
getID() <<
" rs=" <<
getID() <<
" occupied=" <<
toString(occupied) <<
"\n";
786 std::cout <<
" rerouting successful\n";
800 std::string joinVehicle =
"";
803 if (stop !=
nullptr) {
804 joinVehicle = stop->
join;
807 if (conflictLaneOccupied(joinVehicle,
true, closest.first)) {
808 for (
const MSLane* bidi : myBidi) {
809 if (!bidi->empty() && bidi->getBidiLane() !=
nullptr) {
810 occupied.push_back(&bidi->getBidiLane()->getEdge());
813 #ifdef DEBUG_SIGNALSTATE
820 for (
MSLink* link : myProtectingSwitches) {
821 if (!findProtection(closest, link)) {
822 #ifdef DEBUG_SIGNALSTATE
824 std::cout <<
" no protection at switch " << link->getDescription() <<
"\n";
830 for (
MSLink* foeLink : myConflictLinks) {
831 if (hasLinkConflict(closest, foeLink)) {
832 #ifdef DEBUG_SIGNALSTATE
834 std::cout <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
840 if (deadlockLaneOccupied()) {
843 myActive = closest.first;
850 for (
MSLink* foeLink : myConflictLinks) {
851 if (foeLink->getApproaching().size() > 0) {
852 #ifdef DEBUG_SIGNALSTATE
854 std::cout <<
SIMTIME <<
" foeLink=" << foeLink->getDescription() <<
" approachedBy=" << foeLink->getApproaching().begin()->first->getID() <<
"\n";
866 #ifdef DEBUG_SIGNALSTATE_PRIORITY
868 std::cout <<
" checkLinkConflict foeLink=" <<
getTLLinkID(foeLink) <<
"\n";
873 #ifdef DEBUG_SIGNALSTATE_PRIORITY
875 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
879 assert(foeTLL !=
nullptr);
882 if (foeRS !=
nullptr) {
887 !overlap(foeDriveWay)) {
888 #ifdef DEBUG_SIGNALSTATE_PRIORITY
891 std::cout <<
" foe blocked\n";
893 std::cout <<
" foe constrained\n";
895 std::cout <<
" no overlap\n";
901 #ifdef DEBUG_SIGNALSTATE_PRIORITY
904 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
905 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
906 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
907 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
908 <<
" aW=" << veh.first->getWaitingTime() <<
" foeW=" << foe.first->getWaitingTime()
909 <<
" aN=" << veh.first->getNumericalID() <<
" foeN=" << foe.first->getNumericalID()
913 const bool yield = mustYield(veh, foe);
929 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
930 if (foe.second.arrivalTime == veh.second.arrivalTime) {
931 if (foe.first->getSpeed() == veh.first->getSpeed()) {
932 if (foe.second.dist == veh.second.dist) {
933 if (foe.first->getWaitingTime() == veh.first->getWaitingTime()) {
934 return foe.first->getNumericalID() < veh.first->getNumericalID();
936 return foe.first->getWaitingTime() > veh.first->getWaitingTime();
939 return foe.second.dist < veh.second.dist;
942 return foe.first->getSpeed() > veh.first->getSpeed();
945 return foe.second.arrivalTime < veh.second.arrivalTime;
948 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
955 for (
const MSLane* lane : myConflictLanes) {
956 if (!lane->isEmpty()) {
957 #ifdef DEBUG_SIGNALSTATE
959 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied ego=" <<
Named::getIDSecure(ego) <<
" vehNumber=" << lane->getVehicleNumber() <<
"\n";
960 if (joinVehicle !=
"") {
961 std::cout <<
" joinVehicle=" << joinVehicle <<
" occupant=" <<
toString(lane->getVehiclesSecure()) <<
"\n";
962 lane->releaseVehicles();
966 if (lane->getVehicleNumberWithPartials() == 1) {
967 MSVehicle* foe = lane->getLastAnyVehicle();
968 if (joinVehicle !=
"") {
970 #ifdef DEBUG_SIGNALSTATE
972 std::cout <<
" ignore join-target '" << joinVehicle <<
"\n";
978 if (ego !=
nullptr) {
979 if (foe == ego && std::find(myBidi.begin(), myBidi.end(), lane) != myBidi.end()) {
980 #ifdef DEBUG_SIGNALSTATE
982 std::cout <<
" ignore ego as oncoming '" << ego->
getID() <<
"\n";
988 #ifdef DEBUG_SIGNALSTATE
990 std::cout <<
" ignore " << foe->
getID() <<
" for which ego is join-target\n";
1008 for (
const MSLane* lane : myBidiExtended) {
1009 if (!lane->empty()) {
1010 assert(myBidi.size() != 0);
1011 const MSEdge* lastBidi = myBidi.back()->getNextNormal();
1012 MSVehicle* foe = lane->getVehiclesSecure().front();
1013 #ifdef DEBUG_SIGNALSTATE
1015 std::cout <<
" check for deadlock with " << foe->
getID() <<
"\n";
1020 const int minEdges = (int)myBidiExtended.size();
1023 bool conflict =
false;
1024 for (
int i = 0; i < minEdges && foeIt != foeEnd; i++) {
1025 if ((*foeIt) == lastBidi) {
1026 #ifdef DEBUG_SIGNALSTATE
1028 std::cout <<
" vehicle will enter " << lastBidi->
getID() <<
"\n";
1036 lane->releaseVehicles();
1051 double flankApproachingDist = std::numeric_limits<double>::max();
1054 flankApproachingDist = closest.second.dist;
1056 #ifdef DEBUG_FIND_PROTECTION
1058 std::cout <<
SIMTIME <<
" findProtection for link=" << link->
getDescription() <<
" flankApproachingDist=" << flankApproachingDist <<
"\n";
1062 if (l2->getLane() != link->
getLane()) {
1063 #ifdef DEBUG_FIND_PROTECTION
1065 std::cout <<
" protectionCandidate=" << l2->getDescription() <<
" l2Via=" <<
Named::getIDSecure(l2->getViaLane())
1066 <<
" occupied=" << (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) <<
"\n";
1069 if (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) {
1070 #ifdef DEBUG_FIND_PROTECTION
1072 std::cout <<
" protection from internal=" << l2->getViaLane()->getID() <<
"\n";
1077 if (l2->getApproaching().size() > 0) {
1079 if (closest2.second.dist < flankApproachingDist) {
1080 #ifdef DEBUG_FIND_PROTECTION
1082 std::cout <<
" protection from veh=" << closest2.first->getID() <<
"\n";
1096 tmp.
myFlank.push_back(before);
1107 return tmp.
reserve(veh, occupied);
1114 for (
int i = 0; i < myCoreSize; i++) {
1116 const MSEdge* edge = myRoute[i];
1130 for (
const MSLane* lane : myForward) {
1132 if (lane == lane2) {
1137 if (lane == lane2) {
1149 if (myCoreSize != (
int)myRoute.size()) {
1157 if (myBidiExtended.size() > 0) {
1167 od.
openTag(
"protectingSwitches");
1168 std::vector<std::string> links;
1169 for (
MSLink* link : myProtectingSwitches) {
1176 std::vector<std::string> signals;
1177 for (
MSLink* link : myConflictLinks) {
1190 bool seekForwardSignal =
true;
1191 bool seekBidiSwitch =
true;
1192 bool foundUnsafeSwitch =
false;
1194 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1199 while ((seekForwardSignal || seekBidiSwitch)) {
1203 " exceeds maximum length (stopped searching after edge '" + toLane->
getEdge().
getID() +
"' (length=" +
toString(length) +
"m).");
1209 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1214 if (visited.count(toLane) != 0) {
1220 myRoute.push_back(&toLane->
getEdge());
1228 if (seekForwardSignal) {
1229 if (!foundUnsafeSwitch) {
1230 myForward.push_back(toLane);
1232 }
else if (bidi ==
nullptr) {
1233 seekBidiSwitch =
false;
1234 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1236 std::cout <<
" noBidi, abort search for bidiSwitch\n";
1240 if (bidi !=
nullptr) {
1241 if (foundUnsafeSwitch) {
1242 myBidiExtended.push_back(bidi);
1244 myBidi.push_back(bidi);
1247 if (!seekForwardSignal) {
1253 for (
const MSLink*
const link : ili.lane->getLinkCont()) {
1257 if (link->getViaLaneOrLane() != bidi) {
1261 myCoreSize = (int)myRoute.size();
1263 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1265 std::cout <<
" abort: found protecting switch " << ili.viaLink->getDescription() <<
"\n";
1270 myProtectedBidi = bidiNext;
1271 std::set<const MSEdge*> visitedEdges;
1272 for (
auto item : visited) {
1273 visitedEdges.insert(&item.first->getEdge());
1275 while (next != end && visitedEdges.count(*next) == 0) {
1277 visitedEdges.insert(*next);
1279 if (nextBidi !=
nullptr) {
1280 visitedEdges.insert(nextBidi);
1282 myRoute.push_back(*next);
1287 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1289 std::cout <<
" found unsafe switch " << ili.viaLink->getDescription() <<
" (used=" << bidiNext->
getID() <<
")\n";
1294 foundUnsafeSwitch =
true;
1298 myFlankSwitches.push_back(ili.viaLink);
1307 const std::vector<MSLink*>& links = toLane->
getLinkCont();
1310 for (
const MSLink*
const link : links) {
1311 if ((next != end && &link->getLane()->getEdge() == *next)
1312 &&
isRailway(link->getViaLaneOrLane()->getPermissions())) {
1313 toLane = link->getViaLaneOrLane();
1314 if (link->getLane()->getBidiLane() !=
nullptr && &link->getLane()->getEdge() == current->
getBidiEdge()) {
1316 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1318 std::cout <<
" abort: turn-around\n";
1321 myFoundReversal =
true;
1324 if (link->getTLLogic() !=
nullptr) {
1325 if (link->getTLLogic() == origin->
getTLLogic()) {
1330 seekForwardSignal =
false;
1331 myFoundSignal =
true;
1332 seekBidiSwitch = bidi !=
nullptr;
1333 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1335 std::cout <<
" found forwardSignal " << link->getTLLogic()->
getID() <<
" seekBidiSwitch=" << seekBidiSwitch <<
"\n";
1342 if (toLane ==
nullptr) {
1345 toLane = (*next)->getLanes()[0];
1346 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1348 std::cout <<
" abort: turn-around or jump\n";
1351 myFoundReversal =
true;
1354 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1356 std::cout <<
" abort: no next lane available\n";
1368 #ifdef DEBUG_CHECK_FLANKS
1369 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
"\n visited=" <<
formatVisitedMap(visited) <<
" allFoes=" << allFoes <<
"\n";
1375 if (reverseOriginLink !=
nullptr) {
1379 for (
int i = 0; i < (int)lanes.size(); i++) {
1380 const MSLane* lane = lanes[i];
1381 const MSLane* prev = i > 0 ? lanes[i - 1] :
nullptr;
1382 const MSLane* next = i + 1 < (int)lanes.size() ? lanes[i + 1] :
nullptr;
1387 if (ili.viaLink == originLink
1388 || ili.viaLink == reverseOriginLink
1393 if (ili.lane != prev && ili.lane != next) {
1394 #ifdef DEBUG_CHECK_FLANKS
1395 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";
1397 flankSwitches.push_back(ili.viaLink);
1398 }
else if (allFoes) {
1400 checkCrossingFlanks(ili.viaLink, visited, flankSwitches);
1409 #ifdef DEBUG_CHECK_FLANKS
1413 if (junction ==
nullptr) {
1417 if (logic ==
nullptr) {
1421 if (in->isInternal()) {
1424 for (
MSLane* inLane : in->getLanes()) {
1425 if (
isRailway(inLane->getPermissions()) && visited.count(inLane) == 0) {
1426 for (
MSLink* link : inLane->getLinkCont()) {
1427 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
1428 && visited.count(link->getLane()) == 0) {
1429 #ifdef DEBUG_CHECK_FLANKS
1430 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
1432 if (link->getViaLane() ==
nullptr) {
1433 flankSwitches.push_back(link);
1435 flankSwitches.push_back(link->getViaLane()->getLinkCont().front());
1446 #ifdef DEBUG_CHECK_FLANKS
1447 std::cout <<
" findFlankProtection link=" << link->
getDescription() <<
" length=" << length <<
" origLink=" << origLink->
getDescription() <<
"\n";
1451 #ifdef DEBUG_CHECK_FLANKS
1452 std::cout <<
" flank guarded by " << link->
getTLLogic()->
getID() <<
"\n";
1454 myConflictLinks.push_back(link);
1464 const bool isNew = visited.count(lane) == 0;
1465 if (isNew || (visited[lane] > visited[origLink->
getLane()] && std::find(myForward.begin(), myForward.end(), lane) == myForward.end())) {
1471 flank.push_back(lane);
1472 findFlankProtection(lane->
getIncomingLanes().front().viaLink, length, visited, origLink, flank);
1474 bool foundPSwitch =
false;
1476 #ifdef DEBUG_CHECK_FLANKS
1477 std::cout <<
" lane=" << lane->
getID() <<
" visitedIndex=" << visited[lane] <<
" origIndex=" << visited[origLink->
getLane()] <<
" cand=" << l2->getDescription() <<
"\n";
1480 foundPSwitch =
true;
1482 #ifdef DEBUG_CHECK_FLANKS
1483 std::cout <<
" protectingSwitch=" << l2->getDescription() <<
" for flank=" << link->
getDescription() <<
"\n";
1485 myProtectingSwitches.push_back(link);
1486 if (std::find(myBidi.begin(), myBidi.end(), origLink->
getLane()) != myBidi.end()) {
1487 #ifdef DEBUG_CHECK_FLANKS
1488 std::cout <<
" (is bidi-switch)\n";
1490 myProtectingSwitchesBidi.push_back(link);
1494 if (!foundPSwitch) {
1495 flank.push_back(lane);
1499 findFlankProtection(ili.viaLink, length, visited, origLink, flank);
1505 #ifdef DEBUG_CHECK_FLANKS
1506 std::cout <<
" laneBefore=" << lane->
getID() <<
" already visited. index=" << visited[lane] <<
" origAfter=" << origLink->
getLane()->
getID() <<
" origIndex=" << visited[origLink->
getLane()] <<
"\n";
1510 myMaxFlankLength =
MAX2(myMaxFlankLength, length);
1526 driveway.
reserve(closest, occupied);
1562 for (
const DriveWay& dw : li.myDriveways) {
1575 for (
auto it = li.myDriveways.begin(); it != li.myDriveways.end(); it++) {
1578 #ifdef DEBUG_DRIVEWAY_UPDATE
1579 std::cout <<
SIMTIME <<
" rail signal junction '" <<
getID() <<
"' requires update for driveway " << numericalID <<
"\n";
1581 std::vector<const MSEdge*> route = dw.
myRoute;
1582 li.myDriveways.erase(it);
1583 if (li.myDriveways.size() == 0) {
1585 li.myDriveways.push_back(li.buildDriveWay(route.begin(), route.end()));
1600 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1613 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1626 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1639 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1649 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, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions 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 SUMOVehicleParameter::Stop * getNextStopParameter() const
return parameters for the next stop (SUMOVehicle Interface)
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.
bool isNormal() const
return whether this edge is an internal edge
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
const MSJunction * getFromJunction() const
double getLength() const
return the length of the edge
const MSJunction * getToJunction() const
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
The base class for an intersection.
const ConstMSEdgeVector & getIncoming() const
SumoXMLNodeType getType() const
return the type of this Junction
virtual const MSJunctionLogic * getLogic() const
virtual const MSLogicJunction::LinkBits & getFoesFor(int linkIndex) const
Returns the foes for the given link.
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
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.
double getLength() const
Returns the lane's length.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
MSEdge & getEdge() const
Returns the lane's edge.
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
MSLane * getLane() const
Returns the connected lane.
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
int getIndex() const
Returns the respond index (for visualization)
int getTLIndex() const
Returns the TLS index.
ApproachingVehicleInformation getApproaching(const SUMOVehicle *veh) const
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
std::string getDescription() const
get string description for this link
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
MSJunction * getJunction() const
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)
const std::set< const MSEdge * > & getUsedEdges() const
void addGreenFlankSwitch(MSLink *link, int dwID)
static MSRailSignalControl & getInstance()
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 constraint 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
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 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 constraint for signal switching
static bool hasOncomingRailTraffic(MSLink *link, const MSVehicle *ego, bool &brakeBeforeSignal)
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.
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.
const ConstMSEdgeVector & getEdges() const
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 & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
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 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 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 const MSRoute & getRoute() const =0
Returns the current route.
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles 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