44 #define DEBUG_COND (getID()=="C")
49 #define DEFAULT_MAX_GAP "3.0"
50 #define DEFAULT_PASSING_TIME "1.9"
51 #define DEFAULT_DETECTOR_GAP "2.0"
52 #define DEFAULT_INACTIVE_THRESHOLD "180"
53 #define DEFAULT_CURRENT_PRIORITY 10
55 #define DEFAULT_LENGTH_WITH_GAP 7.5
62 const std::string&
id,
const std::string& programID,
65 const std::map<std::string, std::string>& parameter,
66 const std::string& basePath) :
68 myLastTrySwitchTime(0) {
89 const int numLinks = (int)
myLinks.size();
112 std::map<const MSLane*, MSInductLoop*> laneInductLoopMap;
113 std::map<MSInductLoop*, const MSLane*> inductLoopLaneMap;
114 double maxDetectorGap = 0;
116 for (
MSLane* lane : lanes) {
121 if (laneInductLoopMap.find(lane) != laneInductLoopMap.end()) {
126 if (minDur == std::numeric_limits<SUMOTime>::max()) {
130 const std::string customID =
getParameter(lane->getID());
131 double length = lane->getLength();
133 double inductLoopPosition;
135 if (customID ==
"") {
136 double speed = lane->getSpeedLimit();
137 inductLoopPosition =
MIN2(
142 ilpos = length - inductLoopPosition;
143 MSLane* placementLane = lane;
144 while (ilpos < 0 && placementLane->getIncomingLanes().size() == 1) {
152 std::string
id =
"TLS" +
myID +
"_" +
myProgramID +
"_InductLoopOn_" + lane->getID();
157 if (loop ==
nullptr) {
158 WRITE_ERROR(
"Unknown inductionLoop '" + customID +
"' given as custom detector for actuated tlLogic '" +
getID() +
"', program '" +
getProgramID() +
".");
162 inductLoopPosition = length - ilpos;
164 laneInductLoopMap[lane] = loop;
165 inductLoopLaneMap[loop] = lane;
167 maxDetectorGap =
MAX2(maxDetectorGap, length - ilpos);
192 std::map<int, std::set<MSInductLoop*> > linkToLoops;
193 std::set<int> actuatedLinks;
195 std::vector<bool> neverMajor(numLinks,
true);
197 const std::string& state = phase->getState();
198 for (
int i = 0; i < numLinks; i++) {
200 neverMajor[i] =
false;
204 std::vector<bool> oneLane(numLinks,
false);
205 std::vector<bool> turnaround(numLinks,
true);
206 for (
int i = 0; i < numLinks; i++) {
209 int numMotorized = 0;
211 if ((l->getPermissions() & motorized) != 0) {
215 if (numMotorized == 1) {
221 if (!link->isTurnaround()) {
222 turnaround[i] =
false;
231 std::set<MSInductLoop*> loops;
232 if (phase->minDuration != phase->maxDuration) {
234 const std::string& state = phase->getState();
236 std::set<int> greenLinks;
238 std::map<MSInductLoop*, std::set<int> > loopLinks;
240 for (
int i = 0; i < numLinks; i++) {
243 && (((neverMajor[i] || turnaround[i])
247 greenLinks.insert(i);
249 actuatedLinks.insert(i);
252 #ifdef DEBUG_DETECTORS
254 std::cout <<
" phase=" << phaseIndex <<
" i=" << i <<
" state=" << state[i] <<
" green=" << greenLinks.count(i) <<
" oneLane=" << oneLane[i]
255 <<
" turn=" << turnaround[i] <<
" loopLanes=";
257 if (laneInductLoopMap.count(lane) != 0) {
258 std::cout << lane->getID() <<
" ";
265 if (laneInductLoopMap.count(lane) != 0) {
266 loopLinks[laneInductLoopMap[lane]].insert(i);
270 for (
auto& item : loopLinks) {
272 const MSLane* loopLane = inductLoopLaneMap[loop];
275 for (
int j : item.second) {
276 if (greenLinks.count(j) == 0) {
278 #ifdef DEBUG_DETECTORS
280 std::cout <<
" phase=" << phaseIndex <<
" check1: loopLane=" << loopLane->
getID() <<
" notGreen=" << j <<
" oneLane[j]=" << oneLane[j] <<
"\n";
289 if (link->isTurnaround()) {
292 const MSLane* next = link->getLane();
293 if (laneInductLoopMap.count(next) != 0) {
295 for (
int j : loopLinks[nextLoop]) {
296 if (greenLinks.count(j) == 0) {
298 #ifdef DEBUG_DETECTORS
299 if (
DEBUG_COND) std::cout <<
" phase=" << phaseIndex <<
" check2: loopLane=" << loopLane->
getID()
300 <<
" nextLane=" << next->
getID() <<
" nextLink=" << j <<
" nextState=" << state[j] <<
"\n";
310 loops.insert(item.first);
311 #ifdef DEBUG_DETECTORS
313 std::cout <<
" phase=" << phaseIndex <<
" usableLoops=" << item.first->getID() <<
" links=" <<
joinToString(item.second,
" ") <<
"\n";
316 for (
int j : item.second) {
317 linkToLoops[j].insert(item.first);
321 if (loops.size() == 0) {
325 #ifdef DEBUG_DETECTORS
327 std::cout <<
" phase=" << phaseIndex <<
" loops=" <<
joinNamedToString(loops,
" ") <<
"\n";
330 std::cout <<
" linkToLoops:\n";
331 for (
auto item : linkToLoops) {
332 std::cout <<
" link=" << item.first <<
" loops=" <<
joinNamedToString(item.second,
" ") <<
"\n";
336 std::vector<InductLoopInfo*> loopInfos;
340 if (loopInfo.loop == loop) {
342 loopInfo.servedPhase[phaseIndex] =
true;
347 #ifdef DEBUG_DETECTORS
349 std::cout <<
"final linkToLoops:\n";
350 for (
auto item : linkToLoops) {
351 std::cout <<
" link=" << item.first <<
" loops=" <<
joinNamedToString(item.second,
" ") <<
"\n";
355 for (
int i : actuatedLinks) {
356 if (linkToLoops[i].size() == 0 &&
myLinks[i].size() > 0
357 && (
myLinks[i].front()->getLaneBefore()->getPermissions() & motorized) != 0) {
366 WRITE_ERROR(
"Invalid link '" + kv.first.substr(11) +
"' given as linkMaxDur parameter for actuated tlLogic '" +
getID() +
"', program '" +
getProgramID() +
".");
376 WRITE_ERROR(
"Invalid link '" + kv.first.substr(11) +
"' given as linkMinDur parameter for actuated tlLogic '" +
getID() +
"', program '" +
getProgramID() +
".");
394 SUMOTime result = std::numeric_limits<SUMOTime>::max();
396 const std::string& state = phase->getState();
397 for (
int i = 0; i < (int)state.size(); i++) {
401 if (phase->minDuration != phase->maxDuration) {
402 result =
MIN2(result, phase->minDuration);
414 for (
int i = 0; i < (int)state.size(); i++) {
417 for (
MSLane* lane : lanes) {
434 loopInfo.loop->setVisible(
true);
443 loopInfo.loop->setVisible(
false);
458 if (state[i] ==
'G' || state[i] ==
'g') {
469 #ifdef DEBUG_PHASE_SELECTION
471 std::cout <<
SIMTIME <<
" p=" <<
myStep <<
" trySwitch dGap=" << detectionGap <<
" multi=" << multiTarget <<
"\n";
474 if (detectionGap < std::numeric_limits<double>::max() && !multiTarget) {
478 const int origStep =
myStep;
490 if (nextStep == (
int)
myPhases.size()) {
494 if (linkMinDur > 0) {
497 return multiTarget ?
TIME2STEPS(1) : linkMinDur;
512 loopInfo->lastGreenTime = now;
531 if (newDuration % 1000 != 0) {
532 const SUMOTime totalDur = newDuration + actDuration;
533 newDuration = (totalDur / 1000 + 1) * 1000 - actDuration;
545 double result = std::numeric_limits<double>::max();
552 if (loopInfo.lastGreenTime < loopInfo.loop->getLastDetectionTime()) {
555 loopInfo.loop->setSpecialColor(
nullptr);
575 result =
MIN2(result, actualGap);
588 int result = cands.front();
596 #ifdef DEBUG_PHASE_SELECTION
599 if (currentPrio > maxPrio) {
601 maxPrio = currentPrio;
604 for (
int step : cands) {
607 #ifdef DEBUG_PHASE_SELECTION
620 if (prio > maxPrio) {
621 result = cands.front();
624 +
"', starvation at e1Detector '" + loopInfo.loop->getID()
625 +
"' which cannot be reached from the default phase " +
toString(
myStep) +
".");
628 #ifdef DEBUG_PHASE_SELECTION
630 std::cout <<
SIMTIME <<
" p=" <<
myStep <<
" loop=" << loopInfo.loop->getID() <<
" prio=" << prio <<
" next=" << result <<
"\n";
644 while (!
myPhases[step]->isGreenPhase()) {
645 if (
myPhases[step]->nextPhases.size() > 0 &&
myPhases[step]->nextPhases.front() >= 0) {
646 if (
myPhases[step]->nextPhases.size() > 1) {
647 WRITE_WARNING(
"At actuated tlLogic '" +
getID() +
"', transition phase " +
toString(step) +
" should not have multiple next phases");
649 step =
myPhases[step]->nextPhases.front();
651 step = (step + 1) %
myPhases.size();
653 if (step == origStep) {
669 #ifdef DEBUG_PHASE_SELECTION
731 const std::string& targetState =
myPhases[target]->getState();
734 targetState[i] ==
'G' || targetState[i] ==
'g')) {
747 const std::string& targetState =
myPhases[target]->getState();
750 && (state[i] ==
'G' || state[i] ==
'g')
751 && !(targetState[i] ==
'G' || targetState[i] ==
'g')) {
765 if (key ==
"detector-gap" || key ==
"passing-time" || key ==
"file" || key ==
"freq" || key ==
"vTypes"
768 throw InvalidArgument(key +
" cannot be changed dynamically for actuated traffic light '" +
getID() +
"'");
769 }
else if (key ==
"max-gap") {
771 }
else if (key ==
"show-detectors") {
773 }
else if (key ==
"inactive-threshold") {
#define DEFAULT_DETECTOR_GAP
#define DEFAULT_PASSING_TIME
#define DEFAULT_LENGTH_WITH_GAP
#define DEFAULT_INACTIVE_THRESHOLD
#define DEFAULT_CURRENT_PRIORITY
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
bool noVehicles(SVCPermissions permissions)
Returns whether an edge with the given permission forbids vehicles.
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
std::string joinNamedToString(const std::set< T *, C > &ns, const T_BETWEEN &between)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static std::string checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessable from the current working directory.
double myDetectorGap
The detector distance in seconds.
double myMaxGap
The maximum gap to check in seconds.
void activateProgram()
called when switching programs
~MSActuatedTrafficLightLogic()
Destructor.
int getTarget(int step)
get the green phase following step
void setParameter(const std::string &key, const std::string &value)
Sets a parameter and updates internal constants.
SUMOTime myLastTrySwitchTime
last time trySwitch was called
int getDetectorPriority(const InductLoopInfo &loopInfo) const
SUMOTime myFreq
The frequency for aggregating detector output.
SUMOTime getMinimumMinDuration(MSLane *lane) const
get the minimum min duration for all stretchable phases that affect the given lane
bool myShowDetectors
Whether the detectors shall be shown in the GUI.
std::vector< SUMOTime > myLinkMaxGreenTimes
maximum consecutive time that the given link may remain green
std::string myVehicleTypes
Whether detector output separates by vType.
double gapControl()
Return the minimum detection gap of all detectors if the current phase should be extended and double:...
void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
std::vector< SUMOTime > myLinkMinGreenTimes
minimum consecutive time that the given link must remain green
SUMOTime trySwitch()
Switches to the next phase.
double myPassingTime
The passing time used in seconds.
SUMOTime getLinkMinDuration(int target) const
the minimum duratin for keeping the current phase due to linkMinDur constraints
MSActuatedTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const MSSimpleTrafficLightLogic::Phases &phases, int step, SUMOTime delay, const std::map< std::string, std::string > ¶meter, const std::string &basePath)
Constructor.
bool canExtendLinkGreen(int target)
whether the target phase is acceptable in light of linkMaxDur constraints
InductLoopMap myInductLoopsForPhase
A map from phase to induction loops to be used for gap control.
void setShowDetectors(bool show)
int getPhasePriority(int step) const
count the number of active detectors for the given step
SUMOTime duration(const double detectionGap) const
Returns the minimum duration of the current phase.
std::vector< InductLoopInfo > myInductLoops
bool maxLinkDurationReached()
whether the current phase cannot be continued due to linkMaxDur constraints
bool hasMajor(const std::string &state, const LaneVector &lanes) const
return whether there is a major link from the given lane in the given phase
std::vector< SUMOTime > myLinkGreenTimes
consecutive time that the given link index has been green
std::string myFile
The output file for generated detectors.
int decideNextPhase()
select am candidate phases based on detector states
SUMOTime myInactiveThreshold
The time threshold to avoid starved phases.
const NamedObjectCont< MSDetectorFileOutput * > & getTypedDetectors(SumoXMLTag type) const
Returns the list of detectors of the given type.
void add(SumoXMLTag type, MSDetectorFileOutput *d, const std::string &device, SUMOTime splInterval, SUMOTime begin=-1)
Adds a detector/output combination into the containers.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
An unextended detector measuring at a fixed position on a fixed lane.
double getPosition() const
Returns the position of the detector on the lane.
virtual void setSpecialColor(const RGBColor *)
allows for special color in the gui version
double getTimeSinceLastDetection() const
Returns the time since the last vehicle left the detector.
SUMOTime getLastDetectionTime() const
return last time a vehicle was on the detector
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
double getLength() const
Returns the lane's length.
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
MSEdge & getEdge() const
Returns the lane's edge.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSDetectorControl & getDetectorControl()
Returns the detector control.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
SUMOTime maxDuration
The maximum duration of the phase.
SUMOTime minDuration
The minimum duration of the phase.
A fixed traffic light logic.
Phases myPhases
The list of phases this logic uses.
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
int myStep
The current step.
A class that stores and controls tls and switching of their programs.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
virtual void deactivateProgram()
const std::string myProgramID
The id of the logic.
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
int myNumLinks
number of controlled links
virtual void activateProgram()
called when switching programs
const LaneVector & getLanesAt(int i) const
Returns the list of lanes that are controlled by the signals at the given position.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
const std::string & getProgramID() const
Returns this tl-logic's id.
Builds detectors for microsim.
virtual MSDetectorFileOutput * createInductLoop(const std::string &id, MSLane *lane, double pos, const std::string &vTypes, bool show=true)
Creates an instance of an e1 detector using the given values.
std::string myID
The name of the object.
const std::string & getID() const
Returns the id.
T get(const std::string &id) const
Retrieves an item.
static OptionsCont & getOptions()
Retrieves the options.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
static const RGBColor GREEN
static const RGBColor RED
named colors
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
std::vector< bool > servedPhase