void MSRailSignal::collectConflictLinks(MSLane* toLane, double length, std::vector<MSLane*>& backwardBlock, std::vector<MSLink*>& conflictLinks, LaneSet& visited, bool checkFoes) { while (toLane != nullptr) { //std::cout << "collectConflictLinks " << getID() << " toLane=" << toLane->getID() << " length=" << length // << " backward=" << toString(backwardBlock) // << " conflictLinks=" << conflictLinks.size() // << " visited=" << visited.size() // << " checkFoes=" << checkFoes // << "\n"; const auto& incomingLaneInfos = toLane->getIncomingLanes(); MSLane* orig = toLane; toLane = nullptr; for (const auto& ili : incomingLaneInfos) { if (ili.viaLink->getDirection() == LINKDIR_TURN) { continue; } if (visited.count(ili.lane) != 0) { continue; } if (ili.viaLink->getTLLogic() != nullptr) { conflictLinks.push_back(ili.viaLink); continue; } backwardBlock.push_back(ili.lane); visited.insert(ili.lane); length += orig->getLength(); if (length > MAX_BLOCK_LENGTH) { if (myNumWarnings < MAX_SIGNAL_WARNINGS) { WRITE_WARNING("incoming conflict block after rail signal junction '" + getID() + "' exceeds maximum length (stopped searching after lane '" + orig->getID() + "' (length=" + toString(length) + "m)."); } myNumWarnings++; return; } if (toLane == nullptr) { toLane = ili.lane; } else { collectConflictLinks(ili.lane, length, backwardBlock, conflictLinks, visited, false); } } if (checkFoes && orig->isInternal()) { // check for crossed tracks MSLink* link = orig->getIncomingLanes().front().viaLink; if (link->getDirection() != LINKDIR_TURN) { for (const MSLane* foeConst : link->getFoeLanes()) { MSLane* foe = const_cast<MSLane*>(foeConst); if (visited.count(foe) == 0) { backwardBlock.push_back(foe); visited.insert(foe); collectConflictLinks(foe, length, backwardBlock, conflictLinks, visited, false); } } } } } }
const std::vector<MSLane*> MSLogicJunction::getInternalLanes() const { // Besides the lanes im myInternal lanes, which are only the last parts of the connections, // this collects all lanes on the junction std::vector<MSLane*> allInternalLanes; for (std::vector<MSLane*>::const_iterator i = myInternalLanes.begin(); i != myInternalLanes.end(); ++i) { MSLane* l = *i; while (l != nullptr) { allInternalLanes.push_back(l); const std::vector<MSLane::IncomingLaneInfo> incoming = l->getIncomingLanes(); if (incoming.size() == 0) { break; } assert(l->getIncomingLanes().size() == 1); l = l->getIncomingLanes()[0].lane; if (!l->isInternal()) { break; } } } return allInternalLanes; }
std::pair<MSVehicle * const, SUMOReal> MSLane::getFollowerOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal leaderSpeed, SUMOReal backOffset) const { // ok, a vehicle has not noticed the lane about itself; // iterate as long as necessary to search for an approaching one std::set<MSLane*> visited; std::vector<std::pair<MSVehicle *, SUMOReal> > possible; std::vector<MSLane::IncomingLaneInfo> newFound; std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes; while (toExamine.size()!=0) { for (std::vector<MSLane::IncomingLaneInfo>::iterator i=toExamine.begin(); i!=toExamine.end(); ++i) { /* if ((*i).viaLink->getState()==MSLink::LINKSTATE_TL_RED) { continue; } */ MSLane *next = (*i).lane; if (next->getFirstVehicle()!=0) { MSVehicle * v = (MSVehicle*) next->getFirstVehicle(); SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset; if (!v->getCarFollowModel().hasSafeGap(v->getCarFollowModel().maxNextSpeed(v->getSpeed()), agap, leaderSpeed, v->getLane().getMaxSpeed())) { possible.push_back(std::make_pair(v, (*i).length-v->getPositionOnLane()+seen)); } } else { if ((*i).length+seen<dist) { const std::vector<MSLane::IncomingLaneInfo> &followers = next->getIncomingLanes(); for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j=followers.begin(); j!=followers.end(); ++j) { if (visited.find((*j).lane)==visited.end()) { visited.insert((*j).lane); MSLane::IncomingLaneInfo ili; ili.lane = (*j).lane; ili.length = (*j).length + (*i).length; ili.viaLink = (*j).viaLink; newFound.push_back(ili); } } } } } toExamine.clear(); swap(newFound, toExamine); } if (possible.size()==0) { return std::pair<MSVehicle * const, SUMOReal>(0, -1); } sort(possible.begin(), possible.end(), by_second_sorter()); return *(possible.begin()); }