49 #ifdef CHECK_MEMORY_LEAKS
51 #endif // CHECK_MEMORY_LEAKS
61 : myCurrentProgram(0) {
66 std::map<std::string, MSTrafficLightLogic*>::const_iterator j;
67 for (std::map<std::string, MSTrafficLightLogic*>::iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
70 for (std::vector<OnSwitchAction*>::iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
78 bool hadErrors =
false;
79 for (std::map<std::string, MSTrafficLightLogic*>::const_iterator j = myVariants.begin(); j != myVariants.end(); ++j) {
81 unsigned int linkNo = (
unsigned int)(*j).second->getLinks().size();
82 bool hadProgramErrors =
false;
83 for (MSTrafficLightLogic::Phases::const_iterator i = phases.begin(); i != phases.end(); ++i) {
84 if ((*i)->getState().length() < linkNo) {
85 hadProgramErrors =
true;
88 if (hadProgramErrors) {
89 WRITE_ERROR(
"Mismatching phase size in tls '" + (*j).second->getID() +
"', program '" + (*j).first +
"'.");
99 myOriginalLinkStates = myCurrentProgram->collectLinkStates();
106 if (myVariants.find(programID) != myVariants.end()) {
112 if (myCurrentProgram == 0) {
113 throw ProcessError(
"No initial signal plan loaded for tls '" + logic->
getID() +
"'.");
117 throw ProcessError(
"Mismatching phase size in tls '" + logic->
getID() +
"', program '" + programID +
"'.");
121 if (myVariants.size() == 0 || isNewDefault) {
122 myCurrentProgram = logic;
125 myVariants[programID] = logic;
126 if (myVariants.size() == 1 || isNewDefault) {
128 executeOnSwitchActions();
136 if (myVariants.find(programID) == myVariants.end()) {
139 return myVariants.find(programID)->second;
145 const std::string& programID) {
146 if (myVariants.find(programID) == myVariants.end()) {
147 if (programID ==
"off") {
151 throw ProcessError(
"Could not build an off-state for tls '" + myCurrentProgram->getID() +
"'.");
155 throw ProcessError(
"Can not switch tls '" + myCurrentProgram->getID() +
"' to program '" + programID +
"';\n The program is not known.");
158 return getLogic(programID);
164 mySwitchActions.push_back(c);
168 std::vector<MSTrafficLightLogic*>
170 std::vector<MSTrafficLightLogic*> ret;
171 std::map<std::string, MSTrafficLightLogic*>::const_iterator i;
172 for (i = myVariants.begin(); i != myVariants.end(); ++i) {
173 ret.push_back((*i).second);
181 return tl == myCurrentProgram;
187 return myCurrentProgram;
194 myCurrentProgram = getLogicInstantiatingOff(tlc, programID);
200 for (std::vector<OnSwitchAction*>::const_iterator i = mySwitchActions.begin(); i != mySwitchActions.end(); ++i) {
208 for (std::map<std::string, MSTrafficLightLogic*>::iterator i = myVariants.begin(); i != myVariants.end(); ++i) {
209 (*i).second->addLink(link, lane, pos);
224 if (val.length() == 0) {
236 return gspTime == programTime;
244 assert(toTime >= startOfPhase);
245 return toTime - startOfPhase;
252 SUMOTime diff = getDiffToStartOfPhase(logic, toTime);
294 if (isPosAtGSP(step, *myFrom)) {
296 if (mySwitchSynchron) {
299 switchToPos(step, *myTo,
TIME2STEPS(getGSPValue(*myTo)));
312 unsigned int stepTo = myTo->getIndexFromOffset(gspTo);
313 SUMOTime cycleTimeTo = myTo->getDefaultCycleTime();
314 if (gspTo == cycleTimeTo) {
318 SUMOTime currentPosTo = myTo->getOffsetFromIndex(myTo->getCurrentPhaseIndex());
319 currentPosTo += (myTo->getCurrentPhaseDef().duration - (myTo->getNextSwitchTime() - step));
320 SUMOTime diff = getDiffToStartOfPhase(*myTo, gspTo);
323 if (gspTo >= currentPosTo) {
324 deltaToStretch = (gspTo - currentPosTo);
326 deltaToStretch = (cycleTimeTo - currentPosTo + gspTo);
328 unsigned int newdur = (
unsigned int) myTo->getPhase(stepTo).duration - diff + deltaToStretch;
329 myTo->changeStepAndDuration(myControl, step, stepTo, newdur);
349 if (isPosAtGSP(step, *myFrom)) {
351 if (mySwitchSynchron) {
354 switchToPos(step, *myTo,
TIME2STEPS(getGSPValue(*myTo)));
367 SUMOTime cycleTime = myTo->getDefaultCycleTime();
369 SUMOTime posAfterSyn = myTo->getPhaseIndexAtTime(step);
372 if (posAfterSyn < gspTo) {
373 deltaToCut = posAfterSyn + cycleTime - gspTo;
375 deltaToCut = posAfterSyn - gspTo;
379 int areasNo = getStretchAreaNo(myTo);
380 for (
int i = 0; i < areasNo; i++) {
386 deltaPossible = stretchUmlaufAnz * deltaPossible;
387 if ((deltaPossible > deltaToCut) && (deltaToCut < (cycleTime / 2))) {
388 cutLogic(step, gspTo, deltaToCut);
390 SUMOTime deltaToStretch = (cycleTime - deltaToCut) % cycleTime;
391 stretchLogic(step, gspTo, deltaToStretch);
398 unsigned int actStep = myTo->getIndexFromOffset(startPos);
400 int areasNo = getStretchAreaNo(myTo);
402 for (
int i = 0; i < areasNo; i++) {
406 size_t stepOfBegin = myTo->getIndexFromOffset(begin);
407 if (stepOfBegin == actStep) {
408 if (begin < startPos) {
409 toCut = end - startPos;
413 toCut =
MIN2(allCutTime, toCut);
414 allCutTime = allCutTime - toCut;
417 SUMOTime remainingDur = myTo->getPhase(actStep).duration - getDiffToStartOfPhase(*myTo, startPos);
418 SUMOTime newDur = remainingDur - toCut;
419 myTo->changeStepAndDuration(myControl, step, actStep, newDur);
422 int currStep = (actStep + 1) % (
int)myTo->getPhases().size();
423 while (allCutTime > 0) {
424 for (
int i = currStep; i < (
int) myTo->getPhases().size(); i++) {
425 SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
426 SUMOTime durOfPhase = myTo->getPhase(i).duration;
427 SUMOTime endOfPhase = beginOfPhase + durOfPhase;
428 for (
int i = 0; i < areasNo; i++) {
432 if ((beginOfPhase <= begin) && (endOfPhase >= end)) {
434 allCutTime = allCutTime - maxCutOfPhase;
435 durOfPhase = durOfPhase - maxCutOfPhase;
438 myTo->addOverridingDuration(durOfPhase);
446 unsigned int currStep = myTo->getIndexFromOffset(startPos);
447 SUMOTime durOfPhase = myTo->getPhase(currStep).duration;
448 SUMOTime remainingStretchTime = allStretchTime;
450 unsigned int stretchUmlaufAnz = (
unsigned int)
TplConvert::_2SUMOReal(myTo->getParameter(
"StretchUmlaufAnz",
"").c_str());
452 int areasNo = getStretchAreaNo(myTo);
453 for (
int x = 0; x < areasNo; x++) {
457 facSum *= stretchUmlaufAnz;
460 SUMOTime diffToStart = getDiffToStartOfPhase(*myTo, startPos);
461 for (
int x = 0; x < areasNo; x++) {
464 SUMOTime endOfPhase = (startPos + durOfPhase - diffToStart);
465 if (end <= endOfPhase && end >= startPos) {
468 facSum = facSum - fac;
470 remainingStretchTime = allStretchTime - StretchTimeOfPhase;
474 WRITE_WARNING(
"The computed factor sum in WAUT '" + myWAUT.id +
"' at time '" +
toString(
STEPS2TIME(step)) +
"' equals zero;\n assuming an error in WAUT definition.");
477 durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase;
478 myTo->changeStepAndDuration(myControl, step, currStep, durOfPhase);
480 currStep = (currStep + 1) % (
int)myTo->getPhases().size();
482 while (remainingStretchTime > 0) {
483 for (
unsigned int i = currStep; i < myTo->getPhases().size() && remainingStretchTime > 0; i++) {
484 durOfPhase = myTo->getPhase(i).duration;
485 SUMOTime beginOfPhase = myTo->getOffsetFromIndex(i);
486 SUMOTime endOfPhase = beginOfPhase + durOfPhase;
487 for (
int j = 0; j < areasNo && remainingStretchTime > 0; j++) {
491 if ((beginOfPhase <= end) && (endOfPhase >= end)) {
495 durOfPhase += StretchTimeOfPhase;
496 remainingStretchTime -= StretchTimeOfPhase;
499 myTo->addOverridingDuration(durOfPhase);
535 for (std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
539 for (std::map<std::string, WAUT*>::const_iterator i =
myWAUTs.begin(); i !=
myWAUTs.end(); ++i) {
547 for (std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
548 (*i).second->getActive()->setTrafficLightSignals(t);
553 std::vector<MSTrafficLightLogic*>
555 std::vector<MSTrafficLightLogic*> ret;
556 std::map<std::string, TLSLogicVariants*>::const_iterator i;
558 std::vector<MSTrafficLightLogic*> s = (*i).second->getAllLogics();
559 copy(s.begin(), s.end(), back_inserter(ret));
566 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
576 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
580 return (*i).second->getLogic(programID);
584 std::vector<std::string>
586 std::vector<std::string> ret;
587 for (std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
588 ret.push_back((*i).first);
600 std::map<std::string, TLSLogicVariants*>::iterator i =
myLogics.find(
id);
608 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
618 bool hadErrors =
false;
619 for (std::map<std::string, TLSLogicVariants*>::iterator i =
myLogics.begin(); i !=
myLogics.end(); ++i) {
620 hadErrors |= !(*i).second->checkOriginalTLS();
621 (*i).second->saveInitialStates();
630 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(tl->
getID());
634 return (*i).second->isActive(tl);
640 std::map<std::string, TLSLogicVariants*>::const_iterator i =
myLogics.find(
id);
644 return (*i).second->getActive();
651 std::map<std::string, TLSLogicVariants*>::iterator i =
myLogics.find(
id);
654 throw ProcessError(
"Could not switch tls '" +
id +
"' to program '" + programID +
"': No such tls exists.");
656 (*i).second->switchTo(*
this, programID);
662 const std::string& startProg) {
678 SUMOTime when,
const std::string& to) {
687 s.
when = (
myWAUTs[wautid]->refTime + when) % 86400000;
688 myWAUTs[wautid]->switches.push_back(s);
694 const std::string& tls,
695 const std::string& proc,
705 throw InvalidArgument(
"TLS '" + tls +
"' to switch in WAUT '" + wautid +
"' was not yet defined.");
711 myWAUTs[wautid]->junctions.push_back(j);
713 std::string initProg =
myWAUTs[wautid]->startProg;
714 std::vector<WAUTSwitch>::const_iterator first =
myWAUTs[wautid]->switches.end();
716 for (std::vector<WAUTSwitch>::const_iterator i =
myWAUTs[wautid]->switches.begin(); i !=
myWAUTs[wautid]->switches.end(); ++i) {
718 minExecTime = (*i).when;
721 if (first !=
myWAUTs[wautid]->switches.begin()) {
722 initProg = (*(first - 1)).to;
738 std::string initProg =
myWAUTs[wautid]->startProg;
740 std::vector<WAUTSwitch>::const_iterator first = w->
switches.end();
742 for (std::vector<WAUTSwitch>::const_iterator i = w->
switches.begin(); i != w->
switches.end(); ++i) {
744 minExecTime = (*i).when;
750 std::vector<WAUTSwitch>::const_iterator mbegin = w->
switches.begin();
766 const std::string& wautid = cmd.
getWAUTID();
767 unsigned int& index = cmd.
getIndex();
769 for (std::vector<WAUTJunction>::iterator i =
myWAUTs[wautid]->junctions.begin(); i !=
myWAUTs[wautid]->junctions.end(); ++i) {
775 if ((*i).procedure ==
"GSP") {
777 }
else if ((*i).procedure ==
"Stretch") {
792 if (index == static_cast<unsigned int>(
myWAUTs[wautid]->switches.size())) {
805 switchTo((*i).to->getID(), (*i).to->getProgramID());
814 std::pair<SUMOTime, MSPhaseDefinition>
bool checkOriginalTLS() const
Verifies traffic lights loaded from the network.
TLSLogicVariants()
Constructor.
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
bool add(const std::string &id, const std::string &programID, MSTrafficLightLogic *logic, bool newDefault=true)
Adds a tls program to the container.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
~WAUTSwitchProcedure_GSP()
Destructor.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
void cutLogic(SUMOTime step, SUMOTime startPos, SUMOTime allCutTime)
Cuts the logic to synchronize.
const std::string & getState() const
Returns the state within this phase.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
SUMOReal end
The end of a stretch/cut area (time, in s)
std::map< std::string, TLSLogicVariants * > myLogics
A map from ids to the corresponding variants.
virtual unsigned int getCurrentPhaseIndex() const =0
Returns the current index within the program.
unsigned int getGSPValue(const MSTrafficLightLogic &logic) const
Returns the GSP-value.
Storage for all programs of a single tls.
Base class for things to execute if a tls switches to a new phase.
~TLSLogicVariants()
Destructor.
void switchTo(const std::string &id, const std::string &programID)
Switches the named (id) tls to the named (programID) program.
static SUMOReal _2SUMOReal(const E *const data)
~WAUTSwitchProcedure_Stretch()
Destructor.
~WAUTSwitchProcedure_JustSwitch()
Destructor.
~MSTLLogicControl()
Destructor.
WAUTSwitchProcedure_GSP(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
virtual const MSPhaseDefinition & getPhase(unsigned int givenstep) const =0
Returns the definition of the phase from the given position within the plan.
void setTrafficLightSignals(SUMOTime t) const
Lets all running (current) tls programs apply their current signal states to links they control...
A definition of a stretch - Bereich.
MSTrafficLightLogic * getActive(const std::string &id) const
Returns the active program of a named tls.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
std::string junction
The id of the junction to switch.
std::string procedure
The procedure to switch the junction with.
WAUTSwitchProcedure_Stretch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
std::vector< std::string > getAllTLIds() const
virtual SUMOTime getOffsetFromIndex(unsigned int index) const =0
Returns the position (start of a phase during a cycle) from of a given step.
MSTLLogicControl()
Constructor.
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
void closeWAUT(const std::string &wautid)
Closes loading of a WAUT.
MSTrafficLightLogic * getLogic(const std::string &programID) const
SUMOTime initWautSwitch(SwitchInitCommand &cmd)
Initialises switching a WAUT.
void addLink(MSLink *link, MSLane *lane, unsigned int pos)
bool myNetWasLoaded
Information whether the net was completely loaded.
Storage for a junction assigned to a WAUT.
#define WRITE_WARNING(msg)
A traffic lights logic which represents a tls in an off-mode.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, unsigned int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
A class that stores and controls tls and switching of their programs.
std::vector< MSTrafficLightLogic * > getAllLogics() const
const std::string & getID() const
Returns the id.
SUMOTime duration
The duration of the phase.
bool addLogic(const std::string &programID, MSTrafficLightLogic *logic, bool netWasLoaded, bool isNewDefault=true)
Adds a logic (program)
void addSwitchCommand(OnSwitchAction *c)
MSTrafficLightLogic * getLogicInstantiatingOff(MSTLLogicControl &tlc, const std::string &programID)
bool isActive(const MSTrafficLightLogic *tl) const
virtual unsigned int getIndexFromOffset(SUMOTime offset) const =0
Returns the step (the phasenumber) of a given position of the cycle.
MSTrafficLightLogic * getActive() const
std::pair< SUMOTime, MSPhaseDefinition > getPhaseDef(const std::string &tlid) const
return the complete phase definition for a named traffic lights logic
WAUTSwitchProcedure * proc
The used procedure.
void adaptLogic(SUMOTime step)
Stretches the destination program's phase to which the tls was switched.
SUMOReal fac
The weight factor of a stretch/cut area.
This class simply switches to the next program.
bool synchron
Information whether this junction shall be switched synchron.
void adaptLogic(SUMOTime step)
Determines the destination program's changes and applies them.
virtual bool trySwitch(SUMOTime step)=0
Determines whether a switch is possible.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
MSTrafficLightLogic * to
The program to switch the tls to.
This class switches using the Stretch algorithm.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
void check2Switch(SUMOTime step)
Checks whether any WAUT is trying to switch a tls into another program.
int getStretchAreaNo(MSTrafficLightLogic *from) const
Returns the number of given Stretch-areas for the given program.
SUMOTime when
The time the WAUT shall switch the TLS.
void stretchLogic(SUMOTime step, SUMOTime startPos, SUMOTime allStretchTime)
Stretches the logic to synchronize.
SUMOReal begin
The begin of a stretch/cut area (time, in s)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
bool knows(const std::string &id) const
Returns the information whether the named tls is stored.
bool trySwitch(SUMOTime step)
Determines whether a switch is possible.
std::string startProg
The name of the start program.
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
const std::string & getWAUTID() const
Returns the WAUT-id.
WAUTSwitchProcedure_JustSwitch(MSTLLogicControl &control, WAUT &waut, MSTrafficLightLogic *from, MSTrafficLightLogic *to, bool synchron)
Constructor.
void addWAUTJunction(const std::string &wautid, const std::string &tls, const std::string &proc, bool synchron)
Adds a tls to the list of tls to be switched by the named WAUT.
std::vector< WAUTSwitchProcess > myCurrentlySwitched
A list of currently running switching procedures.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
An initialised switch process.
void switchTo(MSTLLogicControl &tlc, const std::string &programID)
StretchBereichDef getStretchBereichDef(MSTrafficLightLogic *from, int index) const
Returns the numbered Stretch-area for the given program.
static int _2int(const E *const data)
std::vector< WAUTSwitch > switches
The list of switches to be done by the WAUT.
unsigned int & getIndex()
Returns a reference to the index.
void switchToPos(SUMOTime simStep, MSTrafficLightLogic &logic, SUMOTime toTime)
switches the given logic directly to the given position
This event-class is used to initialise a WAUT switch at a certain time.
void addWAUT(SUMOTime refTime, const std::string &id, const std::string &startProg)
Adds a WAUT definition.
This class switches using the GSP algorithm.
SUMOTime getDiffToStartOfPhase(MSTrafficLightLogic &logic, SUMOTime toTime)
Returns the difference between a given time and the start of the phase.
SUMOTime refTime
The reference time (offset to the switch times)
This is the abstract base class for switching from one tls program to another.
void executeOnSwitchActions() const
std::string id
The id of the WAUT.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
std::map< std::string, WAUT * > myWAUTs
A map of ids to corresponding WAUTs.
bool isPosAtGSP(SUMOTime currentTime, const MSTrafficLightLogic &logic)
Checks, whether the position of a signal programm is at the GSP ("GuenstigerUmschaltPunkt") ...
The parent class for traffic light logics.
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.
std::vector< MSTrafficLightLogic * > getAllLogics() const
Returns a vector which contains all logics.
MSTrafficLightLogic * from
The current program of the tls.
MSEventControl & getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
The definition of a single phase of a tls logic.
Representation of a lane in the micro simulation.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
std::string junction
The junction name.