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