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