|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // A fixed 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 <cassert> 00031 #include <utility> 00032 #include <vector> 00033 #include <bitset> 00034 #include <sstream> 00035 #include <microsim/MSEventControl.h> 00036 #include "MSTrafficLightLogic.h" 00037 #include "MSSimpleTrafficLightLogic.h" 00038 00039 #ifdef CHECK_MEMORY_LEAKS 00040 #include <foreign/nvwa/debug_new.h> 00041 #endif // CHECK_MEMORY_LEAKS 00042 00043 00044 // =========================================================================== 00045 // member method definitions 00046 // =========================================================================== 00047 MSSimpleTrafficLightLogic::MSSimpleTrafficLightLogic(MSTLLogicControl& tlcontrol, 00048 const std::string& id, const std::string& subid, const Phases& phases, 00049 unsigned int step, SUMOTime delay) 00050 : MSTrafficLightLogic(tlcontrol, id, subid, delay), myPhases(phases), 00051 myStep(step) { 00052 for (size_t i=0; i<myPhases.size(); i++) { 00053 myDefaultCycleTime += myPhases[i]->duration; 00054 } 00055 } 00056 00057 00058 MSSimpleTrafficLightLogic::~MSSimpleTrafficLightLogic() { 00059 for (size_t i=0; i<myPhases.size(); i++) { 00060 delete myPhases[i]; 00061 } 00062 } 00063 00064 00065 // ------------ Switching and setting current rows 00066 SUMOTime 00067 MSSimpleTrafficLightLogic::trySwitch(bool) { 00068 // check whether the current duration shall be increased 00069 if (myCurrentDurationIncrement>0) { 00070 SUMOTime delay = myCurrentDurationIncrement; 00071 myCurrentDurationIncrement = 0; 00072 return delay; 00073 } 00074 00075 // increment the index 00076 myStep++; 00077 // if the last phase was reached ... 00078 if (myStep==myPhases.size()) { 00079 // ... set the index to the first phase 00080 myStep = 0; 00081 } 00082 assert(myPhases.size()>myStep); 00083 //stores the time the phase started 00084 myPhases[myStep]->myLastSwitch = MSNet::getInstance()->getCurrentTimeStep(); 00085 // check whether the next duration was overridden 00086 if (myOverridingTimes.size()>0) { 00087 SUMOTime nextDuration = myOverridingTimes[0]; 00088 myOverridingTimes.erase(myOverridingTimes.begin()); 00089 return nextDuration; 00090 } 00091 // return offset to the next switch 00092 return myPhases[myStep]->duration; 00093 } 00094 00095 00096 // ------------ Static Information Retrieval 00097 unsigned int 00098 MSSimpleTrafficLightLogic::getPhaseNumber() const { 00099 return (unsigned int) myPhases.size(); 00100 } 00101 00102 00103 const MSSimpleTrafficLightLogic::Phases& 00104 MSSimpleTrafficLightLogic::getPhases() const { 00105 return myPhases; 00106 } 00107 00108 00109 MSSimpleTrafficLightLogic::Phases& 00110 MSSimpleTrafficLightLogic::getPhases() { 00111 return myPhases; 00112 } 00113 00114 00115 const MSPhaseDefinition& 00116 MSSimpleTrafficLightLogic::getPhase(unsigned int givenStep) const { 00117 assert(myPhases.size()>givenStep); 00118 return *myPhases[givenStep]; 00119 } 00120 00121 00122 // ------------ Dynamic Information Retrieval 00123 unsigned int 00124 MSSimpleTrafficLightLogic::getCurrentPhaseIndex() const { 00125 return myStep; 00126 } 00127 00128 00129 const MSPhaseDefinition& 00130 MSSimpleTrafficLightLogic::getCurrentPhaseDef() const { 00131 return *myPhases[myStep]; 00132 } 00133 00134 00135 // ------------ Conversion between time and phase 00136 SUMOTime 00137 MSSimpleTrafficLightLogic::getPhaseIndexAtTime(SUMOTime simStep) const { 00138 SUMOTime position = 0; 00139 if (myStep > 0) { 00140 for (unsigned int i=0; i < myStep; i++) { 00141 position = position + getPhase(i).duration; 00142 } 00143 } 00144 position = position + simStep - getPhase(myStep).myLastSwitch; 00145 position = position % myDefaultCycleTime; 00146 assert(position <= myDefaultCycleTime); 00147 return position; 00148 } 00149 00150 00151 SUMOTime 00152 MSSimpleTrafficLightLogic::getOffsetFromIndex(unsigned int index) const { 00153 assert(index < myPhases.size()); 00154 if (index == 0) { 00155 return 0; 00156 } 00157 unsigned int pos = 0; 00158 for (unsigned int i=0; i < index; i++) { 00159 pos += getPhase(i).duration; 00160 } 00161 return pos; 00162 } 00163 00164 00165 unsigned int 00166 MSSimpleTrafficLightLogic::getIndexFromOffset(SUMOTime offset) const { 00167 assert(offset <= myDefaultCycleTime); 00168 if (offset == myDefaultCycleTime) { 00169 return 0; 00170 } 00171 SUMOTime testPos = 0; 00172 for (unsigned int i=0; i < myPhases.size(); i++) { 00173 testPos = testPos + getPhase(i).duration; 00174 if (testPos > offset) { 00175 return i; 00176 } 00177 if (testPos == offset) { 00178 assert(myPhases.size() > (i+1)); 00179 return (i+1); 00180 } 00181 } 00182 return 0; 00183 } 00184 00185 00186 // ------------ Changing phases and phase durations 00187 void 00188 MSSimpleTrafficLightLogic::changeStepAndDuration(MSTLLogicControl& tlcontrol, 00189 SUMOTime simStep, unsigned int step, SUMOTime stepDuration) { 00190 mySwitchCommand->deschedule(this); 00191 mySwitchCommand = new SwitchCommand(tlcontrol, this, stepDuration+simStep); 00192 myStep = step; 00193 MSNet::getInstance()->getBeginOfTimestepEvents().addEvent( 00194 mySwitchCommand, stepDuration+simStep, 00195 MSEventControl::ADAPT_AFTER_EXECUTION); 00196 } 00197 00198 00199 /****************************************************************************/ 00200