View Javadoc
1   package org.opentrafficsim.road.gtu.lane;
2   
3   import java.lang.reflect.Constructor;
4   import java.lang.reflect.InvocationTargetException;
5   import java.util.LinkedHashMap;
6   import java.util.Map;
7   import java.util.Set;
8   
9   import javax.naming.NamingException;
10  
11  import nl.tudelft.simulation.dsol.SimRuntimeException;
12  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
13  import nl.tudelft.simulation.language.reflection.ClassUtil;
14  
15  import org.djunits.unit.AccelerationUnit;
16  import org.djunits.unit.LengthUnit;
17  import org.djunits.value.vdouble.scalar.Acceleration;
18  import org.djunits.value.vdouble.scalar.Length;
19  import org.djunits.value.vdouble.scalar.Speed;
20  import org.opentrafficsim.core.dsol.OTSAnimatorInterface;
21  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
22  import org.opentrafficsim.core.geometry.OTSGeometryException;
23  import org.opentrafficsim.core.gtu.GTUException;
24  import org.opentrafficsim.core.gtu.GTUType;
25  import org.opentrafficsim.core.gtu.RelativePosition;
26  import org.opentrafficsim.core.gtu.RelativePosition.TYPE;
27  import org.opentrafficsim.core.gtu.animation.GTUColorer;
28  import org.opentrafficsim.core.network.NetworkException;
29  import org.opentrafficsim.core.network.OTSNetwork;
30  import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
31  import org.opentrafficsim.road.gtu.lane.perception.LanePerceptionFull;
32  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
33  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
34  
35  /**
36   * Augments the AbstractLaneBasedIndividualGTU with a LaneBasedIndividualCarBuilder and animation support
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: 1401 $, $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, by $Author: averbraeck $,
42   *          initial version Oct 22, 2014 <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 class LaneBasedIndividualGTU extends AbstractLaneBasedIndividualGTU
47  {
48      /** */
49      private static final long serialVersionUID = 20141025L;
50  
51      /** The animation. */
52      private Renderable2D animation;
53  
54      /** Sensing positions. */
55      private final Map<RelativePosition.TYPE, RelativePosition> relativePositions = new LinkedHashMap<>();
56  
57      /**
58       * @param id ID; the id of the GTU
59       * @param gtuType GTUType; the type of GTU, e.g. TruckType, CarType, BusType
60       * @param initialLongitudinalPositions Map&lt;Lane, Length.Rel&gt;; the initial positions of the car on one or more lanes
61       * @param initialSpeed Speed; the initial speed of the car on the lane
62       * @param length Length.Rel; the maximum length of the GTU (parallel with driving direction)
63       * @param width Length.Rel; the maximum width of the GTU (perpendicular to driving direction)
64       * @param maximumVelocity Speed;the maximum speed of the GTU (in the driving direction)
65       * @param simulator OTSDEVSSimulatorInterface; the simulator
66       * @param strategicalPlanner the strategical planner (e.g., route determination) to use
67       * @param perception the lane-based perception model of the GTU
68       * @param network the network that the GTU is initially registered in
69       * @throws NamingException if an error occurs when adding the animation handler
70       * @throws NetworkException when the GTU cannot be placed on the given lane
71       * @throws SimRuntimeException when the move method cannot be scheduled
72       * @throws GTUException when a parameter is invalid
73       * @throws OTSGeometryException when the initial path is wrong
74       */
75      @SuppressWarnings("checkstyle:parameternumber")
76      public LaneBasedIndividualGTU(final String id, final GTUType gtuType,
77          final Set<DirectedLanePosition> initialLongitudinalPositions, final Speed initialSpeed,
78          final Length.Rel length, final Length.Rel width, final Speed maximumVelocity,
79          final OTSDEVSSimulatorInterface simulator, final LaneBasedStrategicalPlanner strategicalPlanner,
80          final LanePerceptionFull perception, final OTSNetwork network) throws NamingException, NetworkException,
81          SimRuntimeException, GTUException, OTSGeometryException
82      {
83          this(id, gtuType, initialLongitudinalPositions, initialSpeed, length, width, maximumVelocity, simulator,
84              strategicalPlanner, perception, DefaultCarAnimation.class, null, network);
85      }
86  
87      /**
88       * Construct a new LaneBasedIndividualCar.
89       * @param id ID; the id of the GTU
90       * @param gtuType GTUTYpe; the type of GTU, e.g. TruckType, CarType, BusType
91       * @param initialLongitudinalPositions Map&lt;Lane, Length.Rel&gt;; the initial positions of the car on one or more lanes
92       * @param initialSpeed Speed; the initial speed of the car on the lane
93       * @param length Length.Rel; the maximum length of the GTU (parallel with driving direction)
94       * @param width Length.Rel; the maximum width of the GTU (perpendicular to driving direction)
95       * @param maximumVelocity Speed;the maximum speed of the GTU (in the driving direction)
96       * @param simulator OTSDEVSSimulatorInterface; the simulator
97       * @param strategicalPlanner the strategical planner (e.g., route determination) to use
98       * @param perception the lane-based perception model of the GTU
99       * @param animationClass Class&lt;? extends Renderable2D&gt;; the class for animation or null if no animation
100      * @param gtuColorer GTUColorer; the GTUColorer that will be linked from the animation to determine the color (may be null
101      *            in which case a default will be used)
102      * @param network the network that the GTU is initially registered in
103      * @throws NamingException if an error occurs when adding the animation handler
104      * @throws NetworkException when the GTU cannot be placed on the given lane
105      * @throws SimRuntimeException when the move method cannot be scheduled
106      * @throws GTUException when a parameter is invalid
107      * @throws OTSGeometryException when the initial path is wrong
108      */
109     @SuppressWarnings("checkstyle:parameternumber")
110     public LaneBasedIndividualGTU(final String id, final GTUType gtuType,
111         final Set<DirectedLanePosition> initialLongitudinalPositions, final Speed initialSpeed,
112         final Length.Rel length, final Length.Rel width, final Speed maximumVelocity,
113         final OTSDEVSSimulatorInterface simulator, final LaneBasedStrategicalPlanner strategicalPlanner,
114         final LanePerceptionFull perception, final Class<? extends Renderable2D> animationClass,
115         final GTUColorer gtuColorer, final OTSNetwork network) throws NamingException, NetworkException,
116         SimRuntimeException, GTUException, OTSGeometryException
117     {
118         super(id, gtuType, initialLongitudinalPositions, initialSpeed, length, width, maximumVelocity, simulator,
119             strategicalPlanner, perception, network);
120 
121         // sensor positions.
122         // We take the rear position of the Car to be the reference point. So the front is the length
123         // of the Car away from the reference point in the positive (driving) X-direction.
124         Length.Rel dx2 = new Length.Rel(getLength().getSI() / 2.0, LengthUnit.METER);
125         this.relativePositions.put(RelativePosition.FRONT, new RelativePosition(dx2, Length.Rel.ZERO, Length.Rel.ZERO,
126             RelativePosition.FRONT));
127         this.relativePositions.put(RelativePosition.REAR, new RelativePosition(dx2.multiplyBy(-1.0), Length.Rel.ZERO,
128             Length.Rel.ZERO, RelativePosition.REAR));
129         this.relativePositions.put(RelativePosition.REFERENCE, RelativePosition.REFERENCE_POSITION);
130 
131         setMaximumAcceleration(new Acceleration(1.0, AccelerationUnit.METER_PER_SECOND_2));
132         setMaximumDeceleration(new Acceleration(-1.0, AccelerationUnit.METER_PER_SECOND_2));
133 
134         // animation
135         if (simulator instanceof OTSAnimatorInterface && animationClass != null)
136         {
137             try
138             {
139                 Constructor<?> constructor;
140 
141                 if (null == gtuColorer)
142                 {
143                     constructor = ClassUtil.resolveConstructor(animationClass, new Object[]{this, simulator});
144                     this.animation = (Renderable2D) constructor.newInstance(this, simulator);
145                 }
146                 else
147                 {
148                     constructor =
149                         ClassUtil.resolveConstructor(animationClass, new Object[]{this, simulator, gtuColorer});
150                     this.animation = (Renderable2D) constructor.newInstance(this, simulator, gtuColorer);
151                 }
152             }
153             catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException
154                 | IllegalArgumentException | InvocationTargetException exception)
155             {
156                 throw new NetworkException("Could not instantiate car animation of type " + animationClass.getName(),
157                     exception);
158             }
159         }
160     }
161 
162     /** {@inheritDoc} */
163     @Override
164     @SuppressWarnings("checkstyle:designforextension")
165     public RelativePosition getFront()
166     {
167         return this.relativePositions.get(RelativePosition.FRONT);
168     }
169 
170     /** {@inheritDoc} */
171     @Override
172     @SuppressWarnings("checkstyle:designforextension")
173     public RelativePosition getRear()
174     {
175         return this.relativePositions.get(RelativePosition.REAR);
176     }
177 
178     /** {@inheritDoc} */
179     @Override
180     public final Map<TYPE, RelativePosition> getRelativePositions()
181     {
182         return this.relativePositions;
183     }
184 
185     /** {@inheritDoc} */
186     @Override
187     public final void destroy()
188     {
189         if (this.animation != null)
190         {
191             try
192             {
193                 this.animation.destroy();
194                 this.animation = null;
195             }
196             catch (Exception e)
197             {
198                 System.err.println("Car: " + this.getId());
199                 e.printStackTrace();
200             }
201         }
202         super.destroy();
203     }
204 
205     /**
206      * Build an individual car and use easy setter methods to instantiate the car. Typical use looks like:
207      * 
208      * <pre>
209      * LaneBasedIndividualCar&lt;String&gt; car = new LaneBasedIndividualCarBuilder&lt;String&gt;().setId("Car:"+nr)
210      *    .setLength(new Length.Rel(4.0, METER))....build(); 
211      *    
212      * or
213      * 
214      * LaneBasedIndividualCarBuilder&lt;String&gt; carBuilder = new LaneBasedIndividualCarBuilder&lt;String&gt;();
215      * carBuilder.setId("Car:"+nr);
216      * carBuilder.setLength(new Length.Rel(4.0, METER));
217      * carBuilder.setWidth(new Length.Rel(1.8, METER));
218      * ...
219      * LaneBasedIndividualCar&lt;String&gt; car = carBuilder.build();
220      * </pre>
221      * <p>
222      * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. <br>
223      * All rights reserved. <br>
224      * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
225      * <p>
226      * @version $Revision: 1401 $, $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, by $Author: averbraeck $,
227      *          initial Feb 3, 2015 <br>
228      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
229      */
230     @SuppressWarnings("checkstyle:hiddenfield")
231     public static class LaneBasedIndividualCarBuilder
232     {
233         /** The id of the GTU. */
234         private String id = null;
235 
236         /** The type of GTU, e.g. TruckType, CarType, BusType. */
237         private GTUType gtuType = null;
238 
239         /** The initial positions of the car on one or more lanes. */
240         private Set<DirectedLanePosition> initialLongitudinalPositions = null;
241 
242         /** The initial speed of the car on the lane. */
243         private Speed initialSpeed = null;
244 
245         /** The length of the GTU (parallel with driving direction). */
246         private Length.Rel length = null;
247 
248         /** The width of the GTU (perpendicular to driving direction). */
249         private Length.Rel width = null;
250 
251         /** The maximum speed of the GTU (in the driving direction). */
252         private Speed maximumVelocity = null;
253 
254         /** The simulator. */
255         private OTSDEVSSimulatorInterface simulator = null;
256 
257         /** Animation. */
258         private Class<? extends Renderable2D> animationClass = null;
259 
260         /** GTUColorer. */
261         private GTUColorer gtuColorer = null;
262 
263         /** Strategic planner. */
264         private LaneBasedStrategicalPlanner strategicalPlanner = null;
265 
266         /** Perception. */
267         private LanePerceptionFull perception = null;
268 
269         /** Network. */
270         private OTSNetwork network = null;
271 
272         /**
273          * @param id set id
274          * @return the class itself for chaining the setters
275          */
276         public final LaneBasedIndividualCarBuilder setId(final String id)
277         {
278             this.id = id;
279             return this;
280         }
281 
282         /**
283          * @param gtuType set gtuType
284          * @return the class itself for chaining the setters
285          */
286         public final LaneBasedIndividualCarBuilder setGtuType(final GTUType gtuType)
287         {
288             this.gtuType = gtuType;
289             return this;
290         }
291 
292         /**
293          * @param initialLongitudinalPositions set initialLongitudinalPositions
294          * @return the class itself for chaining the setters
295          */
296         public final LaneBasedIndividualCarBuilder setInitialLongitudinalPositions(
297             final Set<DirectedLanePosition> initialLongitudinalPositions)
298         {
299             this.initialLongitudinalPositions = initialLongitudinalPositions;
300             return this;
301         }
302 
303         /**
304          * @param initialSpeed set initialSpeed
305          * @return the class itself for chaining the setters
306          */
307         public final LaneBasedIndividualCarBuilder setInitialSpeed(final Speed initialSpeed)
308         {
309             this.initialSpeed = initialSpeed;
310             return this;
311         }
312 
313         /**
314          * @param length set length
315          * @return the class itself for chaining the setters
316          */
317         public final LaneBasedIndividualCarBuilder setLength(final Length.Rel length)
318         {
319             this.length = length;
320             return this;
321         }
322 
323         /**
324          * @param width set width
325          * @return the class itself for chaining the setters
326          */
327         public final LaneBasedIndividualCarBuilder setWidth(final Length.Rel width)
328         {
329             this.width = width;
330             return this;
331         }
332 
333         /**
334          * @param maximumVelocity set maximumVelocity
335          * @return the class itself for chaining the setters
336          */
337         public final LaneBasedIndividualCarBuilder setMaximumVelocity(final Speed maximumVelocity)
338         {
339             this.maximumVelocity = maximumVelocity;
340             return this;
341         }
342 
343         /**
344          * @param simulator set simulator
345          * @return the class itself for chaining the setters
346          */
347         public final LaneBasedIndividualCarBuilder setSimulator(final OTSDEVSSimulatorInterface simulator)
348         {
349             this.simulator = simulator;
350             return this;
351         }
352 
353         /**
354          * @param strategicalPlanner set strategicalPlanner
355          * @return the class itself for chaining the setters
356          */
357         public final LaneBasedIndividualCarBuilder
358             setStrategicalPlanner(LaneBasedStrategicalPlanner strategicalPlanner)
359         {
360             this.strategicalPlanner = strategicalPlanner;
361             return this;
362         }
363 
364         /**
365          * @param perception set perception
366          * @return the class itself for chaining the setters
367          */
368         public final LaneBasedIndividualCarBuilder setPerception(LanePerceptionFull perception)
369         {
370             this.perception = perception;
371             return this;
372         }
373 
374         /**
375          * @param animationClass set animation class
376          * @return the class itself for chaining the setters
377          */
378         public final LaneBasedIndividualCarBuilder
379             setAnimationClass(final Class<? extends Renderable2D> animationClass)
380         {
381             this.animationClass = animationClass;
382             return this;
383         }
384 
385         /**
386          * @param gtuColorer set gtuColorer.
387          * @return the class itself for chaining the setters
388          */
389         public final LaneBasedIndividualCarBuilder setGtuColorer(final GTUColorer gtuColorer)
390         {
391             this.gtuColorer = gtuColorer;
392             return this;
393         }
394 
395         /**
396          * @param network set network
397          * @return the class itself for chaining the setters
398          */
399         public final LaneBasedIndividualCarBuilder setNetwork(final OTSNetwork network)
400         {
401             this.network = network;
402             return this;
403         }
404 
405         /**
406          * @return id.
407          */
408         public final String getId()
409         {
410             return this.id;
411         }
412 
413         /**
414          * @return gtuType.
415          */
416         public final GTUType getGtuType()
417         {
418             return this.gtuType;
419         }
420 
421         /**
422          * @return initialLongitudinalPositions.
423          */
424         public final Set<DirectedLanePosition> getInitialLongitudinalPositions()
425         {
426             return this.initialLongitudinalPositions;
427         }
428 
429         /**
430          * @return initialSpeed.
431          */
432         public final Speed getInitialSpeed()
433         {
434             return this.initialSpeed;
435         }
436 
437         /**
438          * @return length.
439          */
440         public final Length.Rel getLength()
441         {
442             return this.length;
443         }
444 
445         /**
446          * @return width.
447          */
448         public final Length.Rel getWidth()
449         {
450             return this.width;
451         }
452 
453         /**
454          * @return maximumVelocity.
455          */
456         public final Speed getMaximumVelocity()
457         {
458             return this.maximumVelocity;
459         }
460 
461         /**
462          * @return simulator.
463          */
464         public final OTSDEVSSimulatorInterface getSimulator()
465         {
466             return this.simulator;
467         }
468 
469         /**
470          * @return strategicalPlanner
471          */
472         public final LaneBasedStrategicalPlanner getStrategicalPlanner()
473         {
474             return this.strategicalPlanner;
475         }
476 
477         /**
478          * @return perception
479          */
480         public final LanePerceptionFull getPerception()
481         {
482             return this.perception;
483         }
484 
485         /**
486          * @return animationClass.
487          */
488         public final Class<? extends Renderable2D> getAnimationClass()
489         {
490             return this.animationClass;
491         }
492 
493         /**
494          * @return gtuColorer.
495          */
496         public final GTUColorer getGtuColorer()
497         {
498             return this.gtuColorer;
499         }
500 
501         /**
502          * @return network
503          */
504         public final OTSNetwork getNetwork()
505         {
506             return this.network;
507         }
508 
509         /**
510          * Build one LaneBasedIndividualCar.
511          * @return the built Car with the set properties
512          * @throws Exception when not all required values have been set
513          */
514         public final LaneBasedIndividualGTU build() throws Exception
515         {
516             if (null == this.id || null == this.gtuType || null == this.strategicalPlanner || null == this.perception
517                 || null == this.initialLongitudinalPositions || null == this.initialSpeed || null == this.length
518                 || null == this.width || null == this.maximumVelocity || null == this.simulator || null == this.network)
519             {
520                 // TODO Should throw a more specific Exception type
521                 throw new GTUException("factory settings incomplete");
522             }
523 
524             LaneBasedIndividualGTU gtu =
525                 new LaneBasedIndividualGTU(this.id, this.gtuType, this.initialLongitudinalPositions, this.initialSpeed,
526                     this.length, this.width, this.maximumVelocity, this.simulator, this.strategicalPlanner,
527                     this.perception, this.animationClass, this.gtuColorer, this.network);
528             return gtu;
529 
530         }
531 
532     }
533 
534 }