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),
103 myIsSubDriveway(false)
137 dw->myTrains.clear();
145#ifdef DEBUG_MOVEREMINDER
176#ifdef DEBUG_MOVEREMINDER
189 const MSLane* leftLane = (*(
dynamic_cast<SUMOVehicle&
>(veh).getCurrentRouteEdge()))->getLanes().front();
202#ifdef DEBUG_MOVEREMINDER
223#ifdef DEBUG_MOVEREMINDER
269 if (foe->myOrigin !=
nullptr) {
285#ifdef DEBUG_SIGNALSTATE
287 std::cout <<
getID() <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
300#ifdef DEBUG_SIGNALSTATE_PRIORITY
307#ifdef DEBUG_SIGNALSTATE_PRIORITY
309 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
312 if (foe.first == veh.first) {
316 assert(foeTLL !=
nullptr);
319 if (foeRS !=
nullptr) {
327#ifdef DEBUG_SIGNALSTATE_PRIORITY
330 std::cout <<
" foe blocked\n";
332 std::cout <<
" foe constrained\n";
333 }
else if (!
overlap(foeDriveWay)) {
334 std::cout <<
" no overlap with foeDW=" << foeDriveWay.
getID() <<
"\n";
336 std::cout <<
" foeDW=" << foeDriveWay.
getID() <<
" is not a foe to " <<
getID() <<
"\n";
337 }
else if (
canUseSiding(veh.first, &foeDriveWay).first) {
338 std::cout <<
" use siding\n";
344#ifdef DEBUG_SIGNALSTATE_PRIORITY
347 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
348 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
349 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
350 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
351 <<
" aW=" << veh.first->getWaitingTime() <<
" foeW=" << foe.first->getWaitingTime()
352 <<
" aN=" << veh.first->getNumericalID() <<
" foeN=" << foe.first->getNumericalID()
386 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
387 if (foe.second.arrivalTime == veh.second.arrivalTime) {
388 if (foe.first->getSpeed() == veh.first->getSpeed()) {
389 if (foe.second.dist == veh.second.dist) {
390 if (foe.first->getWaitingTime() == veh.first->getWaitingTime()) {
391 return foe.first->getNumericalID() < veh.first->getNumericalID();
393 return foe.first->getWaitingTime() > veh.first->getWaitingTime();
396 return foe.second.dist < veh.second.dist;
399 return foe.first->getSpeed() > veh.first->getSpeed();
402 return foe.second.arrivalTime < veh.second.arrivalTime;
405 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
413 if (!lane->isEmpty()) {
414 std::string joinVehicle =
"";
417 if (stop !=
nullptr) {
418 joinVehicle = stop->
join;
421#ifdef DEBUG_SIGNALSTATE
423 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied ego=" <<
Named::getIDSecure(ego) <<
" vehNumber=" << lane->getVehicleNumber() <<
"\n";
424 if (joinVehicle !=
"") {
425 std::cout <<
" joinVehicle=" << joinVehicle <<
" occupant=" <<
toString(lane->getVehiclesSecure()) <<
"\n";
426 lane->releaseVehicles();
430 if (lane->getVehicleNumberWithPartials() == 1) {
431 MSVehicle* foe = lane->getLastAnyVehicle();
432 if (joinVehicle !=
"") {
434#ifdef DEBUG_SIGNALSTATE
436 std::cout <<
" ignore join-target '" << joinVehicle <<
"\n";
442 if (ego !=
nullptr) {
444#ifdef DEBUG_SIGNALSTATE
446 std::cout <<
" ignore ego as oncoming '" << ego->
getID() <<
"\n";
452#ifdef DEBUG_SIGNALSTATE
454 std::cout <<
" ignore " << foe->
getID() <<
" for which ego is join-target\n";
474 if (foeDW->myOrigin !=
nullptr && foeDW->myOrigin->getApproaching().size() > 0) {
475#ifdef DEBUG_SIGNALSTATE
477 std::cout <<
SIMTIME <<
" foeLink=" << foeDW->myOrigin->getDescription() <<
" approachedBy=" << foeDW->myOrigin->getApproaching().begin()->first->getID() <<
"\n";
490 if (!foeDW->myTrains.empty()) {
491#ifdef DEBUG_SIGNALSTATE
496 if (foeDW->myTrains.size() == 1) {
499#ifdef DEBUG_SIGNALSTATE
510 std::pair<bool, const MSDriveWay*> useSiding =
canUseSiding(ego, foeDW);
511#ifdef DEBUG_SIGNALSTATE
516 numSidings = it->second.size();
518 std::cout <<
" useSiding=" << useSiding.first <<
" sidingFoe=" <<
Named::getIDSecure(useSiding.second) <<
" numSidings=" << numSidings <<
"\n";
521 if (useSiding.first) {
531 occupied.push_back(
const_cast<MSEdge*
>(foe->getEdge()));
532 MSEdge* bidi =
const_cast<MSEdge*
>(foe->getEdge()->getBidiEdge());
533 if (bidi !=
nullptr) {
534 occupied.push_back(bidi);
541 SUMOVehicle* foe = *(useSiding.second ==
nullptr ? foeDW : useSiding.second)->
myTrains.begin();
547 }
else if (foeDW !=
this &&
isDepartDriveway() && !foeDW->isDepartDriveway()) {
548 if (foeDW->myOrigin->getApproaching().size() > 0) {
554 if (foeDW->match(firstIt, foe->
getRoute().
end())) {
556#ifdef DEBUG_SIGNALSTATE
558 std::cout <<
SIMTIME <<
" " <<
getID() <<
" blocked by " << foeDW->getID() <<
" (approached by " << foe->
getID() <<
") useSiding=" << useSiding <<
"\n";
573 for (
const std::set<const MSDriveWay*>& dlFoes :
myDeadlocks) {
574 bool allOccupied =
true;
576 if (dlFoe->myTrains.empty()) {
583#ifdef DEBUG_SIGNALSTATE
601 std::string joinVehicle =
"";
603 if (stop !=
nullptr) {
604 joinVehicle = stop->
join;
610 joinVehicle = it->pars.join;
612 if (joinVehicle !=
"") {
613#ifdef DEBUG_SIGNALSTATE
615 std::cout <<
" joinVehicle=" << joinVehicle <<
"\n";
619#ifdef DEBUG_SIGNALSTATE
621 std::cout <<
" ignore join-target '" << joinVehicle <<
"\n";
629#ifdef DEBUG_SIGNALSTATE
631 std::cout <<
" ignore " << foe->
getID() <<
" for which ego is join-target\n";
641std::pair<bool, const MSDriveWay*>
645 for (
auto siding : it->second) {
647 if (ego ==
nullptr || siding.length >= ego->
getLength()) {
651 if (!sidingApproach->myTrains.empty()) {
660 if (foeVeh ==
nullptr) {
670#ifdef DEBUG_SIGNALSTATE
674 <<
" sidingEnd=" << sidingEnd->
getID() <<
" sidingApproach=" << sidingApproach->getID() <<
" approaching=" <<
toString(sidingApproach->myTrains) <<
"\n";
677 return std::make_pair(
false, sidingApproach);
683 return std::make_pair(
true,
nullptr);
687 return std::make_pair(
false,
nullptr);
741 if (lane->isNormal() && lane2->isNormal() && lane->getEdge().getToJunction() == lane2->getEdge().getToJunction()) {
809 if (edge2 ==
myForward.front()->getNextNormal() && !secondCheck) {
813 if (forward.count(edge2->getBidiEdge()) != 0) {
847 std::vector<std::string> signals;
854 std::vector<std::string> foes;
856 foes.push_back(dw->myID);
858 if (foes.size() > 0) {
865 od.
writeAttr(
"foe", item.first->getID());
866 for (
auto siding : item.second) {
884 sub->writeBlocks(od);
886#ifdef DRIVEWAY_SANITY_CHECK
887 std::set<MSDriveWay*> uFoes(
myFoes.begin(),
myFoes.end());
888 if (uFoes.size() !=
myFoes.size()) {
901 od.
openTag(ve.isEntry ?
"entry" :
"exit");
910 sub->writeBlockVehicles(od);
919 std::set<MSLink*>& flankSwitches) {
921 bool seekForwardSignal =
true;
922 bool seekBidiSwitch =
true;
923 bool foundUnsafeSwitch =
false;
925 const std::string warnID = origin ?
"rail signal " +
getClickableTLLinkID(origin) :
"insertion lane '" + toLane->
getID() +
"'";
926#ifdef DEBUG_DRIVEWAY_BUILDROUTE
938 WRITE_WARNINGF(
"Block after % exceeds maximum length (stopped searching after edge '%' (length=%m).",
944#ifdef DEBUG_DRIVEWAY_BUILDROUTE
946 std::cout <<
" abort: length=" << length <<
"\n";
951#ifdef DEBUG_DRIVEWAY_BUILDROUTE
966 if (seekForwardSignal) {
967 if (!foundUnsafeSwitch) {
982 }
else if (bidi ==
nullptr) {
984#ifdef DEBUG_DRIVEWAY_BUILDROUTE
986 std::cout <<
" continue bidiSearch beyond turnaround\n";
990 seekBidiSwitch =
false;
991#ifdef DEBUG_DRIVEWAY_BUILDROUTE
993 std::cout <<
" noBidi, abort search for bidiSwitch\n";
998 if (bidi !=
nullptr) {
999 if (!seekForwardSignal && !foundUnsafeSwitch && bidi->
isNormal()) {
1005 if (!
myBidi.empty() && link->getViaLaneOrLane() !=
myBidi.back()) {
1008#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1010 std::cout <<
" found unsafe switch " << link->
getDescription() <<
" (used=" << (used ==
nullptr ?
"NULL" : used->
getDescription()) <<
")\n";
1014 foundUnsafeSwitch =
true;
1016 if (used !=
nullptr) {
1018 flankSwitches.insert(used);
1024 if (foundUnsafeSwitch) {
1030 const std::vector<MSLink*>& links = toLane->
getLinkCont();
1032 for (
const MSLink*
const link : links) {
1033 if ((next != end && &link->getLane()->getEdge() == *next)
1035 toLane = link->getViaLaneOrLane();
1037 if (link == origin) {
1038 if (seekForwardSignal) {
1043#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1045 std::cout <<
" abort: found circle\n";
1050 seekForwardSignal =
false;
1052 seekBidiSwitch = bidi !=
nullptr;
1053#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1055 std::cout <<
" found forwardSignal " << link->getTLLogic()->
getID() <<
" seekBidiSwitch=" << seekBidiSwitch <<
"\n";
1065 if (link->getLane()->getBidiLane() !=
nullptr && &link->getLane()->getEdge() == current->
getBidiEdge()) {
1073 if (toLane ==
nullptr) {
1076 toLane = (*next)->getLanes()[0];
1077#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1079 std::cout <<
" abort: turn-around or jump\n";
1085#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1087 std::cout <<
" abort: no next lane available\n";
1096#ifdef DEBUG_DRIVEWAY_BUILDROUTE
1098 std::cout <<
" normalEnd myBidiEnded=" <<
myBidiEnded <<
"\n";
1107 if (other->getLane() != link->
getLane() && !other->isTurnaround()) {
1112 if (ili.viaLink != link && !ili.viaLink->
isTurnaround()) {
1117 if (bidi !=
nullptr) {
1130#ifdef DEBUG_CHECK_FLANKS
1131 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
" allFoes=" << allFoes <<
"\n";
1137 if (reverseOriginLink !=
nullptr) {
1141 for (
int i = 0; i < (int)lanes.size(); i++) {
1142 const MSLane* lane = lanes[i];
1143 const MSLane* prev = i > 0 ? lanes[i - 1] :
nullptr;
1144 const MSLane* next = i + 1 < (int)lanes.size() ? lanes[i + 1] :
nullptr;
1149 if (ili.viaLink == originLink
1150 || ili.viaLink == reverseOriginLink
1153 || (originLink ==
nullptr && i == 0 && movingBlock)) {
1156 if (ili.lane != prev && ili.lane != next) {
1157#ifdef DEBUG_CHECK_FLANKS
1158 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";
1160 flankSwitches.insert(ili.viaLink);
1161 }
else if (allFoes) {
1172#ifdef DEBUG_CHECK_FLANKS
1176 if (junction ==
nullptr) {
1180 if (logic ==
nullptr) {
1184 if (in->isInternal()) {
1187 for (
MSLane* inLane : in->getLanes()) {
1189 if (
isRailwayOrShared(inLane->getPermissions()) && visited.count(inLane) == 0 && (inBidi ==
nullptr || visited.count(inBidi) == 0)) {
1190 for (
MSLink* link : inLane->getLinkCont()) {
1191 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
1192 && visited.count(link->getLane()) == 0) {
1193#ifdef DEBUG_CHECK_FLANKS
1194 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
1196 if (link->getViaLane() ==
nullptr) {
1197 flankSwitches.insert(link);
1199 flankSwitches.insert(link->getViaLane()->getLinkCont().front());
1210#ifdef DEBUG_CHECK_FLANKS
1216#ifdef DEBUG_CHECK_FLANKS
1217 std::cout <<
" flank guarded by " << entry->
getTLLogic()->
getID() <<
"\n";
1225 std::vector<MSLink*> predLinks;
1227 if (!ili.viaLink->isTurnaround()) {
1228 predLinks.push_back(ili.viaLink);
1231 if (predLinks.size() > 1) {
1233#ifdef DEBUG_ADD_FOES
1234 std::cout <<
" predecessors of " << link->
getDescription() <<
" isSwitch\n";
1236 for (
MSLink* pred : predLinks) {
1239 }
else if (predLinks.size() == 1) {
1251#ifdef DEBUG_ADD_FOES
1252 std::cout <<
" foe " << foe->getID() <<
" departs on flank=" << lane->
getID() <<
"\n";
1256#ifdef DEBUG_ADD_FOES
1257 std::cout <<
" cand foe " << foe->getID() <<
" departs on flank=" << lane->
getID() <<
" rejected\n";
1270#ifdef DEBUG_ADD_FOES
1271 std::cout <<
" driveway " <<
myID <<
" addSwitchFoes for link " << link->
getDescription() <<
"\n";
1275#ifdef DEBUG_ADD_FOES
1276 std::cout <<
" foe=" << foe->myID
1277 <<
" fc1=" <<
flankConflict(*foe) <<
" fc2=" << foe->flankConflict(*
this)
1278 <<
" cc1=" <<
crossingConflict(*foe) <<
" cc2=" << foe->crossingConflict(*
this) <<
"\n";
1282#ifdef DEBUG_ADD_FOES
1283 std::cout <<
" cand=" << foe->myID <<
"\n";
1317 std::vector<const MSLane*> before;
1318 MSLane* fromBidi =
nullptr;
1319 if (link !=
nullptr) {
1323 std::set<MSLink*> flankSwitches;
1325 if (fromBidi !=
nullptr) {
1326 before.push_back(fromBidi);
1328 dw->
buildRoute(link, first, end, visited, flankSwitches);
1332 const bool movingBlock = (rs && rs->
isMovingBlock()) || (!rs &&
1338 dw->
checkFlanks(link, before, visited,
true, movingBlock, flankSwitches);
1339 for (
MSLink* fsLink : flankSwitches) {
1340#ifdef DEBUG_ADD_FOES
1342 std::cout <<
" fsLink=" << fsLink->getDescription() <<
"\n";
1347 std::set<MSLink*> flankSwitchesBidiExtended;
1349 for (
MSLink*
const flink : flankSwitchesBidiExtended) {
1350#ifdef DEBUG_ADD_FOES
1352 std::cout <<
" fsLinkExtended=" << flink->getDescription() <<
"\n";
1357#ifdef DEBUG_BUILD_DRIVEWAY
1359 std::cout <<
SIMTIME <<
" buildDriveWay " << dw->
myID <<
" link=" << (link ==
nullptr ?
"NULL" : link->
getDescription())
1382 std::set<MSDriveWay*, ComparatorNumericalIdLess> uniqueFoes(dw->
myFoes.begin(), dw->
myFoes.end());
1385 if (movingBlock && uniqueFoes.count(dw) == 0) {
1386 std::set<const MSJunction*> forwardJunctions;
1388 if (fw->isNormal()) {
1389 const MSJunction* fwTo = fw->getEdge().getToJunction();
1390 if (forwardJunctions.count(fwTo) == 1) {
1391 dw->
myFoes.push_back(dw);
1392#ifdef DEBUG_ADD_FOES
1394 std::cout <<
" self-intersecting movingBlock for dw=" << dw->
getID() <<
"\n";
1399 forwardJunctions.insert(fwTo);
1406 const MSEdge* foeLastEdge = &foe->myForward.back()->getEdge();
1407 const bool sameLast = foeLastEdge == lastEdge;
1408 if (sameLast && !movingBlock) {
1409 dw->
myFoes.push_back(foe);
1411 foe->myFoes.push_back(dw);
1414 if (foe->bidiBlockedByEnd(*dw)) {
1415#ifdef DEBUG_ADD_FOES
1417 std::cout <<
" setting " << dw->
getID() <<
" as foe of " << foe->getID() <<
"\n";
1420 foe->myFoes.push_back(dw);
1421 foe->addSidings(dw);
1427#ifdef DEBUG_ADD_FOES
1429 std::cout <<
" addFoeCheckSiding " << foe->getID() <<
"\n";
1432 dw->
myFoes.push_back(foe);
1435 foe->buildSubFoe(dw, movingBlock);
1440 foe->addConflictLink(link);
1443 if (foe->myRoute.front()->getFromJunction() != dw->
myRoute.front()->getFromJunction()) {
1444 for (
auto ili : foe->myForward.front()->getIncomingLanes()) {
1445 if (ili.viaLink->getTLLogic() !=
nullptr) {
1447 const MSLane* origin = ili.viaLink->getLaneBefore();
1449 uniqueCLink.insert(ili.viaLink);
1461 if (uniqueFoes.count(sameEnd) == 0) {
1462 dw->
myFoes.push_back(sameEnd);
1463 if (sameEnd != dw) {
1464 sameEnd->myFoes.push_back(dw);
1469#ifdef DEBUG_BUILD_DRIVEWAY
1471 std::cout << dw->
myID <<
" mb=" << movingBlock <<
" finalFoes " <<
toString(dw->
myFoes) <<
"\n";
1516 const int tmp = (int)map.size();
1523 auto itRoute = firstIt;
1524 auto itDwRoute =
myRoute.begin();
1526 while (itRoute != endIt && itDwRoute !=
myRoute.end()) {
1527 if (*itRoute != *itDwRoute) {
1530 std::cout <<
" check dw=" <<
getID() <<
" match failed at vehEdge=" << (*itRoute)->getID() <<
" dwEdge=" << (*itDwRoute)->getID() <<
"\n";
1542 if (itRoute != endIt) {
1544 const MSEdge* next = *itRoute;
1549 std::cout <<
" check dw=" <<
getID() <<
" prev=" << prev->
getID() <<
" next=" << next->
getID() <<
"\n";
1569#ifdef DEBUG_ADD_FOES
1570 std::cout <<
"driveway " <<
myID <<
" addFoes for link " << link->
getDescription() <<
"\n";
1573 if (rs !=
nullptr) {
1575#ifdef DEBUG_ADD_FOES
1576 std::cout <<
" cand foe=" << foe->
myID <<
" fc1=" <<
flankConflict(*foe) <<
" fc2=" << foe->flankConflict(*
this) <<
" cc1=" <<
crossingConflict(*foe) <<
" cc2=" << foe->crossingConflict(*
this) <<
"\n";
1579#ifdef DEBUG_ADD_FOES
1580 std::cout <<
" foe=" << foe->myID <<
"\n";
1591#ifdef DEBUG_ADD_FOES
1592 std::cout <<
"driveway " <<
myID <<
" addBidiFoes extended=" << extended <<
"\n";
1595 for (
const MSLane* bidi : bidiLanes) {
1596 for (
auto ili : bidi->getIncomingLanes()) {
1598 if (rs !=
nullptr && rs != ownSignal &&
1599 std::find(bidiLanes.begin(), bidiLanes.end(), ili.lane) != bidiLanes.end()) {
1603 const MSEdge* bidiEdge = &bidi->getEdge();
1607#ifdef DEBUG_ADD_FOES
1608 std::cout <<
" foe " << foe->
getID() <<
" departs on bidi=" << bidiEdge->
getID() <<
"\n";
1612#ifdef DEBUG_ADD_FOES
1613 std::cout <<
" cand foe " << foe->getID() <<
" departs on bidi=" << bidiEdge->
getID() <<
" rejected\n";
1621#ifdef DEBUG_ADD_FOES
1622 std::cout <<
" foe " << foe->getID() <<
" ends on bidi=" << bidiEdge->
getID() <<
"\n";
1626#ifdef DEBUG_ADD_FOES
1627 std::cout <<
" cand foe " << foe->getID() <<
" ends on bidi=" << bidiEdge->
getID() <<
" rejected\n";
1638#ifdef DEBUG_ADD_FOES
1639 std::cout <<
"driveway " <<
myID <<
" addParallelFoes\n";
1647#ifdef DEBUG_ADD_FOES
1648 std::cout <<
" foe " << foe->getID() <<
" departs on first=" << first->
getID() <<
"\n";
1659#ifdef DEBUG_ADD_FOES
1660 std::cout <<
"driveway " <<
myID <<
" addReversalFoes\n";
1662 std::set<const MSEdge*> forward;
1664 if (lane->isNormal()) {
1665 forward.insert(&lane->getEdge());
1670 if (forward.count(e) != 0 && !movingBlock) {
1684#ifdef DEBUG_ADD_FOES
1688 std::set<const MSEdge*> foeForward;
1689 for (
const MSLane* lane : foe->myForward) {
1690 if (lane->isNormal()) {
1691 foeForward.insert(&lane->getEdge());
1692 if (lane->getBidiLane() !=
nullptr) {
1693 foeForward.insert(lane->getEdge().getBidiEdge());
1697#ifdef DEBUG_ADD_FOES
1698 std::cout <<
" reversal cand=" << foe->getID() <<
" foeForward " <<
toString(foeForward) <<
"\n";
1700 if (foe->forwardRouteConflict(foeForward, *
this,
true)) {
1701#ifdef DEBUG_ADD_FOES
1702 std::cout <<
" foe " << foe->getID() <<
" reverses on edge=" << e->getID() <<
"\n";
1706 }
else if (movingBlock && foe ==
this) {
1707#ifdef DEBUG_ADD_FOES
1708 std::cout <<
" dw " <<
getID() <<
" reverses on forward edge=" << e->getID() <<
" (movingBlock)\n";
1731#ifdef DEBUG_BUILD_SUBDRIVEWAY
1732 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" is subpart of foe=" << foe->
getID() <<
"\n";
1734 foe->
myFoes.push_back(
this);
1737 int subLast = (int)
myForward.size() - 2;
1741#ifdef DEBUG_BUILD_SUBDRIVEWAY
1743 std::cout <<
" " <<
getID() <<
" cannot build subDriveWay for foe " << foe->
getID() <<
" because myForward has only a single lane\n";
1746 bool foundConflict =
false;
1747 bool flankC =
false;
1748 bool zipperC =
false;
1749 bool crossC =
false;
1750 while (subLast >= 0) {
1756 const bool bidiConflict = std::find(foe->
myBidi.begin(), foe->
myBidi.end(), lane) != foe->
myBidi.end();
1758#ifdef DEBUG_BUILD_SUBDRIVEWAY
1759 std::cout <<
" subLast=" << subLast <<
" lane=" << lane->
getID() <<
" fc=" << flankC <<
" cc=" << crossC <<
" bc=" << bidiConflict <<
"\n";
1761 if (flankC || crossC || bidiConflict) {
1762 foundConflict =
true;
1763 if (!movingBlock || bidiConflict) {
1771 foundConflict =
false;
1772#ifdef DEBUG_BUILD_SUBDRIVEWAY
1773 std::cout <<
" ignored movingBlock zipperConflict\n";
1775 if (!flankC && crossC) {
1776#ifdef DEBUG_BUILD_SUBDRIVEWAY
1777 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" movingBlock-save\n";
1782 if (!flankC && crossC) {
1785 }
else if (foundConflict) {
1790#ifdef DEBUG_BUILD_SUBDRIVEWAY
1791 std::cout <<
" subLastFina=" << subLast <<
" movingBlock=" << movingBlock <<
" zipperC=" << zipperC <<
"\n";
1794 if (movingBlock && zipperC) {
1795#ifdef DEBUG_BUILD_SUBDRIVEWAY
1796 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" movingBlock-save\n";
1801 foe->
myFoes.push_back(
this);
1802#ifdef DEBUG_BUILD_SUBDRIVEWAY
1803 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" foe endsOnForward\n";
1807 foe->
myFoes.push_back(
this);
1811#ifdef DEBUG_BUILD_SUBDRIVEWAY
1812 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" terminates\n";
1815 foe->
myFoes.push_back(
this);
1816#ifdef DEBUG_BUILD_SUBDRIVEWAY
1817 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" terminates, foe=" << foe->
getID() <<
"\n";
1821#ifdef DEBUG_BUILD_SUBDRIVEWAY
1822 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" has " << foe->
myReversals.size() <<
" reversals\n";
1825#ifdef DEBUG_BUILD_SUBDRIVEWAY
1826 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" failed\n";
1828#ifdef SUBDRIVEWAY_WARN_NOCONFLICT
1829 WRITE_WARNINGF(
"No point of conflict found between driveway '%' and driveway '%' when creating sub-driveway",
getID(), foe->
getID());
1834 int subSize = subLast + 1;
1836 if ((
int)cand->myForward.size() == subSize) {
1838 foe->
myFoes.push_back(cand);
1839 cand->myFoes.push_back(foe);
1840#ifdef DEBUG_BUILD_SUBDRIVEWAY
1841 std::cout <<
SIMTIME <<
" buildSubFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" useExisting=" << cand->getID() <<
"\n";
1847 std::vector<const MSEdge*> route;
1848 for (
const MSLane* lane : forward) {
1849 if (lane->isNormal()) {
1850 route.push_back(&lane->getEdge());
1853 if (route.empty()) {
1854 if (subSize == 1 && crossC
1855 && forward.front()->getFromJunction() == foe->
myForward.front()->getFromJunction()
1857 assert(
myForward.front()->isInternal());
1859 route.push_back(foe->
myForward.front()->getEdge().getNormalSuccessor());
1861#ifdef DEBUG_BUILD_SUBDRIVEWAY
1862 std::cout <<
SIMTIME <<
" abort subFoe dw=" <<
getID() <<
" foe=" << foe->
getID() <<
" empty subRoute\n";
1867 if (
myRoute.size() > route.size()) {
1869 const MSEdge* lastNormal = route.back();
1872#ifdef DEBUG_BUILD_SUBDRIVEWAY
1873 std::cout <<
SIMTIME <<
" abort subFoe dw=" <<
getID() <<
" foe=" << foe->
getID()
1874 <<
" lastNormal=" << lastNormal->
getID() <<
" nextNormal=" << nextNormal->
getID() <<
" endWithReversal\n";
1889 auto itOnSub = std::find(sub->
myRoute.begin(), sub->
myRoute.end(), veh->getEdge());
1890 if (itOnSub != sub->
myRoute.end()) {
1893 const double pos = sub->
myRoute.front()->getLength();
1896 if (ve.id == veh->getID()) {
1903 foe->
myFoes.push_back(sub);
1904 sub->
myFoes.push_back(foe);
1906#ifdef DEBUG_BUILD_SUBDRIVEWAY
1915 assert(lastIndex < (
int)
myForward.size());
1917 for (
int i = 0; i <= lastIndex; i++) {
1926 const MSEdge* foeEndBidi = foe->
myForward.back()->getEdge().getBidiEdge();
1927 int forwardNormals = 0;
1929 if (lane->isNormal()) {
1933 if (forwardNormals == (
int)foe->
myRoute.size()) {
1934#ifdef DEBUG_BUILD_SIDINGS
1935 std::cout <<
"checkSiding " <<
getID() <<
" foe=" << foe->
getID() <<
" forwardNormals=" << forwardNormals <<
" frSize=" << foe->
myRoute.size() <<
" aborted\n";
1939 auto foeSearchBeg = foe->
myRoute.begin() + forwardNormals;
1940 auto foeSearchEnd = foe->
myRoute.end();
1941 if (foeEndBidi ==
nullptr) {
1945 std::vector<int> start;
1946 std::vector<double> length;
1947 for (i = 0; i < (int)
myRoute.size(); i++) {
1948 if (
myRoute[i] == foeEndBidi) {
1952 if (i == (
int)
myRoute.size()) {
1956#ifdef DEBUG_BUILD_SIDINGS
1957 std::cout <<
"checkSiding " <<
getID() <<
" foe=" << foe->
getID() <<
" i=" << i <<
" next=" << next->
getID() <<
" forwardNormals=" << forwardNormals <<
" frSize=" << foe->
myRoute.size() <<
" foeSearchBeg=" << (*foeSearchBeg)->getID() <<
"\n";
1960 for (; i >= 0; i--) {
1962 if (
hasRS(cur, next)) {
1963 if (std::find(foeSearchBeg, foeSearchEnd, cur->
getBidiEdge()) == foeSearchEnd) {
1965 length.push_back(0);
1968 if (!start.empty()) {
1969 auto itFind = std::find(foeSearchBeg, foeSearchEnd, cur->
getBidiEdge());
1970 if (itFind != foeSearchEnd) {
1971#ifdef DEBUG_BUILD_SIDINGS
1974 const int firstIndex = i + 1;
1976 auto& foeSidings = foe->
mySidings[
this];
1979 auto itFirst = std::find(foe->
myRoute.begin(), foe->
myRoute.end(), first);
1980 if (itFirst != foe->
myRoute.end()) {
1981 for (
int j = 0; j < (int)length.size(); j++) {
1983 auto itLast = std::find(itFirst, foe->
myRoute.end(), last);
1984 if (itLast != foe->
myRoute.end()) {
1985 foeSidings.insert(foeSidings.begin(),
Siding((
int)(itFirst - foe->
myRoute.begin()), (
int)(itLast - foe->
myRoute.begin()), length[j]));
1991 for (
int j = 0; j < (int)length.size(); j++) {
1992 foeSidings.insert(foeSidings.begin(),
Siding(firstIndex, start[j], length[j]));
1997 foeSearchBeg = itFind;
1999 for (
int j = 0; j < (int)length.size(); j++) {
2013 for (
auto lane : cur->
getLanes()) {
2014 for (
const MSLink* link : lane->getLinkCont()) {
2015 if (&link->getLane()->getEdge() == next && link->getTLLogic() !=
nullptr) {
2027 const MSEdge* foeForwardEnd = &foe->
myForward.back()->getNormalPredecessorLane()->getEdge();
2049 std::set<const MSDriveWay*> filtered;
2052 filtered.insert(foe);
2067 for (
auto ili : lane->getIncomingLanes()) {
2070 if (rs !=
nullptr) {
2072 if (&dw->
myForward.front()->getEdge() == edge) {
2081 if (dw->match(matchStart, veh->
getRoute().
end())) {
2097 const MSEdge* edge = item.first;
2098 if (item.second.size() > 0) {
2102 if (writeVehicles) {
2103 dw->writeBlockVehicles(od);
2105 dw->writeBlocks(od);
2118 dw->_saveState(out);
2120 sub->_saveState(out);
2133 std::vector<std::string> trainIDs;
2135 trainIDs.push_back(veh->getID());
2147 if (!sub->myTrains.empty()) {
2165 const std::string
id = attrs.
get<std::string>(
SUMO_ATTR_ID,
nullptr, ok);
2177 throw ProcessError(
TLF(
"Unknown driveWay '%' with route '%'",
id, edges));
2182 std::string parentID =
id.substr(0,
id.rfind(
'.'));
2187 throw ProcessError(
TLF(
"Unknown parent driveway '%' for subDriveWay '%'", parentID,
id));
2191 if (sub->myRoute == route) {
2196 if (dw ==
nullptr) {
2205 if (veh ==
nullptr) {
2206 throw ProcessError(
TLF(
"Unknown vehicle '%' in driveway '%'", vehID,
id));
2218 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
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
void checkCrossingFlanks(MSLink *dwLink, const LaneVisitedMap &visited, std::set< MSLink * > &flankSwitches) const
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.
void buildRoute(const MSLink *origin, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap &visited, std::set< MSLink * > &)
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
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
static std::map< std::string, MSDriveWay * > myDriveWayLookup
int matchesPastRoute(SUMOVehicle &sveh) 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
void checkFlanks(const MSLink *originLink, const std::vector< const MSLane * > &lanes, const LaneVisitedMap &visited, bool allFoes, bool movingBlock, std::set< MSLink * > &flankSwitches) const
static void saveState(OutputDevice &out)
Save driveway occupancy into the given stream.
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
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)
bool isFoeOrSubFoe(const MSDriveWay *foe) const
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::pair< bool, const MSDriveWay * > canUseSiding(const SUMOVehicle *ego, const MSDriveWay *foe, bool recurse=true) const
return whether a siding can be used. If a siding exist but is occupied, also return the occupied driv...
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
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.
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 * 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
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 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 & 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.
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 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 int getRoutePosition() const =0
return index of edge within route
virtual const MSEdge * getEdge() const =0
Returns the 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.