void NIVisumTL::build(NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) { for (std::vector<NBNode*>::iterator ni = myNodes.begin(); ni != myNodes.end(); ni++) { NBNode* node = (*ni); TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(OptionsCont::getOptions().getString("tls.default-type")); NBLoadedTLDef* def = new NBLoadedTLDef(ec, node->getID(), node, myOffset, type); tlc.insert(def); def->setCycleDuration((unsigned int) myCycleTime); // signalgroups for (std::map<std::string, SignalGroup*>::iterator gi = mySignalGroups.begin(); gi != mySignalGroups.end(); gi++) { std::string groupName = (*gi).first; NIVisumTL::SignalGroup& SG = *(*gi).second; def->addSignalGroup(groupName); def->addToSignalGroup(groupName, SG.connections()); // phases SUMOTime yellowTime = -1; if (myPhaseDefined) { for (std::map<std::string, Phase*>::iterator pi = SG.phases().begin(); pi != SG.phases().end(); pi++) { NIVisumTL::Phase& PH = *(*pi).second; def->addSignalGroupPhaseBegin(groupName, PH.getStartTime(), NBTrafficLightDefinition::TLCOLOR_GREEN); def->addSignalGroupPhaseBegin(groupName, PH.getEndTime(), NBTrafficLightDefinition::TLCOLOR_RED); yellowTime = MAX2(PH.getYellowTime(), yellowTime); }; } else { def->addSignalGroupPhaseBegin(groupName, SG.getStartTime(), NBTrafficLightDefinition::TLCOLOR_GREEN); def->addSignalGroupPhaseBegin(groupName, SG.getEndTime(), NBTrafficLightDefinition::TLCOLOR_RED); yellowTime = MAX2(SG.getYellowTime(), yellowTime); } // yellowTime can be -1 if not given in the input; it will be "patched" later def->setSignalYellowTimes(groupName, myIntermediateTime, yellowTime); } } }
bool NIVissimTL::dict_SetSignals(NBTrafficLightLogicCont& tlc, NBEdgeCont& ec) { size_t ref = 0; size_t ref_groups = 0; size_t ref_signals = 0; size_t no_signals = 0; size_t no_groups = 0; for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { NIVissimTL* tl = (*i).second; /* if(tl->myType!="festzeit") { cout << " Warning: The traffic light '" << tl->myID << "' could not be assigned to a node." << endl; ref++; continue; }*/ std::string id = toString<int>(tl->myID); TrafficLightType type = ((tl->getType() == "festzeit" || tl->getType() == "festzeit_fake") ? TLTYPE_STATIC : TLTYPE_ACTUATED); NBLoadedTLDef* def = new NBLoadedTLDef(id, 0, type); if (!tlc.insert(def)) { WRITE_ERROR("Error on adding a traffic light\n Must be a multiple id ('" + id + "')"); continue; } def->setCycleDuration((unsigned int) tl->myAbsDuration); // add each group to the node's container SGroupDictType sgs = NIVissimTLSignalGroup::getGroupsFor(tl->getID()); for (SGroupDictType::const_iterator j = sgs.begin(); j != sgs.end(); j++) { if (!(*j).second->addTo(def)) { WRITE_WARNING("The signal group '" + toString<int>((*j).first) + "' could not be assigned to tl '" + toString<int>(tl->myID) + "'."); ref_groups++; } no_groups++; } // add the signal group signals to the node SSignalDictType signals = NIVissimTLSignal::getSignalsFor(tl->getID()); for (SSignalDictType::const_iterator k = signals.begin(); k != signals.end(); k++) { if (!(*k).second->addTo(ec, def)) { WRITE_WARNING("The signal '" + toString<int>((*k).first) + "' could not be assigned to tl '" + toString<int>(tl->myID) + "'."); ref_signals++; } no_signals++; } } if (ref != 0) { WRITE_WARNING("Could not set " + toString<size_t>(ref) + " of " + toString<size_t>(myDict.size()) + " traffic lights."); } if (ref_groups != 0) { WRITE_WARNING("Could not set " + toString<size_t>(ref_groups) + " of " + toString<size_t>(no_groups) + " groups."); } if (ref_signals != 0) { WRITE_WARNING("Could not set " + toString<size_t>(ref_signals) + " of " + toString<size_t>(no_signals) + " signals."); } return true; }
void NBNodeCont::setAsTLControlled(NBNode* node, NBTrafficLightLogicCont& tlc, TrafficLightType type, std::string id) { if (id == "") { id = node->getID(); } NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, node, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Building a tl-logic for node '" + id + "' twice is not possible."); delete tlDef; return; } }
void NBNodeCont::joinTLS(NBTrafficLightLogicCont& tlc, SUMOReal maxdist) { std::vector<std::set<NBNode*> > cands; generateNodeClusters(maxdist, cands); unsigned int index = 0; for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end(); ++i) { std::set<NBNode*>& c = (*i); for (std::set<NBNode*>::iterator j = c.begin(); j != c.end();) { if (!(*j)->isTLControlled()) { c.erase(j++); } else { ++j; } } if (c.size() < 2) { continue; } // figure out type of the joined TLS Position dummyPos; bool dummySetTL; std::string dummyId; TrafficLightType type; analyzeCluster(c, dummyId, dummyPos, dummySetTL, type); for (std::set<NBNode*>::iterator j = c.begin(); j != c.end(); ++j) { std::set<NBTrafficLightDefinition*> tls = (*j)->getControllingTLS(); (*j)->removeTrafficLights(); for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) { tlc.removeFully((*j)->getID()); } } std::string id = "joinedS_" + toString(index++); std::vector<NBNode*> nodes; for (std::set<NBNode*>::iterator j = c.begin(); j != c.end(); j++) { nodes.push_back(*j); } NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, nodes, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build a joined tls."); delete tlDef; return; } } }
void NBNodeCont::guessTLs(OptionsCont& oc, NBTrafficLightLogicCont& tlc) { // build list of definitely not tls-controlled junctions std::vector<NBNode*> ncontrolled; if (oc.isSet("tls.unset")) { std::vector<std::string> notTLControlledNodes = oc.getStringVector("tls.unset"); for (std::vector<std::string>::const_iterator i = notTLControlledNodes.begin(); i != notTLControlledNodes.end(); ++i) { NBNode* n = NBNodeCont::retrieve(*i); if (n == 0) { throw ProcessError(" The node '" + *i + "' to set as not-controlled is not known."); } std::set<NBTrafficLightDefinition*> tls = n->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::const_iterator j = tls.begin(); j != tls.end(); ++j) { (*j)->removeNode(n); } n->removeTrafficLights(); ncontrolled.push_back(n); } } TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(OptionsCont::getOptions().getString("tls.default-type")); // loop#1 checking whether the node shall be tls controlled, // because it is assigned to a district if (oc.exists("tls.taz-nodes") && oc.getBool("tls.taz-nodes")) { for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; if (cur->isNearDistrict() && find(ncontrolled.begin(), ncontrolled.end(), cur) == ncontrolled.end()) { setAsTLControlled(cur, tlc, type); } } } // maybe no tls shall be guessed if (!oc.getBool("tls.guess")) { return; } // guess joined tls first, if wished if (oc.getBool("tls.join")) { // get node clusters std::vector<std::set<NBNode*> > cands; generateNodeClusters(oc.getFloat("tls.join-dist"), cands); // check these candidates (clusters) whether they should be controlled by a tls for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end();) { std::set<NBNode*>& c = (*i); // regard only junctions which are not yet controlled and are not // forbidden to be controlled for (std::set<NBNode*>::iterator j = c.begin(); j != c.end();) { if ((*j)->isTLControlled() || find(ncontrolled.begin(), ncontrolled.end(), *j) != ncontrolled.end()) { c.erase(j++); } else { ++j; } } // check whether the cluster should be controlled if (!shouldBeTLSControlled(c)) { i = cands.erase(i); } else { ++i; } } // cands now only contain sets of junctions that shall be joined into being tls-controlled unsigned int index = 0; for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end(); ++i) { std::vector<NBNode*> nodes; for (std::set<NBNode*>::iterator j = (*i).begin(); j != (*i).end(); j++) { nodes.push_back(*j); } std::string id = "joinedG_" + toString(index++); NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, nodes, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build guessed, joined tls"); delete tlDef; return; } } } // guess tls for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; // do nothing if already is tl-controlled if (cur->isTLControlled()) { continue; } // do nothing if in the list of explicit non-controlled junctions if (find(ncontrolled.begin(), ncontrolled.end(), cur) != ncontrolled.end()) { continue; } std::set<NBNode*> c; c.insert(cur); if (!shouldBeTLSControlled(c) || cur->getIncomingEdges().size() < 3) { continue; } setAsTLControlled((*i).second, tlc, type); } }
void NBNodeCont::joinNodeClusters(NodeClusters clusters, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) { for (NodeClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) { std::set<NBNode*> cluster = *i; assert(cluster.size() > 1); Position pos; bool setTL; std::string id; TrafficLightType type; analyzeCluster(cluster, id, pos, setTL, type); if (!insert(id, pos)) { // should not fail WRITE_WARNING("Could not join junctions " + id); continue; } NBNode* newNode = retrieve(id); if (setTL) { NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, newNode, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here delete tlDef; throw ProcessError("Could not allocate tls '" + id + "'."); } } // collect edges std::set<NBEdge*> allEdges; for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) { const EdgeVector& edges = (*j)->getEdges(); allEdges.insert(edges.begin(), edges.end()); } // remap and remove edges which are completely within the new intersection for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) { NBEdge* e = (*j); NBNode* from = e->getFromNode(); NBNode* to = e->getToNode(); if (cluster.count(from) > 0 && cluster.count(to) > 0) { for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) { if (e != *l) { (*l)->replaceInConnections(e, e->getConnections()); } } ec.erase(dc, e); allEdges.erase(j++); // erase does not invalidate the other iterators } else { ++j; } } // remap edges which are incoming / outgoing for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) { NBEdge* e = (*j); std::vector<NBEdge::Connection> conns = e->getConnections(); const bool outgoing = cluster.count(e->getFromNode()) > 0; NBNode* from = outgoing ? newNode : e->getFromNode(); NBNode* to = outgoing ? e->getToNode() : newNode; e->reinitNodes(from, to); // re-add connections which previously existed and may still valid. // connections to removed edges will be ignored for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) { e->addLane2LaneConnection((*k).fromLane, (*k).toEdge, (*k).toLane, NBEdge::L2L_USER, false, (*k).mayDefinitelyPass); } } // remove original nodes registerJoinedCluster(cluster); for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) { erase(*j); } } }
void NBNodeCont::guessTLs(OptionsCont& oc, NBTrafficLightLogicCont& tlc) { // build list of definitely not tls-controlled junctions std::vector<NBNode*> ncontrolled; if (oc.isSet("tls.unset")) { std::vector<std::string> notTLControlledNodes = oc.getStringVector("tls.unset"); for (std::vector<std::string>::const_iterator i = notTLControlledNodes.begin(); i != notTLControlledNodes.end(); ++i) { NBNode* n = NBNodeCont::retrieve(*i); if (n == 0) { throw ProcessError(" The node '" + *i + "' to set as not-controlled is not known."); } std::set<NBTrafficLightDefinition*> tls = n->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::const_iterator j = tls.begin(); j != tls.end(); ++j) { (*j)->removeNode(n); } n->removeTrafficLights(); ncontrolled.push_back(n); } } TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(OptionsCont::getOptions().getString("tls.default-type")); // loop#1 checking whether the node shall be tls controlled, // because it is assigned to a district if (oc.exists("tls.taz-nodes") && oc.getBool("tls.taz-nodes")) { for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; if (cur->isNearDistrict() && find(ncontrolled.begin(), ncontrolled.end(), cur) == ncontrolled.end()) { setAsTLControlled(cur, tlc, type); } } } // figure out which nodes mark the locations of TLS signals // This assumes nodes are already joined if (oc.exists("tls.guess-signals") && oc.getBool("tls.guess-signals")) { // prepare candidate edges const SUMOReal signalDist = oc.getFloat("tls.guess-signals.dist"); for (std::map<std::string, NBNode*>::const_iterator i = myNodes.begin(); i != myNodes.end(); ++i) { NBNode* node = (*i).second; if (node->isTLControlled() && node->geometryLike()) { const EdgeVector& outgoing = node->getOutgoingEdges(); for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) { (*it_o)->setSignalOffset((*it_o)->getLength()); } } } // check which nodes should be controlled for (std::map<std::string, NBNode*>::const_iterator i = myNodes.begin(); i != myNodes.end(); ++i) { NBNode* node = i->second; const EdgeVector& incoming = node->getIncomingEdges(); if (!node->isTLControlled() && incoming.size() > 1 && !node->geometryLike()) { std::vector<NBNode*> signals; bool isTLS = true; for (EdgeVector::const_iterator it_i = incoming.begin(); it_i != incoming.end(); ++it_i) { const NBEdge* inEdge = *it_i; if (inEdge->getSignalOffset() == NBEdge::UNSPECIFIED_SIGNAL_OFFSET || inEdge->getSignalOffset() > signalDist) { isTLS = false; break; } if (inEdge->getSignalOffset() == inEdge->getLength()) { signals.push_back(inEdge->getFromNode()); } } if (isTLS) { for (std::vector<NBNode*>::iterator j = signals.begin(); j != signals.end(); ++j) { std::set<NBTrafficLightDefinition*> tls = (*j)->getControllingTLS(); (*j)->removeTrafficLights(); for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) { tlc.removeFully((*j)->getID()); } } NBTrafficLightDefinition* tlDef = new NBOwnTLDef("GS_" + node->getID(), node, 0, TLTYPE_STATIC); // @todo patch endOffset for all incoming lanes according to the signal positions if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build joined tls '" + node->getID() + "'."); delete tlDef; return; } } } } } // maybe no tls shall be guessed if (!oc.getBool("tls.guess")) { return; } // guess joined tls first, if wished if (oc.getBool("tls.join")) { // get node clusters std::vector<std::set<NBNode*> > cands; generateNodeClusters(oc.getFloat("tls.join-dist"), cands); // check these candidates (clusters) whether they should be controlled by a tls for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end();) { std::set<NBNode*>& c = (*i); // regard only junctions which are not yet controlled and are not // forbidden to be controlled for (std::set<NBNode*>::iterator j = c.begin(); j != c.end();) { if ((*j)->isTLControlled() || find(ncontrolled.begin(), ncontrolled.end(), *j) != ncontrolled.end()) { c.erase(j++); } else { ++j; } } // check whether the cluster should be controlled if (!shouldBeTLSControlled(c)) { i = cands.erase(i); } else { ++i; } } // cands now only contain sets of junctions that shall be joined into being tls-controlled unsigned int index = 0; for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end(); ++i) { std::vector<NBNode*> nodes; for (std::set<NBNode*>::iterator j = (*i).begin(); j != (*i).end(); j++) { nodes.push_back(*j); } std::string id = "joinedG_" + toString(index++); NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, nodes, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build guessed, joined tls"); delete tlDef; return; } } } // guess tls for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; // do nothing if already is tl-controlled if (cur->isTLControlled()) { continue; } // do nothing if in the list of explicit non-controlled junctions if (find(ncontrolled.begin(), ncontrolled.end(), cur) != ncontrolled.end()) { continue; } std::set<NBNode*> c; c.insert(cur); if (!shouldBeTLSControlled(c) || cur->getIncomingEdges().size() < 3) { continue; } setAsTLControlled((*i).second, tlc, type); } }