47 #ifdef CHECK_MEMORY_LEAKS
49 #endif // CHECK_MEMORY_LEAKS
56 const std::vector<NBNode*>& junctions,
SUMOTime offset,
59 myHaveSinglePhase(false)
66 myHaveSinglePhase(false)
73 myHaveSinglePhase(false)
106 for (
unsigned int e1l = 0; e1l < e1->
getNumLanes(); e1l++) {
108 for (
unsigned int e2l = 0; e2l < e2->
getNumLanes(); e2l++) {
110 for (std::vector<NBEdge::Connection>::iterator e1c = approached1.begin(); e1c != approached1.end(); ++e1c) {
114 for (std::vector<NBEdge::Connection>::iterator e2c = approached2.begin(); e2c != approached2.end(); ++e2c) {
118 if (!
foes(e1, (*e1c).toEdge, e2, (*e2c).toEdge)) {
130 std::pair<NBEdge*, NBEdge*>
132 std::pair<NBEdge*, NBEdge*> bestPair(static_cast<NBEdge*>(0), static_cast<NBEdge*>(0));
134 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
135 for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) {
137 if (value > bestValue) {
139 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
140 }
else if (value == bestValue) {
142 const SUMOReal oa =
GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode()));
144 if (bestPair.first->getID() < (*i)->getID()) {
145 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
147 }
else if (oa < ca) {
148 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
157 std::pair<NBEdge*, NBEdge*>
159 if (incoming.size() == 1) {
161 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(),
static_cast<NBEdge*
>(0));
169 used.push_back(*incoming.begin());
172 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio !=
getToPrio(*i); ++i) {
176 if (used.size() < 2) {
180 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
181 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
193 std::vector<bool> isLeftMoverV, isTurnaround;
194 unsigned int noLanesAll = 0;
195 unsigned int noLinksAll = 0;
196 for (
unsigned int i1 = 0; i1 < incoming.size(); i1++) {
197 unsigned int noLanes = incoming[i1]->getNumLanes();
198 noLanesAll += noLanes;
199 for (
unsigned int i2 = 0; i2 < noLanes; i2++) {
200 NBEdge* fromEdge = incoming[i1];
202 noLinksAll += (
unsigned int) approached.size();
203 for (
unsigned int i3 = 0; i3 < approached.size(); i3++) {
204 if (!fromEdge->
mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
208 assert(i3 < approached.size());
209 NBEdge* toEdge = approached[i3].toEdge;
210 fromEdges.push_back(fromEdge);
212 toEdges.push_back(toEdge);
214 isLeftMoverV.push_back(
219 isTurnaround.push_back(
223 isLeftMoverV.push_back(
true);
224 isTurnaround.push_back(
true);
230 std::vector<NBNode::Crossing> crossings;
232 const std::vector<NBNode::Crossing>& c = (*i)->getCrossings();
234 (*i)->setCrossingTLIndices(noLinksAll);
235 copy(c.begin(), c.end(), std::back_inserter(crossings));
236 noLinksAll += (
unsigned int)c.size();
243 while (toProc.size() > 0) {
244 std::pair<NBEdge*, NBEdge*> chosen;
245 if (incoming.size() == 2) {
246 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(0));
247 toProc.erase(toProc.begin());
251 unsigned int pos = 0;
252 std::string state((
size_t) noLinksAll,
'r');
254 for (
unsigned int i1 = 0; i1 < (
unsigned int) incoming.size(); ++i1) {
255 NBEdge* fromEdge = incoming[i1];
256 const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second;
257 const unsigned int numLanes = fromEdge->
getNumLanes();
258 for (
unsigned int i2 = 0; i2 < numLanes; i2++) {
260 for (
unsigned int i3 = 0; i3 < approached.size(); ++i3) {
261 if (!fromEdge->
mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
274 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
275 if (state[i1] ==
'G') {
279 for (
unsigned int i2 = 0; i2 < pos && !
isForbidden; ++i2) {
280 if (state[i2] ==
'G' && !isTurnaround[i2] &&
281 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
290 bool haveForbiddenLeftMover =
false;
291 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
292 if (state[i1] !=
'G') {
295 for (
unsigned int i2 = 0; i2 < pos; ++i2) {
296 if ((state[i2] ==
'G' || state[i2] ==
'g') &&
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true)) {
298 if (!isTurnaround[i1]) {
299 haveForbiddenLeftMover =
true;
306 for (
unsigned int i1 = pos; i1 < pos + crossings.size(); ++i1) {
310 if (brakingTime > 0) {
312 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
313 if (state[i1] !=
'G' && state[i1] !=
'g') {
316 if ((state[i1] >=
'a' && state[i1] <=
'z') && haveForbiddenLeftMover) {
322 logic->
addStep(brakingTime, state);
327 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
328 if (state[i1] ==
'Y' || state[i1] ==
'y') {
332 if (state[i1] ==
'g') {
337 logic->
addStep(leftTurnTime, state);
340 if (brakingTime > 0) {
341 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
342 if (state[i1] !=
'G' && state[i1] !=
'g') {
348 logic->
addStep(brakingTime, state);
353 if (totalDuration > 0) {
354 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) {
368 std::string state,
const std::vector<NBNode::Crossing>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
371 const std::string orig = state;
375 logic->
addStep(greenTime, state);
377 const SUMOTime pedTime = greenTime - pedClearingTime;
378 if (pedTime >= minPedTime) {
380 const size_t pedStates = crossings.size();
381 logic->
addStep(pedTime, state);
382 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
383 logic->
addStep(pedClearingTime, state);
387 logic->
addStep(greenTime, state);
396 std::string result = state;
397 const unsigned int pos = (
unsigned int)(state.size() - crossings.size());
398 for (
int ic = 0; ic < (
int)crossings.size(); ++ic) {
399 const int i1 = pos + ic;
402 for (
unsigned int i2 = 0; i2 < pos && !
isForbidden; ++i2) {
404 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
405 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
408 if (state[i2] !=
'r' && (edge == fromEdges[i2] ||
424 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
425 if (result[i1] ==
'G') {
426 for (
int ic = 0; ic < (
int)crossings.size(); ++ic) {
428 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
429 const int i2 = pos + ic;
static std::string patchStateForCrossings(const std::string &state, const std::vector< NBNode::Crossing > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
compute phase state in regard to pedestrian crossings
The link is a partial left direction.
bool setControllingTLInformation(const NBConnection &c, const std::string &tlID)
Returns if the link could be set as to be controlled.
TrafficLightType myType
The algorithm type for the traffic light.
void collectAllLinks()
helper method for use in NBOwnTLDef and NBLoadedSUMOTLDef
void closeBuilding()
closes the building process
A SUMO-compliant built logic for a traffic light.
const std::string & getProgramID() const
Returns the ProgramID.
The representation of a single edge during network building.
bool mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const
The link is a 180 degree turn.
void collectNodes()
Collects the nodes participating in this traffic light.
std::string time2string(SUMOTime t)
The base class for traffic light logic definitions.
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
const EdgeVector & getIncomingEdges() const
Returns the list of incoming edges (must be build first)
bool isTurningDirectionAt(const NBNode *n, const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
std::vector< Connection > getConnectionsFromLane(unsigned int lane) const
Returns connections from a given lane.
SUMOTime myOffset
The offset in the program.
NBEdge * getFrom() const
returns the from-edge (start of the connection)
The link is a (hard) left direction.
#define WRITE_WARNING(msg)
std::pair< NBEdge *, NBEdge * > getBestPair(EdgeVector &incoming)
Returns the combination of two edges from the given which has most unblocked streams.
static OptionsCont & getOptions()
Retrieves the options.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
The link is a straight direction.
const std::string & getID() const
Returns the id.
void collectEdges()
Build the list of participating edges.
bool mustBrakeForCrossing(const NBEdge *const from, const NBEdge *const to, const Crossing &crossing) const
Returns the information whether the described flow must brake for the given crossing.
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces a removed edge/lane.
std::pair< NBEdge *, NBEdge * > getBestCombination(const EdgeVector &edges)
Returns the combination of two edges from the given which has most unblocked streams.
bool myHaveSinglePhase
Whether left-mover should not have an additional phase.
unsigned int getNumLanes() const
Returns the number of lanes.
Storage for edges, including some functionality operating on multiple edges.
The link is a (hard) right direction.
static std::string addPedestrianPhases(NBTrafficLightLogic *logic, SUMOTime greenTime, std::string state, const std::vector< NBNode::Crossing > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
add 1 or 2 phases depending on the presence of pedestrian crossings
The link is a partial right direction.
SUMOTime getDuration() const
Returns the duration of the complete cycle.
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
SUMOReal computeUnblockedWeightedStreamNumber(const NBEdge *const e1, const NBEdge *const e2)
Returns how many streams outgoing from the edges can pass the junction without being blocked...
NBOwnTLDef(const std::string &id, const std::vector< NBNode * > &junctions, SUMOTime offset, TrafficLightType type)
Constructor.
NBNode * getToNode() const
Returns the destination node of the edge.
void setTLControllingInformation(const NBEdgeCont &ec) const
Informs edges about being controlled by a tls.
void collectLinks()
Collects the links participating in this traffic light If a link could not be found.
SUMOReal getDirectionalWeight(LinkDirection dir)
Returns the weight of a stream given its direction.
std::vector< NBEdge * > EdgeVector
NBTrafficLightLogic * myCompute(const NBEdgeCont &ec, unsigned int brakingTimeSeconds)
Computes the traffic light logic finally in dependence to the type.
static SUMOReal getMinAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
const NBNode * node
The parent node of this crossing.
EdgeVector edges
The edges being crossed.
Represents a single node (junction) during network building.
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
A definition of a pedestrian crossing.
NBEdge * getTurnDestination() const
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
returns the information whether the given link is a left-mover
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
void addStep(SUMOTime duration, const std::string &state, int index=-1)
Adds a phase to the logic.
Sorts edges by their priority within the node they end at.
void setParticipantsInformation()
Builds the list of participating nodes/edges/links.
NBConnectionVector myControlledLinks
The list of controlled links.
int getToPrio(const NBEdge *const e)
Returns this edge's priority at the node it ends at.
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurences of the removed edge in incoming/outgoing edges of all definitions.
The link has no direction (is a dead end link)
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing) const
Returns the representation of the described stream's direction.