unsigned int NIVissimConnection::buildEdgeConnections(NBEdgeCont &ec) { unsigned int unsetConnections = 0; // try to determine the connected edges NBEdge *fromEdge = 0; NBEdge *toEdge = 0; NIVissimEdge *vissimFrom = NIVissimEdge::dictionary(getFromEdgeID()); if (vissimFrom->wasWithinAJunction()) { // this edge was not built, try to get one that approaches it vissimFrom = vissimFrom->getBestIncoming(); if (vissimFrom!=0) { fromEdge = ec.retrievePossiblySplitted(toString(vissimFrom->getID()), toString(getFromEdgeID()), true); } } else { // this edge was built, try to get the proper part fromEdge = ec.retrievePossiblySplitted(toString(getFromEdgeID()), toString(getToEdgeID()), true); } NIVissimEdge *vissimTo = NIVissimEdge::dictionary(getToEdgeID()); if (vissimTo->wasWithinAJunction()) { vissimTo = vissimTo->getBestOutgoing(); if (vissimTo!=0) { toEdge = ec.retrievePossiblySplitted(toString(vissimTo->getID()), toString(getToEdgeID()), true); } } else { toEdge = ec.retrievePossiblySplitted(toString(getToEdgeID()), toString(getFromEdgeID()), false); } // try to get the edges the current connection connects /* NBEdge *fromEdge = ec.retrievePossiblySplitted(toString(getFromEdgeID()), toString(getToEdgeID()), true); NBEdge *toEdge = ec.retrievePossiblySplitted(toString(getToEdgeID()), toString(getFromEdgeID()), false); */ if (fromEdge==0||toEdge==0) { WRITE_WARNING("Could not build connection between '" + toString(getFromEdgeID())+ "' and '" + toString(getToEdgeID())+ "'."); return 1; // !!! actually not 1 } recheckLanes(fromEdge, toEdge); const IntVector &fromLanes = getFromLanes(); const IntVector &toLanes = getToLanes(); if (fromLanes.size()!=toLanes.size()) { MsgHandler::getWarningInstance()->inform("Lane sizes differ for connection '" + toString(getID()) + "'."); } else { for (unsigned int index=0; index<fromLanes.size(); ++index) { if (fromEdge->getNoLanes()<=static_cast<unsigned int>(fromLanes[index])) { MsgHandler::getWarningInstance()->inform("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'."); ++unsetConnections; } else if (!fromEdge->addLane2LaneConnection(fromLanes[index], toEdge, toLanes[index], NBEdge::L2L_VALIDATED)) { MsgHandler::getWarningInstance()->inform("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'."); ++unsetConnections; } } } return unsetConnections; }
void NBOwnTLDef::collectLinks() throw(ProcessError) { // build the list of links which are controled by the traffic light for (EdgeVector::iterator i=myIncomingEdges.begin(); i!=myIncomingEdges.end(); i++) { NBEdge *incoming = *i; unsigned int noLanes = incoming->getNoLanes(); for (unsigned int j=0; j<noLanes; j++) { std::vector<NBEdge::Connection> connected = incoming->getConnectionsFromLane(j); for (std::vector<NBEdge::Connection>::iterator k=connected.begin(); k!=connected.end(); k++) { const NBEdge::Connection &el = *k; if (incoming->mayBeTLSControlled(el.fromLane, el.toEdge, el.toLane)) { if (el.toEdge!=0&&el.toLane>=(int) el.toEdge->getNoLanes()) { throw ProcessError("Connection '" + incoming->getID() + "_" + toString(j) + "->" + el.toEdge->getID() + "_" + toString(el.toLane) + "' yields in a not existing lane."); } myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane)); } } } } }
void NIXMLEdgesHandler::myEndElement(SumoXMLTag element) throw(ProcessError) { if (element==SUMO_TAG_EDGE && myCurrentEdge!=0) { if (!myIsUpdate) { try { if (!myEdgeCont.insert(myCurrentEdge)) { MsgHandler::getErrorInstance()->inform("Duplicate edge occured. ID='" + myCurrentID + "'"); delete myCurrentEdge; } } catch (InvalidArgument &e) { MsgHandler::getErrorInstance()->inform(e.what()); throw; } catch (...) { MsgHandler::getErrorInstance()->inform("An important information is missing in edge '" + myCurrentID + "'."); } } if (mySplits.size()!=0) { std::vector<Split>::iterator i, i2; sort(mySplits.begin(), mySplits.end(), split_sorter()); NBEdge *e = myCurrentEdge; unsigned int noLanesMax = e->getNoLanes(); // compute the node positions and sort the lanes for (i=mySplits.begin(); i!=mySplits.end(); ++i) { (*i).gpos = e->getGeometry().positionAtLengthPosition((*i).pos); sort((*i).lanes.begin(), (*i).lanes.end()); noLanesMax = MAX2(noLanesMax, (unsigned int)(*i).lanes.size()); } // split the edge std::vector<int> currLanes; for (unsigned int l=0; l<noLanesMax; ++l) { currLanes.push_back(l); } std::string edgeid = e->getID(); SUMOReal seen = 0; for (i=mySplits.begin(); i!=mySplits.end(); ++i) { const Split &exp = *i; assert(exp.lanes.size()!=0); if (exp.pos>0 && e->getGeometry().length()+seen>exp.pos) { std::string nid = edgeid + "." + toString(exp.nameid); NBNode *rn = new NBNode(nid, exp.gpos); if (myNodeCont.insert(rn)) { // split the edge std::string nid = myCurrentID + "." + toString(exp.nameid); std::string pid = e->getID(); myEdgeCont.splitAt(myDistrictCont, e, exp.pos-seen, rn, pid, nid, e->getNoLanes(), (unsigned int) exp.lanes.size()); seen = exp.pos; std::vector<int> newLanes = exp.lanes; NBEdge *pe = myEdgeCont.retrieve(pid); NBEdge *ne = myEdgeCont.retrieve(nid); // reconnect lanes pe->invalidateConnections(true); // new on right unsigned int rightMostP = currLanes[0]; unsigned int rightMostN = newLanes[0]; for (int l=0; l<(int) rightMostP-(int) rightMostN; ++l) { pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true); } // new on left unsigned int leftMostP = currLanes.back(); unsigned int leftMostN = newLanes.back(); for (int l=0; l<(int) leftMostN-(int) leftMostP; ++l) { pe->addLane2LaneConnection(pe->getNoLanes()-1, ne, leftMostN-l, NBEdge::L2L_VALIDATED, true); } // all other connected for (unsigned int l=0; l<noLanesMax; ++l) { if (find(currLanes.begin(), currLanes.end(), l)==currLanes.end()) { continue; } if (find(newLanes.begin(), newLanes.end(), l)==newLanes.end()) { continue; } pe->addLane2LaneConnection(l-rightMostP, ne, l-rightMostN, NBEdge::L2L_VALIDATED, true); } // move to next e = ne; currLanes = newLanes; } else { MsgHandler::getWarningInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "')."); } } else if (exp.pos==0) { e->decLaneNo(e->getNoLanes()-exp.lanes.size()); currLanes = exp.lanes; } else { MsgHandler::getWarningInstance()->inform("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "')."); } } // patch lane offsets e = myEdgeCont.retrieve(edgeid); i = mySplits.begin(); if ((*i).pos!=0) { e = e->getToNode()->getOutgoingEdges()[0]; } for (; i!=mySplits.end(); ++i) { unsigned int maxLeft = (*i).lanes.back(); if (maxLeft<noLanesMax) { Position2DVector g = e->getGeometry(); g.move2side(SUMO_const_laneWidthAndOffset*(noLanesMax-1-maxLeft)); e->setGeometry(g); } if (e->getToNode()->getOutgoingEdges().size()!=0) { e = e->getToNode()->getOutgoingEdges()[0]; } } } } }
bool NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont &ec, NBLoadedTLDef *tl) const { NIVissimConnection *c = NIVissimConnection::dictionary(myEdgeID); NBConnectionVector assignedConnections; if (c==0) { // What to do if on an edge? -> close all outgoing connections NBEdge *edge = ec.retrievePossiblySplitted(toString<int>(myEdgeID), myPosition); if (edge==0) { MsgHandler::getWarningInstance()->inform("Could not set tls signal at edge '" + toString(myEdgeID) + "' - the edge was not built."); return false; } // Check whether it is already known, which edges are approached // by which lanes // check whether to use the original lanes only if (edge->lanesWereAssigned()) { std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane-1); for (std::vector<NBEdge::Connection>::iterator i=connections.begin(); i!=connections.end(); i++) { const NBEdge::Connection &conn = *i; assert(myLane-1<(int)edge->getNoLanes()); assignedConnections.push_back(NBConnection(edge, myLane-1, conn.toEdge, conn.toLane)); } } else { WRITE_WARNING("Edge : Lanes were not assigned(!)"); for (unsigned int j=0; j<edge->getNoLanes(); j++) { std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j); for (std::vector<NBEdge::Connection>::iterator i=connections.begin(); i!=connections.end(); i++) { const NBEdge::Connection &conn = *i; assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane)); } } } } else { // get the edges NBEdge *tmpFrom = ec.retrievePossiblySplitted( toString<int>(c->getFromEdgeID()), toString<int>(c->getToEdgeID()), true); NBEdge *tmpTo = ec.retrievePossiblySplitted( toString<int>(c->getToEdgeID()), toString<int>(c->getFromEdgeID()), false); // check whether the edges are known if (tmpFrom!=0&&tmpTo!=0) { // add connections this signal is responsible for assignedConnections.push_back(NBConnection(tmpFrom, -1, tmpTo, -1)); } else { return false; // !!! one of the edges could not be build } } // add to the group assert(myGroupIDs.size()!=0); if (myGroupIDs.size()==1) { return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())), assignedConnections); } else { // !!! return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())), assignedConnections); } return true; }
NBTrafficLightLogic * NBOwnTLDef::myCompute(const NBEdgeCont &, unsigned int brakingTime) throw() { // build complete lists first const EdgeVector &incoming = getIncomingEdges(); std::vector<NBEdge*> fromEdges, toEdges; std::vector<bool> isLeftMoverV, isTurnaround; unsigned int noLanesAll = 0; unsigned int noLinksAll = 0; for (unsigned int i1=0; i1<incoming.size(); i1++) { unsigned int noLanes = incoming[i1]->getNoLanes(); noLanesAll += noLanes; for (unsigned int i2=0; i2<noLanes; i2++) { NBEdge *fromEdge = incoming[i1]; std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2); noLinksAll += (unsigned int) approached.size(); for (unsigned int i3=0; i3<approached.size(); i3++) { if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) { --noLinksAll; continue; } assert(i3<approached.size()); NBEdge *toEdge = approached[i3].toEdge; fromEdges.push_back(fromEdge); //myFromLanes.push_back(i2); toEdges.push_back(toEdge); if (toEdge!=0) { isLeftMoverV.push_back( isLeftMover(fromEdge, toEdge) || fromEdge->isTurningDirectionAt(fromEdge->getToNode(), toEdge)); isTurnaround.push_back( fromEdge->isTurningDirectionAt( fromEdge->getToNode(), toEdge)); } else { isLeftMoverV.push_back(true); isTurnaround.push_back(true); } } } } NBTrafficLightLogic *logic = new NBTrafficLightLogic(getID(), "0", noLinksAll); std::vector<NBEdge*> toProc = incoming; // build all phases while (toProc.size()>0) { std::pair<NBEdge*, NBEdge*> chosen; if (incoming.size()==2) { chosen = std::pair<NBEdge*, NBEdge*>(toProc[0], static_cast<NBEdge*>(0)); toProc.erase(toProc.begin()); } else { chosen = getBestPair(toProc); } unsigned int pos = 0; unsigned int duration = 31; if (OptionsCont::getOptions().isSet("traffic-light-green")) { duration = OptionsCont::getOptions().getInt("traffic-light-green"); } std::string state((size_t) noLinksAll, 'o'); // plain straight movers for (unsigned int i1=0; i1<(unsigned int) incoming.size(); ++i1) { NBEdge *fromEdge = incoming[i1]; bool inChosen = fromEdge==chosen.first||fromEdge==chosen.second;//chosen.find(fromEdge)!=chosen.end(); unsigned int noLanes = fromEdge->getNoLanes(); for (unsigned int i2=0; i2<noLanes; i2++) { std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2); for (unsigned int i3=0; i3<approached.size(); ++i3) { if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) { continue; } if (inChosen) { state[pos] = 'G'; } else { state[pos] = 'r'; } ++pos; } } } // correct behaviour for those that are not in chosen, but may drive, though for (unsigned int i1=0; i1<pos; ++i1) { if (state[i1]=='G') { continue; } bool isForbidden = false; for (unsigned int i2=0; i2<pos&&!isForbidden; ++i2) { if (state[i2]=='G'&&!isTurnaround[i2]&& (forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true)||forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2], true))) { isForbidden = true; } } if (!isForbidden) { state[i1] = 'G'; } } // correct behaviour for those that have to wait (mainly left-mover) bool haveForbiddenLeftMover = false; for (unsigned int i1=0; i1<pos; ++i1) { if (state[i1]!='G') { continue; } for (unsigned int i2=0; i2<pos; ++i2) { if ((state[i2]=='G'||state[i2]=='g')&&forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true)) { state[i1] = 'g'; if (!isTurnaround[i1]) { haveForbiddenLeftMover = true; } } } } // add step logic->addStep(duration, state); if (brakingTime>0) { // build yellow (straight) duration = brakingTime; for (unsigned int i1=0; i1<pos; ++i1) { if (state[i1]!='G'&&state[i1]!='g') { continue; } if ((state[i1]>='a'&&state[i1]<='z')&&haveForbiddenLeftMover) { continue; } state[i1] = 'y'; } // add step logic->addStep(duration, state); } if (haveForbiddenLeftMover) { // build left green duration = 6; for (unsigned int i1=0; i1<pos; ++i1) { if (state[i1]=='Y'||state[i1]=='y') { state[i1] = 'r'; continue; } if (state[i1]=='g') { state[i1] = 'G'; } } // add step logic->addStep(duration, state); // build left yellow if (brakingTime>0) { duration = brakingTime; for (unsigned int i1=0; i1<pos; ++i1) { if (state[i1]!='G'&&state[i1]!='g') { continue; } state[i1] = 'y'; } // add step logic->addStep(duration, state); } } } if (logic->getDuration()>0) { return logic; } else { delete logic; return 0; } }