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