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-sim.org/
16 // Copyright (C) 2001-2013 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.getParameter("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->getParameter("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->getParameter("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->getParameter("B" + toString(no + 1) + ".begin", "") != "") {
509  no++;
510  }
511  return no;
512 }
513 
514 
517  StretchBereichDef def;
518  def.begin = TplConvert::_2SUMOReal(from->getParameter("B" + toString(index) + ".begin", "").c_str());
519  def.end = TplConvert::_2SUMOReal(from->getParameter("B" + toString(index) + ".end", "").c_str());
520  def.fac = TplConvert::_2SUMOReal(from->getParameter("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 
bool checkOriginalTLS() const
Verifies traffic lights loaded from the network.
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
bool add(const std::string &id, const std::string &programID, MSTrafficLightLogic *logic, bool newDefault=true)
Adds a tls program to the container.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
void cutLogic(SUMOTime step, SUMOTime startPos, SUMOTime allCutTime)
Cuts the logic to synchronize.
const std::string & getState() const
Returns the state within this phase.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
SUMOReal end
The end of a stretch/cut area (time, in s)
std::map< std::string, TLSLogicVariants * > myLogics
A map from ids to the corresponding variants.
virtual unsigned int getCurrentPhaseIndex() const =0
Returns the current index within the program.
unsigned int getGSPValue(const MSTrafficLightLogic &logic) const
Returns the GSP-value.
Storage for all programs of a single tls.
Base class for things to execute if a tls switches to a new phase.
void switchTo(const std::string &id, const std::string &programID)
Switches the named (id) tls to the named (programID) program.
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:223
~MSTLLogicControl()
Destructor.
WAUTSwitchProcedure_GSP(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
virtual const MSPhaseDefinition & getPhase(unsigned int givenstep) const =0
Returns the definition of the phase from the given position within the plan.
void setTrafficLightSignals(SUMOTime t) const
Lets all running (current) tls programs apply their current signal states to links they control...
MSTrafficLightLogic * getActive(const std::string &id) const
Returns the active program of a named tls.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:150
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
std::string junction
The id of the junction to switch.
std::string procedure
The procedure to switch the junction with.
WAUTSwitchProcedure_Stretch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
std::vector< std::string > getAllTLIds() const
virtual SUMOTime getOffsetFromIndex(unsigned int index) const =0
Returns the position (start of a phase during a cycle) from of a given step.
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
MSTLLogicControl()
Constructor.
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
Definition: MSNet.cpp:500
void closeWAUT(const std::string &wautid)
Closes loading of a WAUT.
MSTrafficLightLogic * getLogic(const std::string &programID) const
SUMOTime initWautSwitch(SwitchInitCommand &cmd)
Initialises switching a WAUT.
void addLink(MSLink *link, MSLane *lane, unsigned int pos)
bool myNetWasLoaded
Information whether the net was completely loaded.
Storage for a junction assigned to a WAUT.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
A traffic lights logic which represents a tls in an off-mode.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, unsigned int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
A class that stores and controls tls and switching of their programs.
std::vector< MSTrafficLightLogic * > getAllLogics() const
const std::string & getID() const
Returns the id.
Definition: Named.h:60
SUMOTime duration
The duration of the phase.
bool addLogic(const std::string &programID, MSTrafficLightLogic *logic, bool netWasLoaded, bool isNewDefault=true)
Adds a logic (program)
void addSwitchCommand(OnSwitchAction *c)
MSTrafficLightLogic * getLogicInstantiatingOff(MSTLLogicControl &tlc, const std::string &programID)
bool isActive(const MSTrafficLightLogic *tl) const
virtual unsigned int getIndexFromOffset(SUMOTime offset) const =0
Returns the step (the phasenumber) of a given position of the cycle.
MSTrafficLightLogic * getActive() const
std::pair< SUMOTime, MSPhaseDefinition > getPhaseDef(const std::string &tlid) const
return the complete phase definition for a named traffic lights logic
WAUTSwitchProcedure * proc
The used procedure.
void adaptLogic(SUMOTime step)
Stretches the destination program&#39;s phase to which the tls was switched.
SUMOReal fac
The weight factor of a stretch/cut area.
This class simply switches to the next program.
bool synchron
Information whether this junction shall be switched synchron.
void adaptLogic(SUMOTime step)
Determines the destination program&#39;s changes and applies them.
virtual bool trySwitch(SUMOTime step)=0
Determines whether a switch is possible.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
MSTrafficLightLogic * to
The program to switch the tls to.
This class switches using the Stretch algorithm.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
void check2Switch(SUMOTime step)
Checks whether any WAUT is trying to switch a tls into another program.
T MIN2(T a, T b)
Definition: StdDefs.h:57
int getStretchAreaNo(MSTrafficLightLogic *from) const
Returns the number of given Stretch-areas for the given program.
SUMOTime when
The time the WAUT shall switch the TLS.
void stretchLogic(SUMOTime step, SUMOTime startPos, SUMOTime allStretchTime)
Stretches the logic to synchronize.
SUMOReal begin
The begin of a stretch/cut area (time, in s)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
bool knows(const std::string &id) const
Returns the information whether the named tls is stored.
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
std::string startProg
The name of the start program.
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
const std::string & getWAUTID() const
Returns the WAUT-id.
WAUTSwitchProcedure_JustSwitch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
void addWAUTJunction(const std::string &wautid, const std::string &tls, const std::string &proc, bool synchron)
Adds a tls to the list of tls to be switched by the named WAUT.
std::vector< WAUTSwitchProcess > myCurrentlySwitched
A list of currently running switching procedures.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
An initialised switch process.
void switchTo(MSTLLogicControl &tlc, const std::string &programID)
StretchBereichDef getStretchBereichDef(MSTrafficLightLogic *from, int index) const
Returns the numbered Stretch-area for the given program.
static int _2int(const E *const data)
Definition: TplConvert.h:114
std::vector< WAUTSwitch > switches
The list of switches to be done by the WAUT.
unsigned int & getIndex()
Returns a reference to the index.
void switchToPos(SUMOTime simStep, MSTrafficLightLogic &logic, SUMOTime toTime)
switches the given logic directly to the given position
This event-class is used to initialise a WAUT switch at a certain time.
void addWAUT(SUMOTime refTime, const std::string &id, const std::string &startProg)
Adds a WAUT definition.
This class switches using the GSP algorithm.
SUMOTime getDiffToStartOfPhase(MSTrafficLightLogic &logic, SUMOTime toTime)
Returns the difference between a given time and the start of the phase.
SUMOTime refTime
The reference time (offset to the switch times)
This is the abstract base class for switching from one tls program to another.
std::string id
The id of the WAUT.
int SUMOTime
Definition: SUMOTime.h:43
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
std::map< std::string, WAUT * > myWAUTs
A map of ids to corresponding WAUTs.
bool isPosAtGSP(SUMOTime currentTime, const MSTrafficLightLogic &logic)
Checks, whether the position of a signal programm is at the GSP (&quot;GuenstigerUmschaltPunkt&quot;) ...
The parent class for traffic light logics.
#define SUMOReal
Definition: config.h:221
Storage for a WAUTs switch point.
void addWAUTSwitch(const std::string &wautid, SUMOTime when, const std::string &to)
Adds a WAUT switch step to a previously built WAUT.
std::string to
The program name the WAUT shall switch the TLS to.
std::vector< MSTrafficLightLogic * > getAllLogics() const
Returns a vector which contains all logics.
MSTrafficLightLogic * from
The current program of the tls.
MSEventControl & getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:319
The definition of a single phase of a tls logic.
Representation of a lane in the micro simulation.
Definition: MSLane.h:73
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
std::string junction
The junction name.
A WAUT definition.