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.HashMap;
7 import java.util.HashSet;
8 import java.util.Map;
9 import java.util.Set;
10
11 import javax.naming.NamingException;
12
13 import org.djunits.value.vdouble.scalar.Acceleration;
14 import org.djunits.value.vdouble.scalar.Length;
15 import org.djunits.value.vdouble.scalar.Speed;
16 import org.opentrafficsim.core.geometry.OTSGeometryException;
17 import org.opentrafficsim.core.gtu.GTUException;
18 import org.opentrafficsim.core.gtu.GTUType;
19 import org.opentrafficsim.core.gtu.RelativePosition;
20 import org.opentrafficsim.core.gtu.RelativePosition.TYPE;
21 import org.opentrafficsim.core.gtu.animation.GTUColorer;
22 import org.opentrafficsim.core.network.NetworkException;
23 import org.opentrafficsim.core.network.Node;
24 import org.opentrafficsim.core.network.OTSNetwork;
25 import org.opentrafficsim.core.network.route.Route;
26 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
27 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
28 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
29
30 import nl.tudelft.simulation.dsol.SimRuntimeException;
31 import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
32 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
33 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
34 import nl.tudelft.simulation.immutablecollections.Immutable;
35 import nl.tudelft.simulation.immutablecollections.ImmutableHashSet;
36 import nl.tudelft.simulation.immutablecollections.ImmutableLinkedHashMap;
37 import nl.tudelft.simulation.immutablecollections.ImmutableMap;
38 import nl.tudelft.simulation.immutablecollections.ImmutableSet;
39 import nl.tudelft.simulation.language.reflection.ClassUtil;
40
41
42
43
44
45
46
47
48
49
50
51
52 public class LaneBasedIndividualGTU extends AbstractLaneBasedIndividualGTU
53 {
54
55 private static final long serialVersionUID = 20141025L;
56
57
58 private Renderable2D<? super LaneBasedIndividualGTU> animation;
59
60
61 private final Map<RelativePosition.TYPE, RelativePosition> relativePositions = new HashMap<>();
62
63
64 private final RelativePosition frontPos;
65
66
67 private final RelativePosition rearPos;
68
69
70 private final Set<RelativePosition> contourPoints = new HashSet<>();
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 @SuppressWarnings("checkstyle:parameternumber")
86 public LaneBasedIndividualGTU(final String id, final GTUType gtuType, final Length length, final Length width,
87 final Speed maximumSpeed, final Length front, final DEVSSimulatorInterface.TimeDoubleUnit simulator, final OTSNetwork network)
88 throws NamingException, GTUException
89 {
90 super(id, gtuType, length, width, maximumSpeed, simulator, network);
91
92
93 Length dy2 = getWidth().multiplyBy(0.5);
94 this.frontPos = new RelativePosition(front, Length.ZERO, Length.ZERO, RelativePosition.FRONT);
95 this.relativePositions.put(RelativePosition.FRONT, this.frontPos);
96 this.rearPos = new RelativePosition(front.minus(getLength()), Length.ZERO, Length.ZERO, RelativePosition.REAR);
97 this.relativePositions.put(RelativePosition.REAR, this.rearPos);
98 this.relativePositions.put(RelativePosition.REFERENCE, RelativePosition.REFERENCE_POSITION);
99 this.relativePositions.put(RelativePosition.CENTER,
100 new RelativePosition(Length.ZERO, Length.ZERO, Length.ZERO, RelativePosition.CENTER));
101
102
103 for (int i = -1; i <= 1; i += 2)
104 {
105 Length x = i < 0 ? front.minus(getLength()) : front;
106 for (int j = -1; j <= 1; j += 2)
107 {
108 this.contourPoints.add(new RelativePosition(x, dy2.multiplyBy(j), Length.ZERO, RelativePosition.CONTOUR));
109 }
110 }
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125 @SuppressWarnings("unchecked")
126 public final void initWithAnimation(final LaneBasedStrategicalPlanner strategicalPlanner,
127 final Set<DirectedLanePosition> initialLongitudinalPositions, final Speed initialSpeed,
128 final Class<? extends Renderable2D<? super LaneBasedIndividualGTU>> animationClass, final GTUColorer gtuColorer)
129 throws NetworkException, SimRuntimeException, GTUException, OTSGeometryException
130 {
131 super.init(strategicalPlanner, initialLongitudinalPositions, initialSpeed);
132
133
134 if (getSimulator() instanceof AnimatorInterface && animationClass != null)
135 {
136 try
137 {
138 Constructor<?> constructor;
139
140 if (null == gtuColorer)
141 {
142 constructor = ClassUtil.resolveConstructor(animationClass, new Object[] { this, getSimulator() });
143 this.animation = (Renderable2D<LaneBasedIndividualGTU>) constructor.newInstance(this, getSimulator());
144 }
145 else
146 {
147 constructor =
148 ClassUtil.resolveConstructor(animationClass, new Object[] { this, getSimulator(), gtuColorer });
149 this.animation =
150 (Renderable2D<LaneBasedIndividualGTU>) constructor.newInstance(this, getSimulator(), gtuColorer);
151 }
152 }
153 catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException
154 | IllegalArgumentException | InvocationTargetException exception)
155 {
156 throw new GTUException("Could not instantiate car animation of type " + animationClass.getName(), exception);
157 }
158 }
159 }
160
161
162 @Override
163 public final RelativePosition getFront()
164 {
165 return this.frontPos;
166 }
167
168
169 @Override
170 public final RelativePosition getRear()
171 {
172 return this.rearPos;
173 }
174
175
176 @Override
177 public final RelativePosition getCenter()
178 {
179 return this.relativePositions.get(RelativePosition.CENTER);
180 }
181
182
183 @Override
184 public final ImmutableMap<TYPE, RelativePosition> getRelativePositions()
185 {
186 return new ImmutableLinkedHashMap<>(this.relativePositions, Immutable.WRAP);
187 }
188
189
190 @Override
191 public final ImmutableSet<RelativePosition> getContourPoints()
192 {
193 return new ImmutableHashSet<>(this.contourPoints, Immutable.WRAP);
194 }
195
196
197 @Override
198 public final void destroy()
199 {
200 if (this.animation != null)
201 {
202 try
203 {
204 this.animation.destroy();
205 this.animation = null;
206 }
207 catch (@SuppressWarnings("unused") Exception e)
208 {
209 System.err.println("Error when destroying the animation of car: " + this.getId());
210 }
211 }
212 super.destroy();
213 }
214
215
216 @Override
217 public final String toString()
218 {
219 return "LaneBasedIndividualGTU [id=" + getId() + "]";
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247 @SuppressWarnings("checkstyle:hiddenfield")
248 public static class LaneBasedIndividualCarBuilder implements Serializable
249 {
250
251 private static final long serialVersionUID = 20160000L;
252
253
254 private String id = null;
255
256
257 private GTUType gtuType = null;
258
259
260 private Set<DirectedLanePosition> initialLongitudinalPositions = null;
261
262
263 private Speed initialSpeed = null;
264
265
266 private Length length = null;
267
268
269 private Length width = null;
270
271
272 private Speed maximumSpeed = null;
273
274
275 private Acceleration maximumAcceleration = null;
276
277
278 private Acceleration maximumDeceleration = null;
279
280
281 private Length front = null;
282
283
284 private DEVSSimulatorInterface.TimeDoubleUnit simulator = null;
285
286
287 private Class<? extends Renderable2D<? super LaneBasedIndividualGTU>> animationClass = null;
288
289
290 private GTUColorer gtuColorer = null;
291
292
293 private OTSNetwork network = null;
294
295
296
297
298
299 public final LaneBasedIndividualCarBuilder setId(final String id)
300 {
301 this.id = id;
302 return this;
303 }
304
305
306
307
308
309 public final LaneBasedIndividualCarBuilder setGtuType(final GTUType gtuType)
310 {
311 this.gtuType = gtuType;
312 return this;
313 }
314
315
316
317
318
319 public final LaneBasedIndividualCarBuilder setInitialLongitudinalPositions(
320 final Set<DirectedLanePosition> initialLongitudinalPositions)
321 {
322 this.initialLongitudinalPositions = initialLongitudinalPositions;
323 return this;
324 }
325
326
327
328
329
330 public final LaneBasedIndividualCarBuilder setInitialSpeed(final Speed initialSpeed)
331 {
332 this.initialSpeed = initialSpeed;
333 return this;
334 }
335
336
337
338
339
340 public final LaneBasedIndividualCarBuilder setLength(final Length length)
341 {
342 this.length = length;
343 return this;
344 }
345
346
347
348
349
350 public final LaneBasedIndividualCarBuilder setWidth(final Length width)
351 {
352 this.width = width;
353 return this;
354 }
355
356
357
358
359
360 public final LaneBasedIndividualCarBuilder setMaximumSpeed(final Speed maximumSpeed)
361 {
362 this.maximumSpeed = maximumSpeed;
363 return this;
364 }
365
366
367
368
369
370 public final LaneBasedIndividualCarBuilder setMaximumAcceleration(final Acceleration maximumAcceleration)
371 {
372 this.maximumAcceleration = maximumAcceleration;
373 return this;
374 }
375
376
377
378
379
380 public final LaneBasedIndividualCarBuilder setMaximumDeceleration(final Acceleration maximumDeceleration)
381 {
382 this.maximumDeceleration = maximumDeceleration;
383 return this;
384 }
385
386
387
388
389
390 public final LaneBasedIndividualCarBuilder setSimulator(final DEVSSimulatorInterface.TimeDoubleUnit simulator)
391 {
392 this.simulator = simulator;
393 return this;
394 }
395
396
397
398
399
400 public final LaneBasedIndividualCarBuilder setFront(final Length front)
401 {
402 this.front = front;
403 return this;
404 }
405
406
407
408
409
410 public final LaneBasedIndividualCarBuilder setAnimationClass(
411 final Class<? extends Renderable2D<? super LaneBasedIndividualGTU>> animationClass)
412 {
413 this.animationClass = animationClass;
414 return this;
415 }
416
417
418
419
420
421 public final LaneBasedIndividualCarBuilder setGtuColorer(final GTUColorer gtuColorer)
422 {
423 this.gtuColorer = gtuColorer;
424 return this;
425 }
426
427
428
429
430
431 public final LaneBasedIndividualCarBuilder setNetwork(final OTSNetwork network)
432 {
433 this.network = network;
434 return this;
435 }
436
437
438
439
440 public final String getId()
441 {
442 return this.id;
443 }
444
445
446
447
448 public final GTUType getGtuType()
449 {
450 return this.gtuType;
451 }
452
453
454
455
456 public final Set<DirectedLanePosition> getInitialLongitudinalPositions()
457 {
458 return this.initialLongitudinalPositions;
459 }
460
461
462
463
464 public final Speed getInitialSpeed()
465 {
466 return this.initialSpeed;
467 }
468
469
470
471
472 public final Length getLength()
473 {
474 return this.length;
475 }
476
477
478
479
480 public final Length getWidth()
481 {
482 return this.width;
483 }
484
485
486
487
488 public final Speed getMaximumSpeed()
489 {
490 return this.maximumSpeed;
491 }
492
493
494
495
496 public final DEVSSimulatorInterface.TimeDoubleUnit getSimulator()
497 {
498 return this.simulator;
499 }
500
501
502
503
504 public final Class<? extends Renderable2D<? super LaneBasedIndividualGTU>> getAnimationClass()
505 {
506 return this.animationClass;
507 }
508
509
510
511
512 public final GTUColorer getGtuColorer()
513 {
514 return this.gtuColorer;
515 }
516
517
518
519
520 public final OTSNetwork getNetwork()
521 {
522 return this.network;
523 }
524
525
526
527
528
529
530
531
532
533
534 public final LaneBasedIndividualGTU build(
535 final LaneBasedStrategicalPlannerFactory<? extends LaneBasedStrategicalPlanner> laneBasedStrategicalPlannerFactory,
536 final Route route, final Node origin, final Node destination) throws Exception
537 {
538 if (null == this.id || null == this.gtuType || null == this.initialLongitudinalPositions
539 || null == this.initialSpeed || null == this.length || null == this.width || null == this.maximumSpeed
540 || null == this.maximumAcceleration || null == this.maximumDeceleration || null == this.front
541 || null == this.simulator || null == this.network)
542 {
543
544 throw new GTUException("factory settings incomplete");
545 }
546 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU(this.id, this.gtuType, this.length, this.width,
547 this.maximumSpeed, this.front, this.simulator, this.network);
548 gtu.setMaximumAcceleration(this.maximumAcceleration);
549 gtu.setMaximumDeceleration(this.maximumDeceleration);
550 gtu.initWithAnimation(laneBasedStrategicalPlannerFactory.create(gtu, route, origin, destination),
551 this.initialLongitudinalPositions, this.initialSpeed, this.animationClass, this.gtuColorer);
552 return gtu;
553
554 }
555
556
557 @Override
558 public final String toString()
559 {
560 return "LaneBasedIndividualCarBuilder [id=" + this.id + ", gtuType=" + this.gtuType
561 + ", initialLongitudinalPositions=" + this.initialLongitudinalPositions + ", initialSpeed="
562 + this.initialSpeed + ", length=" + this.length + ", width=" + this.width + ", maximumSpeed="
563 + this.maximumSpeed + ", strategicalPlanner=" + "]";
564 }
565
566 }
567
568 }