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