1
2
3
4
5
6
7
8
9
10
11 package nl.tudelft.simulation.traffic.controlpoint.blocks;
12
13 import java.rmi.RemoteException;
14 import java.util.List;
15 import javax.media.j3d.Bounds;
16 import javax.vecmath.Point3d;
17 import nl.tudelft.simulation.dsol.animation.LocatableInterface;
18 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
19 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
20 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
21 import nl.tudelft.simulation.event.Event;
22 import nl.tudelft.simulation.language.d3.BoundingBox;
23 import nl.tudelft.simulation.language.d3.DirectedPoint;
24 import nl.tudelft.simulation.logger.Logger;
25 import nl.tudelft.simulation.traffic.animation.BlockTrafficLightAnimation;
26 import nl.tudelft.simulation.traffic.controlpoint.real.AbstractVisibleControlPoint;
27 import nl.tudelft.simulation.traffic.controlpoint.real.Changeable;
28 import nl.tudelft.simulation.traffic.controlpoint.real.StopSignInterface;
29 import nl.tudelft.simulation.traffic.track.TrackInterface;
30 import nl.tudelft.simulation.traffic.track.util.TrackProgression;
31 import nl.tudelft.simulation.traffic.vehicle.VehiclePhysicalInterface;
32
33 /***
34 * <br>
35 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
36 * University of Technology </a>, the Netherlands. <br>
37 * See for project information <a href="http://www.simulation.tudelft.nl">
38 * www.simulation.tudelft.nl </a> <br>
39 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
40 * License (GPL) </a>, no warranty <br>
41 *
42 * @version May 31, 2004 <br>
43 * @author <a
44 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
45 * Verbraeck </a>
46 */
47 public class BlockTrafficLight extends AbstractVisibleControlPoint
48 implements
49 LocatableInterface,
50 StopSignInterface
51 {
52 /*** GREEN state */
53 public static final String STATE_GREEN = "GREEN";
54
55 /*** YELLOW state */
56 public static final String STATE_YELLOW = "YELLOW";
57
58 /*** RED state */
59 public static final String STATE_RED = "RED";
60
61 /*** BLACK state */
62 public static final String STATE_BLACK = "BLACK";
63
64 /*** GREEN sensor */
65 public static final int SENSOR_GREEN = 0;
66
67 /*** YELLOW sensor */
68 public static final int SENSOR_YELLOW = 1;
69
70 /*** RED sensor */
71 public static final int SENSOR_RED = 2;
72
73 /*** sensor names */
74 public static final String[] sensorNames = new String[]{"GREEN", "YELLOW",
75 "RED"};
76
77 /*** the distance to the sensor AFTER the traffic light for RED */
78 private double distanceRed;
79
80 /*** the distance to the sensor AFTER the traffic light for YELLOW */
81 private double distanceYellow;
82
83 /*** the distance to the sensor AFTER the traffic light for GREEN */
84 private double distanceGreen;
85
86 /*** the STATE of the current block signal */
87 private String currentState = STATE_GREEN;
88
89 /*** the name */
90 private String name;
91
92 /*** dx for animation (bounds) */
93 private double dx;
94
95 /*** dy for animation (bounds) */
96 private double dy;
97
98 /***
99 * @param name
100 * @param track
101 * @param progression
102 * @param visibleDistance
103 * @param distanceRed
104 * @param distanceYellow
105 * @param distanceGreen
106 * @param simulator
107 * @param dx
108 * @param dy
109 */
110 public BlockTrafficLight(final String name, final TrackInterface track,
111 final double progression, final double visibleDistance,
112 final double distanceRed, final double distanceYellow,
113 final double distanceGreen, final DEVSSimulatorInterface simulator,
114 final double dx, final double dy)
115 {
116 super(track, progression, visibleDistance, simulator);
117 this.name = name;
118 System.out.println(this + ", placed on " + track + " progression "
119 + progression + " (length=" + track.getLength() + ")");
120 this.distanceRed = distanceRed;
121 this.distanceYellow = distanceYellow;
122 this.distanceGreen = distanceGreen;
123 addSensors(super.track, progression + this.distanceRed, SENSOR_RED,
124 simulator);
125 addSensors(super.track, progression + this.distanceYellow,
126 SENSOR_YELLOW, simulator);
127 addSensors(super.track, progression + this.distanceGreen, SENSOR_GREEN,
128 simulator);
129 this.dx = dx;
130 this.dy = dy;
131 if (simulator instanceof AnimatorInterface)
132 {
133 new BlockTrafficLightAnimation(this, simulator, dx, dy);
134 }
135 }
136
137 /***
138 * @param track
139 * @param place
140 * @param sensor
141 * @param simulator
142 */
143 private void addSensors(final TrackInterface track, final double place,
144 final int sensor, final SimulatorInterface simulator)
145 {
146 List tpList = track.calculateTrackProgressionListAll(place);
147 for (int i = 0; i < tpList.size(); i++)
148 {
149 TrackProgression tp = (TrackProgression) tpList.get(i);
150 new BlockControlPoint(tp.getTrack(), tp.getProgression(), this,
151 sensor, simulator);
152 System.out.println(this + ", sensor "
153 + BlockTrafficLight.sensorNames[sensor]
154 + " added on track " + tp.getTrack() + ", progression "
155 + tp.getProgression());
156 }
157 }
158
159 /***
160 * The stateful handling of a sensor trigger. Works as follows:
161 * <P>
162 *
163 * <pre>
164 *
165 *
166 *
167 *
168 *
169 * -------------------------------
170 * | OLD___ | SENSOR___ | NEW___ |
171 * | STATE_ | R | Y | G | STATE_ |
172 * -------------------------------
173 * | BLACK_ | X | X | X | BLACK_ | (error)
174 * -------------------------------
175 * | RED___ | X | . | . | BLACK_ | (error)
176 * | RED___ | . | X | . | YELLOW |
177 * | RED___ | . | . | X | RED___ |
178 * -------------------------------
179 * | YELLOW | X | . | . | RED___ |
180 * | YELLOW | . | X | . | BLACK_ | (error)
181 * | YELLOW | . | . | X | GREEN_ |
182 * -------------------------------
183 * | GREEN_ | X | . | . | RED___ |
184 * | GREEN_ | . | X | . | BLACK_ | (error)
185 * | GREEN_ | . | . | X | BLACK_ | (error)
186 * -------------------------------
187 *
188 *
189 *
190 *
191 *
192 *
193 * </pre>
194 *
195 * @param sensor
196 * @param vehicle
197 */
198 public void triggerSensor(final int sensor,
199 final VehiclePhysicalInterface vehicle)
200 {
201 Logger.fine(this, "triggerSensor", this + ", Vehicle "
202 + vehicle.toString() + " triggered sensor "
203 + BlockTrafficLight.sensorNames[sensor] + ", old state was "
204 + this.currentState);
205 System.out.println(this + ", Vehicle " + vehicle.toString()
206 + " triggered sensor " + BlockTrafficLight.sensorNames[sensor]
207 + ", old state was " + this.currentState);
208 if (this.currentState == STATE_BLACK)
209 {
210 this.currentState = STATE_BLACK;
211 } else if (this.currentState == STATE_RED)
212 {
213 switch (sensor)
214 {
215 case SENSOR_RED :
216 this.currentState = STATE_BLACK;
217 Logger.severe(this, "triggerSensor", "RED - RED");
218 break;
219 case SENSOR_YELLOW :
220 this.currentState = STATE_YELLOW;
221 break;
222 case SENSOR_GREEN :
223 this.currentState = STATE_RED;
224 break;
225 default :
226 Logger.severe(this, "triggerSensor",
227 "reported state not RED, YELLOW or GREEN");
228 break;
229 }
230 } else if (this.currentState == STATE_YELLOW)
231 {
232 switch (sensor)
233 {
234 case SENSOR_RED :
235 this.currentState = STATE_RED;
236 break;
237 case SENSOR_YELLOW :
238 this.currentState = STATE_BLACK;
239 Logger.severe(this, "triggerSensor", "YELLOW - YELLOW");
240 break;
241 case SENSOR_GREEN :
242 this.currentState = STATE_GREEN;
243 break;
244 default :
245 Logger.severe(this, "triggerSensor",
246 "reported state not RED, YELLOW or GREEN");
247 break;
248 }
249 } else if (this.currentState == STATE_GREEN)
250 {
251 switch (sensor)
252 {
253 case SENSOR_RED :
254 this.currentState = STATE_RED;
255 break;
256 case SENSOR_YELLOW :
257 this.currentState = STATE_BLACK;
258 Logger.severe(this, "triggerSensor", "GREEN - YELLOW");
259 break;
260 case SENSOR_GREEN :
261 this.currentState = STATE_BLACK;
262 Logger.severe(this, "triggerSensor", "GREEN - GREEN");
263 break;
264 default :
265 Logger.severe(this, "triggerSensor",
266 "reported state not RED, YELLOW or GREEN");
267 break;
268 }
269 } else
270 {
271 Logger.severe(this, "triggerSensor",
272 "BlockTrafficLight not in state RED, YELLOW or GREEN");
273 }
274 Logger.fine(this, "triggerSensor", this + ", Vehicle "
275 + vehicle.toString() + " new state is " + this.currentState);
276 System.out.println(this + ", Vehicle " + vehicle.toString()
277 + " new state is " + this.currentState);
278 Event event = new Event(Changeable.CHANGE_STATUS_EVENT, this, null);
279 this.fireEvent(event);
280 }
281
282 /***
283 * @see nl.tudelft.simulation.traffic.controlpoint.ControlPointInterface#pass(nl.tudelft.simulation.traffic.vehicle.VehiclePhysicalInterface)
284 */
285 public void pass(final VehiclePhysicalInterface vehicle)
286 {
287
288 this.removeListener(vehicle, Changeable.CHANGE_STATUS_EVENT);
289 }
290
291 /***
292 * @see nl.tudelft.simulation.dsol.animation.LocatableInterface#getLocation()
293 */
294 public DirectedPoint getLocation() throws RemoteException
295 {
296 DirectedPoint p = super.getTrack().getLocationOfProgression(
297 super.getProgression());
298 return new DirectedPoint(p.x, p.y, p.z);
299 }
300
301 /***
302 * @see nl.tudelft.simulation.dsol.animation.LocatableInterface#getBounds()
303 */
304 public Bounds getBounds() throws RemoteException
305 {
306 return new BoundingBox(new Point3d(this.dx - 2.0, this.dy, 0),
307 new Point3d(this.dx + 2.0, this.dy + 12.0, 0));
308 }
309
310 /***
311 * @return Returns the currentState.
312 */
313 public String getCurrentState()
314 {
315 return this.currentState;
316 }
317
318 /***
319 * @see nl.tudelft.simulation.traffic.controlpoint.real.Changeable#getStatus()
320 */
321 public String getStatus()
322 {
323 if ((this.currentState == STATE_RED)
324 || (this.currentState == STATE_BLACK))
325 return StopSignInterface.STOP;
326 else
327 return StopSignInterface.CONTINUE;
328 }
329
330 /***
331 * @see java.lang.Object#toString()
332 */
333 public String toString()
334 {
335 return "BlockTrafficLight " + this.name;
336 }
337 }