SUMO - Simulation of Urban MObility
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-2014 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  const std::string& state) {
165  // build only once...
166  MSTrafficLightLogic* logic = getLogic("online");
167  if (logic == 0) {
168  MSPhaseDefinition* phase = new MSPhaseDefinition(DELTA_T, state);
169  std::vector<MSPhaseDefinition*> phases;
170  phases.push_back(phase);
171  logic = new MSSimpleTrafficLightLogic(tlc, myCurrentProgram->getID(), "online", phases, 0,
173  std::map<std::string, std::string>());
174  addLogic("online", logic, true, true);
175  } else {
176  MSPhaseDefinition nphase(DELTA_T, state);
177  *(dynamic_cast<MSSimpleTrafficLightLogic*>(logic)->getPhases()[0]) = nphase;
178  switchTo(tlc, "online");
179  }
180 }
181 
182 
183 void
185  mySwitchActions.push_back(c);
186 }
187 
188 
189 std::vector<MSTrafficLightLogic*>
191  std::vector<MSTrafficLightLogic*> ret;
192  std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
193  for (i = myVariants.begin(); i != myVariants.end(); ++i) {
194  ret.push_back((*i).second);
195  }
196  return ret;
197 }
198 
199 
200 bool
202  return tl == myCurrentProgram;
203 }
204 
205 
208  return myCurrentProgram;
209 }
210 
211 
212 void
214  // set the found wished sub-program as this tls' current one
215  myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
216  myCurrentProgram->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
217  executeOnSwitchActions();
218 }
219 
220 
221 void
223  for (std::vector<OnSwitchAction*>::const_iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
224  (*i)->execute();
225  }
226 }
227 
228 
229 void
231  for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
232  (*i).second->addLink(link, lane, pos);
233  }
234 }
235 
236 
237 
238 /* -------------------------------------------------------------------------
239  * method definitions for the Switching Procedures
240  * ----------------------------------------------------------------------- */
241 /* -------------------------------------------------------------------------
242  * method definitions for WAUTSwitchProcedure
243  * ----------------------------------------------------------------------- */
244 unsigned int
246  std::string val = logic.getParameter("GSP", "");
247  if (val.length() == 0) {
248  return 0;
249  }
250  return TplConvert::_2int(val.c_str());
251 }
252 
253 
254 bool
256  SUMOTime gspTime = TIME2STEPS(getGSPValue(logic)) % logic.getDefaultCycleTime();
257  SUMOTime programTime = logic.getOffsetFromIndex(logic.getCurrentPhaseIndex())
258  + (logic.getCurrentPhaseDef().duration - (logic.getNextSwitchTime() - currentTime));
259  return gspTime == programTime;
260 }
261 
262 
263 SUMOTime
265  unsigned int stepOfMyPos = logic.getIndexFromOffset(toTime);
266  SUMOTime startOfPhase = logic.getOffsetFromIndex(stepOfMyPos);
267  assert(toTime >= startOfPhase);
268  return toTime - startOfPhase;
269 }
270 
271 
272 void
274  unsigned int stepTo = logic.getIndexFromOffset(toTime);
275  SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
276  const MSPhaseDefinition& phase = logic.getPhase(stepTo);
277  SUMOTime leftDuration = phase.duration - diff;
278  logic.changeStepAndDuration(myControl, simStep, stepTo, leftDuration);
279 }
280 
281 
282 
283 /* -------------------------------------------------------------------------
284  * method definitions for WAUTSwitchProcedure_JustSwitch
285  * ----------------------------------------------------------------------- */
287  MSTLLogicControl& control, WAUT& waut,
288  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
289  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
290 
291 
293 
294 
295 bool
297  return true;
298 }
299 
300 
301 
302 /* -------------------------------------------------------------------------
303  * method definitions for WAUTSwitchProcedure_GSP
304  * ----------------------------------------------------------------------- */
306  MSTLLogicControl& control, WAUT& waut,
307  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
308  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
309 
310 
312 
313 
314 bool
316  // switch to the next programm if the GSP is reached
317  if (isPosAtGSP(step, *myFrom)) {
318  // adapt program's state
319  if (mySwitchSynchron) {
320  adaptLogic(step);
321  } else {
322  switchToPos(step, *myTo, TIME2STEPS(getGSPValue(*myTo)));
323  }
324  // switch to destination program
325  return true;
326  }
327  // do not switch, yet
328  return false;
329 }
330 
331 
332 void
334  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
335  unsigned int stepTo = myTo->getIndexFromOffset(gspTo);
336  SUMOTime cycleTimeTo = myTo->getDefaultCycleTime();
337  if (gspTo == cycleTimeTo) {
338  gspTo = 0;
339  }
340 
341  SUMOTime currentPosTo = myTo->getOffsetFromIndex(myTo->getCurrentPhaseIndex());
342  currentPosTo += (myTo->getCurrentPhaseDef().duration - (myTo->getNextSwitchTime() - step));
343  SUMOTime diff = getDiffToStartOfPhase(*myTo, gspTo);
344 
345  SUMOTime deltaToStretch = 0;
346  if (gspTo >= currentPosTo) {
347  deltaToStretch = (gspTo - currentPosTo);
348  } else {
349  deltaToStretch = (cycleTimeTo - currentPosTo + gspTo);
350  }
351  unsigned int newdur = (unsigned int) myTo->getPhase(stepTo).duration - diff + deltaToStretch;
352  myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
353 }
354 
355 
356 
357 /* -------------------------------------------------------------------------
358  * method definitions for WAUTSwitchProcedure_Stretch
359  * ----------------------------------------------------------------------- */
361  MSTLLogicControl& control, WAUT& waut,
362  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
363  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
364 
365 
367 
368 
369 bool
371  // switch to the next programm if the GSP is reached
372  if (isPosAtGSP(step, *myFrom)) {
373  // adapt program's state
374  if (mySwitchSynchron) {
375  adaptLogic(step);
376  } else {
377  switchToPos(step, *myTo, TIME2STEPS(getGSPValue(*myTo)));
378  }
379  // switch to destination program
380  return true;
381  }
382  // do not switch, yet
383  return false;
384 }
385 
386 
387 void
389  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
390  SUMOTime cycleTime = myTo->getDefaultCycleTime();
391  // the position, where the logic has to be after synchronisation
392  SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
393  // calculate the difference, that has to be equalized
394  SUMOTime deltaToCut = 0;
395  if (posAfterSyn < gspTo) {
396  deltaToCut = posAfterSyn + cycleTime - gspTo;
397  } else {
398  deltaToCut = posAfterSyn - gspTo;
399  }
400  // test, wheter cutting of the Signalplan is possible
401  SUMOTime deltaPossible = 0;
402  int areasNo = getStretchAreaNo(myTo);
403  for (int i = 0; i < areasNo; i++) {
404  StretchBereichDef def = getStretchBereichDef(myTo, i + 1);
405  assert(def.end >= def.begin);
406  deltaPossible += TIME2STEPS(def.end - def.begin);
407  }
408  int stretchUmlaufAnz = (int) TplConvert::_2SUMOReal(myTo->getParameter("StretchUmlaufAnz", "").c_str());
409  deltaPossible = stretchUmlaufAnz * deltaPossible;
410  if ((deltaPossible > deltaToCut) && (deltaToCut < (cycleTime / 2))) {
411  cutLogic(step, gspTo, deltaToCut);
412  } else {
413  SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
414  stretchLogic(step, gspTo, deltaToStretch);
415  }
416 }
417 
418 
419 void
421  unsigned int actStep = myTo->getIndexFromOffset(startPos);
422  // switches to startPos and cuts this phase, if there is a "Bereich"
423  int areasNo = getStretchAreaNo(myTo);
424  SUMOTime toCut = 0;
425  for (int i = 0; i < areasNo; i++) {
426  StretchBereichDef def = getStretchBereichDef(myTo, i + 1);
427  SUMOTime begin = TIME2STEPS(def.begin);
428  unsigned int end = TIME2STEPS(def.end);
429  size_t stepOfBegin = myTo->getIndexFromOffset(begin);
430  if (stepOfBegin == actStep) {
431  if (begin < startPos) {
432  toCut = end - startPos;
433  } else {
434  toCut = end - begin;
435  }
436  toCut = MIN2(allCutTime, toCut);
437  allCutTime = allCutTime - toCut;
438  }
439  }
440  SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
441  SUMOTime newDur = remainingDur - toCut;
442  myTo->changeStepAndDuration(myControl, step, actStep, newDur);
443 
444  // changes the duration of all other phases
445  int currStep = (actStep + 1) % (int)myTo->getPhases().size();
446  while (allCutTime > 0) {
447  for (int i = currStep; i < (int) myTo->getPhases().size(); i++) {
448  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
449  SUMOTime durOfPhase = myTo->getPhase(i).duration;
450  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
451  for (int i = 0; i < areasNo; i++) {
452  StretchBereichDef def = getStretchBereichDef(myTo, i + 1);
453  SUMOTime begin = TIME2STEPS(def.begin);
454  SUMOTime end = TIME2STEPS(def.end);
455  if ((beginOfPhase <= begin) && (endOfPhase >= end)) {
456  SUMOTime maxCutOfPhase = MIN2(end - begin, allCutTime);
457  allCutTime = allCutTime - maxCutOfPhase;
458  durOfPhase = durOfPhase - maxCutOfPhase;
459  }
460  }
461  myTo->addOverridingDuration(durOfPhase);
462  }
463  currStep = 0;
464  }
465 }
466 
467 void
469  unsigned int currStep = myTo->getIndexFromOffset(startPos);
470  SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
471  SUMOTime remainingStretchTime = allStretchTime;
472  SUMOTime StretchTimeOfPhase = 0;
473  unsigned int stretchUmlaufAnz = (unsigned int) TplConvert::_2SUMOReal(myTo->getParameter("StretchUmlaufAnz", "").c_str());
474  SUMOReal facSum = 0;
475  int areasNo = getStretchAreaNo(myTo);
476  for (int x = 0; x < areasNo; x++) {
477  StretchBereichDef def = getStretchBereichDef(myTo, x + 1);
478  facSum += def.fac;
479  }
480  facSum *= stretchUmlaufAnz;
481 
482  //switch to startPos and stretch this phase, if there is a end of "bereich" between startpos and end of phase
483  SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
484  for (int x = 0; x < areasNo; x++) {
485  StretchBereichDef def = getStretchBereichDef(myTo, x + 1);
486  SUMOTime end = TIME2STEPS(def.end);
487  SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
488  if (end <= endOfPhase && end >= startPos) {
489  SUMOReal fac = def.fac;
490  SUMOReal actualfac = fac / facSum;
491  facSum = facSum - fac;
492  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
493  remainingStretchTime = allStretchTime - StretchTimeOfPhase;
494  }
495  }
496  if (facSum == 0) {
497  WRITE_WARNING("The computed factor sum in WAUT '" + myWAUT.id + "' at time '" + toString(STEPS2TIME(step)) + "' equals zero;\n assuming an error in WAUT definition.");
498  return;
499  }
500  durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
501  myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
502 
503  currStep = (currStep + 1) % (int)myTo->getPhases().size();
504  // stretch all other phases, if there is a "bereich"
505  while (remainingStretchTime > 0) {
506  for (unsigned int i = currStep; i < myTo->getPhases().size() && remainingStretchTime > 0; i++) {
507  durOfPhase = myTo->getPhase(i).duration;
508  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
509  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
510  for (int j = 0; j < areasNo && remainingStretchTime > 0; j++) {
511  StretchBereichDef def = getStretchBereichDef(myTo, j + 1);
512  SUMOTime end = TIME2STEPS(def.end);
513  SUMOReal fac = def.fac;
514  if ((beginOfPhase <= end) && (endOfPhase >= end)) {
515  SUMOReal actualfac = fac / facSum;
516  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
517  facSum -= fac;
518  durOfPhase += StretchTimeOfPhase;
519  remainingStretchTime -= StretchTimeOfPhase;
520  }
521  }
522  myTo->addOverridingDuration(durOfPhase);
523  }
524  currStep = 0;
525  }
526 }
527 
528 int
530  int no = 0;
531  while (from->getParameter("B" + toString(no + 1) + ".begin", "") != "") {
532  no++;
533  }
534  return no;
535 }
536 
537 
540  StretchBereichDef def;
541  def.begin = TplConvert::_2SUMOReal(from->getParameter("B" + toString(index) + ".begin", "").c_str());
542  def.end = TplConvert::_2SUMOReal(from->getParameter("B" + toString(index) + ".end", "").c_str());
543  def.fac = TplConvert::_2SUMOReal(from->getParameter("B" + toString(index) + ".factor", "").c_str());
544  return def;
545 }
546 
547 
548 
549 /* -------------------------------------------------------------------------
550  * method definitions for MSTLLogicControl
551  * ----------------------------------------------------------------------- */
553  : myNetWasLoaded(false) {}
554 
555 
557  // delete tls
558  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
559  delete(*i).second;
560  }
561  // delete WAUTs
562  for (std::map<std::string, WAUT*>::const_iterator i = myWAUTs.begin(); i != myWAUTs.end(); ++i) {
563  delete(*i).second;
564  }
565 }
566 
567 
568 void
570  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
571  (*i).second->getActive()->setTrafficLightSignals(t);
572  }
573 }
574 
575 
576 std::vector<MSTrafficLightLogic*>
578  std::vector<MSTrafficLightLogic*> ret;
579  std::map<std::string, TLSLogicVariants*>::const_iterator i;
580  for (i = myLogics.begin(); i != myLogics.end(); ++i) {
581  std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
582  copy(s.begin(), s.end(), back_inserter(ret));
583  }
584  return ret;
585 }
586 
588 MSTLLogicControl::get(const std::string& id) const {
589  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
590  if (i == myLogics.end()) {
591  throw InvalidArgument("The tls '" + id + "' is not known.");
592  }
593  return *(*i).second;
594 }
595 
596 
598 MSTLLogicControl::get(const std::string& id, const std::string& programID) const {
599  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
600  if (i == myLogics.end()) {
601  return 0;
602  }
603  return (*i).second->getLogic(programID);
604 }
605 
606 
607 std::vector<std::string>
609  std::vector<std::string> ret;
610  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
611  ret.push_back((*i).first);
612  }
613  return ret;
614 }
615 
616 
617 bool
618 MSTLLogicControl::add(const std::string& id, const std::string& programID,
619  MSTrafficLightLogic* logic, bool newDefault) {
620  if (myLogics.find(id) == myLogics.end()) {
621  myLogics[id] = new TLSLogicVariants();
622  }
623  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
624  TLSLogicVariants* tlmap = (*i).second;
625  return tlmap->addLogic(programID, logic, myNetWasLoaded, newDefault);
626 }
627 
628 
629 bool
630 MSTLLogicControl::knows(const std::string& id) const {
631  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
632  if (i == myLogics.end()) {
633  return false;
634  }
635  return true;
636 }
637 
638 
639 bool
641  bool hadErrors = false;
642  for (std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
643  hadErrors |= !(*i).second->checkOriginalTLS();
644  (*i).second->saveInitialStates();
645  }
646  myNetWasLoaded = true;
647  return !hadErrors;
648 }
649 
650 
651 bool
653  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(tl->getID());
654  if (i == myLogics.end()) {
655  return false;
656  }
657  return (*i).second->isActive(tl);
658 }
659 
660 
662 MSTLLogicControl::getActive(const std::string& id) const {
663  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
664  if (i == myLogics.end()) {
665  return 0;
666  }
667  return (*i).second->getActive();
668 }
669 
670 
671 void
672 MSTLLogicControl::switchTo(const std::string& id, const std::string& programID) {
673  // try to get the tls program definitions
674  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
675  // handle problems
676  if (i == myLogics.end()) {
677  throw ProcessError("Could not switch tls '" + id + "' to program '" + programID + "': No such tls exists.");
678  }
679  (*i).second->switchTo(*this, programID);
680 }
681 
682 
683 void
684 MSTLLogicControl::addWAUT(SUMOTime refTime, const std::string& id,
685  const std::string& startProg) {
686  // check whether the waut was already defined
687  if (myWAUTs.find(id) != myWAUTs.end()) {
688  // report an error if so
689  throw InvalidArgument("Waut '" + id + "' was already defined.");
690  }
691  WAUT* w = new WAUT;
692  w->id = id;
693  w->refTime = refTime;
694  w->startProg = startProg;
695  myWAUTs[id] = w;
696 }
697 
698 
699 void
700 MSTLLogicControl::addWAUTSwitch(const std::string& wautid,
701  SUMOTime when, const std::string& to) {
702  // try to get the waut
703  if (myWAUTs.find(wautid) == myWAUTs.end()) {
704  // report an error if the waut is not known
705  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
706  }
707  // build and save the waut switch definition
708  WAUTSwitch s;
709  s.to = to;
710  s.when = (myWAUTs[wautid]->refTime + when) % 86400000;
711  myWAUTs[wautid]->switches.push_back(s);
712 }
713 
714 
715 void
716 MSTLLogicControl::addWAUTJunction(const std::string& wautid,
717  const std::string& tls,
718  const std::string& proc,
719  bool synchron) {
720  // try to get the waut
721  if (myWAUTs.find(wautid) == myWAUTs.end()) {
722  // report an error if the waut is not known
723  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
724  }
725  // try to get the tls to switch
726  if (myLogics.find(tls) == myLogics.end()) {
727  // report an error if the tls is not known
728  throw InvalidArgument("TLS '" + tls + "' to switch in WAUT '" + wautid + "' was not yet defined.");
729  }
730  WAUTJunction j;
731  j.junction = tls;
732  j.procedure = proc;
733  j.synchron = synchron;
734  myWAUTs[wautid]->junctions.push_back(j);
735 
736  std::string initProg = myWAUTs[wautid]->startProg;
737  std::vector<WAUTSwitch>::const_iterator first = myWAUTs[wautid]->switches.end();
738  SUMOTime minExecTime = -1;
739  for (std::vector<WAUTSwitch>::const_iterator i = myWAUTs[wautid]->switches.begin(); i != myWAUTs[wautid]->switches.end(); ++i) {
740  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
741  minExecTime = (*i).when;
742  first = i;
743  }
744  if (first != myWAUTs[wautid]->switches.begin()) {
745  initProg = (*(first - 1)).to;
746  }
747  }
748  // activate the first one
749  switchTo(tls, initProg);
750 }
751 
752 
753 void
754 MSTLLogicControl::closeWAUT(const std::string& wautid) {
755  // try to get the waut
756  if (myWAUTs.find(wautid) == myWAUTs.end()) {
757  // report an error if the waut is not known
758  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
759  }
760  WAUT* w = myWAUTs.find(wautid)->second;
761  std::string initProg = myWAUTs[wautid]->startProg;
762  // get the switch to be performed as first
763  std::vector<WAUTSwitch>::const_iterator first = w->switches.end();
764  SUMOTime minExecTime = -1;
765  for (std::vector<WAUTSwitch>::const_iterator i = w->switches.begin(); i != w->switches.end(); ++i) {
766  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
767  minExecTime = (*i).when;
768  first = i;
769  }
770  }
771  // activate the first one
772  if (first != w->switches.end()) {
773  std::vector<WAUTSwitch>::const_iterator mbegin = w->switches.begin();
775  new SwitchInitCommand(*this, wautid, (unsigned int)distance(mbegin, first)),
776  (*first).when, MSEventControl::NO_CHANGE);
777  }
778  /*
779  // set the current program to all junctions
780  for(std::vector<WAUTJunction>::const_iterator i=w->junctions.begin(); i!=w->junctions.end(); ++i) {
781  switchTo((*i).junction, initProg);
782  }
783  */
784 }
785 
786 
787 SUMOTime
789  const std::string& wautid = cmd.getWAUTID();
790  unsigned int& index = cmd.getIndex();
791  WAUTSwitch s = myWAUTs[wautid]->switches[index];
792  for (std::vector<WAUTJunction>::iterator i = myWAUTs[wautid]->junctions.begin(); i != myWAUTs[wautid]->junctions.end(); ++i) {
793  // get the current program and the one to instantiate
794  TLSLogicVariants* vars = myLogics.find((*i).junction)->second;
795  MSTrafficLightLogic* from = vars->getActive();
796  MSTrafficLightLogic* to = vars->getLogicInstantiatingOff(*this, s.to);
797  WAUTSwitchProcedure* proc = 0;
798  if ((*i).procedure == "GSP") {
799  proc = new WAUTSwitchProcedure_GSP(*this, *myWAUTs[wautid], from, to, (*i).synchron);
800  } else if ((*i).procedure == "Stretch") {
801  proc = new WAUTSwitchProcedure_Stretch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
802  } else {
803  proc = new WAUTSwitchProcedure_JustSwitch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
804  }
805 
807  p.junction = (*i).junction;
808  p.proc = proc;
809  p.from = from;
810  p.to = to;
811 
812  myCurrentlySwitched.push_back(p);
813  }
814  index++;
815  if (index == static_cast<unsigned int>(myWAUTs[wautid]->switches.size())) {
816  return 0;
817  }
818  return myWAUTs[wautid]->switches[index].when - MSNet::getInstance()->getCurrentTimeStep();
819 }
820 
821 
822 void
824  for (std::vector<WAUTSwitchProcess>::iterator i = myCurrentlySwitched.begin(); i != myCurrentlySwitched.end();) {
825  const WAUTSwitchProcess& proc = *i;
826  if (proc.proc->trySwitch(step)) {
827  delete proc.proc;
828  switchTo((*i).to->getID(), (*i).to->getProgramID());
829  i = myCurrentlySwitched.erase(i);
830  } else {
831  ++i;
832  }
833  }
834 }
835 
836 
837 std::pair<SUMOTime, MSPhaseDefinition>
838 MSTLLogicControl::getPhaseDef(const std::string& tlid) const {
839  MSTrafficLightLogic* tl = getActive(tlid);
840  return std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), tl->getCurrentPhaseDef());
841 }
842 
843 
844 
845 /****************************************************************************/
846 
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:159
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.
Definition: MSNet.h:216
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:200
A fixed traffic light logic.
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'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'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:66
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:53
void setStateInstantiatingOnline(MSTLLogicControl &tlc, const std::string &state)
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:205
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 ("GuenstigerUmschaltPunkt") ...
The parent class for traffic light logics.
#define SUMOReal
Definition: config.h:215
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.
#define DELTA_T
Definition: SUMOTime.h:50
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:340
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
The definition of a single phase of a tls logic.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
std::string junction
The junction name.
A WAUT definition.