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