// ------------ Switching and setting current rows SUMOTime MSRailCrossing::trySwitch() { SUMOTime nextTry = updateCurrentPhase(); setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); //if (getID() == "cluster_1088529493_1260626727") std::cout << " myStep=" << myStep << " nextTry=" << nextTry << "\n"; return nextTry; }
void MSRailCrossing::init(NLDetectorBuilder&) { delete myPhases.front(); myPhases.clear(); myPhases.push_back(new MSPhaseDefinition(1, 1, 1, std::string(myLinks.size(), 'G'))); myPhases.push_back(new MSPhaseDefinition(myYellowTime, myYellowTime, myYellowTime, std::string(myLinks.size(), 'y'))); myPhases.push_back(new MSPhaseDefinition(1, 1, 1, std::string(myLinks.size(), 'r'))); // init phases updateCurrentPhase(); setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); }
// ----------- Handling of controlled links void MSRailCrossing::adaptLinkInformationFrom(const MSTrafficLightLogic& logic) { MSTrafficLightLogic::adaptLinkInformationFrom(logic); updateCurrentPhase(); }
void MSRailSignal::init(NLDetectorBuilder&) { assert(myLanes.size() > 0); myConflictLanes.resize(myLinks.size()); myConflictLinks.resize(myLinks.size()); myRouteConflictLanes.resize(myLinks.size()); myRouteConflictLinks.resize(myLinks.size()); myLastRerouteAttempt.resize(myLinks.size(), std::make_pair(nullptr, -1)); if (OptionsCont::getOptions().isSet("railsignal-block-output")) { OutputDevice& od = OutputDevice::getDeviceByOption("railsignal-block-output"); od.openTag("railSignal"); od.writeAttr(SUMO_ATTR_ID, getID()); } for (LinkVector& links : myLinks) { //for every link index // collect lanes and links that are relevant for setting this signal // for each index we collect // - conflictLanes (signal must be red if any conflict lane is occupied) // - conflictLinks (signal must be red if any conflict link is approached by a vehicle // - that cannot break in time (arrivalSpeedBraking > 0) // - approached by a vehicle with higher switching priority (see #3941) // // forwardBlock // - search forward recursive from outgoing lane until controlled railSignal link found // -> add all found lanes // // bidiBlock (if any forwardBlock edge edge has bidi edge) // - search bidi backward recursive until first switch // - from switch search backward recursive all other incoming until controlled rail signal link // -> add final links // // backwardBlock // - search backward recursive from incoming lanes (not bidi for current outgoing lane) // until controlled railSignal link found // -> add all found lanes // -> add final links // // conditionalBlocks // - for each conflict link (always signalized) that enters from a // bidirectional track // - search bidi backward recursive until first switch that is // accessible from the bidi-direction // - from switch search bidi backward recursive until controlled rail signal link // -> add all found lanes // -> add final links std::vector<MSLink*> conflictLinks; LaneSet visited; std::vector<MSLane*> forwardBlock; std::vector<MSLane*> bidiBlock; std::vector<MSLane*> backwardBlock; // there should be only one link per index for railSignal if (links.size() > 1) { throw ProcessError("At railSignal '" + getID() + "' found " + toString(links.size()) + " links controlled by index " + toString(links[0]->getTLIndex())); } for (MSLink* link : links) { MSLane* toLane = link->getViaLaneOrLane(); //the lane this link is leading to MSLane* fromBidi = link->getLaneBefore()->getBidiLane(); if (fromBidi != nullptr) { // do not extend to forward block beyond the entering track (in case of a loop) visited.insert(fromBidi); } collectForwardBlock(toLane, 0., forwardBlock, visited); #ifdef DEBUG_FORWARD_BLOCK if (DEBUG_COND) { std::cout << "railSignal=" << getID() << " index=" << link->getTLIndex() << " forwardBlock=" << toString(forwardBlock) << "\n"; } #endif for (MSLane* forward : forwardBlock) { if (forward->getEdge().getBidiEdge() != nullptr) { MSLane* bidi = forward->getBidiLane(); for (MSLink* bidiOutLink : bidi->getLinkCont()) { if (bidiOutLink->getViaLane() != nullptr) { bidiBlock.push_back(bidiOutLink->getViaLane()); } } collectBidiBlock(bidi, 0., false, bidiBlock, visited); // assume bidirectional patches are continuous break; } } #ifdef DEBUG_BIDI_BLOCK if (DEBUG_COND) { std::cout << "railSignal=" << getID() << " index=" << link->getTLIndex() << " bidiBlock=" << toString(bidiBlock) << "\n"; } #endif // compute conflict links for (MSLane* cl : forwardBlock) { collectConflictLinks(cl, 0, backwardBlock, conflictLinks, visited, true); } for (MSLane* cl : bidiBlock) { collectConflictLinks(cl, 0, backwardBlock, conflictLinks, visited, false); } auto thisLinkIt = std::find(conflictLinks.begin(), conflictLinks.end(), link); if (thisLinkIt != conflictLinks.end()) { conflictLinks.erase(thisLinkIt); } else { WRITE_WARNING("At railSignal junction '" + getID() + "' link " + toString(link->getTLIndex()) + " with direction " + toString(link->getDirection()) + " should be uncontrolled"); } #ifdef DEBUG_BACKWARD_BLOCK if (DEBUG_COND) { std::cout << "railSignal=" << getID() << " index=" << link->getTLIndex() << " backwardBlock=" << toString(backwardBlock); std::cout << "railSignal=" << getID() << " index=" << link->getTLIndex() << " conflictLinks="; for (MSLink* cl : conflictLinks) { std::cout << toString(cl->getViaLaneOrLane()->getID()) << " "; } std::cout << "\n"; } #endif // compute conditional conflict lanes and links for (MSLink* cl : conflictLinks) { std::vector<MSLane*> routeConflictLanes; std::vector<MSLink*> routeConflictLinks; MSLane* in = const_cast<MSLane*>(cl->getLaneBefore()); LaneSet rCVisited = visited; // only collect if // 1) the in-edge is bidirectional // 2) the foe has no alternative track before reach meeting the end of the forwardBlock // 3) the forward block has no alternative track between the end of the forward block and the conflict link if (in->getEdge().getBidiEdge() != nullptr && !hasAlternativeTrack(cl) && !hasAlternativeTrackBetween(forwardBlock, cl)) { collectBidiBlock(in, 0., false, routeConflictLanes, rCVisited); std::vector<MSLane*> rCBackwardBlock; for (MSLane* rCLane : routeConflictLanes) { collectConflictLinks(rCLane, 0, rCBackwardBlock, routeConflictLinks, rCVisited); } } myRouteConflictLanes[link->getTLIndex()].push_back(routeConflictLanes); myRouteConflictLinks[link->getTLIndex()].push_back(routeConflictLinks); } if (OptionsCont::getOptions().isSet("railsignal-block-output")) { OutputDevice& od = OutputDevice::getDeviceByOption("railsignal-block-output"); od.openTag("link"); od.writeAttr(SUMO_ATTR_TLLINKINDEX, link->getTLIndex()); od.writeAttr(SUMO_ATTR_FROM, link->getLaneBefore()->getID()); od.writeAttr(SUMO_ATTR_TO, link->getViaLaneOrLane()->getID()); od.openTag("forwardBlock"); od.writeAttr(SUMO_ATTR_LANES, toString(forwardBlock)); od.closeTag(); od.openTag("bidiBlock"); od.writeAttr(SUMO_ATTR_LANES, toString(bidiBlock)); od.closeTag(); od.openTag("backwardBlock"); od.writeAttr(SUMO_ATTR_LANES, toString(backwardBlock)); od.closeTag(); od.openTag("conflictLinks"); std::vector<std::string> conflictLinkIDs; // railSignalID_tlIndex for (MSLink* cl : conflictLinks) { conflictLinkIDs.push_back(getTLLinkID(cl)); } od.writeAttr("logicIndex", toString(conflictLinkIDs)); for (int i = 0; i < (int)conflictLinks.size(); i++) { const std::vector<MSLane*>& rCLanes = myRouteConflictLanes[link->getTLIndex()][i]; const std::vector<MSLink*>& rCLinks = myRouteConflictLinks[link->getTLIndex()][i]; if (rCLanes.size() > 0 || rCLinks.size() > 0) { od.openTag("conflictLink"); od.writeAttr("logicIndex", getTLLinkID(conflictLinks[i])); if (rCLanes.size() > 0) { od.writeAttr("lanes", toString(rCLanes)); } if (rCLinks.size() > 0) { std::vector<std::string> rCLinkIDs; for (MSLink* rcl : rCLinks) { rCLinkIDs.push_back(getTLLinkID(rcl)); } od.writeAttr("links", toString(rCLinkIDs)); } od.closeTag(); } } od.closeTag(); // conflictLinks od.closeTag(); // link } std::vector<MSLane*> conflictLanes; conflictLanes.insert(conflictLanes.end(), forwardBlock.begin(), forwardBlock.end()); conflictLanes.insert(conflictLanes.end(), bidiBlock.begin(), bidiBlock.end()); conflictLanes.insert(conflictLanes.end(), backwardBlock.begin(), backwardBlock.end()); myConflictLanes[link->getTLIndex()] = conflictLanes; myConflictLinks[link->getTLIndex()] = conflictLinks; } } if (OptionsCont::getOptions().isSet("railsignal-block-output")) { OutputDevice& od = OutputDevice::getDeviceByOption("railsignal-block-output"); od.closeTag(); } updateCurrentPhase(); //check if this is necessary or if will be done already at another stage setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); }
// ------------ Switching and setting current rows SUMOTime MSRailSignal::trySwitch() { updateCurrentPhase(); setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); return DELTA_T; }