38#define DRIVEWAY_SANITY_CHECK
52#define DEBUG_HELPER(obj) ((obj) != nullptr && (obj)->isSelected())
57#define DEBUG_COND_DW(obj) (obj->getID() == DEBUG_DW_ID || DEBUG_DW_ID == std::string("ALL"))
58#define DEBUG_COND_DW2 (getID() == DEBUG_DW_ID || DEBUG_DW_ID == std::string("ALL"))
93 myNumericalID(temporary ? -1 : myGlobalDriveWayIndex++),
97 myForwardEdgeCount(0),
100 myTerminateRoute(false),
101 myAbortedBuild(false),
137 dw->myTrains.clear();
145#ifdef DEBUG_MOVEREMINDER
178#ifdef DEBUG_MOVEREMINDER
191 const MSLane* leftLane = (*(
dynamic_cast<SUMOVehicle&
>(veh).getCurrentRouteEdge()))->getLanes().front();
204#ifdef DEBUG_MOVEREMINDER
225#ifdef DEBUG_MOVEREMINDER
273 if (foe->myOrigin !=
nullptr) {
289#ifdef DEBUG_SIGNALSTATE
291 std::cout <<
getID() <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
304#ifdef DEBUG_SIGNALSTATE_PRIORITY
311#ifdef DEBUG_SIGNALSTATE_PRIORITY
313 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
316 if (foe.first == veh.first) {
320 assert(foeTLL !=
nullptr);
323 if (foeRS !=
nullptr) {
331#ifdef DEBUG_SIGNALSTATE_PRIORITY
334 std::cout <<
" foe blocked\n";
336 std::cout <<
" foe constrained\n";
337 }
else if (!
overlap(foeDriveWay)) {
338 std::cout <<
" no overlap with foeDW=" << foeDriveWay.
getID() <<
"\n";
340 std::cout <<
" foeDW=" << foeDriveWay.
getID() <<
" is not a foe to " <<
getID() <<
"\n";
341 }
else if (
canUseSiding(veh.first, &foeDriveWay).first) {
342 std::cout <<
" use siding\n";
348#ifdef DEBUG_SIGNALSTATE_PRIORITY
351 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
352 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
353 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
354 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
355 <<
" aW=" << veh.first->getWaitingTime() <<
" foeW=" << foe.first->getWaitingTime()
356 <<
" aN=" << veh.first->getNumericalID() <<
" foeN=" << foe.first->getNumericalID()
381 if (foe !=
nullptr) {
391 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
392 if (foe.second.arrivalTime == veh.second.arrivalTime) {
393 if (foe.first->getSpeed() == veh.first->getSpeed()) {
394 if (foe.second.dist == veh.second.dist) {
395 if (foe.first->getWaitingTime() == veh.first->getWaitingTime()) {
398 return foe.first->getWaitingTime() > veh.first->getWaitingTime();
401 return foe.second.dist < veh.second.dist;
404 return foe.first->getSpeed() > veh.first->getSpeed();
407 return foe.second.arrivalTime < veh.second.arrivalTime;
410 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
418 if (!lane->isEmpty()) {
419 std::string joinVehicle =
"";
422 if (stop !=
nullptr) {
423 joinVehicle = stop->
join;
426#ifdef DEBUG_SIGNALSTATE
428 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied ego=" <<
Named::getIDSecure(ego) <<
" vehNumber=" << lane->getVehicleNumber() <<
"\n";
429 if (joinVehicle !=
"") {
430 std::cout <<
" joinVehicle=" << joinVehicle <<
" occupant=" <<
toString(lane->getVehiclesSecure()) <<
"\n";
431 lane->releaseVehicles();
435 if (lane->getVehicleNumberWithPartials() == 1) {
436 MSVehicle* foe = lane->getLastAnyVehicle();
437 if (joinVehicle !=
"") {
439#ifdef DEBUG_SIGNALSTATE
441 std::cout <<
" ignore join-target '" << joinVehicle <<
"\n";
447 if (ego !=
nullptr) {
449#ifdef DEBUG_SIGNALSTATE
451 std::cout <<
" ignore ego as oncoming '" << ego->
getID() <<
"\n";
457#ifdef DEBUG_SIGNALSTATE
459 std::cout <<
" ignore " << foe->
getID() <<
" for which ego is join-target\n";
479 if (foeDW->myOrigin !=
nullptr && foeDW->myOrigin->getApproaching().size() > 0) {
480#ifdef DEBUG_SIGNALSTATE
482 std::cout <<
SIMTIME <<
" foeLink=" << foeDW->myOrigin->getDescription() <<
" approachedBy=" << foeDW->myOrigin->getApproaching().begin()->first->getID() <<
"\n";
495 if (!foeDW->myTrains.empty()) {
496#ifdef DEBUG_SIGNALSTATE
501 if (foeDW->myTrains.size() == 1) {
504#ifdef DEBUG_SIGNALSTATE
515 std::pair<bool, const MSDriveWay*> useSiding =
canUseSiding(ego, foeDW);
516#ifdef DEBUG_SIGNALSTATE
521 numSidings = it->second.size();
523 std::cout <<
" ego=" <<
Named::getIDSecure(ego) <<
" useSiding=" << useSiding.first <<
" sidingFoe=" <<
Named::getIDSecure(useSiding.second) <<
" numSidings=" << numSidings <<
"\n";
526 if (useSiding.first) {
536 occupied.push_back(
const_cast<MSEdge*
>(foe->getEdge()));
537 MSEdge* bidi =
const_cast<MSEdge*
>(foe->getEdge()->getBidiEdge());
538 if (bidi !=
nullptr) {
539 occupied.push_back(bidi);
546 SUMOVehicle* foe = *(useSiding.second ==
nullptr ? foeDW : useSiding.second)->
myTrains.begin();
552 }
else if (foeDW !=
this &&
isDepartDriveway() && !foeDW->isDepartDriveway()) {
553 if (foeDW->myOrigin->getApproaching().size() > 0) {
559 if (foeDW->match(firstIt, foe->
getRoute().
end())) {
561#ifdef DEBUG_SIGNALSTATE
563 std::cout <<
SIMTIME <<
" " <<
getID() <<
" blocked by " << foeDW->getID() <<
" (approached by " << foe->
getID() <<
") useSiding=" << useSiding <<
"\n";
578 for (
const std::set<const MSDriveWay*>& dlFoes :
myDeadlocks) {
579 bool allOccupied =
true;
581 if (dlFoe->myTrains.empty()) {
588#ifdef DEBUG_SIGNALSTATE
606 std::string joinVehicle =
"";
608 if (stop !=
nullptr) {
609 joinVehicle = stop->
join;
615 joinVehicle = it->pars.join;
617 if (joinVehicle !=
"") {
618#ifdef DEBUG_SIGNALSTATE
620 std::cout <<
" joinVehicle=" << joinVehicle <<
"\n";
624#ifdef DEBUG_SIGNALSTATE
626 std::cout <<
" ignore join-target '" << joinVehicle <<
"\n";
634#ifdef DEBUG_SIGNALSTATE
636 std::cout <<
" ignore " << foe->
getID() <<
" for which ego is join-target\n";
646std::pair<bool, const MSDriveWay*>
650 for (
auto siding : it->second) {
652 if (ego ==
nullptr || siding.length >= ego->
getLength()) {
655 bool checkNext =
false;
657 if (!sidingApproach->myTrains.empty() && *sidingApproach->myTrains.begin() == ego && sidingEnd == recurseSidingEnd) {
660#ifdef DEBUG_SIGNALSTATE
662 std::cout <<
" checkNext\n";
667 if (!sidingApproach->myTrains.empty() && *sidingApproach->myTrains.begin() != ego) {
669 if (recurseSidingEnd ==
nullptr) {
676 if (foeVeh ==
nullptr) {
682#ifdef DEBUG_SIGNALSTATE
684 std::cout <<
" foe2=" << foe2->
getID() <<
" this2=" << this2->
getID() <<
"\n";
687 if (this2 !=
nullptr && foe2->
canUseSiding(foeVeh, this2, sidingEnd).first) {
693#ifdef DEBUG_SIGNALSTATE
697 <<
" sidingEnd=" << sidingEnd->getID() <<
" sidingApproach=" << sidingApproach->getID() <<
" approaching=" <<
toString(sidingApproach->myTrains) <<
"\n";
700 return std::make_pair(
false, sidingApproach);
704 for (
int i : siding.intermediateEnds) {
707 if (!intermediateApproach->myTrains.empty()
708 && (*intermediateApproach->myTrains.begin() != ego || intermediateEnd == recurseSidingEnd)) {
709 SUMOVehicle* onApproach = *intermediateApproach->myTrains.begin();
715 if (recurseSidingEnd ==
nullptr) {
722 if (foeVeh ==
nullptr) {
728 if (this2 !=
nullptr && foe2->
canUseSiding(foeVeh, this2, intermediateEnd).first) {
733#ifdef DEBUG_SIGNALSTATE
737 <<
" sidingEnd=" << sidingEnd->
getID() <<
" intermediateApproach=" << intermediateApproach->getID() <<
" approaching=" <<
toString(intermediateApproach->myTrains) <<
"\n";
740 return std::make_pair(
false, intermediateApproach);
747#ifdef DEBUG_SIGNALSTATE
751 <<
" sidingEnd=" << sidingEnd->
getID() <<
" usable\n";
754 return std::make_pair(
true,
nullptr);
758#ifdef DEBUG_SIGNALSTATE
763 return std::make_pair(
false,
nullptr);
817 if (lane->isNormal() && lane2->isNormal() && lane->getEdge().getToJunction() == lane2->getEdge().getToJunction()) {
834 for (
int i = 0; i < (int)
myForward.size() - 1; i++) {
902 if (edge2 ==
myForward.front()->getNextNormal() && !secondCheck) {
906 if (forward.count(edge2->getBidiEdge()) != 0) {
940 std::vector<std::string> signals;
947 std::vector<std::string> foes;
949 foes.push_back(dw->myID);
951 if (foes.size() > 0) {
958 od.
writeAttr(
"foe", item.first->getID());
959 for (
auto siding : item.second) {
964 if (siding.intermediateEnds.size() > 0) {
965 std::vector<std::string> endEdges;
966 for (
int i : siding.intermediateEnds) {
969 od.
writeAttr(
"intermediateEnds", endEdges);
984 sub->writeBlocks(od);
986#ifdef DRIVEWAY_SANITY_CHECK
987 std::set<MSDriveWay*> uFoes(
myFoes.begin(),
myFoes.end());
988 if (uFoes.size() !=
myFoes.size()) {
1001 od.
openTag(ve.isEntry ?
"entry" :
"exit");
1010 sub->writeBlockVehicles(od);
1019 std::set<MSLink*, MSLink::ComparatorNumericalLaneIdLess>& flankSwitches) {
1021 bool seekForwardSignal =
true;
1022 bool seekBidiSwitch =
true;
1023 bool foundUnsafeSwitch =
false;
1025 const std::string warnID = origin ?
"rail signal " +
getClickableTLLinkID(origin) :
"insertion lane '" + toLane->
getID() +
"'";
1026#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1037 WRITE_WARNINGF(
"Block after % exceeds maximum length (stopped searching after edge '%' (length=%m).",
1043#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1045 std::cout <<
" abort: length=" << length <<
"\n";
1050#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1065 if (seekForwardSignal) {
1066 if (!foundUnsafeSwitch) {
1081 }
else if (bidi ==
nullptr) {
1083#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1085 std::cout <<
" continue bidiSearch beyond turnaround\n";
1089 seekBidiSwitch =
false;
1090#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1092 std::cout <<
" noBidi, abort search for bidiSwitch\n";
1097 if (bidi !=
nullptr) {
1098 if (!seekForwardSignal && !foundUnsafeSwitch && bidi->
isNormal()) {
1104 if (!
myBidi.empty() && link->getViaLaneOrLane() !=
myBidi.back()) {
1107#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1109 std::cout <<
" found unsafe switch " << link->
getDescription() <<
" (used=" << (used ==
nullptr ?
"NULL" : used->
getDescription()) <<
")\n";
1113 foundUnsafeSwitch =
true;
1115 if (used !=
nullptr) {
1117 flankSwitches.insert(used);
1123 if (foundUnsafeSwitch) {
1129 const std::vector<MSLink*>& links = toLane->
getLinkCont();
1131 for (
const MSLink*
const link : links) {
1132 if ((next != end && &link->getLane()->getEdge() == *next)) {
1133 toLane = link->getViaLaneOrLane();
1135 if (link == origin) {
1136 if (seekForwardSignal) {
1141#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1143 std::cout <<
" abort: found circle\n";
1148 seekForwardSignal =
false;
1150 seekBidiSwitch = bidi !=
nullptr;
1151#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1153 std::cout <<
" found forwardSignal " << link->getTLLogic()->
getID() <<
" seekBidiSwitch=" << seekBidiSwitch <<
"\n";
1163 if (link->getLane()->getBidiLane() !=
nullptr && &link->getLane()->getEdge() == current->
getBidiEdge()) {
1171 if (toLane ==
nullptr) {
1174 toLane = (*next)->getLanes()[0];
1175#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1177 std::cout <<
" abort: turn-around or jump\n";
1183#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1185 std::cout <<
" abort: no next lane available\n";
1194#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1196 std::cout <<
" normalEnd myBidiEnded=" <<
myBidiEnded <<
"\n";
1205 if (other->getLane() != link->
getLane() && !other->isTurnaround()) {
1210 if (ili.viaLink != link && !ili.viaLink->
isTurnaround()) {
1215 if (bidi !=
nullptr) {
1228 bool allFoes,
bool movingBlock, std::set<MSLink*, MSLink::ComparatorNumericalLaneIdLess>& flankSwitches)
const {
1229#ifdef DEBUG_CHECK_FLANKS
1231 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
" allFoes=" << allFoes <<
"\n";
1238 if (reverseOriginLink !=
nullptr) {
1242 for (
int i = 0; i < (int)lanes.size(); i++) {
1243 const MSLane* lane = lanes[i];
1244 const MSLane* prev = i > 0 ? lanes[i - 1] :
nullptr;
1245 const MSLane* next = i + 1 < (int)lanes.size() ? lanes[i + 1] :
nullptr;
1250 if (ili.viaLink == originLink
1251 || ili.viaLink == reverseOriginLink
1254 || (originLink ==
nullptr && i == 0 && movingBlock)) {
1257 if (ili.lane != prev && ili.lane != next) {
1258#ifdef DEBUG_CHECK_FLANKS
1260 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";
1263 flankSwitches.insert(ili.viaLink);
1264 }
else if (allFoes) {
1275#ifdef DEBUG_CHECK_FLANKS
1281 if (junction ==
nullptr) {
1285 if (logic ==
nullptr) {
1289 if (in->isInternal()) {
1292 for (
MSLane* inLane : in->getLanes()) {
1294 if (
isRailwayOrShared(inLane->getPermissions()) && visited.count(inLane) == 0 && (inBidi ==
nullptr || visited.count(inBidi) == 0)) {
1295 for (
MSLink* link : inLane->getLinkCont()) {
1296 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
1297 && visited.count(link->getLane()) == 0) {
1298#ifdef DEBUG_CHECK_FLANKS
1300 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
1303 if (link->getViaLane() ==
nullptr) {
1304 flankSwitches.insert(link);
1306 flankSwitches.insert(link->getViaLane()->getLinkCont().front());
1317#ifdef DEBUG_CHECK_FLANKS
1325#ifdef DEBUG_CHECK_FLANKS
1327 std::cout <<
" flank guarded by " << entry->
getTLLogic()->
getID() <<
"\n";
1336 std::vector<MSLink*> predLinks;
1338 if (!ili.viaLink->isTurnaround()) {
1339 predLinks.push_back(ili.viaLink);
1342 if (predLinks.size() > 1) {
1344#ifdef DEBUG_ADD_FOES
1346 std::cout <<
" predecessors of " << link->
getDescription() <<
" isSwitch\n";
1349 for (
MSLink* pred : predLinks) {
1352 }
else if (predLinks.size() == 1) {
1364#ifdef DEBUG_ADD_FOES
1366 std::cout <<
" foe " << foe->getID() <<
" departs on flank=" << lane->
getID() <<
"\n";
1371#ifdef DEBUG_ADD_FOES
1373 std::cout <<
" cand foe " << foe->getID() <<
" departs on flank=" << lane->
getID() <<
" rejected\n";
1387#ifdef DEBUG_ADD_FOES
1389 std::cout <<
" driveway " <<
myID <<
" addSwitchFoes for link " << link->
getDescription() <<
"\n";
1394#ifdef DEBUG_ADD_FOES
1395 if (
gDebugFlag4) std::cout <<
" foe=" << foe->myID
1396 <<
" fc1=" <<
flankConflict(*foe) <<
" fc2=" << foe->flankConflict(*
this)
1397 <<
" cc1=" <<
crossingConflict(*foe) <<
" cc2=" << foe->crossingConflict(*
this) <<
"\n";
1401#ifdef DEBUG_ADD_FOES
1403 std::cout <<
" cand=" << foe->myID <<
"\n";
1438 std::vector<const MSLane*> before;
1439 MSLane* fromBidi =
nullptr;
1440 if (link !=
nullptr) {
1444 std::set<MSLink*, MSLink::ComparatorNumericalLaneIdLess> flankSwitches;
1446 if (fromBidi !=
nullptr) {
1447 before.push_back(fromBidi);
1449#ifdef DEBUG_BUILD_DRIVEWAY
1452 dw->
buildRoute(link, first, end, visited, flankSwitches);
1456 const bool movingBlock = (rs && rs->
isMovingBlock()) || (!rs &&
1462 dw->
checkFlanks(link, before, visited,
true, movingBlock, flankSwitches);
1463 for (
MSLink* fsLink : flankSwitches) {
1464#ifdef DEBUG_ADD_FOES
1466 std::cout <<
" fsLink=" << fsLink->getDescription() <<
"\n";
1471 std::set<MSLink*, MSLink::ComparatorNumericalLaneIdLess> flankSwitchesBidiExtended;
1473 for (
MSLink*
const flink : flankSwitchesBidiExtended) {
1474#ifdef DEBUG_ADD_FOES
1476 std::cout <<
" fsLinkExtended=" << flink->getDescription() <<
"\n";
1481#ifdef DEBUG_BUILD_DRIVEWAY
1483 std::cout <<
SIMTIME <<
" buildDriveWay " << dw->
myID <<
" link=" << (link ==
nullptr ?
"NULL" : link->
getDescription())
1508 std::set<MSDriveWay*, ComparatorNumericalIdLess> uniqueFoes(dw->
myFoes.begin(), dw->
myFoes.end());
1511 if (movingBlock && uniqueFoes.count(dw) == 0) {
1512 std::map<const MSJunction*, std::vector<const MSLink*> > forwardJunctions;
1513 int iLast = (int)dw->
myForward.size() - 1;
1514 bool selfIntersect =
false;
1515 for (
int i = 0; i < iLast && !selfIntersect; i++) {
1520 if (fwLink !=
nullptr) {
1521 for (
const MSLink* link2 : forwardJunctions[fwTo]) {
1522 const std::vector<MSLink*>& foeLinks = fwLink->
getFoeLinks();
1523 const std::vector<MSLink*>& foeLinks2 = link2->getFoeLinks();
1524 if (std::find(foeLinks.begin(), foeLinks.end(), link2) != foeLinks.end()
1525 || std::find(foeLinks2.begin(), foeLinks2.end(), fwLink) != foeLinks2.end()
1528 dw->
myFoes.push_back(dw);
1529 selfIntersect =
true;
1530#ifdef DEBUG_ADD_FOES
1532 std::cout <<
" self-intersecting movingBlock for dw=" << dw->
getID() <<
" at junction " << fwTo->
getID() <<
" fwLink=" << fwLink->
getDescription() <<
" link2=" << link2->getDescription() <<
"\n";
1538 forwardJunctions[fwTo].push_back(fwLink);
1546 const MSEdge* foeLastEdge = &foe->myForward.back()->getEdge();
1547 const bool sameLast = foeLastEdge == lastEdge;
1548 if (sameLast && !movingBlock) {
1549 dw->
myFoes.push_back(foe);
1551 foe->myFoes.push_back(dw);
1554 if (foe->bidiBlockedByEnd(*dw)) {
1555#ifdef DEBUG_ADD_FOES
1557 std::cout <<
" setting " << dw->
getID() <<
" as foe of " << foe->getID() <<
"\n";
1560 foe->myFoes.push_back(dw);
1561 foe->addSidings(dw);
1567#ifdef DEBUG_ADD_FOES
1569 std::cout <<
" addFoeCheckSiding " << foe->getID() <<
"\n";
1572 dw->
myFoes.push_back(foe);
1575 foe->buildSubFoe(dw, movingBlock);
1580 foe->addConflictLink(link);
1583 if (foe->myRoute.front()->getFromJunction() != dw->
myRoute.front()->getFromJunction()) {
1584 for (
auto ili : foe->myForward.front()->getIncomingLanes()) {
1585 if (ili.viaLink->getTLLogic() !=
nullptr) {
1587 const MSLane* origin = ili.viaLink->getLaneBefore();
1589 uniqueCLink.insert(ili.viaLink);
1601 if (uniqueFoes.count(sameEnd) == 0) {
1602 dw->
myFoes.push_back(sameEnd);
1603 if (sameEnd != dw) {
1604 sameEnd->myFoes.push_back(dw);
1609#ifdef DEBUG_BUILD_DRIVEWAY
1611 std::cout << dw->
myID <<
" mb=" << movingBlock <<
" finalFoes " <<
toString(dw->
myFoes) <<
"\n";
1657 const int tmp = (int)map.size();
1664 auto itRoute = firstIt;
1665 auto itDwRoute =
myRoute.begin();
1667 while (itRoute != endIt && itDwRoute !=
myRoute.end()) {
1668 if (*itRoute != *itDwRoute) {
1671 std::cout <<
" check dw=" <<
getID() <<
" match failed at vehEdge=" << (*itRoute)->getID() <<
" dwEdge=" << (*itDwRoute)->getID() <<
"\n";
1683 if (itRoute != endIt) {
1685 const MSEdge* next = *itRoute;
1690 std::cout <<
" check dw=" <<
getID() <<
" prev=" << prev->
getID() <<
" next=" << next->
getID() <<
"\n";
1702 if (
myForward.back()->isInternal() &&
myForward.back()->getNextNormal() != (*itRoute)) {
1717#ifdef DEBUG_ADD_FOES
1719 std::cout <<
"driveway " <<
myID <<
" addFoes for link " << link->
getDescription() <<
"\n";
1723 if (rs !=
nullptr) {
1725#ifdef DEBUG_ADD_FOES
1727 std::cout <<
" cand foe=" << foe->
myID <<
" fc1=" <<
flankConflict(*foe) <<
" fc2=" << foe->flankConflict(*
this) <<
" cc1=" <<
crossingConflict(*foe) <<
" cc2=" << foe->crossingConflict(*
this) <<
"\n";
1731#ifdef DEBUG_ADD_FOES
1733 std::cout <<
" foe=" << foe->myID <<
"\n";
1745#ifdef DEBUG_ADD_FOES
1747 std::cout <<
"driveway " <<
myID <<
" addBidiFoes extended=" << extended <<
"\n";
1751 for (
const MSLane* bidi : bidiLanes) {
1752 for (
auto ili : bidi->getIncomingLanes()) {
1754 if (rs !=
nullptr && rs != ownSignal &&
1755 std::find(bidiLanes.begin(), bidiLanes.end(), ili.lane) != bidiLanes.end()) {
1759 const MSEdge* bidiEdge = &bidi->getEdge();
1763#ifdef DEBUG_ADD_FOES
1765 std::cout <<
" foe " << foe->
getID() <<
" departs on bidi=" << bidiEdge->
getID() <<
"\n";
1770#ifdef DEBUG_ADD_FOES
1772 std::cout <<
" cand foe " << foe->getID() <<
" departs on bidi=" << bidiEdge->
getID() <<
" rejected\n";
1781#ifdef DEBUG_ADD_FOES
1783 std::cout <<
" foe " << foe->getID() <<
" ends on bidi=" << bidiEdge->
getID() <<
"\n";
1788#ifdef DEBUG_ADD_FOES
1790 std::cout <<
" cand foe " << foe->getID() <<
" ends on bidi=" << bidiEdge->
getID() <<
" rejected\n";
1802#ifdef DEBUG_ADD_FOES
1804 std::cout <<
"driveway " <<
myID <<
" addParallelFoes\n";
1813#ifdef DEBUG_ADD_FOES
1815 std::cout <<
" foe " << foe->getID() <<
" departs on first=" << first->
getID() <<
"\n";
1827#ifdef DEBUG_ADD_FOES
1829 std::cout <<
"driveway " <<
myID <<
" addReversalFoes\n";
1832 std::set<const MSEdge*> forward;
1834 if (lane->isNormal()) {
1835 forward.insert(&lane->getEdge());
1840 if (forward.count(e) != 0 && !movingBlock) {
1854#ifdef DEBUG_ADD_FOES
1858 std::set<const MSEdge*> foeForward;
1859 for (
const MSLane* lane : foe->myForward) {
1860 if (lane->isNormal()) {
1861 foeForward.insert(&lane->getEdge());
1862 if (lane->getBidiLane() !=
nullptr) {
1863 foeForward.insert(lane->getEdge().getBidiEdge());
1867#ifdef DEBUG_ADD_FOES
1869 std::cout <<
" reversal cand=" << foe->getID() <<
" foeForward " <<
toString(foeForward) <<
"\n";
1872 if (foe->forwardRouteConflict(foeForward, *
this,
true)) {
1873#ifdef DEBUG_ADD_FOES
1875 std::cout <<
" foe " << foe->getID() <<
" reverses on edge=" << e->getID() <<
"\n";
1880 }
else if (movingBlock && foe ==
this) {
1881#ifdef DEBUG_ADD_FOES
1883 std::cout <<
" dw " <<
getID() <<
" reverses on forward edge=" << e->getID() <<
" (movingBlock)\n";
1907#ifdef DEBUG_BUILD_SUBDRIVEWAY
1909 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" is subpart of foe=" << foe->
getID() <<
"\n";
1912 foe->
myFoes.push_back(
this);
1915 int subLast = (int)
myForward.size() - 2;
1919#ifdef DEBUG_BUILD_SUBDRIVEWAY
1922 std::cout <<
" " <<
getID() <<
" cannot build subDriveWay for foe " << foe->
getID() <<
" because myForward has only a single lane\n";
1926 bool foundConflict =
false;
1927 bool flankC =
false;
1928 bool zipperC =
false;
1929 bool crossC =
false;
1930 while (subLast >= 0) {
1940 const bool bidiConflict = std::find(foe->
myBidi.begin(), foe->
myBidi.end(), lane) != foe->
myBidi.end();
1942#ifdef DEBUG_BUILD_SUBDRIVEWAY
1944 std::cout <<
" subLast=" << subLast <<
" lane=" << lane->
getID() <<
" fc=" << flankC <<
" cc=" << crossC <<
" bc=" << bidiConflict <<
"\n";
1947 if (flankC || crossC || bidiConflict) {
1948 foundConflict =
true;
1949 if (!movingBlock || bidiConflict) {
1957 foundConflict =
false;
1958#ifdef DEBUG_BUILD_SUBDRIVEWAY
1960 std::cout <<
" ignored movingBlock zipperConflict\n";
1963 if (!flankC && crossC) {
1964#ifdef DEBUG_BUILD_SUBDRIVEWAY
1966 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" movingBlock-save\n";
1972 if (!flankC && crossC) {
1975 }
else if (foundConflict) {
1980#ifdef DEBUG_BUILD_SUBDRIVEWAY
1982 std::cout <<
" subLastFinal=" << subLast <<
" movingBlock=" << movingBlock <<
" zipperC=" << zipperC <<
"\n";
1995 if (forward == foeAfterForward ) {
1996 foe->
myFoes.push_back(
this);
1999#ifdef DEBUG_BUILD_SUBDRIVEWAY
2001 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" special case 1\n";
2008 if (movingBlock && zipperC) {
2009#ifdef DEBUG_BUILD_SUBDRIVEWAY
2011 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" movingBlock-save\n";
2017 foe->
myFoes.push_back(
this);
2018#ifdef DEBUG_BUILD_SUBDRIVEWAY
2020 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" foe endsOnForward\n";
2025 foe->
myFoes.push_back(
this);
2029#ifdef DEBUG_BUILD_SUBDRIVEWAY
2031 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" terminates\n";
2035 foe->
myFoes.push_back(
this);
2036#ifdef DEBUG_BUILD_SUBDRIVEWAY
2038 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" terminates, foe=" << foe->
getID() <<
"\n";
2043#ifdef DEBUG_BUILD_SUBDRIVEWAY
2045 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" has " << foe->
myReversals.size() <<
" reversals\n";
2049#ifdef DEBUG_BUILD_SUBDRIVEWAY
2051 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" failed\n";
2054#ifdef SUBDRIVEWAY_WARN_NOCONFLICT
2055 WRITE_WARNINGF(
"No point of conflict found between driveway '%' and driveway '%' when creating sub-driveway",
getID(), foe->
getID());
2060 int subSize = subLast + 1;
2062 if ((
int)cand->myForward.size() == subSize) {
2064 foe->
myFoes.push_back(cand);
2068 cand->myFoes.push_back(foe);
2069#ifdef DEBUG_BUILD_SUBDRIVEWAY
2071 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" useExisting=" << cand->getID() <<
"\n";
2078 std::vector<const MSEdge*> route;
2079 for (
const MSLane* lane : forward) {
2080 if (lane->isNormal()) {
2081 route.push_back(&lane->getEdge());
2084 if (route.empty()) {
2085 if (subSize == 1 && crossC
2086 && forward.front()->getFromJunction() == foe->
myForward.front()->getFromJunction()
2088 assert(
myForward.front()->isInternal());
2090 route.push_back(foe->
myForward.front()->getEdge().getNormalSuccessor());
2092#ifdef DEBUG_BUILD_SUBDRIVEWAY
2094 std::cout <<
SIMTIME <<
" abort subFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" empty subRoute\n";
2100 if (
myRoute.size() > route.size()) {
2102 const MSEdge* lastNormal = route.back();
2105#ifdef DEBUG_BUILD_SUBDRIVEWAY
2107 <<
" lastNormal=" << lastNormal->
getID() <<
" nextNormal=" << nextNormal->
getID() <<
" endWithReversal\n";
2122 auto itOnSub = std::find(sub->
myRoute.begin(), sub->
myRoute.end(), veh->getEdge());
2123 if (itOnSub != sub->
myRoute.end()) {
2126 const double pos = sub->
myRoute.front()->getLength();
2129 if (ve.id == veh->getID()) {
2136 foe->
myFoes.push_back(sub);
2140 sub->
myFoes.push_back(foe);
2142#ifdef DEBUG_BUILD_SUBDRIVEWAY
2153 assert(lastIndex < (
int)
myForward.size());
2155 for (
int i = 0; i <= lastIndex; i++) {
2165 const MSEdge* foeEndBidi = foe->
myForward.back()->getEdge().getBidiEdge();
2166 int foeForwardNormals = 0;
2168 if (lane->isNormal()) {
2169 foeForwardNormals++;
2172 if (foeForwardNormals == (
int)foeRoute.size()) {
2173#ifdef DEBUG_BUILD_SIDINGS
2175 std::cout <<
"checkSiding " <<
getID() <<
" foe=" << foe->
getID() <<
" foeForwardNormals=" << foeForwardNormals <<
" frSize=" << foeRoute.size() <<
" aborted\n";
2180 auto foeSearchBeg = foeRoute.begin() + foeForwardNormals;
2181 auto foeSearchEnd = foeRoute.end();
2182 if (foeEndBidi ==
nullptr) {
2187 std::set<const MSEdge*> foeForwardEdges(foeRoute.begin(), foeRoute.begin() + foeForwardNormals);
2188 int forwardNormals = 0;
2190 if (lane->isNormal()) {
2192 if (foeForwardEdges.count(&lane->getEdge()) != 0) {
2193#ifdef DEBUG_BUILD_SIDINGS
2195 std::cout <<
"checkSiding " <<
getID() <<
" foe=" << foe->
getID() <<
" forwardEdge=" << lane->getEdge().getID() <<
" on foeForward (sidings unsafe)\n";
2203 std::vector<int> start;
2204 std::vector<double> length;
2205 std::vector<std::vector<int> > intermediateRS;
2206 for (i = 0; i < (int)
myRoute.size(); i++) {
2207 if (
myRoute[i] == foeEndBidi) {
2211 if (i == (
int)
myRoute.size()) {
2215#ifdef DEBUG_BUILD_SIDINGS
2217 std::cout <<
"checkSiding " <<
getID() <<
" foe=" << foe->
getID() <<
" i=" << i <<
" next=" << next->
getID() <<
" foeForwardNormals=" << foeForwardNormals <<
" frSize=" << foeRoute.size() <<
" foeSearchBeg=" << (*foeSearchBeg)->getID() <<
"\n";
2222 for (; i >= 0; i--) {
2224 const bool curHasRS =
hasRS(cur, next);
2226 if (std::find(foeSearchBeg, foeSearchEnd, cur->
getBidiEdge()) == foeSearchEnd) {
2229 length.push_back(0);
2230 intermediateRS.push_back({});
2233 if (!start.empty()) {
2235 auto itFind = std::find(foeSearchBeg, foeSearchEnd, cur->
getBidiEdge());
2236 if (itFind != foeSearchEnd) {
2237#ifdef DEBUG_BUILD_SIDINGS
2242 const int firstIndex = i + 1;
2244 auto& foeSidings = foe->
mySidings[
this];
2247 auto itFirst = std::find(foeRoute.begin(), foeRoute.end(), first);
2248 if (itFirst != foeRoute.end()) {
2249 for (
int j = 0; j < (int)length.size(); j++) {
2251 auto itLast = std::find(itFirst, foeRoute.end(), last);
2252 if (itLast != foeRoute.end()) {
2254 foeSidings.insert(foeSidings.begin(),
Siding((
int)(itFirst - foeRoute.begin()), (
int)(itLast - foeRoute.begin()), length[j], {}));
2255 if (foeSidings.size() > 2) {
2256 foeSidings.pop_back();
2263 std::vector<int> furtherRS;
2265 furtherRS.push_back(i);
2267 const MSEdge* next2 = cur;
2268 for (
int i2 = i - 1; i2 >= forwardNormals; i2--) {
2270 if (
hasRS(cur2, next2)) {
2271 furtherRS.push_back(i2);
2276 for (
int j = 0; j < (int)length.size(); j++) {
2277 intermediateRS[j].insert(intermediateRS[j].end(), furtherRS.begin(), furtherRS.end());
2278 foeSidings.insert(foeSidings.begin(),
Siding(firstIndex, start[j], length[j], intermediateRS[j]));
2279 if (foeSidings.size() > 2) {
2280 foeSidings.pop_back();
2286 intermediateRS.clear();
2287 foeSearchBeg = itFind;
2289 for (
int j = 0; j < (int)length.size(); j++) {
2291 if (curHasRS && i != start[j]) {
2292 intermediateRS[j].push_back(i);
2306 for (
auto lane : cur->
getLanes()) {
2307 for (
const MSLink* link : lane->getLinkCont()) {
2308 if (&link->getLane()->getEdge() == next && link->getTLLogic() !=
nullptr) {
2320 const MSEdge* foeForwardEnd = &foe->
myForward.back()->getNormalPredecessorLane()->getEdge();
2342 std::set<const MSDriveWay*> filtered;
2345 filtered.insert(foe);
2360 for (
auto ili : lane->getIncomingLanes()) {
2363 if (rs !=
nullptr) {
2365 if (&dw->
myForward.front()->getEdge() == edge) {
2374 if (dw->match(matchStart, veh->
getRoute().
end())) {
2390 const MSEdge* edge = item.first;
2391 if (item.second.size() > 0) {
2395 if (writeVehicles) {
2396 dw->writeBlockVehicles(od);
2398 dw->writeBlocks(od);
2411 dw->_saveState(out);
2413 sub->_saveState(out);
2426 std::vector<std::string> trainIDs;
2428 trainIDs.push_back(veh->getID());
2440 if (!sub->myTrains.empty()) {
2458 const std::string
id = attrs.
get<std::string>(
SUMO_ATTR_ID,
nullptr, ok);
2476 std::string parentID =
id.substr(0,
id.rfind(
'.'));
2484 if (sub->myRoute == route) {
2489 if (dw ==
nullptr) {
2498 if (veh ==
nullptr) {
2499 throw ProcessError(
TLF(
"Unknown vehicle '%' in driveway '%'", vehID,
id));
2511 if (dw->getID() == id) {
#define DEBUG_HELPER(obj)
#define DEBUG_COND_DW(obj)
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
ConstMSEdgeVector::const_iterator MSRouteIterator
#define WRITE_WARNINGF(...)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
bool isRailwayOrShared(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge or a shared road/rail edge.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SUMO_TAG_DRIVEWAY
Saved driveway information.
@ 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_TIME
trigger: the time of the step
std::string joinNamedToString(const std::set< T *, C > &ns, const T_BETWEEN &between)
std::string joinToStringSorting(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
std::string joinNamedToStringSorting(const std::set< T * > &ns, const T_BETWEEN &between)
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
A single mesoscopic segment (cell)
void addDetector(MSMoveReminder *data, int queueIndex=-1)
Adds a data collector for a detector to this segment.
The base class for microscopic and mesoscopic vehicles.
const SUMOVehicleParameter::Stop * getNextStopParameter() const
return parameters for the next stop (SUMOVehicle Interface)
void addReminder(MSMoveReminder *rem, double pos=0)
Adds a MoveReminder dynamically.
bool isStopped() const
Returns whether the vehicle is at a stop.
SUMOTime getStartupDelay() const
Get the vehicle type's startupDelay.
void addFoes(const MSLink *link)
add all driveWays that start at the given link as foes
std::vector< MSLink * > myConflictLinks
const SUMOVehicle * myActive
whether the current signal is switched green for a train approaching this block
bool crossingConflict(const MSDriveWay &other) const
Wether there is a crossing conflict with the given driveway.
static std::string getJunctionLinkID(const MSLink *link)
return junctionID_junctionLinkIndex
bool haveSubTrains() const
std::vector< MSDriveWay * > mySubDriveWays
std::vector< std::set< const MSDriveWay * > > myDeadlocks
bool myAbortedBuild
whether driveway building was aborted due to MAX_BLOCK_LENGTH
bool buildSubFoe(MSDriveWay *foe, bool movingBlock)
std::set< SUMOVehicle *, ComparatorNumericalIdLess > myTrains
static std::map< const MSJunction *, int > myDepartDrivewayIndex
void buildRoute(const MSLink *origin, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap &visited, std::set< MSLink *, MSLink::ComparatorNumericalLaneIdLess > &)
const MSDriveWay * getFoeOrSubFoe(const MSDriveWay *dw) const
return dw if it is a foe or a subDrivway of dw if it is a foe
static bool hasJoin(const SUMOVehicle *ego, const SUMOVehicle *foe)
bool isDepartDriveway() const
static std::string getClickableTLLinkID(const MSLink *link)
return logicID_linkIndex in a way that allows clicking in sumo-gui
const MSLink * myOrigin
the link that enters this driveway or nullptr for a departure driveWay
static double myMovingBlockMaxDist
std::vector< const MSLane * > myBidi
static bool myWriteVehicles
bool notifyReroute(SUMOTrafficObject &veh)
Called if the vehicle change it's route.
bool hasLinkConflict(const Approaching &closest, const MSLink *foeLink) const
Whether the approaching vehicle is prevent from driving by another vehicle approaching the given link...
void findFlankProtection(MSLink *link, MSLink *origLink, std::vector< const MSLane * > &flank)
std::vector< const MSLane * > myBidiExtended
MSDriveWay(const MSLink *origin, const std::string &id, bool temporary=false)
static bool hasRS(const MSEdge *cur, const MSEdge *next)
void addBidiFoes(const MSRailSignal *ownSignal, bool extended)
derive foe driveways based on myBidi or myBidiExtended
static const MSDriveWay * retrieveDepartDriveWay(const MSEdge *edge, const std::string &id)
void writeBlocks(OutputDevice &od) const
Write block items for this driveway.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder's lane.
std::vector< const MSLane * > myForward
std::vector< const MSEdge * > myReversals
track own occurences in myReversalDriveWays for cleanup in destructor
std::map< const MSDriveWay *, std::vector< Siding >, ComparatorIdLess > mySidings
void writeBlockVehicles(OutputDevice &od) const
virtual ~MSDriveWay()
Destructor.
bool match(MSRouteIterator firstIt, MSRouteIterator endIt) const
whether the give route matches this driveway
static void appendMapIndex(LaneVisitedMap &map, const MSLane *lane)
append to map by map index and avoid undefined behavior
bool overlap(const MSDriveWay &other) const
Wether this driveway (route) overlaps with the given one.
std::vector< const MSLane * > myFlank
static std::string getTLLinkID(const MSLink *link)
return logicID_linkIndex
std::vector< const MSEdge * > myRoute
list of edges for matching against train routes
std::map< const MSLane *, int, ComparatorNumericalIdLess > LaneVisitedMap
static void writeDepatureBlocks(OutputDevice &od, bool writeVehicles)
static std::map< ConstMSEdgeVector, MSDriveWay * > myDriveWayRouteLookup
lookup table for state loading
int getNumericalID() const
static std::set< const MSEdge * > myBlockLengthWarnings
static std::map< const MSEdge *, std::vector< MSDriveWay * > > myReversalDriveWays
all driveways reversing on the given switch (used to look up flank foes)
void _saveState(OutputDevice &out) const
static std::string formatVisitedMap(const LaneVisitedMap &visited)
print link descriptions
void checkFlanks(const MSLink *originLink, const std::vector< const MSLane * > &lanes, const LaneVisitedMap &visited, bool allFoes, bool movingBlock, std::set< MSLink *, MSLink::ComparatorNumericalLaneIdLess > &flankSwitches) const
static std::map< std::string, MSDriveWay * > myDriveWayLookup
int matchesPastRoute(SUMOVehicle &sveh) const
void checkCrossingFlanks(MSLink *dwLink, const LaneVisitedMap &visited, std::set< MSLink *, MSLink::ComparatorNumericalLaneIdLess > &flankSwitches) const
bool flankConflict(const MSDriveWay &other) const
Wether there is a flank conflict with the given driveway.
bool conflictLaneOccupied(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)
void addSwitchFoes(MSLink *link)
bool hasTrain(SUMOVehicle *veh) const
whether the given train is on this driveway
static std::map< const MSEdge *, std::vector< MSDriveWay * > > myDepartureDrivewaysEnds
all driveways that do not start at a rail signal (and are only used at departure) by end edge
int myCoreSize
number of edges in myRoute where overlap with other driveways is forbidden
double getForwardDistance(int lastIndex) const
compute distance along the forward section up to lastIndex
std::pair< const SUMOVehicle *const, const MSLink::ApproachingVehicleInformation > Approaching
void addConflictLink(const MSLink *link)
add symmetical conflict link for foes when building a new driveway
bool notifyLeaveBack(SUMOTrafficObject &veh, Notification reason, const MSLane *leftLane)
Called if the vehicle's back leaves the reminder's lane.
std::string myFirstVehicle
the first vehicle using this driveway
bool forwardEndOnRoute(const MSDriveWay *foe) const
static void saveState(OutputDevice &out)
Save driveway occupancy into the given stream.
MSDriveWay * myParent
set to parent driveway if this is a subDriveway, nullptr otherwise
static std::map< const MSEdge *, std::vector< MSDriveWay * >, ComparatorNumericalIdLess > myDepartureDriveways
all driveways that do not start at a rail signal (and are only used at departure)
void setVehicle(const std::string &vehID)
bool myBidiEnded
whether driveway building was aborted when no further bidi edge was found
static bool mustYield(const Approaching &veh, const Approaching &foe)
Whether veh must yield to the foe train.
void addSidings(MSDriveWay *foe, bool addToFoe=false)
add sidings for the given foe
void enterDriveWay(SUMOVehicle &sveh, Notification reason)
helper method for notifyEnter
bool bidiBlockedByEnd(const MSDriveWay &other) const
Wether there is a bidi conflict with the end of the given driveway.
static int myGlobalDriveWayIndex
bool isSubDriveWay() const
static MSDriveWay * buildDriveWay(const std::string &id, const MSLink *link, MSRouteIterator first, MSRouteIterator end)
construct a new driveway by searching along the given route until all block structures are found
bool myFoundSignal
whether this driveway ends its forward section with a rail signal (and thus comprises a full block)
static std::map< const MSLink *, std::vector< MSDriveWay * > > mySwitchDriveWays
all driveways passing the given switch (used to look up flank foes)
void addReversalFoes(bool movingBlock)
derive foe driveways that enter the bidi section by reversing
int myForwardEdgeCount
number of normal edges in myForward
void addDWDeadlock(const std::vector< const MSDriveWay * > &deadlockFoes)
static std::map< const MSEdge *, std::vector< MSDriveWay * >, ComparatorNumericalIdLess > myEndingDriveways
all driveways that end on the given edge
bool foeDriveWayApproached() const
whether any of my Foes is being approached
static void loadState(const SUMOSAXAttributes &attrs, int tag)
bool forwardRouteConflict(std::set< const MSEdge * > forward, const MSDriveWay &other, bool secondCheck=false)
Wether the route of other passes into the forward section of this driveway.
std::vector< const MSLane * > myConflictLanes
the lanes that must be clear of trains before this signal can switch to green
static const MSDriveWay * getDepartureDriveway(const SUMOVehicle *veh, bool init=false)
std::vector< MSDriveWay * > myFoes
std::vector< VehicleEvent > myVehicleEvents
static bool isSwitch(const MSLink *link)
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering the lane.
bool bidiBlockedBy(const MSDriveWay &other) const
Wether there is a bidi conflict with the given driveway.
bool reserve(const Approaching &closest, MSEdgeVector &occupied)
attempt reserve this driveway for the given vehicle
std::pair< bool, const MSDriveWay * > canUseSiding(const SUMOVehicle *ego, const MSDriveWay *foe, const MSEdge *recurseSidingEnd=nullptr) const
return whether a siding can be used. If a siding exist but is occupied, also return the occupied driv...
void addParallelFoes(const MSLink *link, const MSEdge *first)
derive foe driveways that start at the same signal
bool foeDriveWayOccupied(bool store, const SUMOVehicle *ego, MSEdgeVector &occupied) const
whether any of myFoes is occupied (vehicles that are the target of a join must be ignored)
A road/street connecting two junctions.
static void clear()
Clears the dictionary.
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
const MSEdge * getNormalSuccessor() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
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
bool isConnectedTo(const MSEdge &destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions=false) const
static MELoop * gMesoNet
mesoscopic simulation infrastructure
static SUMOTime gTimeToTeleportRSDeadlock
static double gMaxRailSignalBlockLength
The maximum length of a rail signal block.
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.
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
virtual void addMoveReminder(MSMoveReminder *rem, bool addToVehicles=true)
Add a move-reminder to move-reminder container.
const MSJunction * getToJunction() const
double getLength() const
Returns the lane's length.
const MSJunction * getFromJunction() const
int getIndex() const
Returns the lane's index.
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
MSEdge & getEdge() const
Returns the lane's edge.
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
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)
bool isTurnaround() const
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
const std::vector< MSLink * > & getFoeLinks() const
std::string getDescription() const
get string description for this link
std::pair< const SUMOVehicle *const, const ApproachingVehicleInformation > getClosest() const
get the closest vehicle approaching this link
const MSLink * getCorrespondingEntryLink() const
returns the corresponding entry link for exitLinks to a junction.
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.
Something on a lane to be noticed about vehicle movement.
const std::string & getDescription() const
Notification
Definition of a vehicle state.
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
@ NOTIFICATION_REROUTE
The vehicle changed it's route.
@ NOTIFICATION_SEGMENT
The vehicle changes the segment (meso only)
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
@ NOTIFICATION_PARKING
The vehicle starts or ends parking.
static StringBijection< Notification > Notifications
MSLane * myLane
Lane on which the reminder works.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
void notifyApproach(const MSLink *link)
switch rail signal to active
void addWaitRelation(const SUMOVehicle *waits, const MSRailSignal *rs, const SUMOVehicle *reason, MSRailSignalConstraint *constraint=nullptr)
static MSRailSignalControl & getInstance()
static bool isUsingDriveWays(SVCPermissions svc)
static bool isMovingBlock(SVCPermissions svc)
bool isMovingBlock() const
const MSDriveWay & retrieveDriveWayForVeh(int tlIndex, const SUMOVehicle *veh)
static std::string describeLinks(std::vector< MSLink * > links)
print link descriptions
bool constraintsAllow(const SUMOVehicle *veh, bool storeWaitRelation=false) const
whether the given vehicle is free to drive
static VehicleVector & rivalVehicles()
static bool storeVehicles()
const std::vector< MSDriveWay * > retrieveDriveWays(int tlIndex) const
static VehicleVector & priorityVehicles()
static std::vector< const MSDriveWay * > & blockingDriveWays()
static VehicleVector & blockingVehicles()
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.
The parent class for traffic light logics.
The class responsible for building and deletion of vehicles.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Representation of a vehicle in the micro simulation.
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
Base class for objects which have an id.
std::string myID
The name of the object.
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 isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
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 ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
Representation of a vehicle, person, or container.
virtual bool isVehicle() const
Whether it is a vehicle.
virtual const MSEdge * getCurrentEdge() const =0
Returns the edge (normal or internal) the object is currently at.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const MSLane * getBackLane() const =0
Returns the lane the where the rear of the object is currently at.
virtual SUMOTime getWaitingTime(const bool accumulated=false) const =0
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual int getRoutePosition() const =0
return index of edge within route
virtual const MSEdge * getEdge() const =0
Returns the (normal) route edge the object is currently at.
Representation of a vehicle.
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop and waiting for a person or container to continue.
virtual int getDepartEdge() const =0
Returns the edge on which this vehicle shall depart.
virtual const std::list< MSStop > & getStops() const =0
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual double getLength() const =0
Returns the vehicles's length.
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
virtual double getBrakeGap(bool delayed=false) const =0
get distance for coming to a stop (used for rerouting checks)
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual const SUMOVehicleParameter::Stop * getNextStopParameter() const =0
Returns parameters of the next stop or nullptr.
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
const std::string & getString(const T key) const
get string
std::vector< std::string > getVector()
return vector of strings
#define UNUSED_PARAMETER(x)
Function-object for stable sorting of objects with numerical ids.