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

Generated on Wed May 5 00:06:32 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6