View Javadoc
1   package org.opentrafficsim.road.gtu.lane;
2   
3   import java.util.HashMap;
4   import java.util.LinkedHashMap;
5   import java.util.Map;
6   import java.util.Set;
7   
8   import javax.media.j3d.Bounds;
9   import javax.naming.NamingException;
10  import javax.vecmath.Point3d;
11  
12  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
13  import nl.tudelft.simulation.language.d3.BoundingBox;
14  import nl.tudelft.simulation.language.d3.DirectedPoint;
15  
16  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
17  import org.opentrafficsim.core.gtu.AbstractGTU;
18  import org.opentrafficsim.core.gtu.GTUException;
19  import org.opentrafficsim.core.gtu.GTUType;
20  import org.opentrafficsim.core.gtu.RelativePosition;
21  import org.opentrafficsim.core.gtu.RelativePosition.TYPE;
22  import org.opentrafficsim.core.network.LateralDirectionality;
23  import org.opentrafficsim.core.network.NetworkException;
24  import org.opentrafficsim.core.network.route.CompleteRoute;
25  import org.opentrafficsim.core.network.route.CompleteRouteNavigator;
26  import org.opentrafficsim.road.gtu.animation.LaneChangeUrgeGTUColorer.LaneChangeDistanceAndDirection;
27  import org.opentrafficsim.road.gtu.following.GTUFollowingModel;
28  import org.opentrafficsim.road.gtu.following.HeadwayGTU;
29  import org.opentrafficsim.road.network.lane.Lane;
30  
31  import com.vividsolutions.jts.geom.Coordinate;
32  import com.vividsolutions.jts.geom.LineString;
33  import com.vividsolutions.jts.linearref.LengthIndexedLine;
34  
35  /**
36   * Special GTU that cannot move, but it can be seen by other GTUs.
37   * <p>
38   * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
39   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
40   * <p>
41   * @version $Revision: 1155 $, $LastChangedDate: 2015-07-26 01:01:13 +0200 (Sun, 26 Jul 2015) $, by $Author: averbraeck $,
42   *          initial version 15 jul. 2015 <br>
43   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
44   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
45   */
46  public abstract class AbstractTrafficLight extends AbstractGTU implements LaneBasedGTU
47  {
48      /** */
49      private static final long serialVersionUID = 20150624L;
50  
51      /** the simulator. */
52      private OTSDEVSSimulatorInterface simulator;
53  
54      /** animation. */
55      private Renderable2D animation;
56  
57      /** the lane of the block. */
58      final Lane lane;
59  
60      /** the position of the block on the lane. */
61      final Length.Rel position;
62  
63      /** blocking GTU type. */
64      public static final GTUType BLOCK_GTU;
65  
66      /** null length. */
67      private static final Length.Rel LENGTH_REL_0 = new Length.Rel(0.0, METER);
68  
69      /** null length. */
70      private static final Length.Abs LENGTH_ABS_0 = new Length.Abs(0.0, METER);
71  
72      /** null speed. */
73      private static final Speed.Abs SPEED_ABS_0 = new Speed.Abs(0.0, METER_PER_SECOND);
74  
75      /** null time. */
76      private static Time.Abs TIME_ABS_0 = new Time.Abs(0.0, SECOND);
77  
78      /** null acceleration. */
79      private static final Acceleration.Abs ACCELERATION_ABS_0 = new Acceleration.Abs(0.0, METER_PER_SECOND_2);
80  
81      /** the front, back, and reference positions; all at the same place. */
82      private static final Map<RelativePosition.TYPE, RelativePosition> RELATIVE_POSITIONS = new LinkedHashMap<>();
83  
84      static
85      {
86          BLOCK_GTU = GTUType.makeGTUType("BLOCK");
87  
88          RELATIVE_POSITIONS.put(RelativePosition.FRONT, new RelativePosition(LENGTH_REL_0, LENGTH_REL_0, LENGTH_REL_0,
89              RelativePosition.FRONT));
90          RELATIVE_POSITIONS.put(RelativePosition.REAR, new RelativePosition(LENGTH_REL_0, LENGTH_REL_0, LENGTH_REL_0,
91              RelativePosition.REAR));
92          RELATIVE_POSITIONS.put(RelativePosition.REFERENCE, RelativePosition.REFERENCE_POSITION);
93      }
94  
95      /**
96       * @param name the name or id of the traffic light
97       * @param lane The lane where the block has to be put
98       * @param position the position on the lane as a length
99       * @param simulator the simulator to avoid NullPointerExceptions
100      * @throws GTUException when GTU cannot be created.
101      * @throws NamingException if an error occurs when adding the animation handler
102      * @throws NetworkException when the GTU cannot be placed on the given lane
103      */
104     public AbstractTrafficLight(final String name, final Lane lane, final Length.Rel position,
105         final OTSDEVSSimulatorInterface simulator) throws GTUException, NetworkException, NamingException
106     {
107         super(name, BLOCK_GTU, new CompleteRouteNavigator(new CompleteRoute("")));
108         this.simulator = simulator;
109         this.position = position;
110         this.lane = lane;
111 
112         // register the block on the lanes
113         lane.addGTU(this, position);
114     }
115 
116     private boolean blocked = true;
117 
118     /**
119      * @param blocked set blocked
120      */
121     public final void setBlocked(final boolean blocked)
122     {
123         try
124         {
125             if (this.blocked && !blocked)
126             {
127                 // remove ourselves from the lane
128                 this.lane.removeGTU(this);
129             }
130             else if (!this.blocked && blocked)
131             {
132                 // add ourselves to the lane
133                 this.lane.addGTU(this, this.position);
134             }
135             this.blocked = blocked;
136         }
137         catch (NetworkException exception)
138         {
139             exception.printStackTrace();
140         }
141     }
142 
143     /**
144      * @return blocked
145      */
146     public final boolean isBlocked()
147     {
148         return this.blocked;
149     }
150 
151     /**
152      * @return lane
153      */
154     public final Lane getLane()
155     {
156         return this.lane;
157     }
158 
159     /** {@inheritDoc} */
160     @Override
161     public final Length.Rel getLength()
162     {
163         return LENGTH_REL_0;
164     }
165 
166     /** {@inheritDoc} */
167     @Override
168     public final Length.Rel getWidth()
169     {
170         return LENGTH_REL_0;
171     }
172 
173     /** {@inheritDoc} */
174     @Override
175     public final Speed.Abs getMaximumVelocity()
176     {
177         return SPEED_ABS_0;
178     }
179 
180     /** {@inheritDoc} */
181     @Override
182     public final OTSDEVSSimulatorInterface getSimulator()
183     {
184         return this.simulator;
185     }
186 
187     /** {@inheritDoc} */
188     @Override
189     public final RelativePosition getFront()
190     {
191         return RELATIVE_POSITIONS.get(RelativePosition.FRONT);
192     }
193 
194     /** {@inheritDoc} */
195     @Override
196     public final RelativePosition getRear()
197     {
198         return RELATIVE_POSITIONS.get(RelativePosition.FRONT);
199     }
200 
201     /** {@inheritDoc} */
202     @Override
203     public final Speed.Abs getVelocity()
204     {
205         return SPEED_ABS_0;
206     }
207 
208     /** {@inheritDoc} */
209     @Override
210     public final Map<TYPE, RelativePosition> getRelativePositions()
211     {
212         return RELATIVE_POSITIONS;
213     }
214 
215     /** {@inheritDoc} */
216     @Override
217     public final void destroy()
218     {
219         // nothing to do.
220     }
221 
222     /** {@inheritDoc} */
223     @Override
224     public final Acceleration.Abs getAcceleration()
225     {
226         return ACCELERATION_ABS_0;
227     }
228 
229     /** {@inheritDoc} */
230     @Override
231     public final DirectedPoint getLocation()
232     {
233         // TODO solve problem when point is still on previous lane.
234         Length.Rel longitudinalPos;
235         try
236         {
237             longitudinalPos = position(lane, getReference());
238             double fraction = (longitudinalPos.getSI() + getLength().getSI() / 2.0) / lane.getLength().getSI();
239             LineString line = lane.getCenterLine().getLineString();
240             LengthIndexedLine lil = new LengthIndexedLine(line);
241             // if (fraction > 1)
242             // {
243             // System.out.println("fraction is " + fraction);
244             // }
245             double useFraction = fraction;
246             boolean fractionAdjusted = false;
247             if (fraction < 0)
248             {
249                 useFraction = 0;
250                 fractionAdjusted = true;
251             }
252             if (fraction > 0.99)
253             {
254                 useFraction = 0.99;
255                 fractionAdjusted = true;
256             }
257             // DO NOT MODIFY THE RESULT OF extractPoint (it may be one of the coordinates in line).
258             Coordinate c = new Coordinate(lil.extractPoint(useFraction * line.getLength()));
259             c.z = 0d;
260             Coordinate cb = lil.extractPoint((useFraction + 0.01) * line.getLength());
261             double angle = Math.atan2(cb.y - c.y, cb.x - c.x);
262             if (fractionAdjusted)
263             {
264                 c =
265                     new Coordinate(c.x + (fraction - useFraction) * 100 * (cb.x - c.x), c.y + (fraction - useFraction)
266                         * 100 * (cb.y - c.y), c.z);
267             }
268             if (Double.isNaN(c.x))
269             {
270                 System.out.println("Bad");
271             }
272             return new DirectedPoint(c.x, c.y, c.z + 0.01 /* raise it slightly above the lane surface */, 0.0, 0.0,
273                 angle);
274         }
275         catch (NetworkException exception)
276         {
277             exception.printStackTrace();
278             return null;
279         }
280     }
281 
282     /** {@inheritDoc} */
283     @Override
284     public final Bounds getBounds()
285     {
286         double dx = 2;
287         double dy = 2;
288         return new BoundingBox(new Point3d(-dx, -dy, 0.0), new Point3d(dx, dy, 0.0));
289     }
290 
291     /** {@inheritDoc} */
292     @Override
293     public final Length.Abs getOdometer()
294     {
295         return LENGTH_ABS_0;
296     }
297 
298     /** {@inheritDoc} */
299     @Override
300     public final Speed.Abs getLongitudinalVelocity()
301     {
302         return SPEED_ABS_0;
303     }
304 
305     /** {@inheritDoc} */
306     @Override
307     public final Speed.Abs getLongitudinalVelocity(final Time.Abs when)
308     {
309         return SPEED_ABS_0;
310     }
311 
312     /** {@inheritDoc} */
313     @Override
314     public final Acceleration.Abs getAcceleration(final Time.Abs when)
315     {
316         return ACCELERATION_ABS_0;
317     }
318 
319     /** {@inheritDoc} */
320     @Override
321     public final Speed.Abs getLateralVelocity()
322     {
323         return SPEED_ABS_0;
324     }
325 
326     /** {@inheritDoc} */
327     @Override
328     public final Time.Abs getLastEvaluationTime()
329     {
330         return TIME_ABS_0;
331     }
332 
333     /** {@inheritDoc} */
334     @Override
335     public final Time.Abs getNextEvaluationTime()
336     {
337         return TIME_ABS_0;
338     }
339 
340     /** {@inheritDoc} */
341     @Override
342     public final void enterLane(final Lane lane, final Length.Rel position) throws NetworkException
343     {
344         // do nothing
345     }
346 
347     /** {@inheritDoc} */
348     @Override
349     public final void leaveLane(final Lane lane)
350     {
351         // do nothing
352     }
353 
354     /** {@inheritDoc} */
355     @Override
356     public final Map<Lane, Length.Rel> positions(final RelativePosition relativePosition) throws NetworkException
357     {
358         Map<Lane, Length.Rel> map = new HashMap<Lane, Length.Rel>();
359         map.put(this.lane, this.position);
360         return map;
361     }
362 
363     /** {@inheritDoc} */
364     @Override
365     public final Map<Lane, Length.Rel> positions(final RelativePosition relativePosition, final Time.Abs when)
366         throws NetworkException
367     {
368         return positions(relativePosition);
369     }
370 
371     /** {@inheritDoc} */
372     @Override
373     public final Length.Rel position(final Lane lane, final RelativePosition relativePosition) throws NetworkException
374     {
375         if (this.lane.equals(lane))
376         {
377             return this.position;
378         }
379         throw new NetworkException("BLOCK GTU not on lane " + lane);
380     }
381 
382     /** {@inheritDoc} */
383     @Override
384     public final Length.Rel position(final Lane lane, final RelativePosition relativePosition, final Time.Abs when)
385         throws NetworkException
386     {
387         return position(lane, relativePosition);
388     }
389 
390     /** {@inheritDoc} */
391     @Override
392     public final Map<Lane, Double> fractionalPositions(final RelativePosition relativePosition) throws NetworkException
393     {
394         Map<Lane, Double> map = new HashMap<Lane, Double>();
395         map.put(this.lane, this.position.getSI() / this.lane.getLength().getSI());
396         return map;
397     }
398 
399     /** {@inheritDoc} */
400     @Override
401     public Map<Lane, Double> fractionalPositions(RelativePosition relativePosition, Time.Abs when)
402         throws NetworkException
403     {
404         Map<Lane, Double> result = new HashMap<Lane, Double>();
405         result.put(this.lane, this.position.getSI() / this.lane.getLength().getSI());
406         return result;
407     }
408 
409     /** {@inheritDoc} */
410     @Override
411     public double fractionalPosition(Lane lane, RelativePosition relativePosition, Time.Abs when)
412         throws NetworkException
413     {
414         return this.position.getSI() / lane.getLength().getSI();
415     }
416 
417     /** {@inheritDoc} */
418     @Override
419     public double fractionalPosition(Lane lane, RelativePosition relativePosition) throws NetworkException
420     {
421         return this.position.getSI() / lane.getLength().getSI();
422     }
423 
424     /** {@inheritDoc} */
425     @Override
426     public Length.Rel projectedPosition(Lane projectionLane, RelativePosition relativePosition, Time.Abs when)
427         throws NetworkException
428     {
429         return null;
430     }
431 
432     /** {@inheritDoc} */
433     @Override
434     public HeadwayGTU headway(Length.Rel maxDistance) throws NetworkException
435     {
436         return null;
437     }
438 
439     /** {@inheritDoc} */
440     @Override
441     public HeadwayGTU headway(Lane lane, Length.Rel maxDistance) throws NetworkException
442     {
443         return null;
444     }
445 
446     /** {@inheritDoc} */
447     @Override
448     public Set<LaneBasedGTU> parallel(Lane lane, Time.Abs when) throws NetworkException
449     {
450         return null;
451     }
452 
453     /** {@inheritDoc} */
454     @Override
455     public Set<LaneBasedGTU> parallel(LateralDirectionality lateralDirection, Time.Abs when) throws NetworkException
456     {
457         return null;
458     }
459 
460     /** {@inheritDoc} */
461     @Override
462     public Lane bestAccessibleAdjacentLane(Lane currentLane, LateralDirectionality lateralDirection,
463         Length.Rel longitudinalPosition)
464     {
465         return null;
466     }
467 
468     /** {@inheritDoc} */
469     @Override
470     public Time.Abs timeAtDistance(Length.Rel distance)
471     {
472         return null;
473     }
474 
475     /** {@inheritDoc} */
476     @Override
477     public Time.Rel deltaTimeForDistance(Length.Rel distance)
478     {
479         return null;
480     }
481 
482     /** {@inheritDoc} */
483     @Override
484     public GTUFollowingModel getGTUFollowingModel()
485     {
486         return null;
487     }
488 
489     /** {@inheritDoc} */
490     @Override
491     public LaneChangeDistanceAndDirection getLaneChangeDistanceAndDirection()
492     {
493         return null;
494     }
495 
496     /** {@inheritDoc} */
497     @Override
498     public String toString()
499     {
500         return "AbstractTrafficLight [lane=" + this.lane + ", position=" + this.position + "]";
501     }
502 
503 }