1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2010-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file MSPhasedTrafficLightLogic.cpp
11 /// @author Daniel Krajzewicz
12 /// @date Sept 2002
13 /// @version $Id$
14 ///
15 // The base class for traffic light logic with phases
16 /****************************************************************************/
17
18
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23
24 #include <cassert>
25 #include <utility>
26 #include <vector>
27 #include <bitset>
28 #include <sstream>
29 #include <microsim/MSEventControl.h>
30 #include "MSTrafficLightLogic.h"
31 #include "MSPhasedTrafficLightLogic.h"
32
33
34
35 // ===========================================================================
36 // member method definitions
37 // ===========================================================================
MSPhasedTrafficLightLogic(MSTLLogicControl & tlcontrol,const std::string & id,const std::string & programID,const TrafficLightType logicType,const Phases & phases,int step,SUMOTime delay,const std::map<std::string,std::string> & parameters)38 MSPhasedTrafficLightLogic::MSPhasedTrafficLightLogic(MSTLLogicControl& tlcontrol,
39 const std::string& id, const std::string& programID, const TrafficLightType logicType, const Phases& phases,
40 int step, SUMOTime delay,
41 const std::map<std::string, std::string>& parameters)
42 : MSTrafficLightLogic(tlcontrol, id, programID, logicType, delay, parameters), myPhases(phases),
43 myStep(step) {
44 for (int i = 0; i < (int)myPhases.size(); i++) {
45 myDefaultCycleTime += myPhases[i]->duration;
46 }
47 }
48
49
~MSPhasedTrafficLightLogic()50 MSPhasedTrafficLightLogic::~MSPhasedTrafficLightLogic() {
51 // MSPhasedTrafficLightLogic:deletePhases();
52 /*for (int i=0; i<myPhases.size(); i++) {
53 delete myPhases[i];
54 }*/
55 }
56
57
58 // ------------ Switching and setting current rows
59 /// MEMBER FACTORIZED TO PARENT CLASS (MSTrafficLightLogic)
60 /*SUMOTime
61 MSPhasedTrafficLightLogic::trySwitch(bool) {
62 // check whether the current duration shall be increased
63 if (myCurrentDurationIncrement>0) {
64 SUMOTime delay = myCurrentDurationIncrement;
65 myCurrentDurationIncrement = 0;
66 return delay;
67 }
68
69 // increment the index
70 myStep++;
71 // if the last phase was reached ...
72 if (myStep==(int)myPhases.size()) {
73 // ... set the index to the first phase
74 myStep = 0;
75 }
76 assert((int)myPhases.size()>myStep);
77 //stores the time the phase started
78 myPhases[myStep]->myLastSwitch = MSNet::getInstance()->getCurrentTimeStep();
79 // check whether the next duration was overridden
80 if (myOverridingTimes.size()>0) {
81 SUMOTime nextDuration = myOverridingTimes[0];
82 myOverridingTimes.erase(myOverridingTimes.begin());
83 return nextDuration;
84 }
85 // return offset to the next switch
86 return myPhases[myStep]->duration;
87 }
88 */
89
90
91
proceedToNextStep()92 void MSPhasedTrafficLightLogic::proceedToNextStep() {
93 setStep(myStep + 1);
94
95 }
96
setStep(int step)97 void MSPhasedTrafficLightLogic::setStep(int step) {
98 step = step % myPhases.size();
99 if (myStep != step) {
100 myStep = step;
101 myPhases[myStep]->myLastSwitch = MSNet::getInstance()->getCurrentTimeStep();
102 }
103 }
104
105 // ------------ Static Information Retrieval
106 int
getPhaseNumber() const107 MSPhasedTrafficLightLogic::getPhaseNumber() const {
108 return (int)myPhases.size();
109 }
110
111
112 const MSPhasedTrafficLightLogic::Phases&
getPhases() const113 MSPhasedTrafficLightLogic::getPhases() const {
114 return myPhases;
115 }
116
117 const MSPhaseDefinition&
getPhase(int givenStep) const118 MSPhasedTrafficLightLogic::getPhase(int givenStep) const {
119 assert((int)myPhases.size() > givenStep);
120 return *myPhases[givenStep];
121 }
122
123
124 // ------------ Dynamic Information Retrieval
125 int
getCurrentPhaseIndex() const126 MSPhasedTrafficLightLogic::getCurrentPhaseIndex() const {
127 return myStep;
128 }
129
130
131 const MSPhaseDefinition&
getCurrentPhaseDef() const132 MSPhasedTrafficLightLogic::getCurrentPhaseDef() const {
133 return *myPhases[myStep];
134 }
135
136
137 // ------------ Conversion between time and phase
138 SUMOTime
getPhaseIndexAtTime(SUMOTime simStep) const139 MSPhasedTrafficLightLogic::getPhaseIndexAtTime(SUMOTime simStep) const {
140 SUMOTime position = getOffsetFromIndex(myStep);
141 position += simStep - getPhase(myStep).myLastSwitch;
142 position = position % myDefaultCycleTime;
143 assert(position <= myDefaultCycleTime);
144 return position;
145 }
146
147
148 SUMOTime
getOffsetFromIndex(int index) const149 MSPhasedTrafficLightLogic::getOffsetFromIndex(int index) const {
150 assert(index < (int)myPhases.size());
151 SUMOTime pos = 0;
152 for (int i = 0; i < index; i++) {
153 pos += getPhase(i).duration;
154 }
155 return pos;
156 }
157
158
159 int
getIndexFromOffset(SUMOTime offset) const160 MSPhasedTrafficLightLogic::getIndexFromOffset(SUMOTime offset) const {
161 assert(offset <= myDefaultCycleTime);
162 if (offset == myDefaultCycleTime) {
163 return 0;
164 }
165 SUMOTime pos = offset;
166 SUMOTime testPos = 0;
167 for (int i = 0; i < (int)myPhases.size(); i++) {
168 testPos += getPhase(i).duration;
169 if (testPos > pos) {
170 return i;
171 }
172 if (testPos == pos) {
173 assert((int)myPhases.size() > (i + 1));
174 return i + 1;
175 }
176 }
177 return 0;
178 }
179
180
181 // ------------ Changing phases and phase durations
182 void
changeStepAndDuration(MSTLLogicControl & tlcontrol,SUMOTime simStep,int step,SUMOTime stepDuration)183 MSPhasedTrafficLightLogic::changeStepAndDuration(MSTLLogicControl& tlcontrol,
184 SUMOTime simStep, int step, SUMOTime stepDuration) {
185 mySwitchCommand->deschedule(this);
186 //delete mySwitchCommand;Consider this operation!!!
187 mySwitchCommand = new SwitchCommand(tlcontrol, this, stepDuration + simStep);
188 myStep = step;
189 MSNet::getInstance()->getBeginOfTimestepEvents()->addEvent(
190 mySwitchCommand, stepDuration + simStep);
191 }
192
193
194 /****************************************************************************/
195 void
setPhases(const Phases & phases,int step)196 MSPhasedTrafficLightLogic::setPhases(const Phases& phases, int step) {
197 assert(step < (int)phases.size());
198 deletePhases();
199 myPhases = phases;
200 myStep = step;
201 }
202
203
204 void
deletePhases()205 MSPhasedTrafficLightLogic::deletePhases() {
206 for (int i = 0; i < (int)myPhases.size(); i++) {
207 delete myPhases[i];
208 }
209 }
210
211