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