44#define TRACI_PROGRAM "online"
53 myCurrentProgram(nullptr),
54 myDefaultProgram(nullptr) {
59 std::map<std::string, MSTrafficLightLogic*>::const_iterator j;
60 for (
const auto& var : myVariants) {
71 bool hadErrors =
false;
72 for (std::map<std::string, MSTrafficLightLogic*>::const_iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
74 int linkNo = (int)(*j).second->getLinks().size();
75 bool hadProgramErrors =
false;
76 for (MSTrafficLightLogic::Phases::const_iterator i = phases.begin(); i != phases.end(); ++i) {
77 if ((
int)(*i)->getState().length() < linkNo) {
78 hadProgramErrors =
true;
81 if (hadProgramErrors) {
82 WRITE_ERRORF(
TL(
"Mismatching phase size in tls '%', program '%'."), (*j).second->getID(), (*j).first);
92 myOriginalLinkStates = myCurrentProgram->collectLinkStates();
98 for (
const auto& item : myVariants) {
99 item.second->saveState(out);
107 if (myVariants.find(programID) != myVariants.end()) {
114 if (myCurrentProgram ==
nullptr) {
115 const std::string
id = logic->
getID();
117 throw ProcessError(
TLF(
"No initial signal plan loaded for tls '%'.",
id));
121 const std::string
id = logic->
getID();
123 throw ProcessError(
TLF(
"Mismatching phase size in tls '%', program '%'.",
id, programID));
127 if (myVariants.size() == 0 || isNewDefault) {
128 if (myCurrentProgram !=
nullptr) {
129 myCurrentProgram->deactivateProgram();
131 myCurrentProgram = logic;
133 if (myVariants.size() == 0) {
134 myDefaultProgram = logic;
138 myVariants[programID] = logic;
139 if (myVariants.size() == 1 || isNewDefault) {
141 executeOnSwitchActions();
149 if (myVariants.find(programID) == myVariants.end()) {
152 return myVariants.find(programID)->second;
158 if (myVariants.find(programID) == myVariants.end()) {
159 if (programID ==
"off") {
162 if (!addLogic(
"off", tlLogic,
true,
true)) {
164 throw ProcessError(
TLF(
"Could not build an off-state for tls '%'.", myCurrentProgram->getID()));
168 throw ProcessError(
TLF(
"Can not switch tls '%' to program '%';\n The program is not known.", myCurrentProgram->getID(), programID));
171 return getLogic(programID);
177 const std::string& state) {
180 if (logic ==
nullptr) {
183 std::vector<MSPhaseDefinition*> phases;
184 phases.push_back(phase);
201 mySwitchActions.push_back(c);
205std::vector<MSTrafficLightLogic*>
207 std::vector<MSTrafficLightLogic*> ret;
208 std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
209 for (i = myVariants.begin(); i != myVariants.end(); ++i) {
210 ret.push_back((*i).second);
218 return tl == myCurrentProgram;
224 return myCurrentProgram;
229 return myDefaultProgram;
237 myCurrentProgram->deactivateProgram();
238 myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
239 myCurrentProgram->activateProgram();
241 if (state != myCurrentProgram->getCurrentPhaseDef().getState()) {
242 myCurrentProgram->resetLastSwitch(
SIMSTEP);
244 executeOnSwitchActions();
251 if (myCurrentProgram != tl) {
252 myCurrentProgram->deactivateProgram();
253 myCurrentProgram = tl;
260 for (std::vector<OnSwitchAction*>::const_iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
268 for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
269 (*i).second->
addLink(link, lane, pos);
275 for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
276 (*i).second->ignoreLinkIndex(pos);
290 if (isPosAtGSP(step, *myFrom)) {
292 if (mySwitchSynchron) {
295 switchToPos(step, *myTo, getGSPTime(*myTo));
315 return gspTime == programTime;
323 assert(toTime >= startOfPhase);
324 return toTime - startOfPhase;
331 SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
372 const SUMOTime gspTo = getGSPTime(*myTo) % myTo->getDefaultCycleTime();
373 const SUMOTime currentPosTo = myTo->getOffsetFromIndex(myTo->getCurrentPhaseIndex()) + myTo->getSpentDuration(step);
374 SUMOTime deltaToStretch = gspTo - currentPosTo;
375 if (deltaToStretch < 0) {
376 deltaToStretch += myTo->getDefaultCycleTime();
378 const int stepTo = myTo->getIndexFromOffset(gspTo);
379 const SUMOTime newdur = myTo->getPhase(stepTo).duration - getDiffToStartOfPhase(*myTo, gspTo) + deltaToStretch;
380 myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
410 SUMOTime cycleTime = myTo->getDefaultCycleTime();
412 SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
415 if (posAfterSyn < gspTo) {
416 deltaToCut = posAfterSyn + cycleTime - gspTo;
418 deltaToCut = posAfterSyn - gspTo;
423 assert(def.end >= def.begin);
424 deltaPossible += def.end - def.begin;
427 deltaPossible = stretchUmlaufAnz * deltaPossible;
428 if ((deltaPossible > deltaToCut) && (deltaToCut < (cycleTime / 2))) {
429 cutLogic(step, gspTo, deltaToCut);
431 SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
432 stretchLogic(step, gspTo, deltaToStretch);
439 int actStep = myTo->getIndexFromOffset(startPos);
443 int stepOfBegin = myTo->getIndexFromOffset(def.begin);
444 if (stepOfBegin == actStep) {
445 if (def.begin < startPos) {
446 toCut = def.end - startPos;
448 toCut = def.end - def.begin;
450 toCut =
MIN2(allCutTime, toCut);
451 allCutTime = allCutTime - toCut;
454 SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
455 SUMOTime newDur = remainingDur - toCut;
456 myTo->changeStepAndDuration(myControl, step, actStep, newDur);
459 int currStep = (actStep + 1) % (
int)myTo->getPhases().size();
460 while (allCutTime > 0) {
461 for (
int i = currStep; i < (int) myTo->getPhases().size(); i++) {
462 SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
463 SUMOTime durOfPhase = myTo->getPhase(i).duration;
464 SUMOTime endOfPhase = beginOfPhase + durOfPhase;
466 if ((beginOfPhase <= def.begin) && (endOfPhase >= def.end)) {
467 SUMOTime maxCutOfPhase =
MIN2(def.end - def.begin, allCutTime);
468 allCutTime = allCutTime - maxCutOfPhase;
469 durOfPhase = durOfPhase - maxCutOfPhase;
472 myTo->addOverridingDuration(durOfPhase);
480 int currStep = myTo->getIndexFromOffset(startPos);
481 SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
482 SUMOTime remainingStretchTime = allStretchTime;
489 facSum *= stretchUmlaufAnz;
492 SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
494 SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
495 if (def.end <= endOfPhase && def.end >= startPos) {
496 double actualfac = def.fac / facSum;
497 facSum = facSum - def.fac;
499 remainingStretchTime = allStretchTime - StretchTimeOfPhase;
506 durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
507 myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
509 currStep = (currStep + 1) % (
int)myTo->getPhases().size();
511 while (remainingStretchTime > 0) {
512 for (
int i = currStep; i < (int)myTo->getPhases().size() && remainingStretchTime > 0; i++) {
513 durOfPhase = myTo->getPhase(i).duration;
514 SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
515 SUMOTime endOfPhase = beginOfPhase + durOfPhase;
517 if ((beginOfPhase <= def.end) && (endOfPhase >= def.end)) {
518 double actualfac = def.fac / facSum;
521 durOfPhase += StretchTimeOfPhase;
522 remainingStretchTime -= StretchTimeOfPhase;
525 myTo->addOverridingDuration(durOfPhase);
541 for (std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
545 for (std::map<std::string, WAUT*>::const_iterator i =
myWAUTs.begin(); i !=
myWAUTs.end(); ++i) {
553 for (std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
554 (*i).second->getActive()->setTrafficLightSignals(t);
559std::vector<MSTrafficLightLogic*>
561 std::vector<MSTrafficLightLogic*> ret;
562 std::map<std::string, TLSLogicVariants*>::const_iterator i;
564 std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
565 copy(s.begin(), s.end(), back_inserter(ret));
572 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
582 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
586 return (*i).second->
getLogic(programID);
590std::vector<std::string>
592 std::vector<std::string> ret;
593 for (std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
594 ret.push_back((*i).first);
603 std::map<std::string, TLSLogicVariants*>::iterator it =
myLogics.find(
id);
622 bool hadErrors =
false;
624 hadErrors |= !it.second->checkOriginalTLS();
625 it.second->saveInitialStates();
634 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(tl->
getID());
638 return (*i).second->isActive(tl);
644 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
648 return (*i).second->getActive();
655 std::map<std::string, TLSLogicVariants*>::iterator i =
myLogics.find(
id);
658 throw ProcessError(
TLF(
"Could not switch tls '%' to program '%': No such tls exists.",
id, programID));
660 (*i).second->switchTo(*
this, programID);
666 const std::string& startProg,
SUMOTime period) {
683 SUMOTime when,
const std::string& to) {
697 myWAUTs[wautid]->switches.push_back(s);
703 const std::string& tls,
704 const std::string& proc,
714 throw InvalidArgument(
TLF(
"TLS '%' to switch in WAUT '%' was not yet defined.", tls, wautid));
720 myWAUTs[wautid]->junctions.push_back(j);
722 std::string initProg =
myWAUTs[wautid]->startProg;
723 std::vector<WAUTSwitch>::const_iterator first =
myWAUTs[wautid]->switches.end();
725 for (std::vector<WAUTSwitch>::const_iterator i =
myWAUTs[wautid]->switches.begin(); i !=
myWAUTs[wautid]->switches.end(); ++i) {
727 minExecTime = (*i).when;
730 if (first !=
myWAUTs[wautid]->switches.begin()) {
731 initProg = (*(first - 1)).to;
753 if (s.when >=
SIMSTEP && s.when < minExecTime) {
754 minExecTime = s.when;
760 if (firstIndex >= 0) {
775 const std::string& wautid = cmd.
getWAUTID();
779 for (std::vector<WAUTJunction>::iterator i =
myWAUTs[wautid]->junctions.begin(); i !=
myWAUTs[wautid]->junctions.end(); ++i) {
785 if ((*i).procedure ==
"GSP") {
787 }
else if ((*i).procedure ==
"Stretch") {
802 if (index == (
int)waut->
switches.size()) {
834std::pair<SUMOTime, MSPhaseDefinition>
843 for (
const auto& logic :
myLogics) {
857 for (
const auto& logic :
myLogics) {
858 logic.second->saveState(out);
868 for (
const auto& variants :
myLogics) {
869 for (
auto& logic : variants.second->getAllLogics()) {
876 const SUMOTime cycleTime = logic->getDefaultCycleTime();
877 auto& phases = logic->getPhases();
878 SUMOTime offset = logic->getOffset();
880 offset = (time + cycleTime - (offset % cycleTime)) % cycleTime;
882 offset = (time + ((-offset) % cycleTime)) % cycleTime;
885 while (offset >= phases[step]->duration) {
886 offset -= phases[step]->duration;
889 logic->loadState(*
this, time, step, offset, logic->isActive());
#define WRITE_WARNINGF(...)
#define WRITE_ERRORF(...)
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static void saveState(OutputDevice &out)
Save driveway occupancy into the given stream.
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Representation of a lane in the micro simulation.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
virtual void createTLWrapper(MSTrafficLightLogic *)
creates a wrapper for the given logic (see GUINet)
A traffic lights logic which represents a tls in an off-mode.
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
SUMOTime duration
The duration of the phase.
SUMOTime earliestEnd
The minimum time within the cycle for switching (for coordinated actuation)
static void saveState(OutputDevice &out)
Saves the current constraint states into the given stream.
static void clearState()
Clear all constraint states before quick-loading state.
A fixed traffic light logic.
Base class for things to execute if a tls switches to a new phase.
This event-class is used to initialise a WAUT switch at a certain time.
const std::string & getWAUTID() const
Returns the WAUT-id.
int & getIndex()
Returns a reference to the index.
Storage for all programs of a single tls.
void addLink(MSLink *link, MSLane *lane, int pos)
void switchTo(MSTLLogicControl &tlc, const std::string &programID)
void addSwitchCommand(OnSwitchAction *c)
void ignoreLinkIndex(int pos)
void setStateInstantiatingOnline(MSTLLogicControl &tlc, const std::string &state)
bool checkOriginalTLS() const
Verifies traffic lights loaded from the network.
std::vector< MSTrafficLightLogic * > getAllLogics() const
void saveState(OutputDevice &out)
MSTrafficLightLogic * getLogic(const std::string &programID) const
TLSLogicVariants()
Constructor.
void executeOnSwitchActions() const
bool addLogic(const std::string &programID, MSTrafficLightLogic *logic, bool netWasLoaded, bool isNewDefault=true)
Adds a logic (program). In case of an error the logic gets deleted.
void switchToLoaded(MSTrafficLightLogic *tl)
set current program upon loading saved state
~TLSLogicVariants()
Destructor.
MSTrafficLightLogic * getActive() const
MSTrafficLightLogic * getDefault() const
return the default program (that last used program except TRACI_PROGRAM)
MSTrafficLightLogic * getLogicInstantiatingOff(MSTLLogicControl &tlc, const std::string &programID)
bool isActive(const MSTrafficLightLogic *tl) const
This class switches using the GSP algorithm.
~WAUTSwitchProcedure_GSP()
Destructor.
WAUTSwitchProcedure_GSP(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
void adaptLogic(SUMOTime step)
Stretches the destination program's phase to which the tls was switched.
This class simply switches to the next program.
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
~WAUTSwitchProcedure_JustSwitch()
Destructor.
WAUTSwitchProcedure_JustSwitch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
This class switches using the Stretch algorithm.
~WAUTSwitchProcedure_Stretch()
Destructor.
void adaptLogic(SUMOTime step)
Determines the destination program's changes and applies them.
std::vector< StretchRange > myStretchRanges
the given Stretch-areas for the "to" program, this is 0-based indexed, while the input is 1-based
WAUTSwitchProcedure_Stretch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
void cutLogic(SUMOTime step, SUMOTime startPos, SUMOTime allCutTime)
Cuts the logic to synchronize.
void stretchLogic(SUMOTime step, SUMOTime startPos, SUMOTime allStretchTime)
Stretches the logic to synchronize.
This is the abstract base class for switching from one tls program to another.
virtual bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
MSTrafficLightLogic * myTo
The program to switch the tls to.
bool isPosAtGSP(SUMOTime currentTime, const MSTrafficLightLogic &logic)
Checks, whether the position of a signal programm is at the GSP ("Good Switching Point")
SUMOTime getGSPTime(const MSTrafficLightLogic &logic) const
Returns the GSP-value.
SUMOTime getDiffToStartOfPhase(MSTrafficLightLogic &logic, SUMOTime toTime)
Returns the difference between a given time and the start of the phase.
void switchToPos(SUMOTime simStep, MSTrafficLightLogic &logic, SUMOTime toTime)
switches the given logic directly to the given position
A class that stores and controls tls and switching of their programs.
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.
void clearState(SUMOTime time, bool quickReload=false)
Clear all tls states before quick-loading state.
std::vector< MSTrafficLightLogic * > getAllLogics() const
Returns a vector which contains all logics.
std::vector< WAUTSwitchProcess > myCurrentlySwitched
A list of currently running switching procedures.
std::pair< SUMOTime, MSPhaseDefinition > getPhaseDef(const std::string &tlid) const
return the complete phase definition for a named traffic lights logic
std::map< std::string, TLSLogicVariants * > myLogics
A map from ids to the corresponding variants.
void addWAUT(SUMOTime refTime, const std::string &id, const std::string &startProg, SUMOTime period)
Adds a WAUT definition.
std::vector< std::string > getAllTLIds() const
void switchTo(const std::string &id, const std::string &programID)
Switches the named (id) tls to the named (programID) program.
MSTrafficLightLogic * getActive(const std::string &id) const
Returns the active program of a named tls.
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
void setTrafficLightSignals(SUMOTime t) const
Lets all running (current) tls programs apply their current signal states to links they control.
bool knows(const std::string &id) const
Returns the information whether the named tls is stored.
void saveState(OutputDevice &out)
Saves the current tls states into the given stream.
bool myNetWasLoaded
Information whether the net was completely loaded.
void switchOffAll()
switch all logic variants to 'off'
void addWAUTSwitch(const std::string &wautid, SUMOTime when, const std::string &to)
Adds a WAUT switch step to a previously built WAUT.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
MSTLLogicControl()
Constructor.
SUMOTime initWautSwitch(SwitchInitCommand &cmd)
Initialises switching a WAUT.
~MSTLLogicControl()
Destructor.
void check2Switch(SUMOTime step)
Checks whether any WAUT is trying to switch a tls into another program.
std::map< std::string, WAUT * > myWAUTs
A map of ids to corresponding WAUTs.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
bool add(const std::string &id, const std::string &programID, MSTrafficLightLogic *logic, bool newDefault=true)
Adds a tls program to the container.
void closeWAUT(const std::string &wautid)
Closes loading of a WAUT.
The parent class for traffic light logics.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
virtual int getCurrentPhaseIndex() const =0
Returns the current index within the program.
virtual SUMOTime getOffsetFromIndex(int index) const =0
Returns the position (start of a phase during a cycle) from of a given step.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
virtual const MSPhaseDefinition & getPhase(int givenstep) const =0
Returns the definition of the phase from the given position within the plan.
const std::string & getProgramID() const
Returns this tl-logic's id.
virtual int getIndexFromOffset(SUMOTime offset) const =0
Returns the step (the phasenumber) of a given position of the cycle.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
virtual void activateProgram()
called when switching programs
SUMOTime getSpentDuration(SUMOTime simStep=-1) const
Returns the duration spent in the current phase.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
const std::string & getID() const
Returns the id.
Static storage of an output device and its base (abstract) implementation.
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
std::map< std::string, std::string > Map
parameters map
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
std::string startProg
The name of the start program.
std::vector< WAUTSwitch > switches
The list of switches to be done by the WAUT.
SUMOTime period
The period with which to repeat switches.
std::string id
The id of the WAUT.
SUMOTime refTime
The reference time (offset to the switch times)
Storage for a junction assigned to a WAUT.
std::string procedure
The procedure to switch the junction with.
bool synchron
Information whether this junction shall be switched synchron.
std::string junction
The junction name.
Storage for a WAUTs switch point.
SUMOTime when
The time the WAUT shall switch the TLS.
std::string to
The program name the WAUT shall switch the TLS to.
A definition of a stretch - Bereich.
double fac
The weight factor of a stretch/cut area.
SUMOTime end
The end of a stretch/cut area.
SUMOTime begin
The begin of a stretch/cut area.
An initialised switch process.
MSTrafficLightLogic * to
The program to switch the tls to.
std::string junction
The id of the junction to switch.
MSTrafficLightLogic * from
The current program of the tls.
WAUTSwitchProcedure * proc
The used procedure.