 |
Eclipse SUMO - Simulation of Urban MObility
|
Go to the documentation of this file.
54 #define MAX_BLOCK_LENGTH 20000
55 #define MAX_SIGNAL_WARNINGS 10
60 #define DEBUG_SIGNALSTATE
61 #define DEBUG_SIGNALSTATE_PRIORITY
62 #define DEBUG_FIND_PROTECTION
65 #define DEBUG_COND DEBUG_HELPER(this)
66 #define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
67 #define DEBUG_HELPER(obj) ((obj)->isSelected())
80 const std::string&
id,
const std::string& programID,
SUMOTime delay,
81 const std::map<std::string, std::string>& parameters) :
92 if (links.size() != 1) {
94 +
" links controlled by index " +
toString(links[0]->getTLIndex()));
126 #ifdef DEBUG_SIGNALSTATE
130 std::string state(
myLinks.size(),
'G');
132 if (li.myLink->getApproaching().size() > 0) {
134 DriveWay& driveway = li.getDriveWay(closest.first);
138 if (!driveway.
reserve(closest, occupied)) {
139 state[li.myLink->getTLIndex()] =
'r';
140 if (occupied.size() > 0) {
141 li.reroute(
const_cast<SUMOVehicle*
>(closest.first), occupied);
143 #ifdef DEBUG_SIGNALSTATE
145 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" notReserved\n";
149 state[li.myLink->getTLIndex()] =
'G';
150 #ifdef DEBUG_SIGNALSTATE
152 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" veh=" << closest.first->getID() <<
" reserved\n";
157 DriveWay& driveway = li.myDriveways.front();
159 #ifdef DEBUG_SIGNALSTATE
161 std::cout <<
SIMTIME <<
" rsl=" << li.getID() <<
" red for default driveway\n";
164 state[li.myLink->getTLIndex()] =
'r';
172 #ifdef DEBUG_SIGNALSTATE
243 for (
MSLink* link : links) {
244 result += link->getDescription() +
" ";
252 double minDist = std::numeric_limits<double>::max();
255 if (apprIt->second.dist < minDist) {
256 minDist = apprIt->second.
dist;
286 for (
const DriveWay& dw : li.myDriveways) {
299 if (bidi ==
nullptr) {
340 myLink(link), myUniqueDriveWay(false),
341 myLastRerouteTime(-1),
342 myLastRerouteVehicle(nullptr) {
351 return myLink->getTLLogic()->getID() +
"_" +
toString(myLink->getTLIndex());
357 if (myUniqueDriveWay) {
358 return myDriveways.front();
360 MSEdge* first = &myLink->getLane()->getEdge();
363 WRITE_WARNING(
"Invalid approach information after rerouting");
364 return myDriveways.front();
369 auto itRoute = firstIt;
370 auto itDwRoute = dw.myRoute.begin();
372 while (itRoute != veh->
getRoute().
end() && itDwRoute != dw.myRoute.end()) {
373 if (*itRoute != *itDwRoute) {
386 return buildDriveWay(firstIt, veh->
getRoute().
end());
415 DriveWay dw((
int)myDriveways.size());
417 std::vector<MSLane*> before;
418 visited.insert(myLink->getLaneBefore());
420 if (fromBidi !=
nullptr) {
422 visited.insert(fromBidi);
423 before.push_back(fromBidi);
425 dw.
buildRoute(myLink, 0., first, end, visited);
435 #ifdef DEBUG_BUILD_DRIVEWAY
437 std::cout <<
" buildDriveWay railSignal=" <<
getID() <<
" dw=" << dw.
myIndex
450 myDriveways.push_back(dw);
451 return myDriveways.back();
459 if (rDev !=
nullptr &&
460 (myLastRerouteVehicle != veh
464 myLastRerouteVehicle = veh;
465 myLastRerouteTime = now;
470 std::cout <<
SIMTIME <<
" reroute veh=" << veh->
getID() <<
" rs=" <<
getID() <<
" occupied=" <<
toString(occupied) <<
"\n";
478 std::cout <<
" rerouting successful\n";
492 if (conflictLaneOccupied()) {
493 for (
MSLane* bidi : myBidi) {
494 if (!bidi->empty() && bidi->getBidiLane() !=
nullptr) {
495 occupied.push_back(&bidi->getBidiLane()->getEdge());
498 #ifdef DEBUG_SIGNALSTATE
500 std::cout <<
" conflictLaneOccupied\n";
505 for (
MSLink* link : myProtectingSwitches) {
506 if (!findProtection(closest, link)) {
507 #ifdef DEBUG_SIGNALSTATE
509 std::cout <<
" no protection at switch " << link->getDescription() <<
"\n";
515 for (
MSLink* foeLink : myConflictLinks) {
516 if (hasLinkConflict(closest, foeLink)) {
517 #ifdef DEBUG_SIGNALSTATE
519 std::cout <<
" linkConflict with " <<
getTLLinkID(foeLink) <<
"\n";
525 myActive = closest.first;
532 for (
MSLink* foeLink : myConflictLinks) {
533 if (foeLink->getApproaching().size() > 0) {
543 #ifdef DEBUG_SIGNALSTATE_PRIORITY
545 std::cout <<
" checkLinkConflict foeLink=" <<
getTLLinkID(foeLink) <<
"\n";
550 #ifdef DEBUG_SIGNALSTATE_PRIORITY
552 std::cout <<
" approaching foe=" << foe.first->getID() <<
"\n";
556 assert(foeTLL !=
nullptr);
559 if (foeRS !=
nullptr) {
562 !overlap(foeDriveWay)) {
563 #ifdef DEBUG_SIGNALSTATE_PRIORITY
566 std::cout <<
" foe blocked\n";
568 std::cout <<
" no overlap\n";
574 #ifdef DEBUG_SIGNALSTATE_PRIORITY
577 <<
" aSB=" << veh.second.arrivalSpeedBraking <<
" foeASB=" << foe.second.arrivalSpeedBraking
578 <<
" aT=" << veh.second.arrivalTime <<
" foeAT=" << foe.second.arrivalTime
579 <<
" aS=" << veh.first->getSpeed() <<
" foeS=" << foe.first->getSpeed()
580 <<
" aD=" << veh.second.dist <<
" foeD=" << foe.second.dist
584 if (foe.second.arrivalSpeedBraking == veh.second.arrivalSpeedBraking) {
585 if (foe.second.arrivalTime == veh.second.arrivalTime) {
586 if (foe.first->getSpeed() == veh.first->getSpeed()) {
587 if (foe.second.dist == veh.second.dist) {
588 return foe.first->getNumericalID() < veh.first->getNumericalID();
590 return foe.second.dist < veh.second.dist;
593 return foe.first->getSpeed() > veh.first->getSpeed();
596 return foe.second.arrivalTime < veh.second.arrivalTime;
599 return foe.second.arrivalSpeedBraking > veh.second.arrivalSpeedBraking;
609 for (
const MSLane* lane : myConflictLanes) {
610 if (!lane->isEmpty()) {
611 #ifdef DEBUG_SIGNALSTATE
613 std::cout <<
SIMTIME <<
" conflictLane " << lane->getID() <<
" occupied\n";
625 double flankApproachingDist = std::numeric_limits<double>::max();
628 flankApproachingDist = closest.second.dist;
630 #ifdef DEBUG_FIND_PROTECTION
632 std::cout <<
SIMTIME <<
" findProtection for link=" << link->
getDescription() <<
" flankApproachingDist=" << flankApproachingDist <<
"\n";
636 if (l2->getLane() != link->
getLane()) {
637 #ifdef DEBUG_FIND_PROTECTION
639 std::cout <<
" protectionCandidate=" << l2->getDescription() <<
" l2Via=" <<
Named::getIDSecure(l2->getViaLane()) <<
" occupied=" << !l2->getViaLane()->isEmpty() <<
"\n";
642 if (l2->getViaLane() !=
nullptr && !l2->getViaLane()->isEmpty()) {
643 #ifdef DEBUG_FIND_PROTECTION
645 std::cout <<
" protection from internal=" << l2->getViaLane()->getID() <<
"\n";
650 if (l2->getApproaching().size() > 0) {
652 if (closest2.second.dist < flankApproachingDist) {
653 #ifdef DEBUG_FIND_PROTECTION
655 std::cout <<
" protection from veh=" << closest2.first->getID() <<
"\n";
679 return tmp.
reserve(veh, occupied);
686 for (
const MSEdge* edge : myRoute) {
712 std::vector<std::string> signals;
713 for (
MSLink* link : myConflictLinks) {
726 bool seekForwardSignal =
true;
727 bool seekBidiSwitch =
true;
730 while ((seekForwardSignal || seekBidiSwitch)) {
734 " exceeds maximum length (stopped searching after edge '" + toLane->
getEdge().
getID() +
"' (length=" +
toString(length) +
"m).");
741 if (visited.count(toLane) != 0) {
746 myRoute.push_back(&toLane->
getEdge());
751 visited.insert(toLane);
754 if (seekForwardSignal) {
755 myForward.push_back(toLane);
756 }
else if (bidi ==
nullptr) {
757 seekBidiSwitch =
false;
759 if (bidi !=
nullptr) {
760 myBidi.push_back(bidi);
761 visited.insert(bidi);
762 if (!seekForwardSignal) {
768 for (
MSLink* link : ili.lane->getLinkCont()) {
772 if (link->getViaLaneOrLane() != bidi) {
774 myProtectingSwitches.push_back(ili.viaLink);
783 for (
MSLink* link : links) {
784 if (((next != end && &link->getLane()->getEdge() == *next) ||
786 &&
isRailway(link->getViaLaneOrLane()->getPermissions())) {
787 toLane = link->getViaLaneOrLane();
788 if (link->getTLLogic() !=
nullptr) {
789 if (link->getTLLogic() == origin->
getTLLogic()) {
793 seekForwardSignal =
false;
794 seekBidiSwitch = bidi !=
nullptr;
799 if (toLane ==
nullptr) {
802 toLane = (*next)->getLanes()[0];
813 #ifdef DEBUG_CHECK_FLANKS
814 std::cout <<
" checkFlanks lanes=" <<
toString(lanes) <<
"\n visited=" <<
joinNamedToString(visited,
" ") <<
" allFoes=" << allFoes <<
"\n";
816 for (
MSLane* lane : lanes) {
817 if (lane->isInternal()) {
820 for (
auto ili : lane->getIncomingLanes()) {
821 if (visited.count(ili.lane->getNormalPredecessorLane()) == 0) {
822 #ifdef DEBUG_CHECK_FLANKS
823 std::cout <<
" add flankSwitch junction=" << ili.viaLink->getJunction()->getID() <<
" index=" << ili.viaLink->getIndex() <<
"\n";
825 myFlankSwitches.push_back(ili.viaLink);
826 }
else if (allFoes) {
828 checkCrossingFlanks(ili.viaLink, visited);
837 #ifdef DEBUG_CHECK_FLANKS
842 assert(logic !=
nullptr);
844 if (in->isInternal()) {
847 for (
MSLane* inLane : in->getLanes()) {
848 if (
isRailway(inLane->getPermissions()) && visited.count(inLane) == 0) {
849 for (
MSLink* link : inLane->getLinkCont()) {
850 if (link->getIndex() >= 0 && logic->
getFoesFor(dwLink->
getIndex()).test(link->getIndex())
851 && visited.count(link->getLane()) == 0) {
852 #ifdef DEBUG_CHECK_FLANKS
853 std::cout <<
" add crossing flankSwitch junction=" << junction->
getID() <<
" index=" << link->getIndex() <<
"\n";
855 if (link->getViaLane() ==
nullptr) {
856 myFlankSwitches.push_back(link);
858 myFlankSwitches.push_back(link->getViaLane()->getLinkCont().front());
869 #ifdef DEBUG_CHECK_FLANKS
870 std::cout <<
" findFlankProtection link=" << link->
getDescription() <<
" length=" << length <<
" origLink=" << origLink->
getDescription() <<
"\n";
874 myConflictLinks.push_back(link);
884 if (visited.count(lane) == 0) {
885 visited.insert(lane);
888 myFlank.push_back(lane);
889 findFlankProtection(lane->
getIncomingLanes().front().viaLink, length, visited, origLink);
891 bool foundPSwitch =
false;
893 #ifdef DEBUG_CHECK_FLANKS
894 std::cout <<
" lane=" << lane->
getID() <<
" cand=" << l2->getDescription() <<
"\n";
899 #ifdef DEBUG_CHECK_FLANKS
900 std::cout <<
" protectingSwitch=" << l2->getDescription() <<
" for flank=" << link->
getDescription() <<
"\n";
902 myProtectingSwitches.push_back(link);
906 myFlank.push_back(lane);
910 findFlankProtection(ili.viaLink, length, visited, origLink);
917 myMaxFlankLength =
MAX2(myMaxFlankLength, length);
std::vector< const MSLane * > myConflictLanes
the lanes that must be clear of trains before this signal can switch to green
#define MAX_SIGNAL_WARNINGS
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
LinkState getState() const
Returns the current state of the link.
SUMOTime getOffsetFromIndex(int index) const
Returns the position (start of a phase during a cycle) from of a given step.
int getIndexFromOffset(SUMOTime offset) const
Returns the step (the phasenumber) of a given position of the cycle.
A device that performs vehicle rerouting based on current edge speeds.
int myIndex
index in the list of driveways
#define WRITE_WARNING(msg)
Representation of a lane in the micro simulation.
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const
Returns the index of the logic at the given simulation step.
SUMOTime trySwitch()
Switches to the next phase.
SUMOTime getPeriod() const
The base class for an intersection.
Static storage of an output device and its base (abstract) implementation.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
std::vector< MSLink * > myProtectingSwitches
ConstMSEdgeVector::const_iterator MSRouteIterator
void buildRoute(MSLink *origin, double length, MSRouteIterator next, MSRouteIterator end, LaneSet &visited)
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
virtual const std::string & getID() const =0
Get the vehicle's ID.
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
bool hasLinkConflict(const Approaching &closest, MSLink *foeLink) const
Whether the approaching vehicle is prevent from driving by another vehicle approaching the given link...
ApproachingVehicleInformation getApproaching(const SUMOVehicle *veh) const
LinkInfo(MSLink *link)
constructor
int myPhaseIndex
MSTrafficLightLogic requires that the phase index changes whenever signals change their state.
std::vector< MSLane * > myBidi
Representation of a vehicle.
const MSRoute & getRoute() const
Returns the current route.
std::vector< const MSEdge * > ConstMSEdgeVector
void init(NLDetectorBuilder &nb)
Initialises the rail signal with information about adjacent rail signals.
int getPhaseNumber() const
Returns the number of phases.
const ConstMSEdgeVector & getEdges() const
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
const Phases & getPhases() const
Returns the phases of this tls program.
bool overlap(const DriveWay &other) const
Wether this driveway overlaps with the given one.
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
static std::string getTLLinkID(MSLink *link)
return logicID_linkIndex
int getIndex() const
Returns the respond index (for visualization)
void findFlankProtection(MSLink *link, double length, LaneSet &visited, MSLink *origLink)
find upstream protection from the given link
std::vector< const MSLane * > myFlank
bool isNormal() const
return whether this edge is an internal edge
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
const ConstMSEdgeVector & getIncoming() const
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
void setState(const std::string &_state)
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
std::set< const MSLane *, ComparatorNumericalIdLess > LaneSet
void checkCrossingFlanks(MSLink *dwLink, const LaneSet &visited)
find links that cross the driveway without entering it
std::string getDescription() const
get string description for this link
void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
std::vector< DriveWay > myDriveways
all driveways immediately following this link
@ LINKDIR_TURN
The link is a 180 degree turn.
virtual const MSRoute & getRoute() const =0
Returns the current route.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool conflictLinkApproached() const
Whether any of the conflict linkes have approaching vehicles.
static Approaching getClosest(MSLink *link)
get the closest vehicle approaching the given link
const MSJunction * getFromJunction() const
static std::string getClickableTLLinkID(MSLink *link)
return logicID_linkIndex in a way that allows clicking in sumo-gui
DriveWay & getDriveWay(const SUMOVehicle *)
retrieve an existing Driveway or construct a new driveway based on the vehicles route
MSLane * getLane() const
Returns the connected lane.
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
int getCurrentPhaseIndex() const
Returns the current index within the program.
static std::string describeLinks(std::vector< MSLink * > links)
print link descriptions
const std::string & getState() const
Returns the state within this phase.
std::pair< const SUMOVehicle *const, const MSLink::ApproachingVehicleInformation > Approaching
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
MSJunction * getJunction() const
virtual MSVehicleDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
std::string joinNamedToString(const std::set< T *, C > &ns, const T_BETWEEN &between)
@ SUMO_ATTR_EDGES
the edges of a route
double getLength() const
Returns the lane's length.
void checkFlanks(const std::vector< MSLane * > &lanes, const LaneSet &visited, bool allFoes)
find switches that threathen this driveway
bool findProtection(const Approaching &veh, MSLink *link) const
find protection for the given vehicle starting at a switch
void writeBlocks(OutputDevice &od) const
write rail signal block output for all links and driveways
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
MSPhaseDefinition myCurrentPhase
The current phase.
virtual const MSJunctionLogic * getLogic() const
void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
std::vector< const MSEdge * > myRoute
list of lanes for matching against train routes
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
A road/street connecting two junctions.
~MSRailSignal()
Destructor.
SumoXMLNodeType getType() const
return the type of this Junction
The parent class for traffic light logics.
std::string getID() const
return id for this railsignal-link
const MSJunction * getToJunction() const
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
void reroute(SUMOVehicle *veh, const MSEdgeVector &occupied)
try rerouting vehicle if reservation failed
MSEdge & getEdge() const
Returns the lane's edge.
Phases myPhases
The list of phases this logic uses.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
@ 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::vector< MSEdge * > MSEdgeVector
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
MSRailSignal(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, SUMOTime delay, const std::map< std::string, std::string > ¶meters)
Constructor.
bool conflictLaneOccupied() const
whether any of myConflictLanes is occupied
std::vector< MSLink * > myFlankSwitches
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
static bool hasOncomingRailTraffic(MSLink *link)
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
SUMOTime myDefaultCycleTime
The cycle time (without changes)
void updateCurrentPhase()
returns the state of the signal that actually required
#define DEBUG_COND_LINKINFO
A class that stores and controls tls and switching of their programs.
bool reserve(const Approaching &closest, MSEdgeVector &occupied)
attempt reserve this driveway for the given vehicle
@ LINKSTATE_TL_RED
The link has red light (must brake)
std::vector< LinkInfo > myLinkInfos
data storage for every link at this node (more than one when directly guarding a switch)
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
The definition of a single phase of a tls logic.
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
std::vector< MSLane * > myForward
int getTLIndex() const
Returns the TLS index.
const std::string & getID() const
Returns the id.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
void writeBlocks(OutputDevice &od) const
Write block items for this driveway.
const MSPhaseDefinition & getPhase(int givenstep) const
Returns the definition of the phase from the given position within the plan.
Builds detectors for microsim.
virtual const MSLogicJunction::LinkBits & getFoesFor(int linkIndex) const
Returns the foes for the given link.
std::vector< MSLink * > myConflictLinks
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
Representation of a vehicle in the micro simulation.
DriveWay & buildDriveWay(MSRouteIterator first, MSRouteIterator end)
construct a new driveway by searching along the given route until all block structures are found