View Javadoc

1   /*
2    * @(#)SingleTrackBlockTrafficLight.java May 31, 2004
3    * 
4    * Copyright (c) 2003, 2004 Delft University of Technology Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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         // cancel the listener of the vehicle
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 }