47 #ifdef CHECK_MEMORY_LEAKS 49 #endif // CHECK_MEMORY_LEAKS 51 #define MIN_GREEN_TIME 5 57 const std::vector<NBNode*>& junctions,
SUMOTime offset,
60 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 (!
forbids(e1, (*e1c).toEdge, e2, (*e2c).toEdge,
true)) {
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));
199 std::vector<bool> isTurnaround;
200 std::vector<int> fromLanes;
201 unsigned int noLanesAll = 0;
202 unsigned int noLinksAll = 0;
203 for (
unsigned int i1 = 0; i1 < incoming.size(); i1++) {
204 unsigned int noLanes = incoming[i1]->getNumLanes();
205 noLanesAll += noLanes;
206 for (
unsigned int i2 = 0; i2 < noLanes; i2++) {
207 NBEdge* fromEdge = incoming[i1];
209 noLinksAll += (
unsigned int) approached.size();
210 for (
unsigned int i3 = 0; i3 < approached.size(); i3++) {
211 if (!fromEdge->
mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
215 assert(i3 < approached.size());
216 NBEdge* toEdge = approached[i3].toEdge;
217 fromEdges.push_back(fromEdge);
218 fromLanes.push_back((
int)i2);
219 toEdges.push_back(toEdge);
223 isTurnaround.push_back(
true);
229 std::vector<NBNode::Crossing> crossings;
231 const std::vector<NBNode::Crossing>& c = (*i)->getCrossings();
234 (*i)->setCrossingTLIndices(noLinksAll);
236 copy(c.begin(), c.end(), std::back_inserter(crossings));
237 noLinksAll += (
unsigned int)c.size();
245 std::vector<int> greenPhases;
246 std::vector<bool> hadGreenMajor(noLinksAll,
false);
247 while (toProc.size() > 0) {
248 std::pair<NBEdge*, NBEdge*> chosen;
249 if (incoming.size() == 2) {
252 SUMOReal angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
255 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(0));
256 toProc.erase(toProc.begin());
263 unsigned int pos = 0;
264 std::string state((
size_t) noLinksAll,
'r');
267 for (
unsigned int i1 = 0; i1 < (
unsigned int) incoming.size(); ++i1) {
268 NBEdge* fromEdge = incoming[i1];
269 const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second;
270 const unsigned int numLanes = fromEdge->
getNumLanes();
271 for (
unsigned int i2 = 0; i2 < numLanes; i2++) {
273 for (
unsigned int i3 = 0; i3 < approached.size(); ++i3) {
274 if (!fromEdge->
mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
289 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
290 if (state[i1] ==
'G') {
294 for (
unsigned int i2 = 0; i2 < pos && !
isForbidden; ++i2) {
295 if (state[i2] ==
'G' && !isTurnaround[i2] &&
296 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
300 if (!isForbidden && !
hasCrossing(fromEdges[i1], toEdges[i1], crossings)) {
306 bool haveForbiddenLeftMover =
false;
307 std::vector<bool> rightTurnConflicts(pos,
false);
308 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
309 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
310 if (state[i1] ==
'G') {
311 hadGreenMajor[i1] =
true;
315 const std::string vehicleState = state;
316 greenPhases.push_back((
int)logic->
getPhases().size());
319 for (
unsigned int i1 = pos; i1 < pos + crossings.size(); ++i1) {
322 const bool buildLeftGreenPhase = haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0;
323 if (brakingTime > 0) {
325 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
326 if (state[i1] !=
'G' && state[i1] !=
'g') {
329 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z') && buildLeftGreenPhase && !rightTurnConflicts[i1]) {
335 logic->
addStep(brakingTime, state);
338 if (buildLeftGreenPhase) {
340 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
341 if (state[i1] ==
'Y' || state[i1] ==
'y') {
345 if (state[i1] ==
'g') {
350 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
353 logic->
addStep(leftTurnTime, state);
356 if (brakingTime > 0) {
357 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
358 if (state[i1] !=
'G' && state[i1] !=
'g') {
364 logic->
addStep(brakingTime, state);
369 if (crossings.size() > 0) {
379 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
381 greenPhaseTime += dur;
382 minGreenDuration =
MIN2(minGreenDuration, dur);
384 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / greenPhases.size());
385 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
389 || greenPhases.size() == 0) {
395 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
398 if (greenPhases.size() > 0) {
408 if (totalDuration > 0) {
409 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) {
424 for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
428 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
429 const NBEdge* edge = *it_e;
430 if (edge == from || edge == to) {
442 std::string state,
const std::vector<NBNode::Crossing>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
445 const std::string orig = state;
449 logic->
addStep(greenTime, state);
451 const SUMOTime pedTime = greenTime - pedClearingTime;
452 if (pedTime >= minPedTime) {
454 const size_t pedStates = crossings.size();
455 logic->
addStep(pedTime, state);
456 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
457 logic->
addStep(pedClearingTime, state);
461 logic->
addStep(greenTime, state);
470 std::string result = state;
471 const unsigned int pos = (
unsigned int)(state.size() - crossings.size());
472 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
473 const int i1 = pos + ic;
476 for (
unsigned int i2 = 0; i2 < pos && !
isForbidden; ++i2) {
478 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
479 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
482 if (state[i2] !=
'r' && (edge == fromEdges[i2] ||
498 for (
unsigned int i1 = 0; i1 < pos; ++i1) {
499 if (result[i1] ==
'G') {
500 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
502 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
503 const int i2 = pos + ic;
569 (*i)->removeTrafficLight(&dummy);
579 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
580 if ((*it)->getConnections().size() == 0 || (*it)->isInnerEdge()) {
581 it = result.erase(it);
595 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
596 if (state[i1] ==
'G') {
599 bool followsChosen =
false;
600 for (
int i2 = 0; i2 < (int)fromEdges.size() && !followsChosen; ++i2) {
601 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
602 followsChosen =
true;
617 const std::vector<bool>& isTurnaround,
618 const std::vector<int>& fromLanes,
619 const std::vector<bool>& hadGreenMajor,
620 bool& haveForbiddenLeftMover,
621 std::vector<bool>& rightTurnConflicts) {
623 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
624 if (state[i1] ==
'G') {
625 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
626 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
628 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
629 rightTurnConflicts[i1] =
true;
631 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
634 if (!isTurnaround[i1] && !hadGreenMajor[i1]) {
635 haveForbiddenLeftMover =
true;
641 if (state[i1] ==
'r') {
643 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LINKDIR_RIGHT) {
646 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
647 if (state[i2] ==
'G' && !isTurnaround[i2] &&
648 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
661 const std::vector<NBNode::Crossing>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
662 const int vehLinks = noLinksAll - (int)crossings.size();
663 std::vector<bool> foundGreen(crossings.size(),
false);
664 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
665 for (
int i = 0; i < (int)phases.size(); ++i) {
666 const std::string state = phases[i].state;
667 for (
int j = 0; j < (int)crossings.size(); ++j) {
670 foundGreen[j] =
true;
674 for (
int j = 0; j < (int)foundGreen.size(); ++j) {
675 if (!foundGreen[j]) {
678 if (phases.size() > 0) {
679 bool needYellowPhase =
false;
680 std::string state = phases.back().state;
681 for (
int i1 = 0; i1 < vehLinks; ++i1) {
682 if (state[i1] ==
'G' || state[i1] ==
'g') {
684 needYellowPhase =
true;
688 if (needYellowPhase) {
689 logic->
addStep(brakingTime, state);
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
static const std::string DummyID
id for temporary definitions
static void addPedestrianScramble(NBTrafficLightLogic *logic, unsigned int noLinksAll, SUMOTime greenTime, SUMOTime yellowTime, const std::vector< NBNode::Crossing > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
add an additional pedestrian phase if there are crossings that did not get green yet ...
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
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)
NBTrafficLightLogic * myCompute(unsigned int brakingTimeSeconds)
Computes the traffic light logic finally in dependence to the type.
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.
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 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
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.
virtual bool amInvalid() const
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 setTLControllingInformation() const
Informs edges about being controlled by a tls.
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.