SUMO - Simulation of Urban MObility

NBTrafficLightDefinition.cpp

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