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