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 2001-2010 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 <utils/common/MsgHandler.h>
00035 #include <utils/common/ToString.h>
00036 #include "NBTrafficLightDefinition.h"
00037 #include <utils/options/OptionsCont.h>
00038 #include "NBTrafficLightDefinition.h"
00039 #include "NBLinkPossibilityMatrix.h"
00040 #include "NBTrafficLightLogic.h"
00041 #include "NBContHelper.h"
00042 
00043 #ifdef CHECK_MEMORY_LEAKS
00044 #include <foreign/nvwa/debug_new.h>
00045 #endif // CHECK_MEMORY_LEAKS
00046 
00047 
00048 // ===========================================================================
00049 // method definitions
00050 // ===========================================================================
00051 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string &id,
00052         const std::vector<NBNode*> &junctions) throw()
00053         : Named(id), myControlledNodes(junctions) {
00054     std::vector<NBNode*>::iterator i=myControlledNodes.begin();
00055     while (i!=myControlledNodes.end()) {
00056         for (std::vector<NBNode*>::iterator j=i+1; j!=myControlledNodes.end();) {
00057             if (*i==*j) {
00058                 j = myControlledNodes.erase(j);
00059             } else {
00060                 j++;
00061             }
00062         }
00063         i++;
00064     }
00065     std::sort(myControlledNodes.begin(), myControlledNodes.end(), NBNode::nodes_by_id_sorter());
00066     for (std::vector<NBNode*>::const_iterator i=junctions.begin(); i!=junctions.end(); i++) {
00067         (*i)->addTrafficLight(this);
00068     }
00069 }
00070 
00071 
00072 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string &id,
00073         NBNode *junction) throw()
00074         : Named(id) {
00075     addNode(junction);
00076     junction->addTrafficLight(this);
00077 }
00078 
00079 
00080 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string &id) throw()
00081         : Named(id) {}
00082 
00083 
00084 NBTrafficLightDefinition::~NBTrafficLightDefinition() throw() {}
00085 
00086 
00087 NBTrafficLightLogic *
00088 NBTrafficLightDefinition::compute(const NBEdgeCont &ec, OptionsCont &oc) throw() {
00089     // it is not really a traffic light if no incoming edge exists
00090     if (myIncomingEdges.size()==0) {
00091         WRITE_WARNING("The traffic light '" + getID() + "' has no incoming edges; it will not be build.");
00092         return 0;
00093     }
00094     // compute the time needed to brake
00095     unsigned int brakingTime = computeBrakingTime(oc.getFloat("min-decel"));
00096     // perform the computation depending on whether the traffic light
00097     //  definition was loaded or shall be computed new completely
00098     if (oc.isSet("traffic-light-yellow")) {
00099         brakingTime = oc.getInt("traffic-light-yellow");
00100     }
00101     return myCompute(ec, brakingTime);
00102 }
00103 
00104 
00105 unsigned int
00106 NBTrafficLightDefinition::computeBrakingTime(SUMOReal minDecel) const throw() {
00107     SUMOReal vmax = NBContHelper::maxSpeed(myIncomingEdges);
00108     return (unsigned int)(vmax / minDecel);
00109 }
00110 
00111 
00112 void
00113 NBTrafficLightDefinition::setParticipantsInformation() throw() {
00114     // collect the information about participating edges and links
00115     collectEdges();
00116     collectLinks();
00117 }
00118 
00119 
00120 void
00121 NBTrafficLightDefinition::collectEdges() throw() {
00122     EdgeVector myOutgoing;
00123     // collect the edges from the participating nodes
00124     for (std::vector<NBNode*>::iterator i=myControlledNodes.begin(); i!=myControlledNodes.end(); i++) {
00125         const EdgeVector &incoming = (*i)->getIncomingEdges();
00126         copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges));
00127         const EdgeVector &outgoing = (*i)->getOutgoingEdges();
00128         copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing));
00129     }
00130     // check which of the edges are completely within the junction
00131     //  remove these edges from the list of incoming edges
00132     //  add them to the list of edges lying within the node
00133     for (EdgeVector::iterator j=myIncomingEdges.begin(); j!=myIncomingEdges.end();) {
00134         NBEdge *edge = *j;
00135         // an edge lies within the logic if it is outgoing as well as incoming
00136         EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge);
00137         if (k!=myOutgoing.end()) {
00138             if (find(myControlledInnerEdges.begin(), myControlledInnerEdges.end(), edge->getID())==myControlledInnerEdges.end()) {
00139                 myEdgesWithin.push_back(edge);
00140                 (*j)->setIsInnerEdge();
00141                 j = myIncomingEdges.erase(j);
00142                 continue;
00143             }
00144         }
00145         ++j;
00146     }
00147 }
00148 
00149 
00150 void
00151 NBTrafficLightDefinition::collectLinks() throw(ProcessError) {
00152     // build the list of links which are controled by the traffic light
00153     for (EdgeVector::iterator i=myIncomingEdges.begin(); i!=myIncomingEdges.end(); i++) {
00154         NBEdge *incoming = *i;
00155         unsigned int noLanes = incoming->getNoLanes();
00156         for (unsigned int j=0; j<noLanes; j++) {
00157             std::vector<NBEdge::Connection> connected = incoming->getConnectionsFromLane(j);
00158             for (std::vector<NBEdge::Connection>::iterator k=connected.begin(); k!=connected.end(); k++) {
00159                 const NBEdge::Connection &el = *k;
00160                 if (incoming->mayBeTLSControlled(el.fromLane, el.toEdge, el.toLane)) {
00161                     myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane));
00162                 }
00163             }
00164         }
00165     }
00166     // set the information about the link's positions within the tl into the
00167     //  edges the links are starting at, respectively
00168     unsigned int pos = 0;
00169     for (NBConnectionVector::iterator j=myControlledLinks.begin(); j!=myControlledLinks.end(); j++) {
00170         const NBConnection &conn = *j;
00171         NBEdge *edge = conn.getFrom();
00172         if (edge->setControllingTLInformation(conn.getFromLane(), conn.getTo(), conn.getToLane(), getID(), pos)) {
00173             pos++;
00174         }
00175     }
00176 }
00177 
00178 
00179 std::pair<unsigned int, unsigned int>
00180 NBTrafficLightDefinition::getSizes() const throw() {
00181     unsigned int noLanes = 0;
00182     unsigned int noLinks = 0;
00183     for (EdgeVector::const_iterator i=myIncomingEdges.begin(); i!=myIncomingEdges.end(); i++) {
00184         unsigned int noLanesEdge = (*i)->getNoLanes();
00185         for (unsigned int j=0; j<noLanesEdge; j++) {
00186             assert((*i)->getConnectionsFromLane(j).size()!=0);
00187             noLinks += (unsigned int)(*i)->getConnectionsFromLane(j).size();
00188         }
00189         noLanes += noLanesEdge;
00190     }
00191     return std::pair<unsigned int, unsigned int>(noLanes, noLinks);
00192 }
00193 
00194 
00195 bool
00196 NBTrafficLightDefinition::isLeftMover(const NBEdge * const from,const NBEdge * const to) const throw() {
00197     // the destination edge may be unused
00198     if (to==0) {
00199         return false;
00200     }
00201     // get the node which is holding this connection
00202     std::vector<NBNode*>::const_iterator i =
00203         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00204                 NBContHelper::node_with_incoming_finder(from));
00205     assert(i!=myControlledNodes.end());
00206     NBNode *node = *i;
00207     return node->isLeftMover(from, to);
00208 }
00209 
00210 
00211 bool
00212 NBTrafficLightDefinition::mustBrake(const NBEdge * const from, const NBEdge * const to) const throw() {
00213     std::vector<NBNode*>::const_iterator i =
00214         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00215                 NBContHelper::node_with_incoming_finder(from));
00216     assert(i!=myControlledNodes.end());
00217     NBNode *node = *i;
00218     if (!node->hasOutgoing(to)) {
00219         return true; // !!!
00220     }
00221     return node->mustBrake(from, to, -1);
00222 }
00223 
00224 
00225 bool
00226 NBTrafficLightDefinition::mustBrake(const NBEdge * const possProhibitedFrom,
00227                                     const NBEdge * const possProhibitedTo,
00228                                     const NBEdge * const possProhibitorFrom,
00229                                     const NBEdge * const possProhibitorTo,
00230                                     bool regardNonSignalisedLowerPriority) const throw() {
00231     return forbids(possProhibitorFrom, possProhibitorTo,
00232                    possProhibitedFrom, possProhibitedTo,
00233                    regardNonSignalisedLowerPriority);
00234 }
00235 
00236 
00237 bool
00238 NBTrafficLightDefinition::mustBrake(const NBConnection &possProhibited,
00239                                     const NBConnection &possProhibitor,
00240                                     bool regardNonSignalisedLowerPriority) const throw() {
00241     return forbids(possProhibitor.getFrom(), possProhibitor.getTo(),
00242                    possProhibited.getFrom(), possProhibited.getTo(),
00243                    regardNonSignalisedLowerPriority);
00244 }
00245 
00246 
00247 bool
00248 NBTrafficLightDefinition::forbids(const NBEdge * const possProhibitorFrom,
00249                                   const NBEdge * const possProhibitorTo,
00250                                   const NBEdge * const possProhibitedFrom,
00251                                   const NBEdge * const possProhibitedTo,
00252                                   bool regardNonSignalisedLowerPriority) const throw() {
00253     if (possProhibitorFrom==0||possProhibitorTo==0||possProhibitedFrom==0||possProhibitedTo==0) {
00254         return false;
00255     }
00256     // retrieve both nodes
00257     std::vector<NBNode*>::const_iterator incoming =
00258         find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorFrom));
00259     std::vector<NBNode*>::const_iterator outgoing =
00260         find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(possProhibitedTo));
00261     assert(incoming!=myControlledNodes.end());
00262     NBNode *incnode = *incoming;
00263     NBNode *outnode = *outgoing;
00264     EdgeVector::const_iterator i;
00265     if (incnode!=outnode) {
00266         // the links are located at different nodes
00267         const EdgeVector &ev1 = possProhibitedTo->getConnectedEdges();
00268         // go through the following edge,
00269         //  check whether one of these connections is prohibited
00270         for (i=ev1.begin(); i!=ev1.end(); ++i) {
00271             std::vector<NBNode*>::const_iterator outgoing2 =
00272                 find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(*i));
00273             if (outgoing2==myControlledNodes.end()) {
00274                 continue;
00275             }
00276             NBNode *outnode2 = *outgoing2;
00277             if (incnode!=outnode2) {
00278                 continue;
00279             }
00280             bool ret1 = incnode->foes(possProhibitorTo, *i,
00281                                       possProhibitedFrom, possProhibitedTo);
00282             bool ret2 = incnode->forbids(possProhibitorFrom, possProhibitorTo,
00283                                          possProhibitedTo, *i,
00284                                          regardNonSignalisedLowerPriority);
00285             bool ret = ret1||ret2;
00286             if (ret) {
00287                 return true;
00288             }
00289         }
00290 
00291         const EdgeVector &ev2 = possProhibitorTo->getConnectedEdges();
00292         // go through the following edge,
00293         //  check whether one of these connections is prohibited
00294         for (i=ev2.begin(); i!=ev2.end(); ++i) {
00295             std::vector<NBNode*>::const_iterator incoming2 =
00296                 find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorTo));
00297             if (incoming2==myControlledNodes.end()) {
00298                 continue;
00299             }
00300             NBNode *incnode2 = *incoming2;
00301             if (incnode2!=outnode) {
00302                 continue;
00303             }
00304             bool ret1 = incnode2->foes(possProhibitorTo, *i,
00305                                        possProhibitedFrom, possProhibitedTo);
00306             bool ret2 = incnode2->forbids(possProhibitorTo, *i,
00307                                           possProhibitedFrom, possProhibitedTo,
00308                                           regardNonSignalisedLowerPriority);
00309             bool ret = ret1||ret2;
00310             if (ret) {
00311                 return true;
00312             }
00313         }
00314         return false;
00315     }
00316     // both links are located at the same node
00317     //  check using this node's information
00318     return incnode->forbids(possProhibitorFrom, possProhibitorTo,
00319                             possProhibitedFrom, possProhibitedTo,
00320                             regardNonSignalisedLowerPriority);
00321 }
00322 
00323 
00324 bool
00325 NBTrafficLightDefinition::foes(const NBEdge * const from1, const NBEdge * const to1,
00326                                const NBEdge * const from2, const NBEdge * const to2) const throw() {
00327     if (to1==0||to2==0) {
00328         return false;
00329     }
00330     // retrieve both nodes (it is possible that a connection
00331     std::vector<NBNode*>::const_iterator incoming =
00332         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00333                 NBContHelper::node_with_incoming_finder(from1));
00334     std::vector<NBNode*>::const_iterator outgoing =
00335         find_if(myControlledNodes.begin(), myControlledNodes.end(),
00336                 NBContHelper::node_with_outgoing_finder(to1));
00337     assert(incoming!=myControlledNodes.end());
00338     NBNode *incnode = *incoming;
00339     NBNode *outnode = *outgoing;
00340     if (incnode!=outnode) {
00341         return false;
00342     }
00343     return incnode->foes(from1, to1, from2, to2);
00344 }
00345 
00346 
00347 void
00348 NBTrafficLightDefinition::addNode(NBNode *node) throw() {
00349     if (std::find(myControlledNodes.begin(), myControlledNodes.end(), node)==myControlledNodes.end()) {
00350         myControlledNodes.push_back(node);
00351         std::sort(myControlledNodes.begin(), myControlledNodes.end(), NBNode::nodes_by_id_sorter());
00352         node->addTrafficLight(this);
00353     }
00354 }
00355 
00356 
00357 void
00358 NBTrafficLightDefinition::removeNode(NBNode *node) throw() {
00359     std::vector<NBNode*>::iterator i = std::find(myControlledNodes.begin(), myControlledNodes.end(), node);
00360     if (i!=myControlledNodes.end()) {
00361         myControlledNodes.erase(i);
00362     }
00363     // !!! remove in node?
00364 }
00365 
00366 
00367 void
00368 NBTrafficLightDefinition::addControlledInnerEdges(const std::vector<std::string> &edges) throw() {
00369     copy(edges.begin(), edges.end(), back_inserter(myControlledInnerEdges));
00370 }
00371 
00372 
00373 const EdgeVector &
00374 NBTrafficLightDefinition::getIncomingEdges() const throw() {
00375     return myIncomingEdges;
00376 }
00377 
00378 
00379 /****************************************************************************/
00380 

Generated on Wed May 5 00:06:33 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6