|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // A container for traffic light definitions and built programs 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 #include <map> 00030 #include <string> 00031 #include <algorithm> 00032 #include <utils/common/MsgHandler.h> 00033 #include <utils/common/ToString.h> 00034 #include <utils/common/IDSupplier.h> 00035 #include <utils/iodevices/OutputDevice.h> 00036 #include <utils/options/OptionsCont.h> 00037 #include "NBTrafficLightLogic.h" 00038 #include "NBTrafficLightLogicCont.h" 00039 #include "NBEdgeCont.h" 00040 00041 #ifdef CHECK_MEMORY_LEAKS 00042 #include <foreign/nvwa/debug_new.h> 00043 #endif // CHECK_MEMORY_LEAKS 00044 00045 00046 // =========================================================================== 00047 // static members 00048 // =========================================================================== 00049 const NBTrafficLightLogicCont::Program2Def NBTrafficLightLogicCont::EmptyDefinitions = NBTrafficLightLogicCont::Program2Def(); 00050 00051 // =========================================================================== 00052 // method definitions 00053 // =========================================================================== 00054 NBTrafficLightLogicCont::NBTrafficLightLogicCont() throw() {} 00055 00056 00057 NBTrafficLightLogicCont::~NBTrafficLightLogicCont() throw() { 00058 clear(); 00059 } 00060 00061 00062 void 00063 NBTrafficLightLogicCont::applyOptions(OptionsCont& oc) throw() { 00064 // check whether any offsets shall be manipulated by setting 00065 // them to half of the duration 00066 if (oc.isSet("tls.half-offset")) { 00067 std::vector<std::string> ids = oc.getStringVector("tls.half-offset"); 00068 myHalfOffsetTLS.insert(ids.begin(), ids.end()); 00069 } 00070 // check whether any offsets shall be manipulated by setting 00071 // them to a quarter of the duration 00072 if (oc.isSet("tls.quarter-offset")) { 00073 std::vector<std::string> ids = oc.getStringVector("tls.quarter-offset"); 00074 myHalfOffsetTLS.insert(ids.begin(), ids.end()); 00075 } 00076 } 00077 00078 00079 bool 00080 NBTrafficLightLogicCont::insert(NBTrafficLightDefinition* logic, bool forceInsert) throw() { 00081 myExtracted.erase(logic); 00082 if (myDefinitions.count(logic->getID())) { 00083 if (myDefinitions[logic->getID()].count(logic->getProgramID())) { 00084 if (forceInsert) { 00085 const Program2Def& programs = myDefinitions[logic->getID()]; 00086 IDSupplier idS("", 0); 00087 for (Program2Def::const_iterator it_prog = programs.begin(); it_prog != programs.end(); it_prog++) { 00088 idS.avoid(it_prog->first); 00089 } 00090 logic->setProgramID(idS.getNext()); 00091 } else { 00092 return false; 00093 } 00094 } 00095 } else { 00096 myDefinitions[logic->getID()] = Program2Def(); 00097 } 00098 myDefinitions[logic->getID()][logic->getProgramID()] = logic; 00099 return true; 00100 } 00101 00102 00103 bool 00104 NBTrafficLightLogicCont::removeFully(const std::string id) { 00105 if (myDefinitions.count(id)) { 00106 // delete all programs 00107 for (Program2Def::iterator i = myDefinitions[id].begin(); i != myDefinitions[id].end(); i++) { 00108 delete i->second; 00109 } 00110 myDefinitions.erase(id); 00111 // also delete any logics that were already computed 00112 if (myComputed.count(id)) { 00113 for (Program2Logic::iterator i = myComputed[id].begin(); i != myComputed[id].end(); i++) { 00114 delete i->second; 00115 } 00116 myComputed.erase(id); 00117 } 00118 return true; 00119 } else { 00120 return false; 00121 } 00122 } 00123 00124 00125 bool 00126 NBTrafficLightLogicCont::removeProgram(const std::string id, const std::string programID, bool del) { 00127 if (myDefinitions.count(id) && myDefinitions[id].count(programID)) { 00128 if (del) { 00129 delete myDefinitions[id][programID]; 00130 } 00131 myDefinitions[id].erase(programID); 00132 return true; 00133 } else { 00134 return false; 00135 } 00136 } 00137 00138 00139 void 00140 NBTrafficLightLogicCont::extract(NBTrafficLightDefinition* definition) { 00141 myExtracted.insert(definition); 00142 removeProgram(definition->getID(), definition->getProgramID(), false); 00143 } 00144 00145 00146 std::pair<unsigned int, unsigned int> 00147 NBTrafficLightLogicCont::computeLogics(NBEdgeCont& ec, OptionsCont& oc) { 00148 // clean previous logics 00149 Logics logics = getComputed(); 00150 for (Logics::iterator it = logics.begin(); it != logics.end(); it++) { 00151 delete *it; 00152 } 00153 myComputed.clear(); 00154 00155 unsigned int numPrograms = 0; 00156 Definitions definitions = getDefinitions(); 00157 for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) { 00158 if (computeSingleLogic(ec, oc, *it)) { 00159 numPrograms++; 00160 } 00161 } 00162 return std::pair<unsigned int, unsigned int>((unsigned int)myComputed.size(), numPrograms); 00163 } 00164 00165 00166 bool 00167 NBTrafficLightLogicCont::computeSingleLogic(NBEdgeCont& ec, OptionsCont& oc, NBTrafficLightDefinition* def) { 00168 const std::string& id = def->getID(); 00169 const std::string& programID = def->getProgramID(); 00170 // build program 00171 NBTrafficLightLogic* built = def->compute(ec, oc); 00172 if (built==0) { 00173 WRITE_WARNING("Could not build program '" + programID + "' for traffic light '" + id + "'"); 00174 return false; 00175 } 00176 // compute offset 00177 SUMOTime T = built->getDuration(); 00178 if (myHalfOffsetTLS.count(id)) { 00179 built->setOffset((SUMOTime)(T/2.)); 00180 } 00181 if (myQuarterOffsetTLS.count(id)) { 00182 built->setOffset((SUMOTime)(T/4.)); 00183 } 00184 // and insert the result after computation 00185 // make sure we don't leak memory if computeSingleLogic is called externally 00186 if (myComputed[id][programID] != 0) { 00187 delete myComputed[id][programID]; 00188 } 00189 myComputed[id][programID] = built; 00190 return true; 00191 } 00192 00193 00194 void 00195 NBTrafficLightLogicCont::clear() throw() { 00196 Definitions definitions = getDefinitions(); 00197 for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) { 00198 delete *it; 00199 } 00200 myDefinitions.clear(); 00201 Logics logics = getComputed(); 00202 for (Logics::iterator it = logics.begin(); it != logics.end(); it++) { 00203 delete *it; 00204 } 00205 myComputed.clear(); 00206 for (std::set<NBTrafficLightDefinition*>::iterator it = myExtracted.begin(); it != myExtracted.end(); it++) { 00207 delete *it; 00208 } 00209 myExtracted.clear(); 00210 } 00211 00212 00213 void 00214 NBTrafficLightLogicCont::remapRemoved(NBEdge* removed, const EdgeVector& incoming, 00215 const EdgeVector& outgoing) throw() { 00216 Definitions definitions = getDefinitions(); 00217 for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) { 00218 (*it)->remapRemoved(removed, incoming, outgoing); 00219 } 00220 } 00221 00222 00223 void 00224 NBTrafficLightLogicCont::replaceRemoved(NBEdge* removed, int removedLane, 00225 NBEdge* by, int byLane) throw() { 00226 Definitions definitions = getDefinitions(); 00227 for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) { 00228 (*it)->replaceRemoved(removed, removedLane, by, byLane); 00229 } 00230 } 00231 00232 00233 NBTrafficLightDefinition* 00234 NBTrafficLightLogicCont::getDefinition(const std::string& id, const std::string& programID) const { 00235 Id2Defs::const_iterator i=myDefinitions.find(id); 00236 if (i!=myDefinitions.end()) { 00237 Program2Def programs = i->second; 00238 Program2Def::const_iterator i2 = programs.find(programID); 00239 if (i2 != programs.end()) { 00240 return i2->second; 00241 } 00242 } 00243 return 0; 00244 } 00245 00246 const NBTrafficLightLogicCont::Program2Def& 00247 NBTrafficLightLogicCont::getPrograms(const std::string& id) const { 00248 Id2Defs::const_iterator it = myDefinitions.find(id); 00249 if (it != myDefinitions.end()) { 00250 return it->second; 00251 } else { 00252 return EmptyDefinitions; 00253 } 00254 } 00255 00256 00257 NBTrafficLightLogic* 00258 NBTrafficLightLogicCont::getLogic(const std::string& id, const std::string& programID) const { 00259 Id2Logics::const_iterator i=myComputed.find(id); 00260 if (i!=myComputed.end()) { 00261 Program2Logic programs = i->second; 00262 Program2Logic::const_iterator i2 = programs.find(programID); 00263 if (i2 != programs.end()) { 00264 return i2->second; 00265 } 00266 } 00267 return 0; 00268 } 00269 00270 00271 void 00272 NBTrafficLightLogicCont::setTLControllingInformation(const NBEdgeCont& ec) throw() { 00273 Definitions definitions = getDefinitions(); 00274 // set the information about all participants, first 00275 for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) { 00276 (*it)->setParticipantsInformation(); 00277 } 00278 // clear previous information because tlDefs may have been removed in NETEDIT 00279 ec.clearControllingTLInformation(); 00280 // insert the information about the tl-controlling 00281 for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) { 00282 (*it)->setTLControllingInformation(ec); 00283 } 00284 } 00285 00286 00287 NBTrafficLightLogicCont::Logics 00288 NBTrafficLightLogicCont::getComputed() const { 00289 Logics result; 00290 for (Id2Logics::const_iterator it_id = myComputed.begin(); it_id != myComputed.end(); it_id++) { 00291 const Program2Logic& programs = it_id->second; 00292 for (Program2Logic::const_iterator it_prog = programs.begin(); it_prog != programs.end(); it_prog++) { 00293 result.push_back(it_prog->second); 00294 } 00295 } 00296 return result; 00297 } 00298 00299 00300 NBTrafficLightLogicCont::Definitions 00301 NBTrafficLightLogicCont::getDefinitions() const { 00302 Definitions result; 00303 for (Id2Defs::const_iterator it_id = myDefinitions.begin(); it_id != myDefinitions.end(); it_id++) { 00304 const Program2Def& programs = it_id->second; 00305 for (Program2Def::const_iterator it_prog = programs.begin(); it_prog != programs.end(); it_prog++) { 00306 result.push_back(it_prog->second); 00307 } 00308 } 00309 return result; 00310 } 00311 00312 00313 /****************************************************************************/ 00314