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