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