SUMO - Simulation of Urban MObility
NBTrafficLightDefinition.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // The base class for traffic light logic definitions
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include <vector>
00034 #include <string>
00035 #include <algorithm>
00036 #include <cassert>
00037 #include <iterator>
00038 #include <utils/common/MsgHandler.h>
00039 #include <utils/common/ToString.h>
00040 #include "NBTrafficLightDefinition.h"
00041 #include <utils/options/OptionsCont.h>
00042 #include "NBTrafficLightDefinition.h"
00043 #include "NBLinkPossibilityMatrix.h"
00044 #include "NBTrafficLightLogic.h"
00045 #include "NBContHelper.h"
00046 
00047 #ifdef CHECK_MEMORY_LEAKS
00048 #include <foreign/nvwa/debug_new.h>
00049 #endif // CHECK_MEMORY_LEAKS
00050 
00051 // ===========================================================================
00052 // static members
00053 // ===========================================================================
00054 const std::string NBTrafficLightDefinition::DefaultProgramID = "0";
00055 
00056 // ===========================================================================
00057 // method definitions
00058 // ===========================================================================
00059 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string& id,
00060         const std::vector<NBNode*> &junctions,
00061         const std::string& programID)
00062     : Named(id), myControlledNodes(junctions), mySubID(programID) {
00063     std::vector<NBNode*>::iterator i = myControlledNodes.begin();
00064     while (i != myControlledNodes.end()) {
00065         for (std::vector<NBNode*>::iterator j = i + 1; j != myControlledNodes.end();) {
00066             if (*i == *j) {
00067                 j = myControlledNodes.erase(j);
00068             } else {
00069                 j++;
00070             }
00071         }
00072         i++;
00073     }
00074     std::sort(myControlledNodes.begin(), myControlledNodes.end(), NBNode::nodes_by_id_sorter());
00075     for (std::vector<NBNode*>::const_iterator i = junctions.begin(); i != junctions.end(); i++) {
00076         (*i)->addTrafficLight(this);
00077     }
00078 }
00079 
00080 
00081 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string& id,
00082         NBNode* junction,
00083         const std::string& programID)
00084     : Named(id), mySubID(programID) {
00085     addNode(junction);
00086     junction->addTrafficLight(this);
00087 }
00088 
00089 
00090 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string& id, const std::string& programID)
00091     : Named(id), mySubID(programID) {}
00092 
00093 
00094 NBTrafficLightDefinition::~NBTrafficLightDefinition() {}
00095 
00096 
00097 NBTrafficLightLogic*
00098 NBTrafficLightDefinition::compute(const NBEdgeCont& ec, OptionsCont& oc) {
00099     // it is not really a traffic light if no incoming edge exists
00100     if (amInvalid()) {
00101         // make a copy of myControlledNodes because it will be modified;
00102         std::vector<NBNode*> nodes = myControlledNodes;
00103         for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
00104             (*it)->removeTrafficLight(this);
00105         }
00106         WRITE_WARNING("The traffic light '" + getID() + "' does not control any links; it will not be build.");
00107         return 0;
00108     }
00109     // compute the time needed to brake
00110     unsigned int brakingTime = computeBrakingTime(oc.getFloat("tls.yellow.min-decel"));
00111     // perform the computation depending on whether the traffic light
00112     //  definition was loaded or shall be computed new completely
00113     if (oc.isSet("tls.yellow.time")) {
00114         brakingTime = oc.getInt("tls.yellow.time");
00115     }
00116     return myCompute(ec, brakingTime);
00117 }
00118 
00119 
00120 bool
00121 NBTrafficLightDefinition::amInvalid() const {
00122     return myControlledLinks.size() == 0;
00123 }
00124 
00125 
00126 unsigned int
00127 NBTrafficLightDefinition::computeBrakingTime(SUMOReal minDecel) const {
00128     SUMOReal vmax = NBContHelper::maxSpeed(myIncomingEdges);
00129     return (unsigned int)(vmax / minDecel);
00130 }
00131 
00132 
00133 void
00134 NBTrafficLightDefinition::setParticipantsInformation() {
00135     // collect the information about participating edges and links
00136     collectEdges();
00137     collectLinks();
00138 }
00139 
00140 
00141 void
00142 NBTrafficLightDefinition::collectEdges() {
00143     myIncomingEdges.clear();
00144     EdgeVector myOutgoing;
00145     // collect the edges from the participating nodes
00146     for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
00147         const EdgeVector& incoming = (*i)->getIncomingEdges();
00148         copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges));
00149         const EdgeVector& outgoing = (*i)->getOutgoingEdges();
00150         copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing));
00151     }
00152     // check which of the edges are completely within the junction
00153     //  remove these edges from the list of incoming edges
00154     //  add them to the list of edges lying within the node
00155     for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end();) {
00156         NBEdge* edge = *j;
00157         // an edge lies within the logic if it is outgoing as well as incoming
00158         EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge);
00159         if (k != myOutgoing.end()) {
00160             if (myControlledInnerEdges.count(edge->getID()) == 0) {
00161                 myEdgesWithin.push_back(edge);
00162                 (*j)->setIsInnerEdge();
00163                 j = myIncomingEdges.erase(j);
00164                 continue;
00165             }
00166         }
00167         ++j;
00168     }
00169 }
00170 
00171 
00172 bool
00173 NBTrafficLightDefinition::isLeftMover(const NBEdge* const from, const NBEdge* const to) const {
00174     // the destination edge may be unused
00175     if (to == 0) {
00176         return false;
00177     }
00178     // get the node which is holding this connection
00179     std::vector<NBNode*>::const_iterator i =
00180         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00181                 NBContHelper::node_with_incoming_finder(from));
00182     assert(i != myControlledNodes.end());
00183     NBNode* node = *i;
00184     return node->isLeftMover(from, to);
00185 }
00186 
00187 
00188 bool
00189 NBTrafficLightDefinition::mustBrake(const NBEdge* const from, const NBEdge* const to) const {
00190     std::vector<NBNode*>::const_iterator i =
00191         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00192                 NBContHelper::node_with_incoming_finder(from));
00193     assert(i != myControlledNodes.end());
00194     NBNode* node = *i;
00195     if (!node->hasOutgoing(to)) {
00196         return true; // !!!
00197     }
00198     return node->mustBrake(from, to, -1);
00199 }
00200 
00201 
00202 bool
00203 NBTrafficLightDefinition::mustBrake(const NBEdge* const possProhibitedFrom,
00204                                     const NBEdge* const possProhibitedTo,
00205                                     const NBEdge* const possProhibitorFrom,
00206                                     const NBEdge* const possProhibitorTo,
00207                                     bool regardNonSignalisedLowerPriority) const {
00208     return forbids(possProhibitorFrom, possProhibitorTo,
00209                    possProhibitedFrom, possProhibitedTo,
00210                    regardNonSignalisedLowerPriority);
00211 }
00212 
00213 
00214 bool
00215 NBTrafficLightDefinition::mustBrake(const NBConnection& possProhibited,
00216                                     const NBConnection& possProhibitor,
00217                                     bool regardNonSignalisedLowerPriority) const {
00218     return forbids(possProhibitor.getFrom(), possProhibitor.getTo(),
00219                    possProhibited.getFrom(), possProhibited.getTo(),
00220                    regardNonSignalisedLowerPriority);
00221 }
00222 
00223 
00224 bool
00225 NBTrafficLightDefinition::forbids(const NBEdge* const possProhibitorFrom,
00226                                   const NBEdge* const possProhibitorTo,
00227                                   const NBEdge* const possProhibitedFrom,
00228                                   const NBEdge* const possProhibitedTo,
00229                                   bool regardNonSignalisedLowerPriority) const {
00230     if (possProhibitorFrom == 0 || possProhibitorTo == 0 || possProhibitedFrom == 0 || possProhibitedTo == 0) {
00231         return false;
00232     }
00233     // retrieve both nodes
00234     std::vector<NBNode*>::const_iterator incoming =
00235         find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorFrom));
00236     std::vector<NBNode*>::const_iterator outgoing =
00237         find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(possProhibitedTo));
00238     assert(incoming != myControlledNodes.end());
00239     NBNode* incnode = *incoming;
00240     NBNode* outnode = *outgoing;
00241     EdgeVector::const_iterator i;
00242     if (incnode != outnode) {
00243         // the links are located at different nodes
00244         const EdgeVector& ev1 = possProhibitedTo->getConnectedEdges();
00245         // go through the following edge,
00246         //  check whether one of these connections is prohibited
00247         for (i = ev1.begin(); i != ev1.end(); ++i) {
00248             std::vector<NBNode*>::const_iterator outgoing2 =
00249                 find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(*i));
00250             if (outgoing2 == myControlledNodes.end()) {
00251                 continue;
00252             }
00253             NBNode* outnode2 = *outgoing2;
00254             if (incnode != outnode2) {
00255                 continue;
00256             }
00257             bool ret1 = incnode->foes(possProhibitorTo, *i,
00258                                       possProhibitedFrom, possProhibitedTo);
00259             bool ret2 = incnode->forbids(possProhibitorFrom, possProhibitorTo,
00260                                          possProhibitedTo, *i,
00261                                          regardNonSignalisedLowerPriority);
00262             bool ret = ret1 || ret2;
00263             if (ret) {
00264                 return true;
00265             }
00266         }
00267 
00268         const EdgeVector& ev2 = possProhibitorTo->getConnectedEdges();
00269         // go through the following edge,
00270         //  check whether one of these connections is prohibited
00271         for (i = ev2.begin(); i != ev2.end(); ++i) {
00272             std::vector<NBNode*>::const_iterator incoming2 =
00273                 find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorTo));
00274             if (incoming2 == myControlledNodes.end()) {
00275                 continue;
00276             }
00277             NBNode* incnode2 = *incoming2;
00278             if (incnode2 != outnode) {
00279                 continue;
00280             }
00281             bool ret1 = incnode2->foes(possProhibitorTo, *i,
00282                                        possProhibitedFrom, possProhibitedTo);
00283             bool ret2 = incnode2->forbids(possProhibitorTo, *i,
00284                                           possProhibitedFrom, possProhibitedTo,
00285                                           regardNonSignalisedLowerPriority);
00286             bool ret = ret1 || ret2;
00287             if (ret) {
00288                 return true;
00289             }
00290         }
00291         return false;
00292     }
00293     // both links are located at the same node
00294     //  check using this node's information
00295     return incnode->forbids(possProhibitorFrom, possProhibitorTo,
00296                             possProhibitedFrom, possProhibitedTo,
00297                             regardNonSignalisedLowerPriority);
00298 }
00299 
00300 
00301 bool
00302 NBTrafficLightDefinition::foes(const NBEdge* const from1, const NBEdge* const to1,
00303                                const NBEdge* const from2, const NBEdge* const to2) const {
00304     if (to1 == 0 || to2 == 0) {
00305         return false;
00306     }
00307     // retrieve both nodes (it is possible that a connection
00308     std::vector<NBNode*>::const_iterator incoming =
00309         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00310                 NBContHelper::node_with_incoming_finder(from1));
00311     std::vector<NBNode*>::const_iterator outgoing =
00312         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00313                 NBContHelper::node_with_outgoing_finder(to1));
00314     assert(incoming != myControlledNodes.end());
00315     NBNode* incnode = *incoming;
00316     NBNode* outnode = *outgoing;
00317     if (incnode != outnode) {
00318         return false;
00319     }
00320     return incnode->foes(from1, to1, from2, to2);
00321 }
00322 
00323 
00324 void
00325 NBTrafficLightDefinition::addNode(NBNode* node) {
00326     if (std::find(myControlledNodes.begin(), myControlledNodes.end(), node) == myControlledNodes.end()) {
00327         myControlledNodes.push_back(node);
00328         std::sort(myControlledNodes.begin(), myControlledNodes.end(), NBNode::nodes_by_id_sorter());
00329         node->addTrafficLight(this);
00330     }
00331 }
00332 
00333 
00334 void
00335 NBTrafficLightDefinition::removeNode(NBNode* node) {
00336     std::vector<NBNode*>::iterator i = std::find(myControlledNodes.begin(), myControlledNodes.end(), node);
00337     if (i != myControlledNodes.end()) {
00338         myControlledNodes.erase(i);
00339     }
00340     // !!! remove in node?
00341 }
00342 
00343 
00344 void
00345 NBTrafficLightDefinition::addControlledInnerEdges(const std::vector<std::string> &edges) {
00346     myControlledInnerEdges.insert(edges.begin(), edges.end());
00347 }
00348 
00349 
00350 const EdgeVector&
00351 NBTrafficLightDefinition::getIncomingEdges() const {
00352     return myIncomingEdges;
00353 }
00354 
00355 
00356 /****************************************************************************/
00357 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines