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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
21 // A class that stores and controls tls and switching of their programs
22 /****************************************************************************/
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <vector>
29 #include <algorithm>
30 #include <cassert>
31 #include <iterator>
32 #include "MSTrafficLightLogic.h"
34 #include "MSTLLogicControl.h"
35 #include "MSOffTrafficLightLogic.h"
37 #include <microsim/MSNet.h>
39 #include <utils/common/ToString.h>
41 
42 
43 // ===========================================================================
44 // method definitions
45 // ===========================================================================
46 /* -------------------------------------------------------------------------
47  * MSTLLogicControl::TLSLogicVariants - methods
48  * ----------------------------------------------------------------------- */
50  : myCurrentProgram(nullptr) {
51 }
52 
53 
55  std::map<std::string, MSTrafficLightLogic*>::const_iterator j;
56  for (std::map<std::string, MSTrafficLightLogic*>::iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
57  delete(*j).second;
58  }
59  for (std::vector<OnSwitchAction*>::iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
60  delete *i;
61  }
62 }
63 
64 
65 bool
67  bool hadErrors = false;
68  for (std::map<std::string, MSTrafficLightLogic*>::const_iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
69  const MSTrafficLightLogic::Phases& phases = (*j).second->getPhases();
70  int linkNo = (int)(*j).second->getLinks().size();
71  bool hadProgramErrors = false;
72  for (MSTrafficLightLogic::Phases::const_iterator i = phases.begin(); i != phases.end(); ++i) {
73  if ((int)(*i)->getState().length() < linkNo) {
74  hadProgramErrors = true;
75  }
76  }
77  if (hadProgramErrors) {
78  WRITE_ERROR("Mismatching phase size in tls '" + (*j).second->getID() + "', program '" + (*j).first + "'.");
79  hadErrors = true;
80  }
81  }
82  return !hadErrors;
83 }
84 
85 
86 void
89 }
90 
91 
92 bool
93 MSTLLogicControl::TLSLogicVariants::addLogic(const std::string& programID,
94  MSTrafficLightLogic* logic, bool netWasLoaded, bool isNewDefault) {
95  if (myVariants.find(programID) != myVariants.end()) {
96  return false;
97  }
98  // assert the links are set
99  if (netWasLoaded) {
100  // this one has not yet its links set
101  if (myCurrentProgram == nullptr) {
102  throw ProcessError("No initial signal plan loaded for tls '" + logic->getID() + "'.");
103  }
105  if (logic->getLinks().size() > logic->getPhase(0).getState().size()) {
106  throw ProcessError("Mismatching phase size in tls '" + logic->getID() + "', program '" + programID + "'.");
107  }
108  }
109  // add to the list of active
110  if (myVariants.size() == 0 || isNewDefault) {
111  myCurrentProgram = logic;
112  }
113  // add to the list of logic
114  myVariants[programID] = logic;
115  if (myVariants.size() == 1 || isNewDefault) {
116  logic->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
118  }
119  return true;
120 }
121 
122 
124 MSTLLogicControl::TLSLogicVariants::getLogic(const std::string& programID) const {
125  if (myVariants.find(programID) == myVariants.end()) {
126  return nullptr;
127  }
128  return myVariants.find(programID)->second;
129 }
130 
131 
134  const std::string& programID) {
135  if (myVariants.find(programID) == myVariants.end()) {
136  if (programID == "off") {
137  // build an off-tll if this switch indicates it
138  if (!addLogic("off", new MSOffTrafficLightLogic(tlc, myCurrentProgram->getID()), true, true)) {
139  // inform the user if this fails
140  throw ProcessError("Could not build an off-state for tls '" + myCurrentProgram->getID() + "'.");
141  }
142  } else {
143  // inform the user about a missing logic
144  throw ProcessError("Can not switch tls '" + myCurrentProgram->getID() + "' to program '" + programID + "';\n The program is not known.");
145  }
146  }
147  return getLogic(programID);
148 }
149 
150 
151 void
153  const std::string& state) {
154  // build only once...
155  MSTrafficLightLogic* logic = getLogic("online");
156  if (logic == nullptr) {
157  MSPhaseDefinition* phase = new MSPhaseDefinition(DELTA_T, state, -1);
158  std::vector<MSPhaseDefinition*> phases;
159  phases.push_back(phase);
160  logic = new MSSimpleTrafficLightLogic(tlc, myCurrentProgram->getID(), "online", TLTYPE_STATIC, phases, 0,
162  std::map<std::string, std::string>());
163  addLogic("online", logic, true, true);
165  } else {
166  MSPhaseDefinition nphase(DELTA_T, state, -1);
167  *(dynamic_cast<MSSimpleTrafficLightLogic*>(logic)->getPhases()[0]) = nphase;
168  switchTo(tlc, "online");
169  }
170 }
171 
172 
173 void
175  mySwitchActions.push_back(c);
176 }
177 
178 
179 std::vector<MSTrafficLightLogic*>
181  std::vector<MSTrafficLightLogic*> ret;
182  std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
183  for (i = myVariants.begin(); i != myVariants.end(); ++i) {
184  ret.push_back((*i).second);
185  }
186  return ret;
187 }
188 
189 
190 bool
192  return tl == myCurrentProgram;
193 }
194 
195 
198  return myCurrentProgram;
199 }
200 
201 
202 void
204  // set the found wished sub-program as this tls' current one
205  myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
208 }
209 
210 
211 void
213  for (std::vector<OnSwitchAction*>::const_iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
214  (*i)->execute();
215  }
216 }
217 
218 
219 void
221  for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
222  (*i).second->addLink(link, lane, pos);
223  }
224 }
225 
226 void
228  for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
229  (*i).second->ignoreLinkIndex(pos);
230  }
231 }
232 
233 
234 /* -------------------------------------------------------------------------
235  * method definitions for the Switching Procedures
236  * ----------------------------------------------------------------------- */
237 /* -------------------------------------------------------------------------
238  * method definitions for WAUTSwitchProcedure
239  * ----------------------------------------------------------------------- */
240 int
242  std::string val = logic.getParameter("GSP", "");
243  if (val.length() == 0) {
244  return 0;
245  }
246  return StringUtils::toInt(val);
247 }
248 
249 
250 bool
252  SUMOTime gspTime = TIME2STEPS(getGSPValue(logic)) % logic.getDefaultCycleTime();
253  SUMOTime programTime = logic.getOffsetFromIndex(logic.getCurrentPhaseIndex())
254  + (logic.getCurrentPhaseDef().duration - (logic.getNextSwitchTime() - currentTime));
255  return gspTime == programTime;
256 }
257 
258 
259 SUMOTime
261  int stepOfMyPos = logic.getIndexFromOffset(toTime);
262  SUMOTime startOfPhase = logic.getOffsetFromIndex(stepOfMyPos);
263  assert(toTime >= startOfPhase);
264  return toTime - startOfPhase;
265 }
266 
267 
268 void
270  int stepTo = logic.getIndexFromOffset(toTime);
271  SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
272  const MSPhaseDefinition& phase = logic.getPhase(stepTo);
273  SUMOTime leftDuration = phase.duration - diff;
274  logic.changeStepAndDuration(myControl, simStep, stepTo, leftDuration);
275 }
276 
277 
278 
279 /* -------------------------------------------------------------------------
280  * method definitions for WAUTSwitchProcedure_JustSwitch
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  return true;
294 }
295 
296 
297 
298 /* -------------------------------------------------------------------------
299  * method definitions for WAUTSwitchProcedure_GSP
300  * ----------------------------------------------------------------------- */
302  MSTLLogicControl& control, WAUT& waut,
303  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
304  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
305 
306 
308 
309 
310 bool
312  // switch to the next programm if the GSP is reached
313  if (isPosAtGSP(step, *myFrom)) {
314  // adapt program's state
315  if (mySwitchSynchron) {
316  adaptLogic(step);
317  } else {
319  }
320  // switch to destination program
321  return true;
322  }
323  // do not switch, yet
324  return false;
325 }
326 
327 
328 void
330  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
331  int stepTo = myTo->getIndexFromOffset(gspTo);
332  SUMOTime cycleTimeTo = myTo->getDefaultCycleTime();
333  if (gspTo == cycleTimeTo) {
334  gspTo = 0;
335  }
336 
338  currentPosTo += (myTo->getCurrentPhaseDef().duration - (myTo->getNextSwitchTime() - step));
339  SUMOTime diff = getDiffToStartOfPhase(*myTo, gspTo);
340 
341  SUMOTime deltaToStretch = 0;
342  if (gspTo >= currentPosTo) {
343  deltaToStretch = (gspTo - currentPosTo);
344  } else {
345  deltaToStretch = (cycleTimeTo - currentPosTo + gspTo);
346  }
347  const SUMOTime newdur = myTo->getPhase(stepTo).duration - diff + deltaToStretch;
348  myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
349 }
350 
351 
352 
353 /* -------------------------------------------------------------------------
354  * method definitions for WAUTSwitchProcedure_Stretch
355  * ----------------------------------------------------------------------- */
357  MSTLLogicControl& control, WAUT& waut,
358  MSTrafficLightLogic* from, MSTrafficLightLogic* to, bool synchron)
359  : MSTLLogicControl::WAUTSwitchProcedure(control, waut, from, to, synchron) {}
360 
361 
363 
364 
365 bool
367  // switch to the next programm if the GSP is reached
368  if (isPosAtGSP(step, *myFrom)) {
369  // adapt program's state
370  if (mySwitchSynchron) {
371  adaptLogic(step);
372  } else {
374  }
375  // switch to destination program
376  return true;
377  }
378  // do not switch, yet
379  return false;
380 }
381 
382 
383 void
385  SUMOTime gspTo = TIME2STEPS(getGSPValue(*myTo));
386  SUMOTime cycleTime = myTo->getDefaultCycleTime();
387  // the position, where the logic has to be after synchronisation
388  SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
389  // calculate the difference, that has to be equalized
390  SUMOTime deltaToCut = 0;
391  if (posAfterSyn < gspTo) {
392  deltaToCut = posAfterSyn + cycleTime - gspTo;
393  } else {
394  deltaToCut = posAfterSyn - gspTo;
395  }
396  // test, wheter cutting of the Signalplan is possible
397  SUMOTime deltaPossible = 0;
398  int areasNo = getStretchAreaNo(myTo);
399  for (int i = 0; i < areasNo; i++) {
401  assert(def.end >= def.begin);
402  deltaPossible += TIME2STEPS(def.end - def.begin);
403  }
404  int stretchUmlaufAnz = (int) StringUtils::toDouble(myTo->getParameter("StretchUmlaufAnz", ""));
405  deltaPossible = stretchUmlaufAnz * deltaPossible;
406  if ((deltaPossible > deltaToCut) && (deltaToCut < (cycleTime / 2))) {
407  cutLogic(step, gspTo, deltaToCut);
408  } else {
409  SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
410  stretchLogic(step, gspTo, deltaToStretch);
411  }
412 }
413 
414 
415 void
417  int actStep = myTo->getIndexFromOffset(startPos);
418  // switches to startPos and cuts this phase, if there is a "Bereich"
419  int areasNo = getStretchAreaNo(myTo);
420  SUMOTime toCut = 0;
421  for (int i = 0; i < areasNo; i++) {
423  const SUMOTime begin = TIME2STEPS(def.begin);
424  const SUMOTime end = TIME2STEPS(def.end);
425  int stepOfBegin = myTo->getIndexFromOffset(begin);
426  if (stepOfBegin == actStep) {
427  if (begin < startPos) {
428  toCut = end - startPos;
429  } else {
430  toCut = end - begin;
431  }
432  toCut = MIN2(allCutTime, toCut);
433  allCutTime = allCutTime - toCut;
434  }
435  }
436  SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
437  SUMOTime newDur = remainingDur - toCut;
438  myTo->changeStepAndDuration(myControl, step, actStep, newDur);
439 
440  // changes the duration of all other phases
441  int currStep = (actStep + 1) % (int)myTo->getPhases().size();
442  while (allCutTime > 0) {
443  for (int i = currStep; i < (int) myTo->getPhases().size(); i++) {
444  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
445  SUMOTime durOfPhase = myTo->getPhase(i).duration;
446  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
447  for (int i = 0; i < areasNo; i++) {
449  SUMOTime begin = TIME2STEPS(def.begin);
450  SUMOTime end = TIME2STEPS(def.end);
451  if ((beginOfPhase <= begin) && (endOfPhase >= end)) {
452  SUMOTime maxCutOfPhase = MIN2(end - begin, allCutTime);
453  allCutTime = allCutTime - maxCutOfPhase;
454  durOfPhase = durOfPhase - maxCutOfPhase;
455  }
456  }
457  myTo->addOverridingDuration(durOfPhase);
458  }
459  currStep = 0;
460  }
461 }
462 
463 void
465  int currStep = myTo->getIndexFromOffset(startPos);
466  SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
467  SUMOTime remainingStretchTime = allStretchTime;
468  SUMOTime StretchTimeOfPhase = 0;
469  int stretchUmlaufAnz = (int) StringUtils::toDouble(myTo->getParameter("StretchUmlaufAnz", ""));
470  double facSum = 0;
471  int areasNo = getStretchAreaNo(myTo);
472  for (int x = 0; x < areasNo; x++) {
474  facSum += def.fac;
475  }
476  facSum *= stretchUmlaufAnz;
477 
478  //switch to startPos and stretch this phase, if there is a end of "bereich" between startpos and end of phase
479  SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
480  for (int x = 0; x < areasNo; x++) {
482  SUMOTime end = TIME2STEPS(def.end);
483  SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
484  if (end <= endOfPhase && end >= startPos) {
485  double fac = def.fac;
486  double actualfac = fac / facSum;
487  facSum = facSum - fac;
488  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
489  remainingStretchTime = allStretchTime - StretchTimeOfPhase;
490  }
491  }
492  if (facSum == 0) {
493  WRITE_WARNING("The computed factor sum in WAUT '" + myWAUT.id + "' at time '" + toString(STEPS2TIME(step)) + "' equals zero;\n assuming an error in WAUT definition.");
494  return;
495  }
496  durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
497  myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
498 
499  currStep = (currStep + 1) % (int)myTo->getPhases().size();
500  // stretch all other phases, if there is a "bereich"
501  while (remainingStretchTime > 0) {
502  for (int i = currStep; i < (int)myTo->getPhases().size() && remainingStretchTime > 0; i++) {
503  durOfPhase = myTo->getPhase(i).duration;
504  SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
505  SUMOTime endOfPhase = beginOfPhase + durOfPhase;
506  for (int j = 0; j < areasNo && remainingStretchTime > 0; j++) {
508  SUMOTime end = TIME2STEPS(def.end);
509  double fac = def.fac;
510  if ((beginOfPhase <= end) && (endOfPhase >= end)) {
511  double actualfac = fac / facSum;
512  StretchTimeOfPhase = TIME2STEPS(int(STEPS2TIME(remainingStretchTime) * actualfac + 0.5));
513  facSum -= fac;
514  durOfPhase += StretchTimeOfPhase;
515  remainingStretchTime -= StretchTimeOfPhase;
516  }
517  }
518  myTo->addOverridingDuration(durOfPhase);
519  }
520  currStep = 0;
521  }
522 }
523 
524 int
526  int no = 0;
527  while (from->getParameter("B" + toString(no + 1) + ".begin", "") != "") {
528  no++;
529  }
530  return no;
531 }
532 
533 
536  StretchBereichDef def;
537  def.begin = StringUtils::toDouble(from->getParameter("B" + toString(index) + ".begin", ""));
538  def.end = StringUtils::toDouble(from->getParameter("B" + toString(index) + ".end", ""));
539  def.fac = StringUtils::toDouble(from->getParameter("B" + toString(index) + ".factor", ""));
540  return def;
541 }
542 
543 
544 
545 /* -------------------------------------------------------------------------
546  * method definitions for MSTLLogicControl
547  * ----------------------------------------------------------------------- */
549  : myNetWasLoaded(false) {}
550 
551 
553  // delete tls
554  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
555  delete(*i).second;
556  }
557  // delete WAUTs
558  for (std::map<std::string, WAUT*>::const_iterator i = myWAUTs.begin(); i != myWAUTs.end(); ++i) {
559  delete(*i).second;
560  }
561 }
562 
563 
564 void
566  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
567  (*i).second->getActive()->setTrafficLightSignals(t);
568  }
569 }
570 
571 
572 std::vector<MSTrafficLightLogic*>
574  std::vector<MSTrafficLightLogic*> ret;
575  std::map<std::string, TLSLogicVariants*>::const_iterator i;
576  for (i = myLogics.begin(); i != myLogics.end(); ++i) {
577  std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
578  copy(s.begin(), s.end(), back_inserter(ret));
579  }
580  return ret;
581 }
582 
584 MSTLLogicControl::get(const std::string& id) const {
585  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
586  if (i == myLogics.end()) {
587  throw InvalidArgument("The tls '" + id + "' is not known.");
588  }
589  return *(*i).second;
590 }
591 
592 
594 MSTLLogicControl::get(const std::string& id, const std::string& programID) const {
595  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
596  if (i == myLogics.end()) {
597  return nullptr;
598  }
599  return (*i).second->getLogic(programID);
600 }
601 
602 
603 std::vector<std::string>
605  std::vector<std::string> ret;
606  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
607  ret.push_back((*i).first);
608  }
609  return ret;
610 }
611 
612 
613 bool
614 MSTLLogicControl::add(const std::string& id, const std::string& programID,
615  MSTrafficLightLogic* logic, bool newDefault) {
616  if (myLogics.find(id) == myLogics.end()) {
617  myLogics[id] = new TLSLogicVariants();
618  }
619  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
620  TLSLogicVariants* tlmap = (*i).second;
621  return tlmap->addLogic(programID, logic, myNetWasLoaded, newDefault);
622 }
623 
624 
625 bool
626 MSTLLogicControl::knows(const std::string& id) const {
627  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
628  if (i == myLogics.end()) {
629  return false;
630  }
631  return true;
632 }
633 
634 
635 bool
637  bool hadErrors = false;
638  for (std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
639  hadErrors |= !(*i).second->checkOriginalTLS();
640  (*i).second->saveInitialStates();
641  }
642  myNetWasLoaded = true;
643  return !hadErrors;
644 }
645 
646 
647 bool
649  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(tl->getID());
650  if (i == myLogics.end()) {
651  return false;
652  }
653  return (*i).second->isActive(tl);
654 }
655 
656 
658 MSTLLogicControl::getActive(const std::string& id) const {
659  std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.find(id);
660  if (i == myLogics.end()) {
661  return nullptr;
662  }
663  return (*i).second->getActive();
664 }
665 
666 
667 void
668 MSTLLogicControl::switchTo(const std::string& id, const std::string& programID) {
669  // try to get the tls program definitions
670  std::map<std::string, TLSLogicVariants*>::iterator i = myLogics.find(id);
671  // handle problems
672  if (i == myLogics.end()) {
673  throw ProcessError("Could not switch tls '" + id + "' to program '" + programID + "': No such tls exists.");
674  }
675  (*i).second->switchTo(*this, programID);
676 }
677 
678 
679 void
680 MSTLLogicControl::addWAUT(SUMOTime refTime, const std::string& id,
681  const std::string& startProg) {
682  // check whether the waut was already defined
683  if (myWAUTs.find(id) != myWAUTs.end()) {
684  // report an error if so
685  throw InvalidArgument("Waut '" + id + "' was already defined.");
686  }
687  WAUT* w = new WAUT;
688  w->id = id;
689  w->refTime = refTime;
690  w->startProg = startProg;
691  myWAUTs[id] = w;
692 }
693 
694 
695 void
696 MSTLLogicControl::addWAUTSwitch(const std::string& wautid,
697  SUMOTime when, const std::string& to) {
698  // try to get the waut
699  if (myWAUTs.find(wautid) == myWAUTs.end()) {
700  // report an error if the waut is not known
701  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
702  }
703  // build and save the waut switch definition
704  WAUTSwitch s;
705  s.to = to;
706  s.when = (myWAUTs[wautid]->refTime + when) % 86400000;
707  myWAUTs[wautid]->switches.push_back(s);
708 }
709 
710 
711 void
712 MSTLLogicControl::addWAUTJunction(const std::string& wautid,
713  const std::string& tls,
714  const std::string& proc,
715  bool synchron) {
716  // try to get the waut
717  if (myWAUTs.find(wautid) == myWAUTs.end()) {
718  // report an error if the waut is not known
719  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
720  }
721  // try to get the tls to switch
722  if (myLogics.find(tls) == myLogics.end()) {
723  // report an error if the tls is not known
724  throw InvalidArgument("TLS '" + tls + "' to switch in WAUT '" + wautid + "' was not yet defined.");
725  }
726  WAUTJunction j;
727  j.junction = tls;
728  j.procedure = proc;
729  j.synchron = synchron;
730  myWAUTs[wautid]->junctions.push_back(j);
731 
732  std::string initProg = myWAUTs[wautid]->startProg;
733  std::vector<WAUTSwitch>::const_iterator first = myWAUTs[wautid]->switches.end();
734  SUMOTime minExecTime = -1;
735  for (std::vector<WAUTSwitch>::const_iterator i = myWAUTs[wautid]->switches.begin(); i != myWAUTs[wautid]->switches.end(); ++i) {
736  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
737  minExecTime = (*i).when;
738  first = i;
739  }
740  if (first != myWAUTs[wautid]->switches.begin()) {
741  initProg = (*(first - 1)).to;
742  }
743  }
744  // activate the first one
745  switchTo(tls, initProg);
746 }
747 
748 
749 void
750 MSTLLogicControl::closeWAUT(const std::string& wautid) {
751  // try to get the waut
752  if (myWAUTs.find(wautid) == myWAUTs.end()) {
753  // report an error if the waut is not known
754  throw InvalidArgument("Waut '" + wautid + "' was not yet defined.");
755  }
756  WAUT* w = myWAUTs.find(wautid)->second;
757  std::string initProg = myWAUTs[wautid]->startProg;
758  // get the switch to be performed as first
759  std::vector<WAUTSwitch>::const_iterator first = w->switches.end();
760  SUMOTime minExecTime = -1;
761  for (std::vector<WAUTSwitch>::const_iterator i = w->switches.begin(); i != w->switches.end(); ++i) {
762  if ((*i).when > MSNet::getInstance()->getCurrentTimeStep() && (minExecTime == -1 || (*i).when < minExecTime)) {
763  minExecTime = (*i).when;
764  first = i;
765  }
766  }
767  // activate the first one
768  if (first != w->switches.end()) {
769  std::vector<WAUTSwitch>::const_iterator mbegin = w->switches.begin();
771  new SwitchInitCommand(*this, wautid, (int)distance(mbegin, first)),
772  (*first).when);
773  }
774  /*
775  // set the current program to all junctions
776  for(std::vector<WAUTJunction>::const_iterator i=w->junctions.begin(); i!=w->junctions.end(); ++i) {
777  switchTo((*i).junction, initProg);
778  }
779  */
780 }
781 
782 
783 SUMOTime
785  const std::string& wautid = cmd.getWAUTID();
786  int& index = cmd.getIndex();
787  WAUTSwitch s = myWAUTs[wautid]->switches[index];
788  for (std::vector<WAUTJunction>::iterator i = myWAUTs[wautid]->junctions.begin(); i != myWAUTs[wautid]->junctions.end(); ++i) {
789  // get the current program and the one to instantiate
790  TLSLogicVariants* vars = myLogics.find((*i).junction)->second;
791  MSTrafficLightLogic* from = vars->getActive();
792  MSTrafficLightLogic* to = vars->getLogicInstantiatingOff(*this, s.to);
793  WAUTSwitchProcedure* proc = nullptr;
794  if ((*i).procedure == "GSP") {
795  proc = new WAUTSwitchProcedure_GSP(*this, *myWAUTs[wautid], from, to, (*i).synchron);
796  } else if ((*i).procedure == "Stretch") {
797  proc = new WAUTSwitchProcedure_Stretch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
798  } else {
799  proc = new WAUTSwitchProcedure_JustSwitch(*this, *myWAUTs[wautid], from, to, (*i).synchron);
800  }
801 
803  p.junction = (*i).junction;
804  p.proc = proc;
805  p.from = from;
806  p.to = to;
807 
808  myCurrentlySwitched.push_back(p);
809  }
810  index++;
811  if (index == static_cast<int>(myWAUTs[wautid]->switches.size())) {
812  return 0;
813  }
814  return myWAUTs[wautid]->switches[index].when - MSNet::getInstance()->getCurrentTimeStep();
815 }
816 
817 
818 void
820  for (std::vector<WAUTSwitchProcess>::iterator i = myCurrentlySwitched.begin(); i != myCurrentlySwitched.end();) {
821  const WAUTSwitchProcess& proc = *i;
822  if (proc.proc->trySwitch(step)) {
823  delete proc.proc;
824  switchTo((*i).to->getID(), (*i).to->getProgramID());
825  i = myCurrentlySwitched.erase(i);
826  } else {
827  ++i;
828  }
829  }
830 }
831 
832 
833 std::pair<SUMOTime, MSPhaseDefinition>
834 MSTLLogicControl::getPhaseDef(const std::string& tlid) const {
835  MSTrafficLightLogic* tl = getActive(tlid);
836  return std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), tl->getCurrentPhaseDef());
837 }
838 
839 
840 void
842  for (std::map<std::string, TLSLogicVariants*>::const_iterator i = myLogics.begin(); i != myLogics.end(); ++i) {
843  (*i).second->addLogic("off", new MSOffTrafficLightLogic(*this, (*i).first), true, true);
844  }
845 }
846 
847 /****************************************************************************/
848 
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;
long long int SUMOTime
Definition: SUMOTime.h:36
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)
virtual void createTLWrapper(MSTrafficLightLogic *)
creates a wrapper for the given logic (see GUINet)
Definition: MSNet.h:488
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:165
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:35
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:78
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
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:241
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:49
WAUTSwitchProcedure * proc
The used procedure.
void adaptLogic(SUMOTime step)
Stretches the destination program&#39;s phase to which the tls was switched.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
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:409
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:58
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:263
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:70
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.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter...
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:247
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)
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
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.
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:78
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.