1 package org.opentrafficsim.road.network.lane.object.trafficlight;
2
3 import java.util.LinkedHashMap;
4 import java.util.LinkedHashSet;
5 import java.util.Map;
6 import java.util.NavigableSet;
7 import java.util.Set;
8 import java.util.SortedMap;
9 import java.util.TreeMap;
10
11 import org.djunits.value.vdouble.scalar.Duration;
12 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
13
14 import nl.tudelft.simulation.dsol.SimRuntimeException;
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 public class TrafficLightControllerFixedDuration implements TrafficLightController
30 {
31
32 private final String id;
33
34
35 private final OTSSimulatorInterface simulator;
36
37
38 private final SortedMap<Integer, Set<TrafficLight>> phases = new TreeMap<>();
39
40
41 private final Map<Integer, Duration> yellowDurations = new LinkedHashMap<>();
42
43
44 private final Map<Integer, Duration> greenDurations = new LinkedHashMap<>();
45
46
47 private int currentPhase;
48
49
50 private TrafficLightColor currentColor = TrafficLightColor.RED;
51
52
53 private Duration clearanceDuration = Duration.ZERO;
54
55
56
57
58
59
60
61 public TrafficLightControllerFixedDuration(final String id, final OTSSimulatorInterface simulator)
62 throws TrafficLightException
63 {
64 this.id = id;
65 this.simulator = simulator;
66 try
67 {
68 this.simulator.scheduleEventNow(this, this, "changePhase", null);
69 }
70 catch (SimRuntimeException exception)
71 {
72 throw new TrafficLightException(exception);
73 }
74 }
75
76
77
78
79
80 protected final void changePhase() throws TrafficLightException
81 {
82 try
83 {
84 if (this.currentColor.isGreen())
85 {
86 for (TrafficLight trafficLight : this.phases.get(this.currentPhase))
87 {
88 trafficLight.setTrafficLightColor(TrafficLightColor.YELLOW);
89 }
90 this.currentColor = TrafficLightColor.YELLOW;
91 this.simulator.scheduleEventRel(this.yellowDurations.get(this.currentPhase), this, this, "changePhase", null);
92 return;
93 }
94 else if (this.currentColor.isYellow())
95 {
96 for (TrafficLight trafficLight : this.phases.get(this.currentPhase))
97 {
98 trafficLight.setTrafficLightColor(TrafficLightColor.RED);
99 }
100 this.currentColor = TrafficLightColor.RED;
101 }
102
103 if (this.currentColor.isRed())
104 {
105 Integer nextPhase = ((NavigableSet<Integer>) this.phases.keySet()).higher(this.currentPhase);
106 if (nextPhase == null)
107 {
108 nextPhase = this.phases.firstKey();
109 }
110 this.currentPhase = nextPhase;
111 this.currentColor = TrafficLightColor.GREEN;
112 this.simulator.scheduleEventRel(this.greenDurations.get(this.currentPhase), this, this, "changePhase", null);
113 }
114 }
115 catch (SimRuntimeException exception)
116 {
117 throw new TrafficLightException(exception);
118 }
119 }
120
121
122 @Override
123 public final int getNumberOfPhases()
124 {
125 return this.phases.size();
126 }
127
128
129 @Override
130 public final int getCurrentPhase()
131 {
132 return this.currentPhase;
133 }
134
135
136 @Override
137 public final Duration getClearanceDurationToNextPhase()
138 {
139 return this.clearanceDuration;
140 }
141
142
143
144
145
146
147
148
149 public final void addPhase(final int phaseId, final Duration yellowDuration, final Duration greenDuration)
150 throws TrafficLightException
151 {
152 if (this.phases.containsKey(phaseId))
153 {
154 throw new TrafficLightException("Phase " + phaseId + " for traffic light " + this.id + " was already defined");
155 }
156 this.phases.put(phaseId, new LinkedHashSet<TrafficLight>());
157 this.yellowDurations.put(phaseId, yellowDuration);
158 this.greenDurations.put(phaseId, greenDuration);
159 }
160
161
162 @Override
163 public final void addTrafficLightToPhase(final int phaseId, final TrafficLight trafficLight) throws TrafficLightException
164 {
165 if (!this.phases.containsKey(phaseId))
166 {
167 throw new TrafficLightException("Phase " + phaseId + " for traffic light " + this.id + " was not defined");
168 }
169 this.phases.get(phaseId).add(trafficLight);
170 trafficLight.setTrafficLightColor(TrafficLightColor.RED);
171 }
172
173
174 @Override
175 public final String getId()
176 {
177 return this.id;
178 }
179
180
181
182
183 public final void setClearanceDuration(final Duration clearanceDuration)
184 {
185 this.clearanceDuration = clearanceDuration;
186 }
187
188
189 @Override
190 @SuppressWarnings("checkstyle:designforextension")
191 public String toString()
192 {
193 return "TrafficLightControllerFixedDuration [id=" + this.id + ", phases=" + this.phases + ", yellowDurations="
194 + this.yellowDurations + ", greenDurations=" + this.greenDurations + ", currentPhase=" + this.currentPhase
195 + ", currentColor=" + this.currentColor + ", clearanceDuration=" + this.clearanceDuration + "]";
196 }
197
198 }