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 <cassert>
36 #include <utility>
37 #include <vector>
38 #include <bitset>
41 #include <microsim/MSNet.h>
42 #include "MSTrafficLightLogic.h"
44 #include <microsim/MSLane.h>
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
57  const std::string& id, const std::string& programID,
58  const Phases& phases,
59  unsigned int step, SUMOTime delay, const std::map<std::string, std::string>& parameter)
60  : MSSimpleTrafficLightLogic(tlcontrol, id, programID, phases, step, delay),
61  myContinue(false) {
62  myMaxGap = SUMOReal(3.1);
63  if (parameter.find("max-gap") != parameter.end()) {
64  myMaxGap = TplConvert::_2SUMOReal(parameter.find("max-gap")->second.c_str());
65  }
66  myPassingTime = SUMOReal(1.9);
67  if (parameter.find("passing-time") != parameter.end()) {
68  myPassingTime = TplConvert::_2SUMOReal(parameter.find("passing-time")->second.c_str());
69  }
70  myDetectorGap = SUMOReal(3.0);
71  if (parameter.find("detector-gap") != parameter.end()) {
72  myDetectorGap = TplConvert::_2SUMOReal(parameter.find("detector-gap")->second.c_str());
73  }
74 }
75 
76 
77 void
79  SUMOReal det_offset = TplConvert::_2SUMOReal(myParameter.find("detector_offset")->second.c_str());
80  // change values for setting the loops and lanestate-detectors, here
81  //SUMOTime inductLoopInterval = 1; //
82  LaneVectorVector::const_iterator i2;
83  LaneVector::const_iterator i;
84  // build the induct loops
85  for (i2 = myLanes.begin(); i2 != myLanes.end(); ++i2) {
86  const LaneVector& lanes = *i2;
87  for (i = lanes.begin(); i != lanes.end(); i++) {
88  MSLane* lane = (*i);
89  SUMOReal length = lane->getLength();
90  SUMOReal speed = lane->getSpeedLimit();
91  SUMOReal inductLoopPosition = myDetectorGap * speed;
92  // check whether the lane is long enough
93  SUMOReal ilpos = length - inductLoopPosition;
94  if (ilpos < 0) {
95  ilpos = 0;
96  }
97  // Build the induct loop and set it into the container
98  std::string id = "TLS" + myID + "_" + myProgramID + "_InductLoopOn_" + lane->getID();
99  if (myInductLoops.find(lane) == myInductLoops.end()) {
100  myInductLoops[lane] = static_cast<MSInductLoop*>(nb.createInductLoop(id, lane, ilpos, false));
101  }
102  }
103  // build the lane state-detectors
104  for (i = lanes.begin(); i != lanes.end(); i++) {
105  MSLane* lane = (*i);
106  SUMOReal length = lane->getLength();
107  // check whether the position is o.k. (not longer than the lane)
108  SUMOReal lslen = det_offset;
109  if (lslen > length) {
110  lslen = length;
111  }
112  }
113  }
114 }
115 
116 
118  for (InductLoopMap::iterator i = myInductLoops.begin(); i != myInductLoops.end(); ++i) {
119  delete(*i).second;
120  }
121 }
122 
123 
124 // ------------ Switching and setting current rows
125 SUMOTime
127  // checks if the actual phase should be continued
128  gapControl();
129  if (myContinue) {
130  return duration();
131  }
132  // increment the index to the current phase
133  myStep++;
134  assert(myStep <= myPhases.size());
135  if (myStep == myPhases.size()) {
136  myStep = 0;
137  }
138  //stores the time the phase started
140  // set the next event
141  return duration();
142 }
143 
144 
145 // ------------ "actuated" algorithm methods
146 SUMOTime
148  if (myContinue) {
149  return 1;
150  }
151  assert(myPhases.size() > myStep);
152  if (!getCurrentPhaseDef().isGreenPhase()) {
153  return getCurrentPhaseDef().duration;
154  }
155  // define the duration depending from the number of waiting vehicles of the actual phase
156  int newduration = (int) getCurrentPhaseDef().minDuration;
157  const std::string& state = getCurrentPhaseDef().getState();
158  for (unsigned int i = 0; i < (unsigned int) state.size(); i++) {
159  if (state[i] == LINKSTATE_TL_GREEN_MAJOR || state[i] == LINKSTATE_TL_GREEN_MINOR) {
160  const std::vector<MSLane*>& lanes = getLanesAt(i);
161  if (lanes.empty()) {
162  break;
163  }
164  for (LaneVector::const_iterator j = lanes.begin(); j != lanes.end(); j++) {
165  InductLoopMap::const_iterator k = myInductLoops.find(*j);
166  SUMOReal waiting = (SUMOReal)(*k).second->getCurrentPassedNumber();
167  SUMOReal tmpdur = myPassingTime * waiting;
168  if (tmpdur > newduration) {
169  // here we cut the decimal places, because we have to return an integer
170  newduration = (int) tmpdur;
171  }
172  if (newduration > (int) getCurrentPhaseDef().maxDuration) {
174  }
175  }
176  }
177  }
178  return newduration;
179 }
180 
181 
182 void
184  //intergreen times should not be lenghtend
185  assert(myPhases.size() > myStep);
186  if (!getCurrentPhaseDef().isGreenPhase()) {
187  myContinue = false;
188  return;
189  }
190 
191  // Checks, if the maxDuration is kept. No phase should longer send than maxDuration.
192  SUMOTime actDuration = MSNet::getInstance()->getCurrentTimeStep() - myPhases[myStep]->myLastSwitch;
193  if (actDuration >= getCurrentPhaseDef().maxDuration) {
194  myContinue = false;
195  return;
196  }
197 
198  // now the gapcontrol starts
199  const std::string& state = getCurrentPhaseDef().getState();
200  for (unsigned int i = 0; i < (unsigned int) state.size(); i++) {
201  if (state[i] == LINKSTATE_TL_GREEN_MAJOR || state[i] == LINKSTATE_TL_GREEN_MINOR) {
202  const std::vector<MSLane*>& lanes = getLanesAt(i);
203  if (lanes.empty()) {
204  break;
205  }
206  for (LaneVector::const_iterator j = lanes.begin(); j != lanes.end(); j++) {
207  if (myInductLoops.find(*j) == myInductLoops.end()) {
208  continue;
209  }
210  SUMOReal actualGap =
211  myInductLoops.find(*j)->second->getTimestepsSinceLastDetection();
212  if (actualGap < myMaxGap) {
213  myContinue = true;
214  return;
215  }
216  }
217  }
218  }
219  myContinue = false;
220 }
221 
222 
223 
224 /****************************************************************************/
225