47 #ifdef CHECK_MEMORY_LEAKS 49 #endif // CHECK_MEMORY_LEAKS 51 #define DUMMY_ID "dummy" 52 #define MIN_GREEN_TIME 5 58 const std::vector<NBNode*>& junctions,
SUMOTime offset,
61 myHaveSinglePhase(false)
107 for (
unsigned int e1l = 0; e1l < e1->
getNumLanes(); e1l++) {
109 for (
unsigned int e2l = 0; e2l < e2->
getNumLanes(); e2l++) {
111 for (std::vector<NBEdge::Connection>::iterator e1c = approached1.begin(); e1c != approached1.end(); ++e1c) {
115 for (std::vector<NBEdge::Connection>::iterator e2c = approached2.begin(); e2c != approached2.end(); ++e2c) {
119 if (!
forbids(e1, (*e1c).toEdge, e2, (*e2c).toEdge,
true)) {
131 std::pair<NBEdge*, NBEdge*>
133 std::pair<NBEdge*, NBEdge*> bestPair(static_cast<NBEdge*>(0), static_cast<NBEdge*>(0));
135 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
136 for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) {
138 if (value > bestValue) {
140 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
141 }
else if (value == bestValue) {
143 const SUMOReal oa =
GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode()));
145 if (bestPair.first->getID() < (*i)->getID()) {
146 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
148 }
else if (oa < ca) {
149 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
158 std::pair<NBEdge*, NBEdge*>
160 if (incoming.size() == 1) {
162 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(),
static_cast<NBEdge*
>(0));
170 used.push_back(*incoming.begin());
173 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio ==
getToPrio(*i); ++i) {
177 if (used.size() < 2) {
181 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
182 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
200 std::vector<bool> isTurnaround;
201 std::vector<int> fromLanes;
202 unsigned int noLanesAll = 0;
203 unsigned int noLinksAll = 0;
204 for (
unsigned int i1 = 0; i1 < incoming.size(); i1++) {
205 unsigned int noLanes = incoming[i1]->getNumLanes();
206 noLanesAll += noLanes;
207 for (
unsigned int i2 = 0; i2 < noLanes; i2++) {
208 NBEdge* fromEdge = incoming[i1];
210 noLinksAll += (
unsigned int) approached.size();
211 for (
unsigned int i3 = 0; i3 < approached.size(); i3++) {
212 if (!fromEdge->
mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
216 assert(i3 < approached.size());
217 NBEdge* toEdge = approached[i3].toEdge;
218 fromEdges.push_back(fromEdge);
219 fromLanes.push_back((
int)i2);
220 toEdges.push_back(toEdge);
224 isTurnaround.push_back(
true);
230 std::vector<NBNode::Crossing> crossings;
232 const std::vector<NBNode::Crossing>& c = (*i)->getCrossings();
235 (*i)->setCrossingTLIndices(noLinksAll);
237 copy(c.begin(), c.end(), std::back_inserter(crossings));
238 noLinksAll += (
unsigned int)c.size();
246 std::vector<int> greenPhases;
247 std::vector<bool> hadGreenMajor(noLinksAll,
false);
248 while (toProc.size() > 0) {
249 std::pair<NBEdge*, NBEdge*> chosen;
250 if (incoming.size() == 2) {
253 SUMOReal angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
256 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(0));
257 toProc.erase(toProc.begin());
264 unsigned int pos = 0;
265 std::string state((
size_t) noLinksAll,
'r');
268 for (
unsigned int i1 = 0; i1 < (
unsigned int) incoming.size(); ++i1) {
269 NBEdge* fromEdge = incoming[i1];
270 const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second;
271 const unsigned int numLanes = fromEdge->
getNumLanes();
272 for (
unsigned int i2 = 0; i2 < numLanes; i2++) {
274 for (
unsigned int i3 = 0; i3 < approached.size(); ++i3) {
275 if (!fromEdge->
mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
290 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
291 if (state[i1] ==
'G') {
295 for (
unsigned int i2 = 0; i2 < pos && !
isForbidden; ++i2) {
296 if (state[i2] ==
'G' && !isTurnaround[i2] &&
297 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
301 if (!isForbidden && !
hasCrossing(fromEdges[i1], toEdges[i1], crossings)) {
304 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LINKDIR_RIGHT) {
307 for (
unsigned int i2 = 0; i2 < pos; ++i2) {
308 if (state[i2] ==
'G' && !isTurnaround[i2] &&
309 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
317 bool haveForbiddenLeftMover =
false;
318 std::vector<bool> rightTurnConflicts(pos,
false);
319 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
320 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
321 if (state[i1] ==
'G') {
322 hadGreenMajor[i1] =
true;
326 const std::string vehicleState = state;
327 greenPhases.push_back((
int)logic->
getPhases().size());
330 for (
unsigned int i1 = pos; i1 < pos + crossings.size(); ++i1) {
334 if (brakingTime > 0) {
336 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
337 if (state[i1] !=
'G' && state[i1] !=
'g') {
340 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z') && haveForbiddenLeftMover && !rightTurnConflicts[i1]) {
346 logic->
addStep(brakingTime, state);
351 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
352 if (state[i1] ==
'Y' || state[i1] ==
'y') {
356 if (state[i1] ==
'g') {
361 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
364 logic->
addStep(leftTurnTime, state);
367 if (brakingTime > 0) {
368 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
369 if (state[i1] !=
'G' && state[i1] !=
'g') {
375 logic->
addStep(brakingTime, state);
380 if (crossings.size() > 0) {
381 const int vehLinks = noLinksAll - (int)crossings.size();
382 std::vector<bool> foundGreen(crossings.size(),
false);
383 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
384 for (
int i = 0; i < (int)phases.size(); ++i) {
385 const std::string state = phases[i].state;
386 for (
int j = 0; j < (int)crossings.size(); ++j) {
389 foundGreen[j] =
true;
393 for (
int j = 0; j < (int)foundGreen.size(); ++j) {
394 if (!foundGreen[j]) {
407 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
408 greenPhaseTime += logic->
getPhases()[*it].duration;
410 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / greenPhases.size());
411 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
419 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
430 if (totalDuration > 0) {
431 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) {
446 for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
450 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
451 const NBEdge* edge = *it_e;
452 if (edge == from || edge == to) {
464 std::string state,
const std::vector<NBNode::Crossing>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
467 const std::string orig = state;
471 logic->
addStep(greenTime, state);
473 const SUMOTime pedTime = greenTime - pedClearingTime;
474 if (pedTime >= minPedTime) {
476 const size_t pedStates = crossings.size();
477 logic->
addStep(pedTime, state);
478 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
479 logic->
addStep(pedClearingTime, state);
483 logic->
addStep(greenTime, state);
492 std::string result = state;
493 const unsigned int pos = (
unsigned int)(state.size() - crossings.size());
494 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
495 const int i1 = pos + ic;
498 for (
unsigned int i2 = 0; i2 < pos && !
isForbidden; ++i2) {
500 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
501 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
504 if (state[i2] !=
'r' && (edge == fromEdges[i2] ||
520 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
521 if (result[i1] ==
'G') {
522 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
524 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
525 const int i2 = pos + ic;
612 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
613 if ((*it)->getConnections().size() == 0 || (*it)->isInnerEdge()) {
614 it = result.erase(it);
628 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
629 if (state[i1] ==
'G') {
632 bool followsChosen =
false;
633 for (
int i2 = 0; i2 < (int)fromEdges.size() && !followsChosen; ++i2) {
634 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
635 followsChosen =
true;
650 const std::vector<bool>& isTurnaround,
651 const std::vector<int>& fromLanes,
652 const std::vector<bool>& hadGreenMajor,
653 bool& haveForbiddenLeftMover,
654 std::vector<bool>& rightTurnConflicts) {
656 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
657 if (state[i1] !=
'G') {
660 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
661 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
663 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
664 rightTurnConflicts[i1] =
true;
666 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
669 if (!isTurnaround[i1] && !hadGreenMajor[i1]) {
670 haveForbiddenLeftMover =
true;
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.
The link has green light, may pass.
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
RightOnRedConflicts myRightOnRedConflicts
A SUMO-compliant built logic for a traffic light.
TrafficLightType getType() const
get the algorithm type (static etc..)
The link has green light, has to brake.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getProgramID() const
Returns the ProgramID.
std::string correctConflicting(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< bool > &isTurnaround, const std::vector< int > &fromLanes, const std::vector< bool > &hadGreenMajor, bool &haveForbiddenLeftMover, std::vector< bool > &rightTurnConflicts)
change 'G' to 'g' for conflicting connections
The representation of a single edge during network building.
std::string allowFollowersOfChosen(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges)
allow connections that follow on of the chosen edges
bool mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const
void collectNodes()
Collects the nodes participating in this traffic light.
std::string time2string(SUMOTime t)
The base class for traffic light logic definitions.
static bool hasCrossing(const NBEdge *from, const NBEdge *to, const std::vector< NBNode::Crossing > &crossings)
compute whether the given connection is crossed by pedestrians
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)
NBTrafficLightLogic * computeLogicAndConts(unsigned int brakingTimeSeconds, bool onlyConts=false)
helper function for myCompute
static EdgeVector getConnectedOuterEdges(const EdgeVector &incoming)
get edges that have connections
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
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.
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane, bool lefthand=false)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
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.
virtual void collectEdges()
Build the list of participating edges.
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
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.
void setPhaseDuration(unsigned int phaseIndex, SUMOTime duration)
Modifies the duration for an existing phase (used by NETEDIT)
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Storage for edges, including some functionality operating on multiple edges.
The link is a (hard) right direction.
static const std::string DefaultProgramID
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
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
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...
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority, bool sameNodeOnly=false) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
bool myRightOnRedConflictsReady
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.
bool myNeedsContRelationReady
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.
NeedsContRelation myNeedsContRelation
EdgeVector edges
The edges being crossed.
Represents a single node (junction) during network building.
A definition of a pedestrian crossing.
void initNeedsContRelation() const
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
data structure for caching needsCont information
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
A traffic light logics which must be computed (only nodes/edges are given)
void addStep(SUMOTime duration, const std::string &state, int index=-1)
Adds a phase to the logic.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
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.
NBEdge * getTurnDestination(bool possibleDestination=false) const
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.
NBNode * getFromNode() const
Returns the origin node of the edge.