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