SUMO - Simulation of Urban MObility
MSTLLogicControl.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
23 // A class that stores and controls tls and switching of their programs
24 /****************************************************************************/
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <vector>
35 #include <algorithm>
36 #include <cassert>
37 #include <iterator>
38 #include "MSTrafficLightLogic.h"
40 #include "MSTLLogicControl.h"
41 #include "MSOffTrafficLightLogic.h"
43 #include <microsim/MSNet.h>
45 #include <utils/common/ToString.h>
47 
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 /* -------------------------------------------------------------------------
53  * MSTLLogicControl::TLSLogicVariants - methods
54  * ----------------------------------------------------------------------- */
56  : myCurrentProgram(0) {
57 }
58 
59 
61  std::map<std::string, MSTrafficLightLogic*>::const_iterator j;
62  for (std::map<std::string, MSTrafficLightLogic*>::iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
63  delete(*j).second;
64  }
65  for (std::vector<OnSwitchAction*>::iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
66  delete *i;
67  }
68 }
69 
70 
71 bool
73  bool hadErrors = false;
74  for (std::map<std::string, MSTrafficLightLogic*>::const_iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
75  const MSTrafficLightLogic::Phases& phases = (*j).second->getPhases();
76  int linkNo = (int)(*j).second->getLinks().size();
77  bool hadProgramErrors = false;
78  for (MSTrafficLightLogic::Phases::const_iterator i = phases.begin(); i != phases.end(); ++i) {
79  if ((int)(*i)->getState().length() < linkNo) {
80  hadProgramErrors = true;
81  }
82  }
83  if (hadProgramErrors) {
84  WRITE_ERROR("Mismatching phase size in tls '" + (*j).second->getID() + "', program '" + (*j).first + "'.");
85  hadErrors = true;
86  }
87  }
88  return !hadErrors;
89 }
90 
91 
92 void
95 }
96 
97 
98 bool
99 MSTLLogicControl::TLSLogicVariants::addLogic(const std::string& programID,
100  MSTrafficLightLogic* logic, bool netWasLoaded, bool isNewDefault) {
101  if (myVariants.find(programID) != myVariants.end()) {
102  return false;
103  }
104  // assert the links are set
105  if (netWasLoaded) {
106  // this one has not yet its links set
107  if (myCurrentProgram == 0) {
108  throw ProcessError("No initial signal plan loaded for tls '" + logic->getID() + "'.");
109  }
111  if (logic->getLinks().size() > logic->getPhase(0).getState().size()) {
112  throw ProcessError("Mismatching phase size in tls '" + logic->getID() + "', program '" + programID + "'.");
113  }
114  }
115  // add to the list of active
116  if (myVariants.size() == 0 || isNewDefault) {
117  myCurrentProgram = logic;
118  }
119  // add to the list of logic
120  myVariants[programID] = logic;
121  if (myVariants.size() == 1 || isNewDefault) {
122  logic->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
124  }
125  return true;
126 }
127 
128 
130 MSTLLogicControl::TLSLogicVariants::getLogic(const std::string& programID) const {
131  if (myVariants.find(programID) == myVariants.end()) {
132  return 0;
133  }
134  return myVariants.find(programID)->second;
135 }
136 
137 
140  const std::string& programID) {
141  if (myVariants.find(programID) == myVariants.end()) {
142  if (programID == "off") {
143  // build an off-tll if this switch indicates it
144  if (!addLogic("off", new MSOffTrafficLightLogic(tlc, myCurrentProgram->getID()), true, true)) {
145  // inform the user if this fails
146  throw ProcessError("Could not build an off-state for tls '" + myCurrentProgram->getID() + "'.");
147  }
148  } else {
149  // inform the user about a missing logic
150  throw ProcessError("Can not switch tls '" + myCurrentProgram->getID() + "' to program '" + programID + "';\n The program is not known.");
151  }
152  }
153  return getLogic(programID);
154 }
155 
156 
157 void
159  const std::string& state) {
160  // build only once...
161  MSTrafficLightLogic* logic = getLogic("online");
162  if (logic == 0) {
163  MSPhaseDefinition* phase = new MSPhaseDefinition(DELTA_T, state);
164  std::vector<MSPhaseDefinition*> phases;
165  phases.push_back(phase);
166  logic = new MSSimpleTrafficLightLogic(tlc, myCurrentProgram->getID(), "online", phases, 0,
168  std::map<std::string, std::string>());
169  addLogic("online", logic, true, true);
170  } else {
171  MSPhaseDefinition nphase(DELTA_T, state);
172  *(dynamic_cast<MSSimpleTrafficLightLogic*>(logic)->getPhases()[0]) = nphase;
173  switchTo(tlc, "online");
174  }
175 }
176 
177 
178 void
180  mySwitchActions.push_back(c);
181 }
182 
183 
184 std::vector<MSTrafficLightLogic*>
186  std::vector<MSTrafficLightLogic*> ret;
187  std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
188  for (i = myVariants.begin(); i != myVariants.end(); ++i) {
189  ret.push_back((*i).second);
190  }
191  return ret;
192 }
193 
194 
195 bool
197  return tl == myCurrentProgram;
198 }
199 
200 
203  return myCurrentProgram;
204 }
205 
206 
207 void
209  // set the found wished sub-program as this tls' current one
210  myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
213 }
214 
215 
216 void
218  for (std::vector<OnSwitchAction*>::const_iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
219  (*i)->execute();
220  }
221 }
222 
223 
224 void
226  for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
227  (*i).second->addLink(link, lane, pos);
228  }
229 }
230 
231 
232 
233 /* -------------------------------------------------------------------------
234  * method definitions for the Switching Procedures
235  * ----------------------------------------------------------------------- */
236 /* -------------------------------------------------------------------------
237  * method definitions for WAUTSwitchProcedure
238  * ----------------------------------------------------------------------- */
239 int
241  std::string val = logic.getParameter("GSP", "");
242  if (val.length() == 0) {
243  return 0;
244  }
245  return TplConvert::_2int(val.c_str());
246 }
247 
248 
249 bool
251  SUMOTime gspTime = TIME2STEPS(getGSPValue(logic)) % logic.getDefaultCycleTime();
252  SUMOTime programTime = logic.getOffsetFromIndex(logic.getCurrentPhaseIndex())
253  + (logic.getCurrentPhaseDef().duration - (logic.getNextSwitchTime() - currentTime));
254  return gspTime == programTime;
255 }
256 
257 
258 SUMOTime
260  int stepOfMyPos = logic.getIndexFromOffset(toTime);
261  SUMOTime startOfPhase = logic.getOffsetFromIndex(stepOfMyPos);
262  assert(toTime >= startOfPhase);
263  return toTime - startOfPhase;
264 }
265 
266 
267 void
269  int stepTo = logic.getIndexFromOffset(toTime);
270  SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
271  const MSPhaseDefinition& phase = logic.getPhase(stepTo);
272  SUMOTime leftDuration = phase.duration - diff;
273  logic.changeStepAndDuration(myControl, simStep, stepTo, leftDuration);
274 }
275 
276 
277 
278 /* -------------------------------------------------------------------------
279  * method definitions for WAUTSwitchProcedure_JustSwitch
280  * ----------------------------------------------------------------------- */
282  MSTLLogicControl& control, WAUT& waut,
283  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
284  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
285 
286 
288 
289 
290 bool
292  return true;
293 }
294 
295 
296 
297 /* -------------------------------------------------------------------------
298  * method definitions for WAUTSwitchProcedure_GSP
299  * ----------------------------------------------------------------------- */
301  MSTLLogicControl& control, WAUT& waut,
302  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
303  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
304 
305 
307 
308 
309 bool
311  // switch to the next programm if the GSP is reached
312  if (isPosAtGSP(step, *myFrom)) {
313  // adapt program's state
314  if (mySwitchSynchron) {
315  adaptLogic(step);
316  } else {
318  }
319  // switch to destination program
320  return true;
321  }
322  // do not switch, yet
323  return false;
324 }
325 
326 
327 void
329  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
330  int stepTo = myTo->getIndexFromOffset(gspTo);
331  SUMOTime cycleTimeTo = myTo->getDefaultCycleTime();
332  if (gspTo == cycleTimeTo) {
333  gspTo = 0;
334  }
335 
337  currentPosTo += (myTo->getCurrentPhaseDef().duration - (myTo->getNextSwitchTime() - step));
338  SUMOTime diff = getDiffToStartOfPhase(*myTo, gspTo);
339 
340  SUMOTime deltaToStretch = 0;
341  if (gspTo >= currentPosTo) {
342  deltaToStretch = (gspTo - currentPosTo);
343  } else {
344  deltaToStretch = (cycleTimeTo - currentPosTo + gspTo);
345  }
346  const SUMOTime newdur = myTo->getPhase(stepTo).duration - diff + deltaToStretch;
347  myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
348 }
349 
350 
351 
352 /* -------------------------------------------------------------------------
353  * method definitions for WAUTSwitchProcedure_Stretch
354  * ----------------------------------------------------------------------- */
356  MSTLLogicControl& control, WAUT& waut,
357  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
358  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
359 
360 
362 
363 
364 bool
366  // switch to the next programm if the GSP is reached
367  if (isPosAtGSP(step, *myFrom)) {
368  // adapt program's state
369  if (mySwitchSynchron) {
370  adaptLogic(step);
371  } else {
373  }
374  // switch to destination program
375  return true;
376  }
377  // do not switch, yet
378  return false;
379 }
380 
381 
382 void
384  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
385  SUMOTime cycleTime = myTo->getDefaultCycleTime();
386  // the position, where the logic has to be after synchronisation
387  SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
388  // calculate the difference, that has to be equalized
389  SUMOTime deltaToCut = 0;
390  if (posAfterSyn < gspTo) {
391  deltaToCut = posAfterSyn + cycleTime - gspTo;
392  } else {
393  deltaToCut = posAfterSyn - gspTo;
394  }
395  // test, wheter cutting of the Signalplan is possible
396  SUMOTime deltaPossible = 0;
397  int areasNo = getStretchAreaNo(myTo);
398  for (int i = 0; i < areasNo; i++) {
400  assert(def.end >= def.begin);
401  deltaPossible += TIME2STEPS(def.end - def.begin);
402  }
403  int stretchUmlaufAnz = (int) TplConvert::_2double(myTo->getParameter("StretchUmlaufAnz", "").c_str());
404  deltaPossible = stretchUmlaufAnz * deltaPossible;
405  if ((deltaPossible > deltaToCut) && (deltaToCut < (cycleTime / 2))) {
406  cutLogic(step, gspTo, deltaToCut);
407  } else {
408  SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
409  stretchLogic(step, gspTo, deltaToStretch);
410  }
411 }
412 
413 
414 void
416  int actStep = myTo->getIndexFromOffset(startPos);
417  // switches to startPos and cuts this phase, if there is a "Bereich"
418  int areasNo = getStretchAreaNo(myTo);
419  SUMOTime toCut = 0;
420  for (int i = 0; i < areasNo; i++) {
422  const SUMOTime begin = TIME2STEPS(def.begin);
423  const SUMOTime end = TIME2STEPS(def.end);
424  int stepOfBegin = myTo->getIndexFromOffset(begin);
425  if (stepOfBegin == actStep) {
426  if (begin < startPos) {
427  toCut = end - startPos;
428  } else {
429  toCut = end - begin;
430  }
431  toCut = MIN2(allCutTime, toCut);
432  allCutTime = allCutTime - toCut;
433  }
434  }
435  SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
436  SUMOTime newDur = remainingDur - toCut;
437  myTo->changeStepAndDuration(myControl, step, actStep, newDur);
438 
439  // changes the duration of all other phases
440  int currStep = (actStep + 1) % (int)myTo->getPhases().size();
441  while (allCutTime > 0) {
442  for (int i = currStep; i < (int) myTo->getPhases().size(); i++) {
443  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
444  SUMOTime durOfPhase = myTo->getPhase(i).duration;
445  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
446  for (int i = 0; i < areasNo; i++) {
448  SUMOTime begin = TIME2STEPS(def.begin);
449  SUMOTime end = TIME2STEPS(def.end);
450  if ((beginOfPhase <= begin) && (endOfPhase >= end)) {
451  SUMOTime maxCutOfPhase = MIN2(end - begin, allCutTime);
452  allCutTime = allCutTime - maxCutOfPhase;
453  durOfPhase = durOfPhase - maxCutOfPhase;
454  }
455  }
456  myTo->addOverridingDuration(durOfPhase);
457  }
458  currStep = 0;
459  }
460 }
461 
462 void
464  int currStep = myTo->getIndexFromOffset(startPos);
465  SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
466  SUMOTime remainingStretchTime = allStretchTime;
467  SUMOTime StretchTimeOfPhase = 0;
468  int stretchUmlaufAnz = (int) TplConvert::_2double(myTo->getParameter("StretchUmlaufAnz", "").c_str());
469  double facSum = 0;
470  int areasNo = getStretchAreaNo(myTo);
471  for (int x = 0; x < areasNo; x++) {
473  facSum += def.fac;
474  }
475  facSum *= stretchUmlaufAnz;
476 
477  //switch to startPos and stretch this phase, if there is a end of "bereich" between startpos and end of phase
478  SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
479  for (int x = 0; x < areasNo; x++) {
481  SUMOTime end = TIME2STEPS(def.end);
482  SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
483  if (end <= endOfPhase && end >= startPos) {
484  double fac = def.fac;
485  double actualfac = fac / facSum;
486  facSum = facSum - fac;
487  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
488  remainingStretchTime = allStretchTime - StretchTimeOfPhase;
489  }
490  }
491  if (facSum == 0) {
492  WRITE_WARNING("The computed factor sum in WAUT '" + myWAUT.id + "' at time '" + toString(STEPS2TIME(step)) + "' equals zero;\n assuming an error in WAUT definition.");
493  return;
494  }
495  durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
496  myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
497 
498  currStep = (currStep + 1) % (int)myTo->getPhases().size();
499  // stretch all other phases, if there is a "bereich"
500  while (remainingStretchTime > 0) {
501  for (int i = currStep; i < (int)myTo->getPhases().size() && remainingStretchTime > 0; i++) {
502  durOfPhase = myTo->getPhase(i).duration;
503  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
504  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
505  for (int j = 0; j < areasNo && remainingStretchTime > 0; j++) {
507  SUMOTime end = TIME2STEPS(def.end);
508  double fac = def.fac;
509  if ((beginOfPhase <= end) && (endOfPhase >= end)) {
510  double actualfac = fac / facSum;
511  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
512  facSum -= fac;
513  durOfPhase += StretchTimeOfPhase;
514  remainingStretchTime -= StretchTimeOfPhase;
515  }
516  }
517  myTo->addOverridingDuration(durOfPhase);
518  }
519  currStep = 0;
520  }
521 }
522 
523 int
525  int no = 0;
526  while (from->getParameter("B" + toString(no + 1) + ".begin", "") != "") {
527  no++;
528  }
529  return no;
530 }
531 
532 
535  StretchBereichDef def;
536  def.begin = TplConvert::_2double(from->getParameter("B" + toString(index) + ".begin", "").c_str());
537  def.end = TplConvert::_2double(from->getParameter("B" + toString(index) + ".end", "").c_str());
538  def.fac = TplConvert::_2double(from->getParameter("B" + toString(index) + ".factor", "").c_str());
539  return def;
540 }
541 
542 
543 
544 /* -------------------------------------------------------------------------
545  * method definitions for MSTLLogicControl
546  * ----------------------------------------------------------------------- */
548  : myNetWasLoaded(false) {}
549 
550 
552  // delete tls
553  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
554  delete(*i).second;
555  }
556  // delete WAUTs
557  for (std::map<std::string, WAUT*>::const_iterator i = myWAUTs.begin(); i != myWAUTs.end(); ++i) {
558  delete(*i).second;
559  }
560 }
561 
562 
563 void
565  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
566  (*i).second->getActive()->setTrafficLightSignals(t);
567  }
568 }
569 
570 
571 std::vector<MSTrafficLightLogic*>
573  std::vector<MSTrafficLightLogic*> ret;
574  std::map<std::string, TLSLogicVariants*>::const_iterator i;
575  for (i = myLogics.begin(); i != myLogics.end(); ++i) {
576  std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
577  copy(s.begin(), s.end(), back_inserter(ret));
578  }
579  return ret;
580 }
581 
583 MSTLLogicControl::get(const std::string& id) const {
584  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
585  if (i == myLogics.end()) {
586  throw InvalidArgument("The tls '" + id + "' is not known.");
587  }
588  return *(*i).second;
589 }
590 
591 
593 MSTLLogicControl::get(const std::string& id, const std::string& programID) const {
594  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
595  if (i == myLogics.end()) {
596  return 0;
597  }
598  return (*i).second->getLogic(programID);
599 }
600 
601 
602 std::vector<std::string>
604  std::vector<std::string> ret;
605  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
606  ret.push_back((*i).first);
607  }
608  return ret;
609 }
610 
611 
612 bool
613 MSTLLogicControl::add(const std::string& id, const std::string& programID,
614  MSTrafficLightLogic* logic, bool newDefault) {
615  if (myLogics.find(id) == myLogics.end()) {
616  myLogics[id] = new TLSLogicVariants();
617  }
618  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
619  TLSLogicVariants* tlmap = (*i).second;
620  return tlmap->addLogic(programID, logic, myNetWasLoaded, newDefault);
621 }
622 
623 
624 bool
625 MSTLLogicControl::knows(const std::string& id) const {
626  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
627  if (i == myLogics.end()) {
628  return false;
629  }
630  return true;
631 }
632 
633 
634 bool
636  bool hadErrors = false;
637  for (std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
638  hadErrors |= !(*i).second->checkOriginalTLS();
639  (*i).second->saveInitialStates();
640  }
641  myNetWasLoaded = true;
642  return !hadErrors;
643 }
644 
645 
646 bool
648  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(tl->getID());
649  if (i == myLogics.end()) {
650  return false;
651  }
652  return (*i).second->isActive(tl);
653 }
654 
655 
657 MSTLLogicControl::getActive(const std::string& id) const {
658  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
659  if (i == myLogics.end()) {
660  return 0;
661  }
662  return (*i).second->getActive();
663 }
664 
665 
666 void
667 MSTLLogicControl::switchTo(const std::string& id, const std::string& programID) {
668  // try to get the tls program definitions
669  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
670  // handle problems
671  if (i == myLogics.end()) {
672  throw ProcessError("Could not switch tls '" + id + "' to program '" + programID + "': No such tls exists.");
673  }
674  (*i).second->switchTo(*this, programID);
675 }
676 
677 
678 void
679 MSTLLogicControl::addWAUT(SUMOTime refTime, const std::string& id,
680  const std::string& startProg) {
681  // check whether the waut was already defined
682  if (myWAUTs.find(id) != myWAUTs.end()) {
683  // report an error if so
684  throw InvalidArgument("Waut '" + id + "' was already defined.");
685  }
686  WAUT* w = new WAUT;
687  w->id = id;
688  w->refTime = refTime;
689  w->startProg = startProg;
690  myWAUTs[id] = w;
691 }
692 
693 
694 void
695 MSTLLogicControl::addWAUTSwitch(const std::string& wautid,
696  SUMOTime when, const std::string& to) {
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  // build and save the waut switch definition
703  WAUTSwitch s;
704  s.to = to;
705  s.when = (myWAUTs[wautid]->refTime + when) % 86400000;
706  myWAUTs[wautid]->switches.push_back(s);
707 }
708 
709 
710 void
711 MSTLLogicControl::addWAUTJunction(const std::string& wautid,
712  const std::string& tls,
713  const std::string& proc,
714  bool synchron) {
715  // try to get the waut
716  if (myWAUTs.find(wautid) == myWAUTs.end()) {
717  // report an error if the waut is not known
718  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
719  }
720  // try to get the tls to switch
721  if (myLogics.find(tls) == myLogics.end()) {
722  // report an error if the tls is not known
723  throw InvalidArgument("TLS '" + tls + "' to switch in WAUT '" + wautid + "' was not yet defined.");
724  }
725  WAUTJunction j;
726  j.junction = tls;
727  j.procedure = proc;
728  j.synchron = synchron;
729  myWAUTs[wautid]->junctions.push_back(j);
730 
731  std::string initProg = myWAUTs[wautid]->startProg;
732  std::vector<WAUTSwitch>::const_iterator first = myWAUTs[wautid]->switches.end();
733  SUMOTime minExecTime = -1;
734  for (std::vector<WAUTSwitch>::const_iterator i = myWAUTs[wautid]->switches.begin(); i != myWAUTs[wautid]->switches.end(); ++i) {
735  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
736  minExecTime = (*i).when;
737  first = i;
738  }
739  if (first != myWAUTs[wautid]->switches.begin()) {
740  initProg = (*(first - 1)).to;
741  }
742  }
743  // activate the first one
744  switchTo(tls, initProg);
745 }
746 
747 
748 void
749 MSTLLogicControl::closeWAUT(const std::string& wautid) {
750  // try to get the waut
751  if (myWAUTs.find(wautid) == myWAUTs.end()) {
752  // report an error if the waut is not known
753  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
754  }
755  WAUT* w = myWAUTs.find(wautid)->second;
756  std::string initProg = myWAUTs[wautid]->startProg;
757  // get the switch to be performed as first
758  std::vector<WAUTSwitch>::const_iterator first = w->switches.end();
759  SUMOTime minExecTime = -1;
760  for (std::vector<WAUTSwitch>::const_iterator i = w->switches.begin(); i != w->switches.end(); ++i) {
761  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
762  minExecTime = (*i).when;
763  first = i;
764  }
765  }
766  // activate the first one
767  if (first != w->switches.end()) {
768  std::vector<WAUTSwitch>::const_iterator mbegin = w->switches.begin();
770  new SwitchInitCommand(*this, wautid, (int)distance(mbegin, first)),
771  (*first).when);
772  }
773  /*
774  // set the current program to all junctions
775  for(std::vector<WAUTJunction>::const_iterator i=w->junctions.begin(); i!=w->junctions.end(); ++i) {
776  switchTo((*i).junction, initProg);
777  }
778  */
779 }
780 
781 
782 SUMOTime
784  const std::string& wautid = cmd.getWAUTID();
785  int& index = cmd.getIndex();
786  WAUTSwitch s = myWAUTs[wautid]->switches[index];
787  for (std::vector<WAUTJunction>::iterator i = myWAUTs[wautid]->junctions.begin(); i != myWAUTs[wautid]->junctions.end(); ++i) {
788  // get the current program and the one to instantiate
789  TLSLogicVariants* vars = myLogics.find((*i).junction)->second;
790  MSTrafficLightLogic* from = vars->getActive();
791  MSTrafficLightLogic* to = vars->getLogicInstantiatingOff(*this, s.to);
792  WAUTSwitchProcedure* proc = 0;
793  if ((*i).procedure == "GSP") {
794  proc = new WAUTSwitchProcedure_GSP(*this, *myWAUTs[wautid], from, to, (*i).synchron);
795  } else if ((*i).procedure == "Stretch") {
796  proc = new WAUTSwitchProcedure_Stretch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
797  } else {
798  proc = new WAUTSwitchProcedure_JustSwitch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
799  }
800 
802  p.junction = (*i).junction;
803  p.proc = proc;
804  p.from = from;
805  p.to = to;
806 
807  myCurrentlySwitched.push_back(p);
808  }
809  index++;
810  if (index == static_cast<int>(myWAUTs[wautid]->switches.size())) {
811  return 0;
812  }
813  return myWAUTs[wautid]->switches[index].when - MSNet::getInstance()->getCurrentTimeStep();
814 }
815 
816 
817 void
819  for (std::vector<WAUTSwitchProcess>::iterator i = myCurrentlySwitched.begin(); i != myCurrentlySwitched.end();) {
820  const WAUTSwitchProcess& proc = *i;
821  if (proc.proc->trySwitch(step)) {
822  delete proc.proc;
823  switchTo((*i).to->getID(), (*i).to->getProgramID());
824  i = myCurrentlySwitched.erase(i);
825  } else {
826  ++i;
827  }
828  }
829 }
830 
831 
832 std::pair<SUMOTime, MSPhaseDefinition>
833 MSTLLogicControl::getPhaseDef(const std::string& tlid) const {
834  MSTrafficLightLogic* tl = getActive(tlid);
835  return std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), tl->getCurrentPhaseDef());
836 }
837 
838 
839 void
841  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
842  (*i).second->addLogic("off", new MSOffTrafficLightLogic(*this, (*i).first), true, true);
843  }
844 }
845 
846 /****************************************************************************/
847 
double end
The end of a stretch/cut area (time, in s)
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.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
const std::string & getState() const
Returns the state within this phase.
void cutLogic(SUMOTime step, SUMOTime startPos, SUMOTime allCutTime)
Cuts the logic to synchronize.
void switchOffAll()
switch all logic variants to &#39;off&#39;
std::map< MSLink *, LinkState > myOriginalLinkStates
Originally loaded link states.
int & getIndex()
Returns a reference to the index.
std::map< std::string, TLSLogicVariants * > myLogics
A map from ids to the corresponding variants.
Storage for all programs of a single tls.
double fac
The weight factor of a stretch/cut area.
virtual SUMOTime getOffsetFromIndex(int index) const =0
Returns the position (start of a phase during a cycle) from of a given step.
Base class for things to execute if a tls switches to a new phase.
int getGSPValue(const MSTrafficLightLogic &logic) const
Returns the GSP-value.
void switchTo(const std::string &id, const std::string &programID)
Switches the named (id) tls to the named (programID) program.
std::map< std::string, MSTrafficLightLogic * > myVariants
A map of subkeys to programs.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
virtual SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const =0
Returns the index of the logic at the given simulation step.
~MSTLLogicControl()
Destructor.
WAUTSwitchProcedure_GSP(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
virtual const MSPhaseDefinition & getPhase(int givenstep) const =0
Returns the definition of the phase from the given position within the plan.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
double begin
The begin of a stretch/cut area (time, in s)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
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.
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
MSTrafficLightLogic * myTo
The program to switch the tls to.
WAUTSwitchProcedure_Stretch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
virtual int getCurrentPhaseIndex() const =0
Returns the current index within the program.
void addLink(MSLink *link, MSLane *lane, int pos)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
MSTLLogicControl()
Constructor.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
WAUT & myWAUT
The WAUT responsible for switching.
void closeWAUT(const std::string &wautid)
Closes loading of a WAUT.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
SUMOTime initWautSwitch(SwitchInitCommand &cmd)
Initialises switching a WAUT.
bool myNetWasLoaded
Information whether the net was completely loaded.
Storage for a junction assigned to a WAUT.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
A fixed traffic light logic.
A traffic lights logic which represents a tls in an off-mode.
A class that stores and controls tls and switching of their programs.
bool mySwitchSynchron
Information whether to switch synchron (?)
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
MSTLLogicControl & myControl
The control the logic belongs to.
SUMOTime duration
The duration of the phase.
std::vector< MSTrafficLightLogic * > getAllLogics() const
bool addLogic(const std::string &programID, MSTrafficLightLogic *logic, bool netWasLoaded, bool isNewDefault=true)
Adds a logic (program)
void addSwitchCommand(OnSwitchAction *c)
StretchBereichDef getStretchBereichDef(MSTrafficLightLogic *from, int index) const
Returns the numbered Stretch-area for the given program.
MSTrafficLightLogic * getLogicInstantiatingOff(MSTLLogicControl &tlc, const std::string &programID)
std::pair< SUMOTime, MSPhaseDefinition > getPhaseDef(const std::string &tlid) const
return the complete phase definition for a named traffic lights logic
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
WAUTSwitchProcedure * proc
The used procedure.
void adaptLogic(SUMOTime step)
Stretches the destination program&#39;s phase to which the tls was switched.
MSTrafficLightLogic * getActive(const std::string &id) const
Returns the active program of a named tls.
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.
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:399
MSTrafficLightLogic * to
The program to switch the tls to.
This class switches using the Stretch algorithm.
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
#define STEPS2TIME(x)
Definition: SUMOTime.h:64
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
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:67
int getStretchAreaNo(MSTrafficLightLogic *from) const
Returns the number of given Stretch-areas for the given program.
bool checkOriginalTLS() const
Verifies traffic lights loaded from the network.
std::map< MSLink *, LinkState > collectLinkStates() const
Returns the (uncontrolled) states of the controlled links.
SUMOTime when
The time the WAUT shall switch the TLS.
void stretchLogic(SUMOTime step, SUMOTime startPos, SUMOTime allStretchTime)
Stretches the logic to synchronize.
std::vector< OnSwitchAction * > mySwitchActions
The list of actions/commands to execute on switch.
void setStateInstantiatingOnline(MSTLLogicControl &tlc, const std::string &state)
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
std::string startProg
The name of the start program.
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.
bool knows(const std::string &id) const
Returns the information whether the named tls is stored.
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
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
void addOverridingDuration(SUMOTime duration)
Changes the duration of the next phase.
An initialised switch process.
void switchTo(MSTLLogicControl &tlc, const std::string &programID)
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:155
std::vector< WAUTSwitch > switches
The list of switches to be done by the WAUT.
void switchToPos(SUMOTime simStep, MSTrafficLightLogic &logic, SUMOTime toTime)
switches the given logic directly to the given position
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
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.
const std::string & getWAUTID() const
Returns the WAUT-id.
std::string id
The id of the WAUT.
bool isActive(const MSTrafficLightLogic *tl) const
static double _2double(const E *const data)
converts a char-type array into the double value described by it
Definition: TplConvert.h:311
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
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.
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.
long long int SUMOTime
Definition: TraCIDefs.h:51
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
MSTrafficLightLogic * getActive() const
MSTrafficLightLogic * from
The current program of the tls.
std::vector< std::string > getAllTLIds() const
MSTrafficLightLogic * getLogic(const std::string &programID) const
void setTrafficLightSignals(SUMOTime t) const
Lets all running (current) tls programs apply their current signal states to links they control...
MSTrafficLightLogic * myFrom
The current program of the tls to switch.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
The definition of a single phase of a tls logic.
MSTrafficLightLogic * myCurrentProgram
The currently used program.
std::vector< MSTrafficLightLogic * > getAllLogics() const
Returns a vector which contains all logics.
virtual int getIndexFromOffset(SUMOTime offset) const =0
Returns the step (the phasenumber) of a given position of the cycle.
std::string junction
The junction name.
A WAUT definition.