56 #define MAX_BLOCK_LENGTH 20000
57 #define MAX_SIGNAL_WARNINGS 10
64 #define DEBUG_SIGNALSTATE
65 #define DEBUG_SIGNALSTATE_PRIORITY
66 #define DEBUG_FIND_PROTECTION
70 #define DEBUG_COND DEBUG_HELPER(this)
71 #define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
72 #define DEBUG_HELPER(obj) ((obj)->isSelected())
95 const std::string&
id,
const std::string& programID,
SUMOTime delay,
96 const std::map<std::string, std::string>& parameters) :
109 if (links.size() != 1) {
111 +
" links controlled by index " +
toString(links[0]->getTLIndex()));
150 #ifdef DEBUG_SIGNALSTATE
154 std::string state(
myLinks.size(),
'G');
156 if (li.myLink->getApproaching().size() > 0) {
158 DriveWay& driveway = li.getDriveWay(closest.first);
163 if (mustWait || !driveway.
reserve(closest, occupied)) {
164 state[li.myLink->getTLIndex()] =
'r';
165 if (occupied.size() > 0) {
166 li.reroute(
const_cast<SUMOVehicle*
>(closest.first), occupied);
168 #ifdef DEBUG_SIGNALSTATE
170 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" notReserved\n";
174 state[li.myLink->getTLIndex()] =
'G';
179 #ifdef DEBUG_SIGNALSTATE
181 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" reserved\n";
186 DriveWay& driveway = li.myDriveways.front();
188 #ifdef DEBUG_SIGNALSTATE
193 state[li.myLink->getTLIndex()] =
'r';
195 #ifdef DEBUG_SIGNALSTATE
197 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" green for default driveway (" <<
toString(driveway.
myRoute) <<
")\n";
207 #ifdef DEBUG_SIGNALSTATE
223 #ifdef DEBUG_SIGNALSTATE
225 std::cout <<
" constraint '" << c->
getDescription() <<
"' not cleared\n";
320 for (
MSLink* link : links) {
321 result += link->getDescription() +
" ";
328 std::vector<const MSLane*> lanes(visited.size(),
nullptr);
329 for (
auto item : visited) {
330 lanes[item.second] = item.first;
338 double minDist = std::numeric_limits<double>::max();
341 if (apprIt->second.dist < minDist) {
342 minDist = apprIt->second.
dist;
372 for (
const DriveWay& dw : li.myDriveways) {
385 if (bidi ==
nullptr) {
395 #ifdef DEBUG_SIGNALSTATE
397 std::cout <<
" oncoming vehicle on bidi-lane " << lane->
getID() <<
"\n";
407 #ifdef DEBUG_SIGNALSTATE
409 std::cout <<
" oncoming vehicle on flank-lane " << lane->
getID() <<
"\n";
420 if (veh->
getSpeed() > 0 && closest.second.arrivalSpeedBraking > 0
422 #ifdef DEBUG_SIGNALSTATE
424 std::cout <<
" oncoming vehicle approaching foe link " << foeLink->
getDescription() <<
"\n";
447 #ifdef DEBUG_SIGNALSTATE
449 std::cout <<
SIMTIME <<
" rsl=" << rs->
getID() <<
" insertion constraint '" << c->
getDescription() <<
"' for vehicle '" << veh->
getID() <<
"' not cleared\n";
466 myLink(link), myUniqueDriveWay(false),
467 myLastRerouteTime(-1),
468 myLastRerouteVehicle(nullptr) {
478 return myLink->getTLLogic()->getID() +
"_" +
toString(myLink->getTLIndex());
484 if (myUniqueDriveWay) {
485 return myDriveways.front();
487 MSEdge* first = &myLink->getLane()->getEdge();
496 while (lookBack > 0 && routeIndex > 0) {
498 if (prevEdge == first) {
509 return myDriveways.front();
514 auto itRoute = firstIt;
515 auto itDwRoute = dw.myRoute.begin();
517 while (itRoute != veh->
getRoute().
end() && itDwRoute != dw.myRoute.end()) {
518 if (*itRoute != *itDwRoute) {
532 myDriveways.push_back(dw);
533 return myDriveways.back();
564 std::vector<MSLane*> before;
565 visited[myLink->getLaneBefore()] = (int)visited.size();
567 if (fromBidi !=
nullptr) {
569 visited[fromBidi] = (int)visited.size();
570 before.push_back(fromBidi);
572 dw.
buildRoute(myLink, 0., first, end, visited);
585 #ifdef DEBUG_BUILD_DRIVEWAY
587 std::cout <<
" buildDriveWay railSignal=" <<
getID()
617 && (myLastRerouteVehicle != veh
621 myLastRerouteVehicle = veh;
622 myLastRerouteTime = now;
627 std::cout <<
SIMTIME <<
" reroute veh=" << veh->
getID() <<
" rs=" <<
getID() <<
" occupied=" <<
toString(occupied) <<
"\n";
635 std::cout <<
" rerouting successful\n";
649 std::string joinVehicle =
"";
652 if (stop !=
nullptr) {
653 joinVehicle = stop->
join;
656 if (conflictLaneOccupied(joinVehicle)) {
657 for (
MSLane* bidi : myBidi) {
658 if (!bidi->empty() && bidi->getBidiLane() !=
nullptr) {
659 occupied.push_back(&bidi->getBidiLane()->getEdge());
662 #ifdef DEBUG_SIGNALSTATE
664 std::cout <<
" conflictLaneOccupied\n";
669 for (
MSLink* link : myProtectingSwitches) {
670 if (!findProtection(closest, link)) {
671 #ifdef DEBUG_SIGNALSTATE
673 std::cout <<
" no protection at switch " << link->getDescription() <<
"\n";
679 for (
MSLink* foeLink : myConflictLinks) {
680 if (hasLinkConflict(closest, foeLink)) {
681 #ifdef DEBUG_SIGNALSTATE
683 std::cout <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
689 if (deadlockLaneOccupied()) {
692 myActive = closest.first;
699 for (
MSLink* foeLink : myConflictLinks) {
700 if (foeLink->getApproaching().size() > 0) {
710 #ifdef DEBUG_SIGNALSTATE_PRIORITY
712 std::cout <<
" checkLinkConflict foeLink=" <<
getTLLinkID(foeLink) <<
"\n";
717 #ifdef DEBUG_SIGNALSTATE_PRIORITY
719 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
723 assert(foeTLL !=
nullptr);
726 if (foeRS !=
nullptr) {
731 !overlap(foeDriveWay)) {
732 #ifdef DEBUG_SIGNALSTATE_PRIORITY
735 std::cout <<
" foe blocked\n";
737 std::cout <<
" foe constrained\n";
739 std::cout <<
" no overlap\n";
745 #ifdef DEBUG_SIGNALSTATE_PRIORITY
748 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
749 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
750 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
751 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
752 <<
" aW=" << veh.first->getWaitingTime() <<
" foeW=" << foe.first->getWaitingTime()
753 <<
" aN=" << veh.first->getNumericalID() <<
" foeN=" << foe.first->getNumericalID()
757 const bool yield = mustYield(veh, foe);
773 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
774 if (foe.second.arrivalTime == veh.second.arrivalTime) {
775 if (foe.first->getSpeed() == veh.first->getSpeed()) {
776 if (foe.second.dist == veh.second.dist) {
777 if (foe.first->getWaitingTime() == veh.first->getWaitingTime()) {
778 return foe.first->getNumericalID() < veh.first->getNumericalID();
780 return foe.first->getWaitingTime() > veh.first->getWaitingTime();
783 return foe.second.dist < veh.second.dist;
786 return foe.first->getSpeed() > veh.first->getSpeed();
789 return foe.second.arrivalTime < veh.second.arrivalTime;
792 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
799 for (
const MSLane* lane : myConflictLanes) {
800 if (!lane->isEmpty()) {
801 #ifdef DEBUG_SIGNALSTATE
803 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied\n";
804 if (joinVehicle !=
"") {
805 std::cout <<
" joinVehicle=" << joinVehicle <<
" occupant=" <<
toString(lane->getVehiclesSecure()) <<
"\n";
806 lane->releaseVehicles();
810 if (lane->getVehicleNumber() == 1 && joinVehicle !=
"") {
811 std::vector<MSVehicle*> vehs = lane->getVehiclesSecure();
812 const bool ignoreJoinTarget = vehs.front()->getID() == joinVehicle && vehs.front()->isStopped();
813 lane->releaseVehicles();
814 if (ignoreJoinTarget) {
815 #ifdef DEBUG_SIGNALSTATE
817 std::cout <<
" ignore join-target '" << joinVehicle <<
";\n";
834 for (
MSLane* lane : myBidiExtended) {
835 if (!lane->empty()) {
836 assert(myBidi.size() != 0);
837 const MSEdge* lastBidi = myBidi.back()->getNextNormal();
838 MSVehicle* foe = lane->getVehiclesSecure().front();
839 #ifdef DEBUG_SIGNALSTATE
841 std::cout <<
" check for deadlock with " << foe->
getID() <<
"\n";
846 const int minEdges = (int)myBidiExtended.size();
849 bool conflict =
false;
850 for (
int i = 0; i < minEdges && foeIt != foeEnd; i++) {
851 if ((*foeIt) == lastBidi) {
852 #ifdef DEBUG_SIGNALSTATE
854 std::cout <<
" vehicle will enter " << lastBidi->
getID() <<
"\n";
862 lane->releaseVehicles();
877 double flankApproachingDist = std::numeric_limits<double>::max();
880 flankApproachingDist = closest.second.dist;
882 #ifdef DEBUG_FIND_PROTECTION
884 std::cout <<
SIMTIME <<
" findProtection for link=" << link->
getDescription() <<
" flankApproachingDist=" << flankApproachingDist <<
"\n";
888 if (l2->getLane() != link->
getLane()) {
889 #ifdef DEBUG_FIND_PROTECTION
891 std::cout <<
" protectionCandidate=" << l2->getDescription() <<
" l2Via=" <<
Named::getIDSecure(l2->getViaLane())
892 <<
" occupied=" << (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) <<
"\n";
895 if (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) {
896 #ifdef DEBUG_FIND_PROTECTION
898 std::cout <<
" protection from internal=" << l2->getViaLane()->getID() <<
"\n";
903 if (l2->getApproaching().size() > 0) {
905 if (closest2.second.dist < flankApproachingDist) {
906 #ifdef DEBUG_FIND_PROTECTION
908 std::cout <<
" protection from veh=" << closest2.first->getID() <<
"\n";
933 return tmp.
reserve(veh, occupied);
940 for (
int i = 0; i < myCoreSize; i++) {
942 const MSEdge* edge = myRoute[i];
956 for (
const MSLane* lane : myForward) {
975 if (myCoreSize != (
int)myRoute.size()) {
983 if (myBidiExtended.size() > 0) {
993 od.
openTag(
"protectingSwitches");
994 std::vector<std::string> links;
995 for (
MSLink* link : myProtectingSwitches) {
1002 std::vector<std::string> signals;
1003 for (
MSLink* link : myConflictLinks) {
1016 bool seekForwardSignal =
true;
1017 bool seekBidiSwitch =
true;
1018 bool foundUnsafeSwitch =
false;
1020 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1025 while ((seekForwardSignal || seekBidiSwitch)) {
1029 " exceeds maximum length (stopped searching after edge '" + toLane->
getEdge().
getID() +
"' (length=" +
toString(length) +
"m).");
1035 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1040 if (visited.count(toLane) != 0) {
1046 myRoute.push_back(&toLane->
getEdge());
1051 visited[toLane] = (int)visited.size();
1054 if (seekForwardSignal) {
1055 if (!foundUnsafeSwitch) {
1056 myForward.push_back(toLane);
1058 }
else if (bidi ==
nullptr) {
1059 seekBidiSwitch =
false;
1060 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1062 std::cout <<
" noBidi, abort search for bidiSwitch\n";
1066 if (bidi !=
nullptr) {
1067 if (foundUnsafeSwitch) {
1068 myBidiExtended.push_back(bidi);
1070 myBidi.push_back(bidi);
1072 visited[bidi] = (int)visited.size();
1073 if (!seekForwardSignal) {
1079 for (
const MSLink*
const link : ili.lane->getLinkCont()) {
1083 if (link->getViaLaneOrLane() != bidi) {
1087 myCoreSize = (int)myRoute.size();
1089 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1091 std::cout <<
" abort: found protecting switch " << ili.viaLink->getDescription() <<
"\n";
1096 myProtectedBidi = bidiNext;
1099 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1101 std::cout <<
" found unsafe switch " << ili.viaLink->getDescription() <<
" (used=" << bidiNext->
getID() <<
")\n";
1106 foundUnsafeSwitch =
true;
1110 myFlankSwitches.push_back(ili.viaLink);
1119 const std::vector<MSLink*>& links = toLane->
getLinkCont();
1122 for (
const MSLink*
const link : links) {
1123 if (((next != end && &link->getLane()->getEdge() == *next) ||
1125 &&
isRailway(link->getViaLaneOrLane()->getPermissions())) {
1126 toLane = link->getViaLaneOrLane();
1127 if (link->getLane()->getBidiLane() !=
nullptr && &link->getLane()->getEdge() == current->
getBidiEdge()) {
1129 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1131 std::cout <<
" abort: turn-around\n";
1136 if (link->getTLLogic() !=
nullptr) {
1137 if (link->getTLLogic() == origin->
getTLLogic()) {
1142 seekForwardSignal =
false;
1143 seekBidiSwitch = bidi !=
nullptr;
1144 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1146 std::cout <<
" found forwardSignal " << link->getTLLogic()->
getID() <<
" seekBidiSwitch=" << seekBidiSwitch <<
"\n";
1153 if (toLane ==
nullptr) {
1156 toLane = (*next)->getLanes()[0];
1158 #ifdef DEBUG_DRIVEWAY_BUILDROUTE
1160 std::cout <<
" abort: no next lane available\n";
1172 #ifdef DEBUG_CHECK_FLANKS
1173 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
"\n visited=" <<
formatVisitedMap(visited) <<
" allFoes=" << allFoes <<
"\n";
1175 for (
MSLane* lane : lanes) {
1176 if (lane->isInternal()) {
1179 for (
auto ili : lane->getIncomingLanes()) {
1180 if (visited.count(ili.lane->getNormalPredecessorLane()) == 0) {
1181 #ifdef DEBUG_CHECK_FLANKS
1182 std::cout <<
" add flankSwitch junction=" << ili.viaLink->getJunction()->getID() <<
" index=" << ili.viaLink->getIndex() <<
"\n";
1184 myFlankSwitches.push_back(ili.viaLink);
1185 }
else if (allFoes) {
1187 checkCrossingFlanks(ili.viaLink, visited);
1196 #ifdef DEBUG_CHECK_FLANKS
1200 if (junction ==
nullptr) {
1204 if (logic ==
nullptr) {
1208 if (in->isInternal()) {
1211 for (
MSLane* inLane : in->getLanes()) {
1212 if (
isRailway(inLane->getPermissions()) && visited.count(inLane) == 0) {
1213 for (
MSLink* link : inLane->getLinkCont()) {
1214 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
1215 && visited.count(link->getLane()) == 0) {
1216 #ifdef DEBUG_CHECK_FLANKS
1217 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
1219 if (link->getViaLane() ==
nullptr) {
1220 myFlankSwitches.push_back(link);
1222 myFlankSwitches.push_back(link->getViaLane()->getLinkCont().front());
1233 #ifdef DEBUG_CHECK_FLANKS
1234 std::cout <<
" findFlankProtection link=" << link->
getDescription() <<
" length=" << length <<
" origLink=" << origLink->
getDescription() <<
"\n";
1238 #ifdef DEBUG_CHECK_FLANKS
1239 std::cout <<
" flank guarded by " << link->
getTLLogic()->
getID() <<
"\n";
1241 myConflictLinks.push_back(link);
1251 const bool isNew = visited.count(lane) == 0;
1252 if (isNew || (visited[lane] > visited[origLink->
getLane()] && std::find(myForward.begin(), myForward.end(), lane) == myForward.end())) {
1254 visited[lane] = (int)visited.size();
1258 myFlank.push_back(lane);
1259 findFlankProtection(lane->
getIncomingLanes().front().viaLink, length, visited, origLink);
1261 bool foundPSwitch =
false;
1263 #ifdef DEBUG_CHECK_FLANKS
1264 std::cout <<
" lane=" << lane->
getID() <<
" visitedIndex=" << visited[lane] <<
" origIndex=" << visited[origLink->
getLane()] <<
" cand=" << l2->getDescription() <<
"\n";
1267 foundPSwitch =
true;
1269 #ifdef DEBUG_CHECK_FLANKS
1270 std::cout <<
" protectingSwitch=" << l2->getDescription() <<
" for flank=" << link->
getDescription() <<
"\n";
1272 myProtectingSwitches.push_back(link);
1275 if (!foundPSwitch) {
1276 myFlank.push_back(lane);
1280 findFlankProtection(ili.viaLink, length, visited, origLink);
1286 #ifdef DEBUG_CHECK_FLANKS
1287 std::cout <<
" laneBefore=" << lane->
getID() <<
" already visited. index=" << visited[lane] <<
" origAfter=" << origLink->
getLane()->
getID() <<
" origIndex=" << visited[origLink->
getLane()] <<
"\n";
1291 myMaxFlankLength =
MAX2(myMaxFlankLength, length);
1307 driveway.
reserve(closest, occupied);
1342 for (
const DriveWay& dw : li.myDriveways) {
1357 if (item.second < item2.second) {
1358 bool conflict =
false;
1359 std::pair<int, int> code(item.second, item2.second);
1362 conflict = it->second;
1372 #ifdef DEBUG_RECHECKGREEN
1383 state[item.first->getTLIndex()] =
'r';
1386 #ifdef DEBUG_RECHECKGREEN
1388 <<
" (" << veh.first->getID() <<
" yields to " << veh2.first->getID() <<
"\n";
1390 #ifdef DEBUG_SIGNALSTATE
1393 <<
" (" << veh.first->getID() <<
" yields to " << veh2.first->getID() <<
"\n";
1398 state[item2.first->getTLIndex()] =
'r';
1401 #ifdef DEBUG_RECHECKGREEN
1403 <<
" (" << veh2.first->getID() <<
" yields to " << veh.first->getID() <<
"\n";
1405 #ifdef DEBUG_SIGNALSTATE
1408 <<
" (" << veh2.first->getID() <<
" yields to " << veh.first->getID() <<
"\n";
1423 for (
auto it = li.myDriveways.begin(); it != li.myDriveways.end(); it++) {
1426 #ifdef DEBUG_DRIVEWAY_UPDATE
1427 std::cout <<
SIMTIME <<
" rail signal junction '" <<
getID() <<
"' requires update for driveway " << numericalID <<
"\n";
1429 std::vector<const MSEdge*> route = dw.
myRoute;
1430 li.myDriveways.erase(it);
1431 if (li.myDriveways.size() == 0) {
1433 li.myDriveways.push_back(li.buildDriveWay(route.begin(), route.end()));
1448 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1461 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1474 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
1487 for (
int i = 0; i < (int)
myLinkInfos.size(); i++) {
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
#define DEBUG_COND_LINKINFO
#define DEBUG_HELPER(obj)
#define MAX_SIGNAL_WARNINGS
ConstMSEdgeVector::const_iterator MSRouteIterator
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
@ TURN
The link is a 180 degree turn.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
const MSRoute & getRoute() const
Returns the current route.
A device that performs vehicle rerouting based on current edge speeds.
SUMOTime getPeriod() const
bool mayRerouteRailSignal() const
return whether the equipped vehicle may receive dispatch information at a rail signal
A road/street connecting two junctions.
bool isNormal() const
return whether this edge is an internal edge
const MSJunction * getFromJunction() const
double getLength() const
return the length of the edge
const MSJunction * getToJunction() const
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
The base class for an intersection.
const ConstMSEdgeVector & getIncoming() const
SumoXMLNodeType getType() const
return the type of this Junction
virtual const MSJunctionLogic * getLogic() const
virtual const MSLogicJunction::LinkBits & getFoesFor(int linkIndex) const
Returns the foes for the given link.
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
const MSEdge * getNextNormal() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
double getLength() const
Returns the lane's length.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
MSEdge & getEdge() const
Returns the lane's edge.
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
LinkState getState() const
Returns the current state of the link.
MSLane * getLane() const
Returns the connected lane.
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
int getIndex() const
Returns the respond index (for visualization)
int getTLIndex() const
Returns the TLS index.
ApproachingVehicleInformation getApproaching(const SUMOVehicle *veh) const
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
std::string getDescription() const
get string description for this link
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
MSJunction * getJunction() const
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
void setState(const std::string &_state)
A base class for constraints.
virtual std::string getDescription() const
virtual bool cleared() const =0
whether the constraint has been met
const std::set< const MSEdge * > & getUsedEdges() const
static MSRailSignalControl & getInstance()
void registerProtectedDriveway(MSRailSignal *rs, int driveWayID, const MSEdge *protectedBidi)
mark driveway that must receive additional checks if protectedBidi is ever used by a train route
bool constraintsAllow(const SUMOVehicle *veh) const
whether the given vehicle is free to drive
static VehicleVector myRivalVehicles
std::string getBlockingVehicleIDs() const
int getIndexFromOffset(SUMOTime offset) const
Returns the step (the phasenumber) of a given position of the cycle.
Phases myPhases
The list of phases this logic uses.
std::string getConstraintInfo(int linkIndex)
return information regarding active rail signal constraints for the closest approaching vehicle
std::map< std::string, std::vector< MSRailSignalConstraint * > > myInsertionConstraints
static VehicleVector myPriorityVehicles
int myPhaseIndex
MSTrafficLightLogic requires that the phase index changes whenever signals change their state.
int getPhaseNumber() const
Returns the number of phases.
static std::string myConstraintInfo
MSPhaseDefinition myCurrentPhase
The current phase.
void addConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
register contraint for signal switching
static std::string getClickableTLLinkID(MSLink *link)
return logicID_linkIndex in a way that allows clicking in sumo-gui
std::vector< LinkInfo > myLinkInfos
data storage for every link at this node (more than one when directly guarding a switch)
std::string getPriorityVehicleIDs() const
static int myDriveWayIndex
static std::string describeLinks(std::vector< MSLink * > links)
print link descriptions
VehicleVector getRivalVehicles(int linkIndex)
return vehicles that approach the intersection/rail signal and are in conflict with vehicles that wis...
void writeBlocks(OutputDevice &od) const
write rail signal block output for all links and driveways
~MSRailSignal()
Destructor.
VehicleVector getPriorityVehicles(int linkIndex)
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
const Phases & getPhases() const
Returns the phases of this tls program.
static VehicleVector myBlockingVehicles
void storeTraCIVehicles(int linkIndex)
update vehicle lists for traci calls
SUMOTime getOffsetFromIndex(int index) const
Returns the position (start of a phase during a cycle) from of a given step.
static Approaching getClosest(MSLink *link)
get the closest vehicle approaching the given link
std::map< std::string, std::vector< MSRailSignalConstraint * > > myConstraints
map from tripId to constraint list
static std::map< std::pair< int, int >, bool > myDriveWayCompatibility
std::pair< const SUMOVehicle *const, const MSLink::ApproachingVehicleInformation > Approaching
SUMOTime trySwitch()
Switches to the next phase.
static void recheckGreen()
final check for driveway compatibility of signals that switched green in this step
static std::string getJunctionLinkID(MSLink *link)
return junctionID_junctionLinkIndex
const DriveWay & retrieveDriveWay(int numericalID) const
static bool myStoreVehicles
void addInsertionConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
register contraint for vehicle insertion
const MSPhaseDefinition & getPhase(int givenstep) const
Returns the definition of the phase from the given position within the plan.
std::map< const MSLane *, int, ComparatorNumericalIdLess > LaneVisitedMap
static std::vector< std::pair< MSLink *, int > > mySwitchedGreenFlanks
list of signals that switched green along with driveway index
void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const
Returns the index of the logic at the given simulation step.
MSRailSignal(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, SUMOTime delay, const std::map< std::string, std::string > ¶meters)
Constructor.
void init(NLDetectorBuilder &nb)
Initialises the rail signal with information about adjacent rail signals.
void updateDriveway(int numericalID)
update driveway for extended deadlock protection
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
std::string getConstraintInfo() const
static std::string formatVisitedMap(const LaneVisitedMap &visited)
print link descriptions
void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
VehicleVector getBlockingVehicles(int linkIndex)
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
void updateCurrentPhase()
returns the state of the signal that actually required
static bool hasInsertionConstraint(MSLink *link, const MSVehicle *veh)
static bool hasOncomingRailTraffic(MSLink *link)
std::string getRivalVehicleIDs() const
int getCurrentPhaseIndex() const
Returns the current index within the program.
static std::string getTLLinkID(MSLink *link)
return logicID_linkIndex
MSRouteIterator end() const
Returns the end of the list of edges to pass.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
const ConstMSEdgeVector & getEdges() const
static void reroute(SUMOVehicle &vehicle, const SUMOTime currentTime, const std::string &info, const bool onInit=false, const bool silent=false, const MSEdgeVector &prohibited=MSEdgeVector())
initiate the rerouting, create router / thread pool on first use
A class that stores and controls tls and switching of their programs.
The parent class for traffic light logics.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
std::vector< const SUMOVehicle * > VehicleVector
list of vehicles
SUMOTime myDefaultCycleTime
The cycle time (without changes)
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
int myNumLinks
number of controlled links
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
Representation of a vehicle in the micro simulation.
Builds detectors for microsim.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
Static storage of an output device and its base (abstract) implementation.
void lf()
writes a line feed if applicable
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
Representation of a vehicle.
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual MSVehicleDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual int getRoutePosition() const =0
return index of edge within 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
void checkFlanks(const std::vector< MSLane * > &lanes, const LaneVisitedMap &visited, bool allFoes)
find switches that threathen this driveway
void writeBlocks(OutputDevice &od) const
Write block items for this driveway.
void buildRoute(MSLink *origin, double length, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap &visited)
std::vector< MSLink * > myFlankSwitches
int myCoreSize
number of edges in myRoute where overlap with other driveways is forbidden
bool deadlockLaneOccupied(bool store=true) const
whether any of myBidiExtended is occupied by a vehicle that targets myBidi
const MSEdge * myProtectedBidi
switch assumed safe from bidi-traffic
std::vector< const MSLane * > myConflictLanes
the lanes that must be clear of trains before this signal can switch to green
bool overlap(const DriveWay &other) const
Wether this driveway (route) overlaps with the given one.
int myNumericalID
global driveway index
std::vector< MSLink * > myConflictLinks
void checkCrossingFlanks(MSLink *dwLink, const LaneVisitedMap &visited)
find links that cross the driveway without entering it
std::vector< MSLane * > myBidi
void findFlankProtection(MSLink *link, double length, LaneVisitedMap &visited, MSLink *origLink)
find upstream protection from the given link
bool conflictLaneOccupied(const std::string &joinVehicle="", bool store=true) const
whether any of myConflictLanes is occupied (vehicles that are the target of a join must be ignored)
std::vector< const MSLane * > myFlank
std::vector< const MSEdge * > myRoute
list of edges for matching against train routes
bool hasLinkConflict(const Approaching &closest, MSLink *foeLink) const
Whether the approaching vehicle is prevent from driving by another vehicle approaching the given link...
bool findProtection(const Approaching &veh, MSLink *link) const
find protection for the given vehicle starting at a switch
std::vector< MSLink * > myProtectingSwitches
std::vector< MSLane * > myForward
bool conflictLinkApproached() const
Whether any of the conflict linkes have approaching vehicles.
bool reserve(const Approaching &closest, MSEdgeVector &occupied)
attempt reserve this driveway for the given vehicle
bool flankConflict(const DriveWay &other) const
Wether there is a flank conflict with the given driveway.
static bool mustYield(const Approaching &veh, const Approaching &foe)
Whether veh must yield to the foe train.
void reroute(SUMOVehicle *veh, const MSEdgeVector &occupied)
try rerouting vehicle if reservation failed
DriveWay buildDriveWay(MSRouteIterator first, MSRouteIterator end)
construct a new driveway by searching along the given route until all block structures are found
DriveWay & getDriveWay(const SUMOVehicle *)
retrieve an existing Driveway or construct a new driveway based on the vehicles route
LinkInfo(MSLink *link)
constructor
std::vector< DriveWay > myDriveways
all driveways immediately following this link
std::string getID() const
return id for this railsignal-link