00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00048
00049
00050
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
00104 if (netWasLoaded) {
00105
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
00115 if (myVariants.size()==0||isNewDefault) {
00116 myCurrentProgram = logic;
00117 }
00118
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
00140 if (!addLogic("off", new MSOffTrafficLightLogic(tlc, myCurrentProgram->getID()), true, false)) {
00141
00142 throw ProcessError("Could not build an off-state for tls '" + myCurrentProgram->getID() + "'.");
00143 }
00144 } else {
00145
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
00185 myCurrentProgram = getLogicInstantiatingOff(tlc, subid);
00186
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
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 ) {
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
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
00393 unsigned int startPos = (unsigned int) position;
00394
00395 size_t posAfterSyn = LogicTo->getPhaseIndexAtTime(step);
00396
00397
00398
00399
00400
00401
00402
00403 size_t deltaToCut = 0;
00404 if (posAfterSyn < startPos) {
00405 deltaToCut = posAfterSyn + cycleTime - startPos;
00406 } else deltaToCut = posAfterSyn - startPos;
00407
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
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
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
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
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
00577
00578 MSTLLogicControl::MSTLLogicControl() throw()
00579 : myNetWasLoaded(false) {}
00580
00581
00582 MSTLLogicControl::~MSTLLogicControl() throw() {
00583
00584 for (std::map<std::string, TLSLogicVariants*>::const_iterator i=myLogics.begin(); i!=myLogics.end(); ++i) {
00585 delete(*i).second;
00586 }
00587
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
00703 std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
00704
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
00716 if (myWAUTs.find(id)!=myWAUTs.end()) {
00717
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
00732 if (myWAUTs.find(wautid)==myWAUTs.end()) {
00733
00734 throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
00735 }
00736
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
00750 if (myWAUTs.find(wautid)==myWAUTs.end()) {
00751
00752 throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
00753 }
00754
00755 if (myLogics.find(tls)==myLogics.end()) {
00756
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
00779 switchTo(tls, initProg);
00780 }
00781
00782
00783 void
00784 MSTLLogicControl::closeWAUT(const std::string &wautid) throw(InvalidArgument) {
00785
00786 if (myWAUTs.find(wautid)==myWAUTs.end()) {
00787
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
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
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
00811
00812
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
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