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 SingleTrackBlockTrafficLight 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 progression
101 * @param visibleDistance
102 * @param track
103 * @param distanceRed
104 * @param distanceYellow
105 * @param distanceGreen
106 * @param simulator
107 * @param dx
108 * @param dy
109 * @throws Exception
110 */
111 public SingleTrackBlockTrafficLight(final String name,
112 final double progression, final double visibleDistance,
113 final TrackInterface track, final double distanceRed,
114 final double distanceYellow, final double distanceGreen,
115 final DEVSSimulatorInterface simulator, final double dx,
116 final double dy) throws Exception
117 {
118 super(track, progression, visibleDistance, simulator);
119 this.name = name;
120 System.out.println(this + ", placed on " + track + " progression "
121 + progression + " (length=" + track.getLength() + ")");
122 this.distanceRed = distanceRed;
123 this.distanceYellow = distanceYellow;
124 this.distanceGreen = distanceGreen;
125 addSensors(super.track, progression + this.distanceRed, SENSOR_RED,
126 simulator);
127 addSensors(super.track, progression + this.distanceYellow,
128 SENSOR_YELLOW, simulator);
129 addSensors(super.track, progression + this.distanceGreen, SENSOR_GREEN,
130 simulator);
131 this.dx = dx;
132 this.dy = dy;
133 if (simulator instanceof AnimatorInterface)
134 {
135 new BlockTrafficLightAnimation(this, simulator, dx, dy);
136 }
137 }
138
139 /***
140 * @param track
141 * @param place
142 * @param sensor
143 * @param simulator
144 * @throws Exception
145 */
146 private void addSensors(final TrackInterface track, final double place,
147 final int sensor, final SimulatorInterface simulator)
148 throws Exception
149 {
150 List tpList = track.calculateTrackProgressionListAll(place);
151 for (int i = 0; i < tpList.size(); i++)
152 {
153 TrackProgression tp = (TrackProgression) tpList.get(i);
154 new SingleTrackControlPoint(tp.getTrack(), tp.getProgression(),
155 this, sensor, simulator);
156 System.out.println(this + ", sensor "
157 + SingleTrackBlockTrafficLight.sensorNames[sensor]
158 + " added on track " + tp.getTrack() + ", progression "
159 + tp.getProgression());
160 }
161 }
162
163 /***
164 * The stateful handling of a sensor trigger. Works as follows:
165 * <P>
166 *
167 * <pre>
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 * </pre>
189 *
190 * @param sensor
191 * @param vehicle
192 */
193 public void triggerSensor(final int sensor,
194 final VehiclePhysicalInterface vehicle)
195 {
196 Logger.fine(this, "triggerSensor", this + ", Vehicle "
197 + vehicle.toString() + " triggered sensor "
198 + SingleTrackBlockTrafficLight.sensorNames[sensor]
199 + ", old state was " + this.currentState);
200 System.out.println(this + ", Vehicle " + vehicle.toString()
201 + " triggered sensor "
202 + SingleTrackBlockTrafficLight.sensorNames[sensor]
203 + ", old state was " + this.currentState);
204 if (this.currentState == STATE_BLACK)
205 {
206 this.currentState = STATE_BLACK;
207 } else if (this.currentState == STATE_RED)
208 {
209 switch (sensor)
210 {
211 case SENSOR_RED :
212 this.currentState = STATE_BLACK;
213 Logger.severe(this, "triggerSensor", "RED - RED");
214 break;
215 case SENSOR_YELLOW :
216 this.currentState = STATE_YELLOW;
217 break;
218 case SENSOR_GREEN :
219 this.currentState = STATE_RED;
220 break;
221 default :
222 Logger.severe(this, "triggerSensor",
223 "reported state not RED, YELLOW or GREEN");
224 break;
225 }
226 } else if (this.currentState == STATE_YELLOW)
227 {
228 switch (sensor)
229 {
230 case SENSOR_RED :
231 this.currentState = STATE_RED;
232 break;
233 case SENSOR_YELLOW :
234 this.currentState = STATE_BLACK;
235 Logger.severe(this, "triggerSensor", "YELLOW - YELLOW");
236 break;
237 case SENSOR_GREEN :
238 this.currentState = STATE_GREEN;
239 break;
240 default :
241 Logger.severe(this, "triggerSensor",
242 "reported state not RED, YELLOW or GREEN");
243 break;
244 }
245 } else if (this.currentState == STATE_GREEN)
246 {
247 switch (sensor)
248 {
249 case SENSOR_RED :
250 this.currentState = STATE_RED;
251 break;
252 case SENSOR_YELLOW :
253 this.currentState = STATE_BLACK;
254 Logger.severe(this, "triggerSensor", "GREEN - YELLOW");
255 break;
256 case SENSOR_GREEN :
257 this.currentState = STATE_BLACK;
258 Logger.severe(this, "triggerSensor", "GREEN - GREEN");
259 break;
260 default :
261 Logger.severe(this, "triggerSensor",
262 "reported state not RED, YELLOW or GREEN");
263 break;
264 }
265 } else
266 {
267 Logger
268 .severe(this, "triggerSensor",
269 "SingleTrackBlockTrafficLight not in state RED, YELLOW or GREEN");
270 }
271 Logger.fine(this, "triggerSensor", this + ", Vehicle "
272 + vehicle.toString() + " new state is " + this.currentState);
273 System.out.println(this + ", Vehicle " + vehicle.toString()
274 + " new state is " + this.currentState);
275 Event event = new Event(Changeable.CHANGE_STATUS_EVENT, this, null);
276 this.fireEvent(event);
277 }
278
279 /***
280 * @see nl.tudelft.simulation.traffic.controlpoint.ControlPointInterface#pass(nl.tudelft.simulation.traffic.vehicle.VehiclePhysicalInterface)
281 */
282 public void pass(final VehiclePhysicalInterface vehicle)
283 {
284
285 this.removeListener(vehicle, Changeable.CHANGE_STATUS_EVENT);
286 }
287
288 /***
289 * @see nl.tudelft.simulation.dsol.animation.LocatableInterface#getLocation()
290 */
291 public DirectedPoint getLocation() throws RemoteException
292 {
293 DirectedPoint p = super.getTrack().getLocationOfProgression(
294 super.getProgression());
295 return new DirectedPoint(p.x, p.y, p.z);
296 }
297
298 /***
299 * @see nl.tudelft.simulation.dsol.animation.LocatableInterface#getBounds()
300 */
301 public Bounds getBounds() throws RemoteException
302 {
303 return new BoundingBox(new Point3d(this.dx - 2.0, this.dy, 0),
304 new Point3d(this.dx + 2.0, this.dy + 12.0, 0));
305 }
306
307 /***
308 * @return Returns the currentState.
309 */
310 public String getCurrentState()
311 {
312 return this.currentState;
313 }
314
315 /***
316 * @see nl.tudelft.simulation.traffic.controlpoint.real.Changeable#getStatus()
317 */
318 public String getStatus()
319 {
320 if ((this.currentState == STATE_RED)
321 || (this.currentState == STATE_BLACK))
322 return StopSignInterface.STOP;
323 else
324 return StopSignInterface.CONTINUE;
325 }
326
327 /***
328 * @see java.lang.Object#toString()
329 */
330 public String toString()
331 {
332 return "SingleBlockTrafficLight " + this.name;
333 }
334 }