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::_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::_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::_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(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
470  remainingStretchTime = allStretchTime - StretchTimeOfPhase;
471  }
472  }
473  if (facSum == 0) {
474  WRITE_WARNING("The computed factor sum in WAUT '" + myWAUT.id + "' at time '" + toString(STEPS2TIME(step)) + "' equals zero;\n assuming an error in WAUT definition.");
475  return;
476  }
477  durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
478  myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
479 
480  currStep = (currStep + 1) % (int)myTo->getPhases().size();
481  // stretch all other phases, if there is a "bereich"
482  while (remainingStretchTime > 0) {
483  for (unsigned int i = currStep; i < myTo->getPhases().size() && remainingStretchTime > 0; i++) {
484  durOfPhase = myTo->getPhase(i).duration;
485  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
486  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
487  for (int j = 0; j < areasNo && remainingStretchTime > 0; j++) {
488  StretchBereichDef def = getStretchBereichDef(myTo, j + 1);
489  SUMOTime end = TIME2STEPS(def.end);
490  SUMOReal fac = def.fac;
491  if ((beginOfPhase <= end) && (endOfPhase >= end)) {
492  SUMOReal actualfac = fac / facSum;
493  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
494  facSum -= fac;
495  durOfPhase += StretchTimeOfPhase;
496  remainingStretchTime -= StretchTimeOfPhase;
497  }
498  }
499  myTo->addOverridingDuration(durOfPhase);
500  }
501  currStep = 0;
502  }
503 }
504 
505 int
507  int no = 0;
508  while (from->getParameterValue("B" + toString(no + 1) + ".begin") != "") {
509  no++;
510  }
511  return no;
512 }
513 
514 
517  StretchBereichDef def;
518  def.begin = TplConvert::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".begin").c_str());
519  def.end = TplConvert::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".end").c_str());
520  def.fac = TplConvert::_2SUMOReal(from->getParameterValue("B" + toString(index) + ".factor").c_str());
521  return def;
522 }
523 
524 
525 
526 /* -------------------------------------------------------------------------
527  * method definitions for MSTLLogicControl
528  * ----------------------------------------------------------------------- */
530  : myNetWasLoaded(false) {}
531 
532 
534  // delete tls
535  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
536  delete(*i).second;
537  }
538  // delete WAUTs
539  for (std::map<std::string, WAUT*>::const_iterator i = myWAUTs.begin(); i != myWAUTs.end(); ++i) {
540  delete(*i).second;
541  }
542 }
543 
544 
545 void
547  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
548  (*i).second->getActive()->setTrafficLightSignals(t);
549  }
550 }
551 
552 
553 std::vector<MSTrafficLightLogic*>
555  std::vector<MSTrafficLightLogic*> ret;
556  std::map<std::string, TLSLogicVariants*>::const_iterator i;
557  for (i = myLogics.begin(); i != myLogics.end(); ++i) {
558  std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
559  copy(s.begin(), s.end(), back_inserter(ret));
560  }
561  return ret;
562 }
563 
565 MSTLLogicControl::get(const std::string& id) const {
566  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
567  if (i == myLogics.end()) {
568  throw InvalidArgument("The tls '" + id + "' is not known.");
569  }
570  return *(*i).second;
571 }
572 
573 
575 MSTLLogicControl::get(const std::string& id, const std::string& programID) const {
576  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
577  if (i == myLogics.end()) {
578  return 0;
579  }
580  return (*i).second->getLogic(programID);
581 }
582 
583 
584 std::vector<std::string>
586  std::vector<std::string> ret;
587  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
588  ret.push_back((*i).first);
589  }
590  return ret;
591 }
592 
593 
594 bool
595 MSTLLogicControl::add(const std::string& id, const std::string& programID,
596  MSTrafficLightLogic* logic, bool newDefault) {
597  if (myLogics.find(id) == myLogics.end()) {
598  myLogics[id] = new TLSLogicVariants();
599  }
600  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
601  TLSLogicVariants* tlmap = (*i).second;
602  return tlmap->addLogic(programID, logic, myNetWasLoaded, newDefault);
603 }
604 
605 
606 bool
607 MSTLLogicControl::knows(const std::string& id) const {
608  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
609  if (i == myLogics.end()) {
610  return false;
611  }
612  return true;
613 }
614 
615 
616 bool
618  bool hadErrors = false;
619  for (std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
620  hadErrors |= !(*i).second->checkOriginalTLS();
621  (*i).second->saveInitialStates();
622  }
623  myNetWasLoaded = true;
624  return !hadErrors;
625 }
626 
627 
628 bool
630  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(tl->getID());
631  if (i == myLogics.end()) {
632  return false;
633  }
634  return (*i).second->isActive(tl);
635 }
636 
637 
639 MSTLLogicControl::getActive(const std::string& id) const {
640  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
641  if (i == myLogics.end()) {
642  return 0;
643  }
644  return (*i).second->getActive();
645 }
646 
647 
648 void
649 MSTLLogicControl::switchTo(const std::string& id, const std::string& programID) {
650  // try to get the tls program definitions
651  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
652  // handle problems
653  if (i == myLogics.end()) {
654  throw ProcessError("Could not switch tls '" + id + "' to program '" + programID + "': No such tls exists.");
655  }
656  (*i).second->switchTo(*this, programID);
657 }
658 
659 
660 void
661 MSTLLogicControl::addWAUT(SUMOTime refTime, const std::string& id,
662  const std::string& startProg) {
663  // check whether the waut was already defined
664  if (myWAUTs.find(id) != myWAUTs.end()) {
665  // report an error if so
666  throw InvalidArgument("Waut '" + id + "' was already defined.");
667  }
668  WAUT* w = new WAUT;
669  w->id = id;
670  w->refTime = refTime;
671  w->startProg = startProg;
672  myWAUTs[id] = w;
673 }
674 
675 
676 void
677 MSTLLogicControl::addWAUTSwitch(const std::string& wautid,
678  SUMOTime when, const std::string& to) {
679  // try to get the waut
680  if (myWAUTs.find(wautid) == myWAUTs.end()) {
681  // report an error if the waut is not known
682  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
683  }
684  // build and save the waut switch definition
685  WAUTSwitch s;
686  s.to = to;
687  s.when = (myWAUTs[wautid]->refTime + when) % 86400000;
688  myWAUTs[wautid]->switches.push_back(s);
689 }
690 
691 
692 void
693 MSTLLogicControl::addWAUTJunction(const std::string& wautid,
694  const std::string& tls,
695  const std::string& proc,
696  bool synchron) {
697  // try to get the waut
698  if (myWAUTs.find(wautid) == myWAUTs.end()) {
699  // report an error if the waut is not known
700  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
701  }
702  // try to get the tls to switch
703  if (myLogics.find(tls) == myLogics.end()) {
704  // report an error if the tls is not known
705  throw InvalidArgument("TLS '" + tls + "' to switch in WAUT '" + wautid + "' was not yet defined.");
706  }
707  WAUTJunction j;
708  j.junction = tls;
709  j.procedure = proc;
710  j.synchron = synchron;
711  myWAUTs[wautid]->junctions.push_back(j);
712 
713  std::string initProg = myWAUTs[wautid]->startProg;
714  std::vector<WAUTSwitch>::const_iterator first = myWAUTs[wautid]->switches.end();
715  SUMOTime minExecTime = -1;
716  for (std::vector<WAUTSwitch>::const_iterator i = myWAUTs[wautid]->switches.begin(); i != myWAUTs[wautid]->switches.end(); ++i) {
717  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
718  minExecTime = (*i).when;
719  first = i;
720  }
721  if (first != myWAUTs[wautid]->switches.begin()) {
722  initProg = (*(first - 1)).to;
723  }
724  }
725  // activate the first one
726  switchTo(tls, initProg);
727 }
728 
729 
730 void
731 MSTLLogicControl::closeWAUT(const std::string& wautid) {
732  // try to get the waut
733  if (myWAUTs.find(wautid) == myWAUTs.end()) {
734  // report an error if the waut is not known
735  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
736  }
737  WAUT* w = myWAUTs.find(wautid)->second;
738  std::string initProg = myWAUTs[wautid]->startProg;
739  // get the switch to be performed as first
740  std::vector<WAUTSwitch>::const_iterator first = w->switches.end();
741  SUMOTime minExecTime = -1;
742  for (std::vector<WAUTSwitch>::const_iterator i = w->switches.begin(); i != w->switches.end(); ++i) {
743  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
744  minExecTime = (*i).when;
745  first = i;
746  }
747  }
748  // activate the first one
749  if (first != w->switches.end()) {
750  std::vector<WAUTSwitch>::const_iterator mbegin = w->switches.begin();
752  new SwitchInitCommand(*this, wautid, (unsigned int)distance(mbegin, first)),
753  (*first).when, MSEventControl::NO_CHANGE);
754  }
755  /*
756  // set the current program to all junctions
757  for(std::vector<WAUTJunction>::const_iterator i=w->junctions.begin(); i!=w->junctions.end(); ++i) {
758  switchTo((*i).junction, initProg);
759  }
760  */
761 }
762 
763 
764 SUMOTime
766  const std::string& wautid = cmd.getWAUTID();
767  unsigned int& index = cmd.getIndex();
768  WAUTSwitch s = myWAUTs[wautid]->switches[index];
769  for (std::vector<WAUTJunction>::iterator i = myWAUTs[wautid]->junctions.begin(); i != myWAUTs[wautid]->junctions.end(); ++i) {
770  // get the current program and the one to instantiate
771  TLSLogicVariants* vars = myLogics.find((*i).junction)->second;
772  MSTrafficLightLogic* from = vars->getActive();
773  MSTrafficLightLogic* to = vars->getLogicInstantiatingOff(*this, s.to);
774  WAUTSwitchProcedure* proc = 0;
775  if ((*i).procedure == "GSP") {
776  proc = new WAUTSwitchProcedure_GSP(*this, *myWAUTs[wautid], from, to, (*i).synchron);
777  } else if ((*i).procedure == "Stretch") {
778  proc = new WAUTSwitchProcedure_Stretch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
779  } else {
780  proc = new WAUTSwitchProcedure_JustSwitch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
781  }
782 
784  p.junction = (*i).junction;
785  p.proc = proc;
786  p.from = from;
787  p.to = to;
788 
789  myCurrentlySwitched.push_back(p);
790  }
791  index++;
792  if (index == static_cast<unsigned int>(myWAUTs[wautid]->switches.size())) {
793  return 0;
794  }
795  return myWAUTs[wautid]->switches[index].when - MSNet::getInstance()->getCurrentTimeStep();
796 }
797 
798 
799 void
801  for (std::vector<WAUTSwitchProcess>::iterator i = myCurrentlySwitched.begin(); i != myCurrentlySwitched.end();) {
802  const WAUTSwitchProcess& proc = *i;
803  if (proc.proc->trySwitch(step)) {
804  delete proc.proc;
805  switchTo((*i).to->getID(), (*i).to->getProgramID());
806  i = myCurrentlySwitched.erase(i);
807  } else {
808  ++i;
809  }
810  }
811 }
812 
813 
814 std::pair<SUMOTime, MSPhaseDefinition>
815 MSTLLogicControl::getPhaseDef(const std::string& tlid) const {
816  MSTrafficLightLogic* tl = getActive(tlid);
817  return std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), tl->getCurrentPhaseDef());
818 }
819 
820 
821 
822 /****************************************************************************/
823