SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSActuatedTrafficLightLogic.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // An actuated (adaptive) traffic light logic
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
14 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <utility>
36 #include <vector>
37 #include <bitset>
40 #include <microsim/MSNet.h>
41 #include "MSTrafficLightLogic.h"
43 #include <microsim/MSLane.h>
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
56  const std::string& id, const std::string& programID,
57  const Phases& phases,
58  unsigned int step, SUMOTime delay, const std::map<std::string, std::string> &parameter)
59  : MSSimpleTrafficLightLogic(tlcontrol, id, programID, phases, step, delay),
60  myContinue(false) {
61  myMaxGap = SUMOReal(3.1);
62  if (parameter.find("max-gap") != parameter.end()) {
63  myMaxGap = TplConvert<char>::_2SUMOReal(parameter.find("max-gap")->second.c_str());
64  }
65  myPassingTime = SUMOReal(1.9);
66  if (parameter.find("passing-time") != parameter.end()) {
67  myPassingTime = TplConvert<char>::_2SUMOReal(parameter.find("passing-time")->second.c_str());
68  }
69  myDetectorGap = SUMOReal(3.0);
70  if (parameter.find("detector-gap") != parameter.end()) {
71  myDetectorGap = TplConvert<char>::_2SUMOReal(parameter.find("detector-gap")->second.c_str());
72  }
73 }
74 
75 
76 void
78  SUMOReal det_offset = TplConvert<char>::_2SUMOReal(myParameter.find("detector_offset")->second.c_str());
79  // change values for setting the loops and lanestate-detectors, here
80  //SUMOTime inductLoopInterval = 1; //
81  LaneVectorVector::const_iterator i2;
82  LaneVector::const_iterator i;
83  // build the induct loops
84  for (i2 = myLanes.begin(); i2 != myLanes.end(); ++i2) {
85  const LaneVector& lanes = *i2;
86  for (i = lanes.begin(); i != lanes.end(); i++) {
87  MSLane* lane = (*i);
88  SUMOReal length = lane->getLength();
89  SUMOReal speed = lane->getMaxSpeed();
90  SUMOReal inductLoopPosition = myDetectorGap * speed;
91  // check whether the lane is long enough
92  SUMOReal ilpos = length - inductLoopPosition;
93  if (ilpos < 0) {
94  ilpos = 0;
95  }
96  // Build the induct loop and set it into the container
97  std::string id = "TLS" + myID + "_" + myProgramID + "_InductLoopOn_" + lane->getID();
98  if (myInductLoops.find(lane) == myInductLoops.end()) {
99  myInductLoops[lane] = static_cast<MSInductLoop*>(nb.createInductLoop(id, lane, ilpos, false));
100  }
101  }
102  // build the lane state-detectors
103  for (i = lanes.begin(); i != lanes.end(); i++) {
104  MSLane* lane = (*i);
105  SUMOReal length = lane->getLength();
106  // check whether the position is o.k. (not longer than the lane)
107  SUMOReal lslen = det_offset;
108  if (lslen > length) {
109  lslen = length;
110  }
111  }
112  }
113 }
114 
115 
117  for (InductLoopMap::iterator i = myInductLoops.begin(); i != myInductLoops.end(); ++i) {
118  delete(*i).second;
119  }
120 }
121 
122 
123 // ------------ Switching and setting current rows
124 SUMOTime
126  // checks if the actual phase should be continued
127  gapControl();
128  if (myContinue) {
129  return duration();
130  }
131  // increment the index to the current phase
132  myStep++;
133  assert(myStep <= myPhases.size());
134  if (myStep == myPhases.size()) {
135  myStep = 0;
136  }
137  //stores the time the phase started
139  // set the next event
140  return duration();
141 }
142 
143 
144 // ------------ "actuated" algorithm methods
145 SUMOTime
147  if (myContinue) {
148  return 1;
149  }
150  assert(myPhases.size() > myStep);
151  if (!getCurrentPhaseDef().isGreenPhase()) {
152  return getCurrentPhaseDef().duration;
153  }
154  // define the duration depending from the number of waiting vehicles of the actual phase
155  int newduration = (int) getCurrentPhaseDef().minDuration;
156  const std::string& state = getCurrentPhaseDef().getState();
157  for (unsigned int i = 0; i < (unsigned int) state.size(); i++) {
158  if (state[i] == LINKSTATE_TL_GREEN_MAJOR || state[i] == LINKSTATE_TL_GREEN_MINOR) {
159  const std::vector<MSLane*> &lanes = getLanesAt(i);
160  if (lanes.empty()) {
161  break;
162  }
163  for (LaneVector::const_iterator j = lanes.begin(); j != lanes.end(); j++) {
164  InductLoopMap::const_iterator k = myInductLoops.find(*j);
165  SUMOReal waiting = (SUMOReal)(*k).second->getCurrentPassedNumber();
166  SUMOReal tmpdur = myPassingTime * waiting;
167  if (tmpdur > newduration) {
168  // here we cut the decimal places, because we have to return an integer
169  newduration = (int) tmpdur;
170  }
171  if (newduration > (int) getCurrentPhaseDef().maxDuration) {
173  }
174  }
175  }
176  }
177  return newduration;
178 }
179 
180 
181 void
183  //intergreen times should not be lenghtend
184  assert(myPhases.size() > myStep);
185  if (!getCurrentPhaseDef().isGreenPhase()) {
186  myContinue = false;
187  return;
188  }
189 
190  // Checks, if the maxDuration is kept. No phase should longer send than maxDuration.
191  SUMOTime actDuration = MSNet::getInstance()->getCurrentTimeStep() - myPhases[myStep]->myLastSwitch;
192  if (actDuration >= getCurrentPhaseDef().maxDuration) {
193  myContinue = false;
194  return;
195  }
196 
197  // now the gapcontrol starts
198  const std::string& state = getCurrentPhaseDef().getState();
199  for (unsigned int i = 0; i < (unsigned int) state.size(); i++) {
200  if (state[i] == LINKSTATE_TL_GREEN_MAJOR || state[i] == LINKSTATE_TL_GREEN_MINOR) {
201  const std::vector<MSLane*> &lanes = getLanesAt(i);
202  if (lanes.empty()) {
203  break;
204  }
205  for (LaneVector::const_iterator j = lanes.begin(); j != lanes.end(); j++) {
206  if (myInductLoops.find(*j) == myInductLoops.end()) {
207  continue;
208  }
209  SUMOReal actualGap =
210  myInductLoops.find(*j)->second->getTimestepsSinceLastDetection();
211  if (actualGap < myMaxGap) {
212  myContinue = true;
213  return;
214  }
215  }
216  }
217  }
218  myContinue = false;
219 }
220 
221 
222 
223 /****************************************************************************/
224