SUMO - Simulation of Urban MObility

MSTLLogicControl.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A class that stores and controls tls and switching of their 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 // included modules
00021 // ===========================================================================
00022 #ifdef _MSC_VER
00023 #include <windows_config.h>
00024 #else
00025 #include <config.h>
00026 #endif
00027 
00028 #include <vector>
00029 #include <algorithm>
00030 #include <cassert>
00031 #include <iterator>
00032 #include "MSTrafficLightLogic.h"
00033 #include "MSSimpleTrafficLightLogic.h"
00034 #include "MSTLLogicControl.h"
00035 #include "MSOffTrafficLightLogic.h"
00036 #include <microsim/MSEventControl.h>
00037 #include <microsim/MSNet.h>
00038 #include <utils/common/TplConvert.h>
00039 #include <utils/common/ToString.h>
00040 #include <utils/common/MsgHandler.h>
00041 
00042 #ifdef CHECK_MEMORY_LEAKS
00043 #include <foreign/nvwa/debug_new.h>
00044 #endif // CHECK_MEMORY_LEAKS
00045 
00046 
00047 // ===========================================================================
00048 // method definitions
00049 // ===========================================================================
00050 /* -------------------------------------------------------------------------
00051  * MSTLLogicControl::TLSLogicVariants - methods
00052  * ----------------------------------------------------------------------- */
00053 MSTLLogicControl::TLSLogicVariants::TLSLogicVariants()
00054     : myCurrentProgram(0) {
00055 }
00056 
00057 
00058 MSTLLogicControl::TLSLogicVariants::~TLSLogicVariants() {
00059     std::map<std::string, MSTrafficLightLogic*>::const_iterator j;
00060     for (std::map<std::string, MSTrafficLightLogic*>::iterator j=myVariants.begin(); j!=myVariants.end(); ++j) {
00061         delete(*j).second;
00062     }
00063     for (std::vector<OnSwitchAction*>::iterator i=mySwitchActions.begin(); i!=mySwitchActions.end(); ++i) {
00064         delete *i;
00065     }
00066 }
00067 
00068 
00069 bool
00070 MSTLLogicControl::TLSLogicVariants::checkOriginalTLS() const {
00071     bool hadErrors = false;
00072     for (std::map<std::string, MSTrafficLightLogic*>::const_iterator j=myVariants.begin(); j!=myVariants.end(); ++j) {
00073         const MSTrafficLightLogic::Phases& phases = (*j).second->getPhases();
00074         unsigned int linkNo = (unsigned int)(*j).second->getLinks().size();
00075         bool hadProgramErrors = false;
00076         for (MSTrafficLightLogic::Phases::const_iterator i=phases.begin(); i!=phases.end(); ++i) {
00077             if ((*i)->getState().length()<linkNo) {
00078                 hadProgramErrors = true;
00079             }
00080         }
00081         if (hadProgramErrors) {
00082             WRITE_ERROR("Mismatching phase size in tls '" + (*j).second->getID() + "', program '" + (*j).first + "'.");
00083             hadErrors = true;
00084         }
00085     }
00086     return !hadErrors;
00087 }
00088 
00089 
00090 void
00091 MSTLLogicControl::TLSLogicVariants::saveInitialStates() {
00092     myOriginalLinkStates = myCurrentProgram->collectLinkStates();
00093 }
00094 
00095 
00096 bool
00097 MSTLLogicControl::TLSLogicVariants::addLogic(const std::string& programID,
00098         MSTrafficLightLogic* logic, bool netWasLoaded, bool isNewDefault) {
00099     if (myVariants.find(programID)!=myVariants.end()) {
00100         return false;
00101     }
00102     // assert the links are set
00103     if (netWasLoaded) {
00104         // this one has not yet its links set
00105         if (myCurrentProgram==0) {
00106             throw ProcessError("No initial signal plan loaded for tls '" + logic->getID() + "'.");
00107         }
00108         logic->adaptLinkInformationFrom(*myCurrentProgram);
00109         if (logic->getLinks().size()>logic->getPhase(0).getState().size()) {
00110             throw ProcessError("Mismatching phase size in tls '" + logic->getID() + "', program '" + programID + "'.");
00111         }
00112     }
00113     // add to the list of active
00114     if (myVariants.size()==0||isNewDefault) {
00115         myCurrentProgram = logic;
00116     }
00117     // add to the list of logic
00118     myVariants[programID] = logic;
00119     if (myVariants.size()==1||isNewDefault) {
00120         logic->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
00121         executeOnSwitchActions();
00122     }
00123     return true;
00124 }
00125 
00126 
00127 MSTrafficLightLogic*
00128 MSTLLogicControl::TLSLogicVariants::getLogic(const std::string& programID) const {
00129     if (myVariants.find(programID)==myVariants.end()) {
00130         return 0;
00131     }
00132     return myVariants.find(programID)->second;
00133 }
00134 
00135 
00136 MSTrafficLightLogic*
00137 MSTLLogicControl::TLSLogicVariants::getLogicInstantiatingOff(MSTLLogicControl& tlc,
00138         const std::string& programID) {
00139     if (myVariants.find(programID)==myVariants.end()) {
00140         if (programID=="off") {
00141             // build an off-tll if this switch indicates it
00142             if (!addLogic("off", new MSOffTrafficLightLogic(tlc, myCurrentProgram->getID()), true, true)) {
00143                 // inform the user if this fails
00144                 throw ProcessError("Could not build an off-state for tls '" + myCurrentProgram->getID() + "'.");
00145             }
00146         } else {
00147             // inform the user about a missing logic
00148             throw ProcessError("Can not switch tls '" + myCurrentProgram->getID() + "' to program '" + programID + "';\n The program is not known.");
00149         }
00150     }
00151     return getLogic(programID);
00152 }
00153 
00154 
00155 void
00156 MSTLLogicControl::TLSLogicVariants::addSwitchCommand(OnSwitchAction* c) {
00157     mySwitchActions.push_back(c);
00158 }
00159 
00160 
00161 std::vector<MSTrafficLightLogic*>
00162 MSTLLogicControl::TLSLogicVariants::getAllLogics() const {
00163     std::vector<MSTrafficLightLogic*> ret;
00164     std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
00165     for (i=myVariants.begin(); i!=myVariants.end(); ++i) {
00166         ret.push_back((*i).second);
00167     }
00168     return ret;
00169 }
00170 
00171 
00172 bool
00173 MSTLLogicControl::TLSLogicVariants::isActive(const MSTrafficLightLogic* tl) const {
00174     return tl==myCurrentProgram;
00175 }
00176 
00177 
00178 MSTrafficLightLogic*
00179 MSTLLogicControl::TLSLogicVariants::getActive() const {
00180     return myCurrentProgram;
00181 }
00182 
00183 
00184 void
00185 MSTLLogicControl::TLSLogicVariants::switchTo(MSTLLogicControl& tlc, const std::string& programID) {
00186     // set the found wished sub-program as this tls' current one
00187     myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
00188 }
00189 
00190 
00191 void
00192 MSTLLogicControl::TLSLogicVariants::executeOnSwitchActions() const {
00193     for (std::vector<OnSwitchAction*>::const_iterator i=mySwitchActions.begin(); i!=mySwitchActions.end(); ++i) {
00194         (*i)->execute();
00195     }
00196 }
00197 
00198 
00199 void
00200 MSTLLogicControl::TLSLogicVariants::addLink(MSLink* link, MSLane* lane, unsigned int pos) {
00201     for (std::map<std::string, MSTrafficLightLogic*>::iterator i=myVariants.begin(); i!=myVariants.end(); ++i) {
00202         (*i).second->addLink(link, lane, pos);
00203     }
00204 }
00205 
00206 
00207 
00208 /* -------------------------------------------------------------------------
00209  * method definitions for the Switching Procedures
00210  * ----------------------------------------------------------------------- */
00211 /* -------------------------------------------------------------------------
00212  * method definitions for WAUTSwitchProcedure
00213  * ----------------------------------------------------------------------- */
00214 unsigned int
00215 MSTLLogicControl::WAUTSwitchProcedure::getGSPValue(const MSTrafficLightLogic& logic) const {
00216     std::string val = logic.getParameterValue("GSP");
00217     if (val.length()==0) {
00218         return 0;
00219     }
00220     return TplConvert<char>::_2int(val.c_str());
00221 }
00222 
00223 
00224 bool
00225 MSTLLogicControl::WAUTSwitchProcedure::isPosAtGSP(SUMOTime currentTime, const MSTrafficLightLogic& logic) {
00226     SUMOTime gspTime = TIME2STEPS(getGSPValue(logic)) % logic.getDefaultCycleTime();
00227     SUMOTime programTime = logic.getOffsetFromIndex(logic.getCurrentPhaseIndex())
00228                            + (logic.getCurrentPhaseDef().duration - (logic.getNextSwitchTime() - currentTime));
00229     return gspTime==programTime;
00230 }
00231 
00232 
00233 SUMOTime
00234 MSTLLogicControl::WAUTSwitchProcedure::getDiffToStartOfPhase(MSTrafficLightLogic& logic, SUMOTime toTime) {
00235     unsigned int stepOfMyPos = logic.getIndexFromOffset(toTime);
00236     SUMOTime startOfPhase = logic.getOffsetFromIndex(stepOfMyPos);
00237     assert(toTime >= startOfPhase);
00238     return toTime - startOfPhase;
00239 }
00240 
00241 
00242 void
00243 MSTLLogicControl::WAUTSwitchProcedure::switchToPos(SUMOTime simStep, MSTrafficLightLogic& logic, SUMOTime toTime) {
00244     unsigned int stepTo = logic.getIndexFromOffset(toTime);
00245     SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
00246     const MSPhaseDefinition& phase = logic.getPhase(stepTo);
00247     SUMOTime leftDuration = phase.duration - diff;
00248     logic.changeStepAndDuration(myControl, simStep, stepTo, leftDuration);
00249 }
00250 
00251 
00252 
00253 /* -------------------------------------------------------------------------
00254  * method definitions for WAUTSwitchProcedure_JustSwitch
00255  * ----------------------------------------------------------------------- */
00256 MSTLLogicControl::WAUTSwitchProcedure_JustSwitch::WAUTSwitchProcedure_JustSwitch(
00257     MSTLLogicControl& control, WAUT& waut,
00258     MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
00259     : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
00260 
00261 
00262 MSTLLogicControl::WAUTSwitchProcedure_JustSwitch::~WAUTSwitchProcedure_JustSwitch() {}
00263 
00264 
00265 bool
00266 MSTLLogicControl::WAUTSwitchProcedure_JustSwitch::trySwitch(SUMOTime) {
00267     return true;
00268 }
00269 
00270 
00271 
00272 /* -------------------------------------------------------------------------
00273  * method definitions for WAUTSwitchProcedure_GSP
00274  * ----------------------------------------------------------------------- */
00275 MSTLLogicControl::WAUTSwitchProcedure_GSP::WAUTSwitchProcedure_GSP(
00276     MSTLLogicControl& control, WAUT& waut,
00277     MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
00278     : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
00279 
00280 
00281 MSTLLogicControl::WAUTSwitchProcedure_GSP::~WAUTSwitchProcedure_GSP() {}
00282 
00283 
00284 bool
00285 MSTLLogicControl::WAUTSwitchProcedure_GSP::trySwitch(SUMOTime step) {
00286     // switch to the next programm if the GSP is reached
00287     if (isPosAtGSP(step, *myFrom)) {
00288         // adapt program's state
00289         if (mySwitchSynchron) {
00290             adaptLogic(step);
00291         } else {
00292             switchToPos(step, *myTo, TIME2STEPS(getGSPValue(*myTo)));
00293         }
00294         // switch to destination program
00295         return true;
00296     }
00297     // do not switch, yet
00298     return false;
00299 }
00300 
00301 
00302 void
00303 MSTLLogicControl::WAUTSwitchProcedure_GSP::adaptLogic(SUMOTime step) {
00304     SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
00305     unsigned int stepTo = myTo->getIndexFromOffset(gspTo);
00306     SUMOTime cycleTimeTo = myTo->getDefaultCycleTime();
00307     if (gspTo == cycleTimeTo) {
00308         gspTo=0;
00309     }
00310 
00311     SUMOTime currentPosTo = myTo->getOffsetFromIndex(myTo->getCurrentPhaseIndex());
00312     currentPosTo += (myTo->getCurrentPhaseDef().duration - (myTo->getNextSwitchTime() - step));
00313     SUMOTime diff = getDiffToStartOfPhase(*myTo, gspTo);
00314 
00315     SUMOTime deltaToStretch = 0;
00316     if (gspTo >= currentPosTo) {
00317         deltaToStretch = (gspTo - currentPosTo);
00318     } else {
00319         deltaToStretch = (cycleTimeTo - currentPosTo + gspTo);
00320     }
00321     unsigned int newdur = (unsigned int) myTo->getPhase(stepTo).duration - diff + deltaToStretch;
00322     myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
00323 }
00324 
00325 
00326 
00327 /* -------------------------------------------------------------------------
00328  * method definitions for WAUTSwitchProcedure_Stretch
00329  * ----------------------------------------------------------------------- */
00330 MSTLLogicControl::WAUTSwitchProcedure_Stretch::WAUTSwitchProcedure_Stretch(
00331     MSTLLogicControl& control, WAUT& waut,
00332     MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
00333     : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
00334 
00335 
00336 MSTLLogicControl::WAUTSwitchProcedure_Stretch::~WAUTSwitchProcedure_Stretch() {}
00337 
00338 
00339 bool
00340 MSTLLogicControl::WAUTSwitchProcedure_Stretch::trySwitch(SUMOTime step) {
00341     // switch to the next programm if the GSP is reached
00342     if (isPosAtGSP(step, *myFrom)) {
00343         // adapt program's state
00344         if (mySwitchSynchron) {
00345             adaptLogic(step);
00346         } else {
00347             switchToPos(step, *myTo, TIME2STEPS(getGSPValue(*myTo)));
00348         }
00349         // switch to destination program
00350         return true;
00351     }
00352     // do not switch, yet
00353     return false;
00354 }
00355 
00356 
00357 void
00358 MSTLLogicControl::WAUTSwitchProcedure_Stretch::adaptLogic(SUMOTime step) {
00359     SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
00360     SUMOTime cycleTime = myTo->getDefaultCycleTime();
00361     // the position, where the logic has to be after synchronisation
00362     SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
00363     // calculate the difference, that has to be equalized
00364     SUMOTime deltaToCut = 0;
00365     if (posAfterSyn < gspTo) {
00366         deltaToCut = posAfterSyn + cycleTime - gspTo;
00367     } else {
00368         deltaToCut =  posAfterSyn - gspTo;
00369     }
00370     // test, wheter cutting of the Signalplan is possible
00371     SUMOTime deltaPossible = 0;
00372     int areasNo = getStretchAreaNo(myTo);
00373     for (int i=0; i<areasNo; i++) {
00374         StretchBereichDef def = getStretchBereichDef(myTo, i+1);
00375         assert(def.end >= def.begin) ;
00376         deltaPossible += TIME2STEPS(def.end - def.begin);
00377     }
00378     int stretchUmlaufAnz = (int) TplConvert<char>::_2SUMOReal(myTo->getParameterValue("StretchUmlaufAnz").c_str());
00379     deltaPossible = stretchUmlaufAnz * deltaPossible;
00380     if ((deltaPossible > deltaToCut)&&(deltaToCut < (cycleTime / 2))) {
00381         cutLogic(step, gspTo, deltaToCut);
00382     } else {
00383         SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
00384         stretchLogic(step, gspTo, deltaToStretch);
00385     }
00386 }
00387 
00388 
00389 void
00390 MSTLLogicControl::WAUTSwitchProcedure_Stretch::cutLogic(SUMOTime step, SUMOTime startPos, SUMOTime allCutTime) {
00391     unsigned int actStep = myTo->getIndexFromOffset(startPos);
00392     // switches to startPos and cuts this phase, if there is a "Bereich"
00393     int areasNo = getStretchAreaNo(myTo);
00394     SUMOTime toCut = 0;
00395     for (int i=0; i<areasNo; i++) {
00396         StretchBereichDef def = getStretchBereichDef(myTo, i+1);
00397         SUMOTime begin = TIME2STEPS(def.begin);
00398         unsigned int end = TIME2STEPS(def.end);
00399         size_t stepOfBegin = myTo->getIndexFromOffset(begin);
00400         if (stepOfBegin == actStep) {
00401             if (begin < startPos) {
00402                 toCut = end - startPos;
00403             } else {
00404                 toCut = end - begin;
00405             }
00406             toCut = MIN2(allCutTime, toCut);
00407             allCutTime = allCutTime - toCut;
00408         }
00409     }
00410     SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
00411     SUMOTime newDur = remainingDur - toCut;
00412     myTo->changeStepAndDuration(myControl,step,actStep,newDur);
00413 
00414     // changes the duration of all other phases
00415     int currStep = (actStep + 1) % (int)myTo->getPhases().size();
00416     while (allCutTime > 0) {
00417         for (int i=currStep; i<(int) myTo->getPhases().size(); i++) {
00418             SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
00419             SUMOTime durOfPhase = myTo->getPhase(i).duration;
00420             SUMOTime endOfPhase = beginOfPhase + durOfPhase;
00421             for (int i=0; i<areasNo; i++) {
00422                 StretchBereichDef def = getStretchBereichDef(myTo, i+1);
00423                 SUMOTime begin = TIME2STEPS(def.begin);
00424                 SUMOTime end = TIME2STEPS(def.end);
00425                 if ((beginOfPhase <= begin) && (endOfPhase >= end)) {
00426                     SUMOTime maxCutOfPhase = MIN2(end - begin, allCutTime);
00427                     allCutTime = allCutTime - maxCutOfPhase;
00428                     durOfPhase = durOfPhase - maxCutOfPhase;
00429                 }
00430             }
00431             myTo->addOverridingDuration(durOfPhase);
00432         }
00433         currStep = 0;
00434     }
00435 }
00436 
00437 void
00438 MSTLLogicControl::WAUTSwitchProcedure_Stretch::stretchLogic(SUMOTime step, SUMOTime startPos, SUMOTime allStretchTime) {
00439     unsigned int currStep = myTo->getIndexFromOffset(startPos);
00440     SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
00441     SUMOTime remainingStretchTime = allStretchTime;
00442     SUMOTime StretchTimeOfPhase = 0;
00443     unsigned int stretchUmlaufAnz = (unsigned int) TplConvert<char>::_2SUMOReal(myTo->getParameterValue("StretchUmlaufAnz").c_str());
00444     SUMOReal facSum = 0;
00445     int areasNo = getStretchAreaNo(myTo);
00446     for (int x=0; x<areasNo; x++) {
00447         StretchBereichDef def = getStretchBereichDef(myTo, x+1);
00448         facSum += def.fac;
00449     }
00450     facSum *= stretchUmlaufAnz;
00451 
00452     //switch to startPos and stretch this phase, if there is a end of "bereich" between startpos and end of phase
00453     SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
00454     for (int x=0; x<areasNo; x++) {
00455         StretchBereichDef def = getStretchBereichDef(myTo, x+1);
00456         SUMOTime end = TIME2STEPS(def.end);
00457         SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
00458         if (end <= endOfPhase && end >= startPos) {
00459             SUMOReal fac = def.fac;
00460             SUMOReal actualfac = fac / facSum;
00461             facSum = facSum - fac;
00462             StretchTimeOfPhase = TIME2STEPS(STEPS2TIME(remainingStretchTime) * actualfac + 0.5);
00463             remainingStretchTime = allStretchTime - StretchTimeOfPhase;
00464         }
00465     }
00466     durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
00467     myTo->changeStepAndDuration(myControl,step,currStep,durOfPhase);
00468 
00469     currStep = (currStep+1) % (int)myTo->getPhases().size();
00470     // stretch all other phases, if there is a "bereich"
00471     while (remainingStretchTime > 0) {
00472         for (unsigned int i=currStep; i<myTo->getPhases().size() && remainingStretchTime > 0; i++) {
00473             durOfPhase = myTo->getPhase(i).duration;
00474             SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
00475             SUMOTime endOfPhase = beginOfPhase + durOfPhase;
00476             for (int j=0; j<areasNo && remainingStretchTime > 0; j++) {
00477                 StretchBereichDef def = getStretchBereichDef(myTo, j+1);
00478                 SUMOTime end = TIME2STEPS(def.end);
00479                 SUMOReal fac = def.fac;
00480                 if ((beginOfPhase <= end) && (endOfPhase >= end)) {
00481                     SUMOReal actualfac = fac / facSum;
00482                     StretchTimeOfPhase = TIME2STEPS(STEPS2TIME(remainingStretchTime) * actualfac + 0.5);
00483                     facSum -= fac;
00484                     durOfPhase += StretchTimeOfPhase;
00485                     remainingStretchTime -= StretchTimeOfPhase;
00486                 }
00487             }
00488             myTo->addOverridingDuration(durOfPhase);
00489         }
00490         currStep = 0;
00491     }
00492 }
00493 
00494 int
00495 MSTLLogicControl::WAUTSwitchProcedure_Stretch::getStretchAreaNo(MSTrafficLightLogic* from) const {
00496     int no = 0;
00497     while (from->getParameterValue("B" + toString(no+1) + ".begin")!="") {
00498         no++;
00499     }
00500     return no;
00501 }
00502 
00503 
00504 MSTLLogicControl::WAUTSwitchProcedure_Stretch::StretchBereichDef
00505 MSTLLogicControl::WAUTSwitchProcedure_Stretch::getStretchBereichDef(MSTrafficLightLogic* from, int index) const {
00506     StretchBereichDef def;
00507     def.begin = TplConvert<char>::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".begin").c_str());
00508     def.end = TplConvert<char>::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".end").c_str());
00509     def.fac = TplConvert<char>::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".factor").c_str());
00510     return def;
00511 }
00512 
00513 
00514 
00515 /* -------------------------------------------------------------------------
00516  * method definitions for MSTLLogicControl
00517  * ----------------------------------------------------------------------- */
00518 MSTLLogicControl::MSTLLogicControl()
00519     : myNetWasLoaded(false) {}
00520 
00521 
00522 MSTLLogicControl::~MSTLLogicControl() {
00523     // delete tls
00524     for (std::map<std::string, TLSLogicVariants*>::const_iterator i=myLogics.begin(); i!=myLogics.end(); ++i) {
00525         delete(*i).second;
00526     }
00527     // delete WAUTs
00528     for (std::map<std::string, WAUT*>::const_iterator i=myWAUTs.begin(); i!=myWAUTs.end(); ++i) {
00529         delete(*i).second;
00530     }
00531 }
00532 
00533 
00534 void
00535 MSTLLogicControl::setTrafficLightSignals(SUMOTime t) const {
00536     for (std::map<std::string, TLSLogicVariants*>::const_iterator i=myLogics.begin(); i!=myLogics.end(); ++i) {
00537         (*i).second->getActive()->setTrafficLightSignals(t);
00538     }
00539 }
00540 
00541 
00542 std::vector<MSTrafficLightLogic*>
00543 MSTLLogicControl::getAllLogics() const {
00544     std::vector<MSTrafficLightLogic*> ret;
00545     std::map<std::string, TLSLogicVariants*>::const_iterator i;
00546     for (i=myLogics.begin(); i!=myLogics.end(); ++i) {
00547         std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
00548         copy(s.begin(), s.end(), back_inserter(ret));
00549     }
00550     return ret;
00551 }
00552 
00553 MSTLLogicControl::TLSLogicVariants&
00554 MSTLLogicControl::get(const std::string& id) const {
00555     std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
00556     if (i==myLogics.end()) {
00557         throw InvalidArgument("The tls '" + id + "' is not known.");
00558     }
00559     return *(*i).second;
00560 }
00561 
00562 
00563 MSTrafficLightLogic*
00564 MSTLLogicControl::get(const std::string& id, const std::string& programID) const {
00565     std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
00566     if (i==myLogics.end()) {
00567         return 0;
00568     }
00569     return (*i).second->getLogic(programID);
00570 }
00571 
00572 
00573 std::vector<std::string>
00574 MSTLLogicControl::getAllTLIds() const {
00575     std::vector<std::string> ret;
00576     for (std::map<std::string, TLSLogicVariants*>::const_iterator i=myLogics.begin(); i!=myLogics.end(); ++i) {
00577         ret.push_back((*i).first);
00578     }
00579     return ret;
00580 }
00581 
00582 
00583 bool
00584 MSTLLogicControl::add(const std::string& id, const std::string& programID,
00585                       MSTrafficLightLogic* logic, bool newDefault) {
00586     if (myLogics.find(id)==myLogics.end()) {
00587         myLogics[id] = new TLSLogicVariants();
00588     }
00589     std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
00590     TLSLogicVariants* tlmap = (*i).second;
00591     return tlmap->addLogic(programID, logic, myNetWasLoaded, newDefault);
00592 }
00593 
00594 
00595 bool
00596 MSTLLogicControl::knows(const std::string& id) const {
00597     std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
00598     if (i==myLogics.end()) {
00599         return false;
00600     }
00601     return true;
00602 }
00603 
00604 
00605 bool
00606 MSTLLogicControl::closeNetworkReading() {
00607     bool hadErrors = false;
00608     for (std::map<std::string, TLSLogicVariants*>::iterator i=myLogics.begin(); i!=myLogics.end(); ++i) {
00609         hadErrors |= !(*i).second->checkOriginalTLS();
00610         (*i).second->saveInitialStates();
00611     }
00612     myNetWasLoaded = true;
00613     return !hadErrors;
00614 }
00615 
00616 
00617 bool
00618 MSTLLogicControl::isActive(const MSTrafficLightLogic* tl) const {
00619     std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(tl->getID());
00620     if (i==myLogics.end()) {
00621         return false;
00622     }
00623     return (*i).second->isActive(tl);
00624 }
00625 
00626 
00627 MSTrafficLightLogic*
00628 MSTLLogicControl::getActive(const std::string& id) const {
00629     std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
00630     if (i==myLogics.end()) {
00631         return 0;
00632     }
00633     return (*i).second->getActive();
00634 }
00635 
00636 
00637 void
00638 MSTLLogicControl::switchTo(const std::string& id, const std::string& programID) {
00639     // try to get the tls program definitions
00640     std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
00641     // handle problems
00642     if (i==myLogics.end()) {
00643         throw ProcessError("Could not switch tls '" + id + "' to program '" + programID + "': No such tls exists.");
00644     }
00645     (*i).second->switchTo(*this, programID);
00646 }
00647 
00648 
00649 void
00650 MSTLLogicControl::addWAUT(SUMOTime refTime, const std::string& id,
00651                           const std::string& startProg) {
00652     // check whether the waut was already defined
00653     if (myWAUTs.find(id)!=myWAUTs.end()) {
00654         // report an error if so
00655         throw InvalidArgument("Waut '" + id + "' was already defined.");
00656     }
00657     WAUT* w = new WAUT;
00658     w->id = id;
00659     w->refTime = refTime;
00660     w->startProg = startProg;
00661     myWAUTs[id] = w;
00662 }
00663 
00664 
00665 void
00666 MSTLLogicControl::addWAUTSwitch(const std::string& wautid,
00667                                 SUMOTime when, const std::string& to) {
00668     // try to get the waut
00669     if (myWAUTs.find(wautid)==myWAUTs.end()) {
00670         // report an error if the waut is not known
00671         throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
00672     }
00673     // build and save the waut switch definition
00674     WAUTSwitch s;
00675     s.to = to;
00676     s.when = (myWAUTs[wautid]->refTime + when) % 86400000;
00677     myWAUTs[wautid]->switches.push_back(s);
00678 }
00679 
00680 
00681 void
00682 MSTLLogicControl::addWAUTJunction(const std::string& wautid,
00683                                   const std::string& tls,
00684                                   const std::string& proc,
00685                                   bool synchron) {
00686     // try to get the waut
00687     if (myWAUTs.find(wautid)==myWAUTs.end()) {
00688         // report an error if the waut is not known
00689         throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
00690     }
00691     // try to get the tls to switch
00692     if (myLogics.find(tls)==myLogics.end()) {
00693         // report an error if the tls is not known
00694         throw InvalidArgument("TLS '" + tls + "' to switch in WAUT '" + wautid + "' was not yet defined.");
00695     }
00696     WAUTJunction j;
00697     j.junction = tls;
00698     j.procedure = proc;
00699     j.synchron = synchron;
00700     myWAUTs[wautid]->junctions.push_back(j);
00701 
00702     std::string initProg = myWAUTs[wautid]->startProg;
00703     std::vector<WAUTSwitch>::const_iterator first = myWAUTs[wautid]->switches.end();
00704     SUMOTime minExecTime = -1;
00705     for (std::vector<WAUTSwitch>::const_iterator i=myWAUTs[wautid]->switches.begin(); i!=myWAUTs[wautid]->switches.end(); ++i) {
00706         if ((*i).when>MSNet::getInstance()->getCurrentTimeStep()&&(minExecTime==-1||(*i).when<minExecTime)) {
00707             minExecTime = (*i).when;
00708             first = i;
00709         }
00710         if (first!=myWAUTs[wautid]->switches.begin()) {
00711             initProg = (*(first-1)).to;
00712         }
00713     }
00714     // activate the first one
00715     switchTo(tls, initProg);
00716 }
00717 
00718 
00719 void
00720 MSTLLogicControl::closeWAUT(const std::string& wautid) {
00721     // try to get the waut
00722     if (myWAUTs.find(wautid)==myWAUTs.end()) {
00723         // report an error if the waut is not known
00724         throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
00725     }
00726     WAUT* w = myWAUTs.find(wautid)->second;
00727     std::string initProg = myWAUTs[wautid]->startProg;
00728     // get the switch to be performed as first
00729     std::vector<WAUTSwitch>::const_iterator first = w->switches.end();
00730     SUMOTime minExecTime = -1;
00731     for (std::vector<WAUTSwitch>::const_iterator i=w->switches.begin(); i!=w->switches.end(); ++i) {
00732         if ((*i).when>MSNet::getInstance()->getCurrentTimeStep()&&(minExecTime==-1||(*i).when<minExecTime)) {
00733             minExecTime = (*i).when;
00734             first = i;
00735         }
00736     }
00737     // activate the first one
00738     if (first!=w->switches.end()) {
00739         std::vector<WAUTSwitch>::const_iterator mbegin = w->switches.begin();
00740         MSNet::getInstance()->getBeginOfTimestepEvents().addEvent(
00741             new SwitchInitCommand(*this, wautid, (unsigned int)distance(mbegin, first)),
00742             (*first).when, MSEventControl::NO_CHANGE);
00743     }
00744     /*
00745     // set the current program to all junctions
00746     for(std::vector<WAUTJunction>::const_iterator i=w->junctions.begin(); i!=w->junctions.end(); ++i) {
00747         switchTo((*i).junction, initProg);
00748     }
00749     */
00750 }
00751 
00752 
00753 SUMOTime
00754 MSTLLogicControl::initWautSwitch(MSTLLogicControl::SwitchInitCommand& cmd) {
00755     const std::string& wautid = cmd.getWAUTID();
00756     unsigned int& index = cmd.getIndex();
00757     WAUTSwitch s = myWAUTs[wautid]->switches[index];
00758     for (std::vector<WAUTJunction>::iterator i=myWAUTs[wautid]->junctions.begin(); i!=myWAUTs[wautid]->junctions.end(); ++i) {
00759         // get the current program and the one to instantiate
00760         TLSLogicVariants* vars = myLogics.find((*i).junction)->second;
00761         MSTrafficLightLogic* from = vars->getActive();
00762         MSTrafficLightLogic* to = vars->getLogicInstantiatingOff(*this, s.to);
00763         WAUTSwitchProcedure* proc = 0;
00764         if ((*i).procedure=="GSP") {
00765             proc = new WAUTSwitchProcedure_GSP(*this, *myWAUTs[wautid], from, to, (*i).synchron);
00766         } else if ((*i).procedure=="Stretch") {
00767             proc = new WAUTSwitchProcedure_Stretch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
00768         } else {
00769             proc = new WAUTSwitchProcedure_JustSwitch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
00770         }
00771 
00772         WAUTSwitchProcess p;
00773         p.junction = (*i).junction;
00774         p.proc = proc;
00775         p.from = from;
00776         p.to = to;
00777 
00778         myCurrentlySwitched.push_back(p);
00779     }
00780     index++;
00781     if (index==(int) myWAUTs[wautid]->switches.size()) {
00782         return 0;
00783     }
00784     return myWAUTs[wautid]->switches[index].when - MSNet::getInstance()->getCurrentTimeStep();
00785 }
00786 
00787 
00788 void
00789 MSTLLogicControl::check2Switch(SUMOTime step) {
00790     for (std::vector<WAUTSwitchProcess>::iterator i=myCurrentlySwitched.begin(); i!=myCurrentlySwitched.end();) {
00791         const WAUTSwitchProcess& proc = *i;
00792         if (proc.proc->trySwitch(step)) {
00793             delete proc.proc;
00794             switchTo((*i).to->getID(), (*i).to->getProgramID());
00795             i = myCurrentlySwitched.erase(i);
00796         } else {
00797             ++i;
00798         }
00799     }
00800 }
00801 
00802 
00803 std::pair<SUMOTime, MSPhaseDefinition>
00804 MSTLLogicControl::getPhaseDef(const std::string& tlid) const {
00805     MSTrafficLightLogic* tl = getActive(tlid);
00806     return std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), tl->getCurrentPhaseDef());
00807 }
00808 
00809 
00810 
00811 /****************************************************************************/
00812 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines