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