MSAgentbasedTrafficLightLogic.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // An agentbased traffic light logic
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 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/MSNet.h>
00036 #include "MSTrafficLightLogic.h"
00037 #include "MSAgentbasedTrafficLightLogic.h"
00038 #include <netload/NLDetectorBuilder.h>
00039 #include <utils/common/TplConvert.h>
00040 
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044 
00045 
00046 // ===========================================================================
00047 // member method definitions
00048 // ===========================================================================
00049 MSAgentbasedTrafficLightLogic::MSAgentbasedTrafficLightLogic(
00050     MSTLLogicControl &tlcontrol,
00051     const std::string &id, const std::string &subid,
00052     const Phases &phases, unsigned int step, SUMOTime delay,
00053     int learnHorizon, int decHorizon, SUMOReal minDiff, int tcycle) throw()
00054         : MSSimpleTrafficLightLogic(tlcontrol, id, subid, phases, step, delay),
00055         tDecide(decHorizon), tSinceLastDecision(0), stepOfLastDecision(0),
00056         numberOfValues(learnHorizon), tCycle(tcycle), deltaLimit(minDiff) {}
00057 
00058 
00059 void
00060 MSAgentbasedTrafficLightLogic::init(NLDetectorBuilder &nb) throw(ProcessError) {
00061     SUMOReal det_offset = TplConvert<char>::_2SUMOReal(myParameter.find("detector_offset")->second.c_str());
00062     LaneVectorVector::const_iterator i2;
00063     LaneVector::const_iterator i;
00064     // build the detectors
00065     for (i2=myLanes.begin(); i2!=myLanes.end(); ++i2) {
00066         const LaneVector &lanes = *i2;
00067         for (i=lanes.begin(); i!=lanes.end(); i++) {
00068             MSLane *lane = (*i);
00069             // Build the lane state detetcor and set it into the container
00070             std::string id = "TL_" + myID + "_" + mySubID + "_E2OverLanesDetectorStartingAt_" + lane->getID();
00071 
00072             if (myE2Detectors.find(lane)==myE2Detectors.end()) {
00073                 MS_E2_ZS_CollectorOverLanes* det =
00074                     nb.buildMultiLaneE2Det(id,
00075                                            DU_TL_CONTROL, lane, 0, det_offset,
00076                                            /*haltingTimeThreshold!!!*/ 1,
00077                                            /*haltingSpeedThreshold!!!*/(SUMOReal)(5.0/3.6),
00078                                            /*jamDistThreshold!!!*/ 10);
00079                 myE2Detectors[lane] = det;
00080             }
00081         }
00082     }
00083 
00084 
00085     // initialise the duration
00086     unsigned int tCycleIst = 0;          // the actual cycletime
00087     unsigned int tCycleMin = 0;          // the minimum cycle time
00088     unsigned int tDeltaGreen = 0;         // the difference between the actual cycle time and the required cycle time
00089 
00091     for (unsigned int actStep = 0; actStep!=myPhases.size(); actStep++) {
00092         unsigned int dur = myPhases[actStep]->duration;
00093         tCycleIst = tCycleIst + dur;
00094         if (myPhases[actStep]->isGreenPhase()) {
00095             unsigned int mindur = myPhases[actStep]->minDuration;
00096             tCycleMin = tCycleMin + mindur;
00097         } else {
00098             tCycleMin = tCycleMin + dur;
00099         }
00100     }
00101     if (tCycle < tCycleMin) {
00102         tCycle = tCycleMin;
00103     }
00104     if (tCycleIst < tCycle) {
00105         tDeltaGreen = tCycle - tCycleIst;
00106         lengthenCycleTime(tDeltaGreen);
00107     }
00108     if (tCycleIst > tCycle) {
00109         tDeltaGreen = tCycleIst - tCycle;
00110         cutCycleTime(tDeltaGreen);
00111     }
00112 }
00113 
00114 
00115 MSAgentbasedTrafficLightLogic::~MSAgentbasedTrafficLightLogic() throw() {}
00116 
00117 
00118 // ------------ Switching and setting current rows
00119 SUMOTime
00120 MSAgentbasedTrafficLightLogic::trySwitch(bool) throw() {
00121     assert(getCurrentPhaseDef().minDuration >=0);
00122     assert(getCurrentPhaseDef().minDuration <= getCurrentPhaseDef().duration);
00123     if (myPhases[myStep]->isGreenPhase()) {
00124         // collects the data for the signal control
00125         collectData();
00126         // decides wheter greentime shall distributed between phases
00127         if (tDecide <= tSinceLastDecision) {
00128             calculateDuration();
00129         }
00130     }
00131     // increment the index to the current phase
00132     nextStep();
00133     // set the next event
00134     while (getCurrentPhaseDef().duration==0) {
00135         nextStep();
00136     }
00137     assert(myPhases.size()>myStep);
00138     return getCurrentPhaseDef().duration;
00139 }
00140 
00141 
00142 // ------------ "agentbased" algorithm methods
00143 unsigned int
00144 MSAgentbasedTrafficLightLogic::nextStep() throw() {
00145     // increment the index to the current phase
00146     myStep++;
00147     assert(myStep<=myPhases.size());
00148     if (myStep==myPhases.size()) {
00149         myStep = 0;
00150     }
00151     // increment the number of cycles since last decision
00152     if (myStep == stepOfLastDecision) {
00153         tSinceLastDecision = tSinceLastDecision +1;
00154     }
00155     return myStep;
00156 }
00157 
00158 
00159 void
00160 MSAgentbasedTrafficLightLogic::collectData() throw() {
00161     //collects the traffic data
00162 
00163     // gets a copy of the driveMask
00164     const std::string &state = getCurrentPhaseDef().getState();
00165     // finds the maximum QUEUE_LENGTH_AHEAD_OF_TRAFFIC_LIGHTS_IN_VEHICLES of one phase
00166     SUMOReal maxPerPhase = 0;
00167     for (unsigned int i=0; i<(unsigned int) state.size(); i++)  {
00168         /* finds the maximum QUEUE_LENGTH_AHEAD_OF_TRAFFIC_LIGHTS_IN_VEHICLES
00169            of all lanes of a bit of the drivemask, that shows green */
00170         if (state[i]==MSLink::LINKSTATE_TL_GREEN_MAJOR||state[i]==MSLink::LINKSTATE_TL_GREEN_MINOR) {
00171             const std::vector<MSLane*> &lanes = getLanesAt(i);
00172             if (lanes.empty())    {
00173                 break;
00174             }
00175             SUMOReal maxPerBit = 0;
00176             for (LaneVector::const_iterator j=lanes.begin(); j!=lanes.end(); j++) {
00177                 if ((*j)->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
00178                     continue;
00179                 }
00188             }
00189             if (maxPerPhase < maxPerBit) {
00190                 maxPerPhase = maxPerBit;
00191             }
00192         }
00193     }
00194     // if still no entry for the phase exists a new entry with an empty value is created
00195     if (myRawDetectorData.find(myStep) == myRawDetectorData.end()) {
00196         ValueType firstData;
00197         myRawDetectorData[myStep] = firstData;
00198     }
00199     /* checks whether the number of values that are already in the dataqueue is
00200        the same number of values taht shall be consideres in the traffic control
00201        if both numbers are the same, the oldest value is deleted */
00202     if (myRawDetectorData[myStep].size()== numberOfValues) {
00203         myRawDetectorData[myStep].pop_back();
00204     }
00205     // adds the detectorvalue of the considered phase
00206     myRawDetectorData[myStep].push_front(maxPerPhase);
00207 }
00208 
00209 
00210 void
00211 MSAgentbasedTrafficLightLogic::aggregateRawData() throw() {
00212     for (PhaseValueMap::const_iterator i = myRawDetectorData.begin(); i!=myRawDetectorData.end(); i++) {
00213         SUMOReal sum = 0;
00214         for (ValueType:: const_iterator it = myRawDetectorData[(*i).first].begin(); it != myRawDetectorData[(*i).first].end(); it ++) {
00215             sum = sum + *it;
00216         }
00217         SUMOReal meanvalue = sum / myRawDetectorData[(*i).first].size();
00218         myMeanDetectorData[(*i).first] = meanvalue;
00219     }
00220 }
00221 
00222 
00223 void
00224 MSAgentbasedTrafficLightLogic::calculateDuration() throw() {
00225     aggregateRawData();
00226     unsigned int stepOfMaxValue = findStepOfMaxValue();
00227     if (stepOfMaxValue == myPhases.size())    {
00228         return;
00229     }
00230     unsigned int stepOfMinValue = findStepOfMinValue();
00231     if (stepOfMinValue == myPhases.size())    {
00232         return;
00233     }
00234     if (stepOfMinValue == stepOfMaxValue)    {
00235         return;
00236     }
00237     SUMOReal deltaIst = (myMeanDetectorData[stepOfMaxValue] - myMeanDetectorData[stepOfMinValue])
00238                         / myMeanDetectorData[stepOfMaxValue];
00239     if (deltaIst > deltaLimit) {
00240         myPhases[stepOfMaxValue]->duration = myPhases[stepOfMaxValue]->duration +1;
00241         myPhases[stepOfMinValue]->duration = myPhases[stepOfMinValue]->duration -1;
00242         tSinceLastDecision = 0;
00243         stepOfLastDecision = myStep;
00244     }
00245 }
00246 
00247 
00248 void
00249 MSAgentbasedTrafficLightLogic::lengthenCycleTime(unsigned int toLengthen) throw() {
00250     typedef std::pair <unsigned int, unsigned int> contentType;
00251     typedef std::vector< std::pair <unsigned int, unsigned int> > GreenPhasesVector;
00252     GreenPhasesVector tmp_phases(myPhases.size());
00253     tmp_phases.clear();
00254     unsigned int maxLengthen = 0;  // the sum of all times, that is possible to lengthen
00255 
00256     /* fills the vector tmp_phases with the difference between
00257        duration and maxduration and the myStep of the phases.
00258        only phases with duration < maxDuration are written in the vector.
00259        sorts the vector after the difference. */
00260     for (unsigned int i_Step = 0; i_Step!=myPhases.size(); i_Step++) {
00261         if (myPhases[i_Step]->isGreenPhase()) {
00262             unsigned int dur = myPhases[i_Step]->duration;
00263             unsigned int maxdur = myPhases[i_Step]->maxDuration;
00264             if (dur < maxdur) {
00265                 contentType tmp;
00266                 tmp.second = i_Step;
00267                 tmp.first = maxdur - dur;
00268                 tmp_phases.push_back(tmp);
00269                 maxLengthen = maxLengthen + tmp.first;
00270             }
00271         }
00272     }
00273     sort(tmp_phases.begin(), tmp_phases.end());
00274     //lengthens the phases acording to the difference between duration and maxDuration
00275     for (GreenPhasesVector::iterator i=tmp_phases.begin(); i!=tmp_phases.end(); i++) {
00276         SUMOTime toLengthenPerPhase = 0;
00277         SUMOReal tmpdb = ((*i).first * toLengthen / SUMOReal(maxLengthen)) + (SUMOReal) 0.5;
00278         toLengthenPerPhase = static_cast<SUMOTime>(tmpdb);
00279         toLengthen = toLengthen - toLengthenPerPhase;
00280         maxLengthen = maxLengthen - (*i).first;
00281         SUMOTime newDur = myPhases[(*i).second]->duration + toLengthenPerPhase;
00282         myPhases[(*i).second]->duration = newDur;
00283     }
00284 }
00285 
00286 
00287 void
00288 MSAgentbasedTrafficLightLogic::cutCycleTime(unsigned int toCut) throw() {
00289     typedef std::pair <unsigned int, unsigned int> contentType;
00290     typedef std::vector< std::pair <unsigned int, unsigned int> > GreenPhasesVector;
00291     GreenPhasesVector tmp_phases(myPhases.size());
00292     tmp_phases.clear();
00293     unsigned maxCut = 0;  // the sum of all times, that is possible to cut
00294 
00295     /* fills the vector tmp_phases with the difference between
00296        duration and minduration and the myStep of the phases.
00297        only phases with duration > minDuration are written in the vector.
00298        sorts the vector after the difference. */
00299     for (unsigned i_Step = 0; i_Step!=myPhases.size(); i_Step++) {
00300         if (myPhases[i_Step]->isGreenPhase()) {
00301             unsigned int dur = myPhases[i_Step]->duration;
00302             unsigned int mindur = myPhases[i_Step]->minDuration;
00303             if (dur > mindur) {
00304                 contentType tmp;
00305                 tmp.second = i_Step;
00306                 tmp.first = dur - mindur;
00307                 tmp_phases.push_back(tmp);
00308                 maxCut = maxCut + tmp.first;
00309             }
00310         }
00311     }
00312     std::sort(tmp_phases.begin(), tmp_phases.end());
00313     //cuts the phases acording to the difference between duration and minDuration
00314     for (GreenPhasesVector::iterator i=tmp_phases.begin(); i!=tmp_phases.end(); i++) {
00315         SUMOTime toCutPerPhase = 0;
00316         SUMOReal tmpdb = ((*i).first * toCut / SUMOReal(maxCut)) + (SUMOReal) 0.5;
00317         toCutPerPhase = static_cast<SUMOTime>(tmpdb);
00318         toCut = toCut - toCutPerPhase;
00319         maxCut = maxCut - (*i).first;
00320         SUMOTime newDur = myPhases[(*i).second]->duration - toCutPerPhase;
00321         myPhases[(*i).second]->duration = newDur;
00322     }
00323 }
00324 
00325 
00326 unsigned int
00327 MSAgentbasedTrafficLightLogic::findStepOfMaxValue() const throw() {
00328     unsigned int StepOfMaxValue = (unsigned int) myPhases.size();
00329     SUMOReal MaxValue = -1;
00330     for (MeanDataMap::const_iterator it = myMeanDetectorData.begin(); it!=myMeanDetectorData.end(); it++) {
00331         // checks whether the actual duruation is shorter than maxduration
00332         // otherwise the phase can't be lenghten
00333         unsigned int maxDur = myPhases[(*it).first]->maxDuration;
00334         unsigned int actDur = myPhases[(*it).first]->duration;
00335         if (actDur >= maxDur) {
00336             continue;
00337         }
00338         if ((*it).second > MaxValue) {
00339             MaxValue = (*it).second;
00340             StepOfMaxValue = (*it).first;
00341         }
00342     }
00343     return StepOfMaxValue;
00344 }
00345 
00346 
00347 unsigned int
00348 MSAgentbasedTrafficLightLogic::findStepOfMinValue() const throw() {
00349     unsigned int StepOfMinValue = (unsigned int) myPhases.size();
00350     SUMOReal MinValue = 9999;
00351     for (MeanDataMap::const_iterator it = myMeanDetectorData.begin(); it!=myMeanDetectorData.end(); it++) {
00352         // checks whether the actual duruation is longer than minduration
00353         // otherwise the phase can't be cut
00354         unsigned int minDur = myPhases[(*it).first]->minDuration;
00355         unsigned int actDur = myPhases[(*it).first]->duration;
00356         if (actDur <= minDur) {
00357             continue;
00358         }
00359         if ((*it).second < MinValue) {
00360             MinValue = (*it).second;
00361             StepOfMinValue = (*it).first;
00362         }
00363     }
00364     return StepOfMinValue;
00365 }
00366 
00367 
00368 /*
00369 SUMOReal
00370 MSAgentbasedTrafficLightLogic::currentForLane(E2::DetType what,
00371         MSLane *lane) const
00372 {
00373 
00374     E2DetectorMap::const_iterator i=myE2Detectors.find(lane);
00375     return (*i).second->getCurrent(what);
00376 }
00377 */
00378 
00379 
00380 /****************************************************************************/
00381 

Generated on Wed May 5 00:06:30 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6