|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // The basic traffic light logic 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 00020 00021 // =========================================================================== 00022 // included modules 00023 // =========================================================================== 00024 #ifdef _MSC_VER 00025 #include <windows_config.h> 00026 #else 00027 #include <config.h> 00028 #endif 00029 00030 #include <utility> 00031 #include <vector> 00032 #include <bitset> 00033 #include <microsim/MSEventControl.h> 00034 #include <microsim/output/MSInductLoop.h> 00035 #include <microsim/MSLaneState.h> 00036 #include <microsim/MSNet.h> 00037 #include "MSTrafficLightLogic.h" 00038 #include "MSUnboundActuatedTrafficLightLogic.h" 00039 #include <microsim/MSLane.h> 00040 #include <netload/NLDetectorBuilder.h> 00041 00042 #ifdef CHECK_MEMORY_LEAKS 00043 #include <foreign/nvwa/debug_new.h> 00044 #endif // CHECK_MEMORY_LEAKS 00045 00046 00047 // =========================================================================== 00048 // method definitions 00049 // =========================================================================== 00050 MSUnboundActuatedTrafficLightLogic::MSUnboundActuatedTrafficLightLogic( 00051 const std::string& id, 00052 const Phases& phases, 00053 size_t step, size_t delay, 00054 SUMOReal maxGap, SUMOReal passingTime, SUMOReal detectorGap) 00055 : MSSimpleTrafficLightLogic(id, phases, step, delay), 00056 myContinue(false), 00057 myMaxGap(maxGap), myPassingTime(passingTime), myDetectorGap(detectorGap) {} 00058 00059 00060 void 00061 MSUnboundActuatedTrafficLightLogic::init(NLDetectorBuilder& nb, 00062 const std::vector<MSLane*> &lanes, 00063 std::map<std::string, std::vector<std::string> > &laneContinuations, 00064 SUMOReal det_offset) { 00065 // change values for setting the loops and lanestate-detectors, here 00066 SUMOTime inductLoopInterval = 1; // 00067 // as the laneStateDetector shall end at the end of the lane, the position 00068 // is calculated, not given 00069 SUMOTime laneStateDetectorInterval = 1; // 00070 00071 std::vector<MSLane*>::const_iterator i; 00072 // build the induct loops 00073 for (i=lanes.begin(); i!=lanes.end(); i++) { 00074 MSLane* lane = (*i); 00075 SUMOReal length = lane->length(); 00076 SUMOReal speed = lane->maxSpeed(); 00077 SUMOReal inductLoopPosition = myDetectorGap * speed; 00078 // check whether the lane is long enough 00079 SUMOReal ilpos = length - inductLoopPosition; 00080 if (ilpos<0) { 00081 ilpos = 0; 00082 } 00083 // Build the induct loop and set it into the container 00084 std::string id = "TLS" + myId + "_InductLoopOn_" + lane->getID(); 00085 if (myInductLoops.find(lane)==myInductLoops.end()) { 00086 myInductLoops[lane] = 00087 nb.createInductLoop(id, lane, ilpos, inductLoopInterval); 00088 } 00089 } 00090 // build the lane state-detectors 00091 for (i=lanes.begin(); i!=lanes.end(); i++) { 00092 MSLane* lane = (*i); 00093 SUMOReal length = lane->length(); 00094 // check whether the position is o.k. (not longer than the lane) 00095 SUMOReal lslen = det_offset; 00096 if (lslen>length) { 00097 lslen = length; 00098 } 00099 SUMOReal lspos = length - lslen; 00100 // Build the lane state detetcor and set it into the container 00101 std::string id = "TLS" + myId + "_LaneStateOff_" + lane->getID(); 00102 if (myLaneStates.find(lane)==myLaneStates.end()) { 00103 MSLaneState* loop = 00104 new MSLaneState(id, lane, lspos, lslen, 00105 laneStateDetectorInterval); 00106 myLaneStates[lane] = loop; 00107 } 00108 } 00109 } 00110 00111 00112 00113 MSUnboundActuatedTrafficLightLogic::~MSUnboundActuatedTrafficLightLogic() {} 00114 00115 00116 SUMOTime 00117 MSUnboundActuatedTrafficLightLogic::duration() const { 00118 if (myContinue) { 00119 return 1; 00120 } 00121 assert(myPhases.size()>myStep); 00122 if (!isGreenPhase()) { 00123 return currentPhaseDef()->duration; 00124 } 00125 // define the duration depending from the number of waiting vehicles of the actual phase 00126 int newduration = currentPhaseDef()->minDuration; 00127 const std::bitset<64> &isgreen = currentPhaseDef()->getDriveMask(); 00128 for (size_t i=0; i<isgreen.size(); i++) { 00129 if (isgreen.test(i)) { 00130 const std::vector<MSLane*> &lanes = getLanesAt(i); 00131 if (lanes.empty()) { 00132 break; 00133 } 00134 for (LaneVector::const_iterator j=lanes.begin(); j!=lanes.end(); j++) { 00135 LaneStateMap::const_iterator k = myLaneStates.find(*j); 00136 SUMOReal waiting = (*k).second->getCurrentNumberOfWaiting(); 00137 SUMOReal tmpdur = myPassingTime * waiting; 00138 if (tmpdur > newduration) { 00139 // here we cut the decimal places, because we have to return an integer 00140 newduration = (int) tmpdur; 00141 } 00142 if (newduration > (int) currentPhaseDef()->maxDuration) { 00143 return currentPhaseDef()->maxDuration; 00144 } 00145 } 00146 } 00147 } 00148 return newduration; 00149 } 00150 00151 00152 SUMOTime 00153 MSUnboundActuatedTrafficLightLogic::trySwitch(bool) { 00154 // checks if the actual phase should be continued 00155 gapControl(); 00156 if (myContinue) { 00157 return duration(); 00158 } 00159 // increment the index to the current phase 00160 myStep++; 00161 assert(myStep<=myPhases.size()); 00162 if (myStep==myPhases.size()) { 00163 myStep = 0; 00164 } 00165 //stores the time the phase started 00166 static_cast<MSActuatedPhaseDefinition*>(myPhases[myStep])->myLastSwitch = 00167 MSNet::getInstance()->getCurrentTimeStep(); 00168 // set the next event 00169 return duration(); 00170 } 00171 00172 00173 bool 00174 MSUnboundActuatedTrafficLightLogic::isGreenPhase() const { 00175 if (currentPhaseDef()->getDriveMask().none()) { 00176 return false; 00177 } 00178 if (currentPhaseDef()->getYellowMask().any()) { 00179 return false; 00180 } 00181 return true; 00182 } 00183 00184 00185 bool 00186 MSUnboundActuatedTrafficLightLogic::gapControl() { 00187 //intergreen times should not be lenghtend 00188 assert(myPhases.size()>myStep); 00189 if (!isGreenPhase()) { 00190 return myContinue = false; 00191 } 00192 00193 // Checks, if the maxDuration is kept. No phase should longer send than maxDuration. 00194 SUMOTime actDuration = 00195 MSNet::getInstance()->getCurrentTimeStep() - static_cast<MSActuatedPhaseDefinition*>(myPhases[myStep])->myLastSwitch; 00196 if (actDuration >= currentPhaseDef()->maxDuration) { 00197 return myContinue = false; 00198 } 00199 00200 // now the gapcontrol starts 00201 const std::bitset<64> &isgreen = currentPhaseDef()->getDriveMask(); 00202 for (size_t i=0; i<isgreen.size(); i++) { 00203 if (isgreen.test(i)) { 00204 const std::vector<MSLane*> &lanes = getLanesAt(i); 00205 if (lanes.empty()) { 00206 break; 00207 } 00208 for (LaneVector::const_iterator j=lanes.begin(); j!=lanes.end(); j++) { 00209 if (myInductLoops.find(*j)==myInductLoops.end()) { 00210 continue; 00211 } 00212 SUMOReal actualGap = 00213 myInductLoops.find(*j)->second->getTimestepsSinceLastDetection(); 00214 if (actualGap < myMaxGap) { 00215 return myContinue = true; 00216 } 00217 } 00218 } 00219 } 00220 return myContinue = false; 00221 } 00222 00223 00224 MSActuatedPhaseDefinition* 00225 MSUnboundActuatedTrafficLightLogic::currentPhaseDef() const { 00226 assert(myPhases.size()>myStep); 00227 return static_cast<MSActuatedPhaseDefinition*>(myPhases[myStep]); 00228 } 00229 00230 00231 00232 /****************************************************************************/ 00233