|
SUMO - Simulation of Urban MObility
|
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