SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSTLLogicControl.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // A class that stores and controls tls and switching of their programs
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
16 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <vector>
36 #include <algorithm>
37 #include <cassert>
38 #include <iterator>
39 #include "MSTrafficLightLogic.h"
41 #include "MSTLLogicControl.h"
42 #include "MSOffTrafficLightLogic.h"
44 #include <microsim/MSNet.h>
46 #include <utils/common/ToString.h>
48 
49 #ifdef CHECK_MEMORY_LEAKS
50 #include <foreign/nvwa/debug_new.h>
51 #endif // CHECK_MEMORY_LEAKS
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57 /* -------------------------------------------------------------------------
58  * MSTLLogicControl::TLSLogicVariants - methods
59  * ----------------------------------------------------------------------- */
61  : myCurrentProgram(0) {
62 }
63 
64 
66  std::map<std::string, MSTrafficLightLogic*>::const_iterator j;
67  for (std::map<std::string, MSTrafficLightLogic*>::iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
68  delete(*j).second;
69  }
70  for (std::vector<OnSwitchAction*>::iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
71  delete *i;
72  }
73 }
74 
75 
76 bool
78  bool hadErrors = false;
79  for (std::map<std::string, MSTrafficLightLogic*>::const_iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
80  const MSTrafficLightLogic::Phases& phases = (*j).second->getPhases();
81  unsigned int linkNo = (unsigned int)(*j).second->getLinks().size();
82  bool hadProgramErrors = false;
83  for (MSTrafficLightLogic::Phases::const_iterator i = phases.begin(); i != phases.end(); ++i) {
84  if ((*i)->getState().length() < linkNo) {
85  hadProgramErrors = true;
86  }
87  }
88  if (hadProgramErrors) {
89  WRITE_ERROR("Mismatching phase size in tls '" + (*j).second->getID() + "', program '" + (*j).first + "'.");
90  hadErrors = true;
91  }
92  }
93  return !hadErrors;
94 }
95 
96 
97 void
99  myOriginalLinkStates = myCurrentProgram->collectLinkStates();
100 }
101 
102 
103 bool
104 MSTLLogicControl::TLSLogicVariants::addLogic(const std::string& programID,
105  MSTrafficLightLogic* logic, bool netWasLoaded, bool isNewDefault) {
106  if (myVariants.find(programID) != myVariants.end()) {
107  return false;
108  }
109  // assert the links are set
110  if (netWasLoaded) {
111  // this one has not yet its links set
112  if (myCurrentProgram == 0) {
113  throw ProcessError("No initial signal plan loaded for tls '" + logic->getID() + "'.");
114  }
115  logic->adaptLinkInformationFrom(*myCurrentProgram);
116  if (logic->getLinks().size() > logic->getPhase(0).getState().size()) {
117  throw ProcessError("Mismatching phase size in tls '" + logic->getID() + "', program '" + programID + "'.");
118  }
119  }
120  // add to the list of active
121  if (myVariants.size() == 0 || isNewDefault) {
122  myCurrentProgram = logic;
123  }
124  // add to the list of logic
125  myVariants[programID] = logic;
126  if (myVariants.size() == 1 || isNewDefault) {
127  logic->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
128  executeOnSwitchActions();
129  }
130  return true;
131 }
132 
133 
135 MSTLLogicControl::TLSLogicVariants::getLogic(const std::string& programID) const {
136  if (myVariants.find(programID) == myVariants.end()) {
137  return 0;
138  }
139  return myVariants.find(programID)->second;
140 }
141 
142 
145  const std::string& programID) {
146  if (myVariants.find(programID) == myVariants.end()) {
147  if (programID == "off") {
148  // build an off-tll if this switch indicates it
149  if (!addLogic("off", new MSOffTrafficLightLogic(tlc, myCurrentProgram->getID()), true, true)) {
150  // inform the user if this fails
151  throw ProcessError("Could not build an off-state for tls '" + myCurrentProgram->getID() + "'.");
152  }
153  } else {
154  // inform the user about a missing logic
155  throw ProcessError("Can not switch tls '" + myCurrentProgram->getID() + "' to program '" + programID + "';\n The program is not known.");
156  }
157  }
158  return getLogic(programID);
159 }
160 
161 
162 void
164  mySwitchActions.push_back(c);
165 }
166 
167 
168 std::vector<MSTrafficLightLogic*>
170  std::vector<MSTrafficLightLogic*> ret;
171  std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
172  for (i = myVariants.begin(); i != myVariants.end(); ++i) {
173  ret.push_back((*i).second);
174  }
175  return ret;
176 }
177 
178 
179 bool
181  return tl == myCurrentProgram;
182 }
183 
184 
187  return myCurrentProgram;
188 }
189 
190 
191 void
193  // set the found wished sub-program as this tls' current one
194  myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
195 }
196 
197 
198 void
200  for (std::vector<OnSwitchAction*>::const_iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
201  (*i)->execute();
202  }
203 }
204 
205 
206 void
208  for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
209  (*i).second->addLink(link, lane, pos);
210  }
211 }
212 
213 
214 
215 /* -------------------------------------------------------------------------
216  * method definitions for the Switching Procedures
217  * ----------------------------------------------------------------------- */
218 /* -------------------------------------------------------------------------
219  * method definitions for WAUTSwitchProcedure
220  * ----------------------------------------------------------------------- */
221 unsigned int
223  std::string val = logic.getParameterValue("GSP");
224  if (val.length() == 0) {
225  return 0;
226  }
227  return TplConvert<char>::_2int(val.c_str());
228 }
229 
230 
231 bool
233  SUMOTime gspTime = TIME2STEPS(getGSPValue(logic)) % logic.getDefaultCycleTime();
234  SUMOTime programTime = logic.getOffsetFromIndex(logic.getCurrentPhaseIndex())
235  + (logic.getCurrentPhaseDef().duration - (logic.getNextSwitchTime() - currentTime));
236  return gspTime == programTime;
237 }
238 
239 
240 SUMOTime
242  unsigned int stepOfMyPos = logic.getIndexFromOffset(toTime);
243  SUMOTime startOfPhase = logic.getOffsetFromIndex(stepOfMyPos);
244  assert(toTime >= startOfPhase);
245  return toTime - startOfPhase;
246 }
247 
248 
249 void
251  unsigned int stepTo = logic.getIndexFromOffset(toTime);
252  SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
253  const MSPhaseDefinition& phase = logic.getPhase(stepTo);
254  SUMOTime leftDuration = phase.duration - diff;
255  logic.changeStepAndDuration(myControl, simStep, stepTo, leftDuration);
256 }
257 
258 
259 
260 /* -------------------------------------------------------------------------
261  * method definitions for WAUTSwitchProcedure_JustSwitch
262  * ----------------------------------------------------------------------- */
264  MSTLLogicControl& control, WAUT& waut,
265  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
266  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
267 
268 
270 
271 
272 bool
274  return true;
275 }
276 
277 
278 
279 /* -------------------------------------------------------------------------
280  * method definitions for WAUTSwitchProcedure_GSP
281  * ----------------------------------------------------------------------- */
283  MSTLLogicControl& control, WAUT& waut,
284  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
285  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
286 
287 
289 
290 
291 bool
293  // switch to the next programm if the GSP is reached
294  if (isPosAtGSP(step, *myFrom)) {
295  // adapt program's state
296  if (mySwitchSynchron) {
297  adaptLogic(step);
298  } else {
299  switchToPos(step, *myTo, TIME2STEPS(getGSPValue(*myTo)));
300  }
301  // switch to destination program
302  return true;
303  }
304  // do not switch, yet
305  return false;
306 }
307 
308 
309 void
311  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
312  unsigned int stepTo = myTo->getIndexFromOffset(gspTo);
313  SUMOTime cycleTimeTo = myTo->getDefaultCycleTime();
314  if (gspTo == cycleTimeTo) {
315  gspTo = 0;
316  }
317 
318  SUMOTime currentPosTo = myTo->getOffsetFromIndex(myTo->getCurrentPhaseIndex());
319  currentPosTo += (myTo->getCurrentPhaseDef().duration - (myTo->getNextSwitchTime() - step));
320  SUMOTime diff = getDiffToStartOfPhase(*myTo, gspTo);
321 
322  SUMOTime deltaToStretch = 0;
323  if (gspTo >= currentPosTo) {
324  deltaToStretch = (gspTo - currentPosTo);
325  } else {
326  deltaToStretch = (cycleTimeTo - currentPosTo + gspTo);
327  }
328  unsigned int newdur = (unsigned int) myTo->getPhase(stepTo).duration - diff + deltaToStretch;
329  myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
330 }
331 
332 
333 
334 /* -------------------------------------------------------------------------
335  * method definitions for WAUTSwitchProcedure_Stretch
336  * ----------------------------------------------------------------------- */
338  MSTLLogicControl& control, WAUT& waut,
339  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
340  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
341 
342 
344 
345 
346 bool
348  // switch to the next programm if the GSP is reached
349  if (isPosAtGSP(step, *myFrom)) {
350  // adapt program's state
351  if (mySwitchSynchron) {
352  adaptLogic(step);
353  } else {
354  switchToPos(step, *myTo, TIME2STEPS(getGSPValue(*myTo)));
355  }
356  // switch to destination program
357  return true;
358  }
359  // do not switch, yet
360  return false;
361 }
362 
363 
364 void
366  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
367  SUMOTime cycleTime = myTo->getDefaultCycleTime();
368  // the position, where the logic has to be after synchronisation
369  SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
370  // calculate the difference, that has to be equalized
371  SUMOTime deltaToCut = 0;
372  if (posAfterSyn < gspTo) {
373  deltaToCut = posAfterSyn + cycleTime - gspTo;
374  } else {
375  deltaToCut = posAfterSyn - gspTo;
376  }
377  // test, wheter cutting of the Signalplan is possible
378  SUMOTime deltaPossible = 0;
379  int areasNo = getStretchAreaNo(myTo);
380  for (int i = 0; i < areasNo; i++) {
381  StretchBereichDef def = getStretchBereichDef(myTo, i + 1);
382  assert(def.end >= def.begin) ;
383  deltaPossible += TIME2STEPS(def.end - def.begin);
384  }
385  int stretchUmlaufAnz = (int) TplConvert<char>::_2SUMOReal(myTo->getParameterValue("StretchUmlaufAnz").c_str());
386  deltaPossible = stretchUmlaufAnz * deltaPossible;
387  if ((deltaPossible > deltaToCut) && (deltaToCut < (cycleTime / 2))) {
388  cutLogic(step, gspTo, deltaToCut);
389  } else {
390  SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
391  stretchLogic(step, gspTo, deltaToStretch);
392  }
393 }
394 
395 
396 void
398  unsigned int actStep = myTo->getIndexFromOffset(startPos);
399  // switches to startPos and cuts this phase, if there is a "Bereich"
400  int areasNo = getStretchAreaNo(myTo);
401  SUMOTime toCut = 0;
402  for (int i = 0; i < areasNo; i++) {
403  StretchBereichDef def = getStretchBereichDef(myTo, i + 1);
404  SUMOTime begin = TIME2STEPS(def.begin);
405  unsigned int end = TIME2STEPS(def.end);
406  size_t stepOfBegin = myTo->getIndexFromOffset(begin);
407  if (stepOfBegin == actStep) {
408  if (begin < startPos) {
409  toCut = end - startPos;
410  } else {
411  toCut = end - begin;
412  }
413  toCut = MIN2(allCutTime, toCut);
414  allCutTime = allCutTime - toCut;
415  }
416  }
417  SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
418  SUMOTime newDur = remainingDur - toCut;
419  myTo->changeStepAndDuration(myControl, step, actStep, newDur);
420 
421  // changes the duration of all other phases
422  int currStep = (actStep + 1) % (int)myTo->getPhases().size();
423  while (allCutTime > 0) {
424  for (int i = currStep; i < (int) myTo->getPhases().size(); i++) {
425  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
426  SUMOTime durOfPhase = myTo->getPhase(i).duration;
427  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
428  for (int i = 0; i < areasNo; i++) {
429  StretchBereichDef def = getStretchBereichDef(myTo, i + 1);
430  SUMOTime begin = TIME2STEPS(def.begin);
431  SUMOTime end = TIME2STEPS(def.end);
432  if ((beginOfPhase <= begin) && (endOfPhase >= end)) {
433  SUMOTime maxCutOfPhase = MIN2(end - begin, allCutTime);
434  allCutTime = allCutTime - maxCutOfPhase;
435  durOfPhase = durOfPhase - maxCutOfPhase;
436  }
437  }
438  myTo->addOverridingDuration(durOfPhase);
439  }
440  currStep = 0;
441  }
442 }
443 
444 void
446  unsigned int currStep = myTo->getIndexFromOffset(startPos);
447  SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
448  SUMOTime remainingStretchTime = allStretchTime;
449  SUMOTime StretchTimeOfPhase = 0;
450  unsigned int stretchUmlaufAnz = (unsigned int) TplConvert<char>::_2SUMOReal(myTo->getParameterValue("StretchUmlaufAnz").c_str());
451  SUMOReal facSum = 0;
452  int areasNo = getStretchAreaNo(myTo);
453  for (int x = 0; x < areasNo; x++) {
454  StretchBereichDef def = getStretchBereichDef(myTo, x + 1);
455  facSum += def.fac;
456  }
457  facSum *= stretchUmlaufAnz;
458 
459  //switch to startPos and stretch this phase, if there is a end of "bereich" between startpos and end of phase
460  SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
461  for (int x = 0; x < areasNo; x++) {
462  StretchBereichDef def = getStretchBereichDef(myTo, x + 1);
463  SUMOTime end = TIME2STEPS(def.end);
464  SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
465  if (end <= endOfPhase && end >= startPos) {
466  SUMOReal fac = def.fac;
467  SUMOReal actualfac = fac / facSum;
468  facSum = facSum - fac;
469  StretchTimeOfPhase = TIME2STEPS(STEPS2TIME(remainingStretchTime) * actualfac + 0.5);
470  remainingStretchTime = allStretchTime - StretchTimeOfPhase;
471  }
472  }
473  durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
474  myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
475 
476  currStep = (currStep + 1) % (int)myTo->getPhases().size();
477  // stretch all other phases, if there is a "bereich"
478  while (remainingStretchTime > 0) {
479  for (unsigned int i = currStep; i < myTo->getPhases().size() && remainingStretchTime > 0; i++) {
480  durOfPhase = myTo->getPhase(i).duration;
481  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
482  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
483  for (int j = 0; j < areasNo && remainingStretchTime > 0; j++) {
484  StretchBereichDef def = getStretchBereichDef(myTo, j + 1);
485  SUMOTime end = TIME2STEPS(def.end);
486  SUMOReal fac = def.fac;
487  if ((beginOfPhase <= end) && (endOfPhase >= end)) {
488  SUMOReal actualfac = fac / facSum;
489  StretchTimeOfPhase = TIME2STEPS(STEPS2TIME(remainingStretchTime) * actualfac + 0.5);
490  facSum -= fac;
491  durOfPhase += StretchTimeOfPhase;
492  remainingStretchTime -= StretchTimeOfPhase;
493  }
494  }
495  myTo->addOverridingDuration(durOfPhase);
496  }
497  currStep = 0;
498  }
499 }
500 
501 int
503  int no = 0;
504  while (from->getParameterValue("B" + toString(no + 1) + ".begin") != "") {
505  no++;
506  }
507  return no;
508 }
509 
510 
513  StretchBereichDef def;
514  def.begin = TplConvert<char>::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".begin").c_str());
515  def.end = TplConvert<char>::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".end").c_str());
516  def.fac = TplConvert<char>::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".factor").c_str());
517  return def;
518 }
519 
520 
521 
522 /* -------------------------------------------------------------------------
523  * method definitions for MSTLLogicControl
524  * ----------------------------------------------------------------------- */
526  : myNetWasLoaded(false) {}
527 
528 
530  // delete tls
531  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
532  delete(*i).second;
533  }
534  // delete WAUTs
535  for (std::map<std::string, WAUT*>::const_iterator i = myWAUTs.begin(); i != myWAUTs.end(); ++i) {
536  delete(*i).second;
537  }
538 }
539 
540 
541 void
543  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
544  (*i).second->getActive()->setTrafficLightSignals(t);
545  }
546 }
547 
548 
549 std::vector<MSTrafficLightLogic*>
551  std::vector<MSTrafficLightLogic*> ret;
552  std::map<std::string, TLSLogicVariants*>::const_iterator i;
553  for (i = myLogics.begin(); i != myLogics.end(); ++i) {
554  std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
555  copy(s.begin(), s.end(), back_inserter(ret));
556  }
557  return ret;
558 }
559 
561 MSTLLogicControl::get(const std::string& id) const {
562  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
563  if (i == myLogics.end()) {
564  throw InvalidArgument("The tls '" + id + "' is not known.");
565  }
566  return *(*i).second;
567 }
568 
569 
571 MSTLLogicControl::get(const std::string& id, const std::string& programID) const {
572  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
573  if (i == myLogics.end()) {
574  return 0;
575  }
576  return (*i).second->getLogic(programID);
577 }
578 
579 
580 std::vector<std::string>
582  std::vector<std::string> ret;
583  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
584  ret.push_back((*i).first);
585  }
586  return ret;
587 }
588 
589 
590 bool
591 MSTLLogicControl::add(const std::string& id, const std::string& programID,
592  MSTrafficLightLogic* logic, bool newDefault) {
593  if (myLogics.find(id) == myLogics.end()) {
594  myLogics[id] = new TLSLogicVariants();
595  }
596  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
597  TLSLogicVariants* tlmap = (*i).second;
598  return tlmap->addLogic(programID, logic, myNetWasLoaded, newDefault);
599 }
600 
601 
602 bool
603 MSTLLogicControl::knows(const std::string& id) const {
604  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
605  if (i == myLogics.end()) {
606  return false;
607  }
608  return true;
609 }
610 
611 
612 bool
614  bool hadErrors = false;
615  for (std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
616  hadErrors |= !(*i).second->checkOriginalTLS();
617  (*i).second->saveInitialStates();
618  }
619  myNetWasLoaded = true;
620  return !hadErrors;
621 }
622 
623 
624 bool
626  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(tl->getID());
627  if (i == myLogics.end()) {
628  return false;
629  }
630  return (*i).second->isActive(tl);
631 }
632 
633 
635 MSTLLogicControl::getActive(const std::string& id) const {
636  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
637  if (i == myLogics.end()) {
638  return 0;
639  }
640  return (*i).second->getActive();
641 }
642 
643 
644 void
645 MSTLLogicControl::switchTo(const std::string& id, const std::string& programID) {
646  // try to get the tls program definitions
647  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
648  // handle problems
649  if (i == myLogics.end()) {
650  throw ProcessError("Could not switch tls '" + id + "' to program '" + programID + "': No such tls exists.");
651  }
652  (*i).second->switchTo(*this, programID);
653 }
654 
655 
656 void
657 MSTLLogicControl::addWAUT(SUMOTime refTime, const std::string& id,
658  const std::string& startProg) {
659  // check whether the waut was already defined
660  if (myWAUTs.find(id) != myWAUTs.end()) {
661  // report an error if so
662  throw InvalidArgument("Waut '" + id + "' was already defined.");
663  }
664  WAUT* w = new WAUT;
665  w->id = id;
666  w->refTime = refTime;
667  w->startProg = startProg;
668  myWAUTs[id] = w;
669 }
670 
671 
672 void
673 MSTLLogicControl::addWAUTSwitch(const std::string& wautid,
674  SUMOTime when, const std::string& to) {
675  // try to get the waut
676  if (myWAUTs.find(wautid) == myWAUTs.end()) {
677  // report an error if the waut is not known
678  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
679  }
680  // build and save the waut switch definition
681  WAUTSwitch s;
682  s.to = to;
683  s.when = (myWAUTs[wautid]->refTime + when) % 86400000;
684  myWAUTs[wautid]->switches.push_back(s);
685 }
686 
687 
688 void
689 MSTLLogicControl::addWAUTJunction(const std::string& wautid,
690  const std::string& tls,
691  const std::string& proc,
692  bool synchron) {
693  // try to get the waut
694  if (myWAUTs.find(wautid) == myWAUTs.end()) {
695  // report an error if the waut is not known
696  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
697  }
698  // try to get the tls to switch
699  if (myLogics.find(tls) == myLogics.end()) {
700  // report an error if the tls is not known
701  throw InvalidArgument("TLS '" + tls + "' to switch in WAUT '" + wautid + "' was not yet defined.");
702  }
703  WAUTJunction j;
704  j.junction = tls;
705  j.procedure = proc;
706  j.synchron = synchron;
707  myWAUTs[wautid]->junctions.push_back(j);
708 
709  std::string initProg = myWAUTs[wautid]->startProg;
710  std::vector<WAUTSwitch>::const_iterator first = myWAUTs[wautid]->switches.end();
711  SUMOTime minExecTime = -1;
712  for (std::vector<WAUTSwitch>::const_iterator i = myWAUTs[wautid]->switches.begin(); i != myWAUTs[wautid]->switches.end(); ++i) {
713  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
714  minExecTime = (*i).when;
715  first = i;
716  }
717  if (first != myWAUTs[wautid]->switches.begin()) {
718  initProg = (*(first - 1)).to;
719  }
720  }
721  // activate the first one
722  switchTo(tls, initProg);
723 }
724 
725 
726 void
727 MSTLLogicControl::closeWAUT(const std::string& wautid) {
728  // try to get the waut
729  if (myWAUTs.find(wautid) == myWAUTs.end()) {
730  // report an error if the waut is not known
731  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
732  }
733  WAUT* w = myWAUTs.find(wautid)->second;
734  std::string initProg = myWAUTs[wautid]->startProg;
735  // get the switch to be performed as first
736  std::vector<WAUTSwitch>::const_iterator first = w->switches.end();
737  SUMOTime minExecTime = -1;
738  for (std::vector<WAUTSwitch>::const_iterator i = w->switches.begin(); i != w->switches.end(); ++i) {
739  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
740  minExecTime = (*i).when;
741  first = i;
742  }
743  }
744  // activate the first one
745  if (first != w->switches.end()) {
746  std::vector<WAUTSwitch>::const_iterator mbegin = w->switches.begin();
748  new SwitchInitCommand(*this, wautid, (unsigned int)distance(mbegin, first)),
749  (*first).when, MSEventControl::NO_CHANGE);
750  }
751  /*
752  // set the current program to all junctions
753  for(std::vector<WAUTJunction>::const_iterator i=w->junctions.begin(); i!=w->junctions.end(); ++i) {
754  switchTo((*i).junction, initProg);
755  }
756  */
757 }
758 
759 
760 SUMOTime
762  const std::string& wautid = cmd.getWAUTID();
763  unsigned int& index = cmd.getIndex();
764  WAUTSwitch s = myWAUTs[wautid]->switches[index];
765  for (std::vector<WAUTJunction>::iterator i = myWAUTs[wautid]->junctions.begin(); i != myWAUTs[wautid]->junctions.end(); ++i) {
766  // get the current program and the one to instantiate
767  TLSLogicVariants* vars = myLogics.find((*i).junction)->second;
768  MSTrafficLightLogic* from = vars->getActive();
769  MSTrafficLightLogic* to = vars->getLogicInstantiatingOff(*this, s.to);
770  WAUTSwitchProcedure* proc = 0;
771  if ((*i).procedure == "GSP") {
772  proc = new WAUTSwitchProcedure_GSP(*this, *myWAUTs[wautid], from, to, (*i).synchron);
773  } else if ((*i).procedure == "Stretch") {
774  proc = new WAUTSwitchProcedure_Stretch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
775  } else {
776  proc = new WAUTSwitchProcedure_JustSwitch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
777  }
778 
780  p.junction = (*i).junction;
781  p.proc = proc;
782  p.from = from;
783  p.to = to;
784 
785  myCurrentlySwitched.push_back(p);
786  }
787  index++;
788  if (index == (int) myWAUTs[wautid]->switches.size()) {
789  return 0;
790  }
791  return myWAUTs[wautid]->switches[index].when - MSNet::getInstance()->getCurrentTimeStep();
792 }
793 
794 
795 void
797  for (std::vector<WAUTSwitchProcess>::iterator i = myCurrentlySwitched.begin(); i != myCurrentlySwitched.end();) {
798  const WAUTSwitchProcess& proc = *i;
799  if (proc.proc->trySwitch(step)) {
800  delete proc.proc;
801  switchTo((*i).to->getID(), (*i).to->getProgramID());
802  i = myCurrentlySwitched.erase(i);
803  } else {
804  ++i;
805  }
806  }
807 }
808 
809 
810 std::pair<SUMOTime, MSPhaseDefinition>
811 MSTLLogicControl::getPhaseDef(const std::string& tlid) const {
812  MSTrafficLightLogic* tl = getActive(tlid);
813  return std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), tl->getCurrentPhaseDef());
814 }
815 
816 
817 
818 /****************************************************************************/
819