1 package org.opentrafficsim.graphs;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertTrue;
6 import static org.junit.Assert.fail;
7
8 import java.awt.Component;
9 import java.awt.Container;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.MouseListener;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import javax.swing.JLabel;
16 import javax.swing.JOptionPane;
17
18 import nl.tudelft.simulation.dsol.SimRuntimeException;
19 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
20
21 import org.djunits.unit.AccelerationUnit;
22 import org.djunits.unit.LengthUnit;
23 import org.djunits.unit.TimeUnit;
24 import org.djunits.unit.UNITS;
25 import org.djunits.value.vdouble.scalar.Acceleration;
26 import org.djunits.value.vdouble.scalar.DoubleScalar;
27 import org.djunits.value.vdouble.scalar.Length;
28 import org.djunits.value.vdouble.scalar.Speed;
29 import org.djunits.value.vdouble.scalar.Time;
30 import org.jfree.chart.ChartPanel;
31 import org.jfree.data.DomainOrder;
32 import org.junit.Test;
33 import org.opentrafficsim.core.dsol.OTSModelInterface;
34 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
35 import org.opentrafficsim.core.geometry.OTSPoint3D;
36 import org.opentrafficsim.core.gtu.GTUType;
37 import org.opentrafficsim.core.network.LongitudinalDirectionality;
38 import org.opentrafficsim.core.network.OTSNetwork;
39 import org.opentrafficsim.core.network.OTSNode;
40 import org.opentrafficsim.road.car.CarTest;
41 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
42 import org.opentrafficsim.road.gtu.lane.tactical.following.FixedAccelerationModel;
43 import org.opentrafficsim.road.gtu.lane.tactical.following.SequentialFixedAccelerationModel;
44 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Egoistic;
45 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.LaneChangeModel;
46 import org.opentrafficsim.road.network.factory.LaneFactory;
47 import org.opentrafficsim.road.network.lane.Lane;
48 import org.opentrafficsim.road.network.lane.LaneType;
49 import org.opentrafficsim.simulationengine.SimpleSimulator;
50
51
52
53
54
55
56
57
58
59
60
61 public class ContourPlotTest implements UNITS
62 {
63
64
65
66
67
68
69
70 private List<Lane> dummyPath(final LaneType laneType, final GTUType gtuType) throws Exception
71 {
72 OTSNode b = new OTSNode("B", new OTSPoint3D(12345, 0, 0));
73 ArrayList<Lane> result = new ArrayList<Lane>();
74 Lane[] lanes =
75 LaneFactory.makeMultiLane("AtoB", new OTSNode("A", new OTSPoint3D(1234, 0, 0)), b, null, 1, laneType,
76 new Speed(100, KM_PER_HOUR), null, LongitudinalDirectionality.DIR_PLUS);
77 result.add(lanes[0]);
78
79 lanes =
80 LaneFactory.makeMultiLane("BtoC", b, new OTSNode("C", new OTSPoint3D(99999, 0, 0)), null, 1, laneType,
81 new Speed(100, KM_PER_HOUR), null, LongitudinalDirectionality.DIR_PLUS);
82
83
84 return result;
85 }
86
87
88
89
90
91 @SuppressWarnings("static-method")
92 @Test
93 public final void accelerationContourTest() throws Exception
94 {
95 LaneType laneType = new LaneType("CarLane");
96 GTUType gtuType = GTUType.makeGTUType("Car");
97 laneType.addCompatibility(gtuType);
98 List<Lane> path = dummyPath(laneType, gtuType);
99 AccelerationContourPlot acp = new AccelerationContourPlot("Acceleration", path);
100 assertTrue("newly created AccelerationContourPlot should not be null", null != acp);
101 assertEquals("SeriesKey should be \"acceleration\"", "acceleration", acp.getSeriesKey(0));
102 standardContourTests(acp, path.get(0), gtuType, Double.NaN, 0);
103 }
104
105
106
107
108
109 @SuppressWarnings("static-method")
110 @Test
111 public final void densityContourTest() throws Exception
112 {
113 LaneType laneType = new LaneType("CarLane");
114 GTUType gtuType = GTUType.makeGTUType("Car");
115 laneType.addCompatibility(gtuType);
116 List<Lane> path = dummyPath(laneType, gtuType);
117 DensityContourPlot dcp = new DensityContourPlot("Density", path);
118 assertTrue("newly created DensityContourPlot should not be null", null != dcp);
119 assertEquals("SeriesKey should be \"density\"", "density", dcp.getSeriesKey(0));
120 standardContourTests(dcp, path.get(0), gtuType, 0, Double.NaN);
121 }
122
123
124
125
126
127
128
129
130
131 static void printMatrix(ContourPlot cp, int fromX, int toX, int fromY, int toY)
132 {
133 System.out.println("Contour plot data:");
134 int maxItem = cp.getItemCount(0);
135 for (int y = fromY; y <= toY; y++)
136 {
137 System.out.print(String.format("y=%3d ", y));
138 for (int x = fromX; x <= toX; x++)
139 {
140
141 int item;
142 for (item = 0; item < maxItem; item++)
143 {
144 if (cp.getXValue(0, item) == x && cp.getYValue(0, item) == y)
145 {
146 break;
147 }
148 }
149 if (item < maxItem)
150 {
151 System.out.print(String.format("%10.6f", cp.getZValue(0, item)));
152 }
153 else
154 {
155 System.out.print(" -------- ");
156 }
157 }
158 System.out.println("");
159 }
160 System.out.print("");
161 }
162
163
164
165
166
167 @SuppressWarnings("static-method")
168 @Test
169 public final void flowContourTest() throws Exception
170 {
171 LaneType laneType = new LaneType("CarLane");
172 GTUType gtuType = GTUType.makeGTUType("Car");
173 laneType.addCompatibility(gtuType);
174 List<Lane> path = dummyPath(laneType, gtuType);
175 FlowContourPlot fcp = new FlowContourPlot("Density", path);
176 assertTrue("newly created DensityContourPlot should not be null", null != fcp);
177 assertEquals("SeriesKey should be \"flow\"", "flow", fcp.getSeriesKey(0));
178 standardContourTests(fcp, path.get(0), gtuType, 0, Double.NaN);
179 }
180
181
182
183
184
185 @SuppressWarnings("static-method")
186 @Test
187 public final void speedContourTest() throws Exception
188 {
189 LaneType laneType = new LaneType("CarLane");
190 GTUType gtuType = GTUType.makeGTUType("Car");
191 laneType.addCompatibility(gtuType);
192 List<Lane> path = dummyPath(laneType, gtuType);
193 SpeedContourPlot scp = new SpeedContourPlot("Density", path);
194 assertTrue("newly created DensityContourPlot should not be null", null != scp);
195 assertEquals("SeriesKey should be \"speed\"", "speed", scp.getSeriesKey(0));
196 standardContourTests(scp, path.get(0), gtuType, Double.NaN, 50);
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210 public static void standardContourTests(final ContourPlot cp, Lane lane, GTUType gtuType,
211 final double expectedZValue, final double expectedZValueWithTraffic) throws Exception
212 {
213 assertEquals("seriesCount should be 1", 1, cp.getSeriesCount());
214 assertEquals("domainOrder should be ASCENDING", DomainOrder.ASCENDING, cp.getDomainOrder());
215 assertEquals("indexOf always returns 0", 0, cp.indexOf(0));
216 assertEquals("indexOf always returns 0", 0, cp.indexOf("abc"));
217 assertEquals("getGroup always returns null", null, cp.getGroup());
218 int xBins = cp.xAxisBins();
219 int yBins = cp.yAxisBins();
220 int expectedXBins =
221 (int) Math.ceil((DoubleScalar.minus(ContourPlot.INITIALUPPERTIMEBOUND, ContourPlot.INITIALLOWERTIMEBOUND)
222 .getSI()) / ContourPlot.STANDARDTIMEGRANULARITIES[ContourPlot.STANDARDINITIALTIMEGRANULARITYINDEX]);
223 assertEquals("Initial xBins should be " + expectedXBins, expectedXBins, xBins);
224 int expectedYBins =
225 (int) Math.ceil(lane.getLength().getSI()
226 / ContourPlot.STANDARDDISTANCEGRANULARITIES[ContourPlot.STANDARDINITIALDISTANCEGRANULARITYINDEX]);
227 assertEquals("yBins should be " + expectedYBins, expectedYBins, yBins);
228 int bins = cp.getItemCount(0);
229 assertEquals("Total bin count is product of xBins * yBins", xBins * yBins, bins);
230
231
232 String initialLowerTimeBoundString = ContourPlot.INITIALLOWERTIMEBOUND.toString();
233 String initialUpperTimeBoundString = ContourPlot.INITIALUPPERTIMEBOUND.toString();
234
235 for (double timeGranularity : ContourPlot.STANDARDTIMEGRANULARITIES)
236 {
237 cp.actionPerformed(new ActionEvent(cp, 0, "setTimeGranularity " + timeGranularity));
238 for (double distanceGranularity : ContourPlot.STANDARDDISTANCEGRANULARITIES)
239 {
240 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity " + distanceGranularity));
241 cp.reGraph();
242 expectedXBins =
243 (int) Math.ceil((DoubleScalar.minus(ContourPlot.INITIALUPPERTIMEBOUND,
244 ContourPlot.INITIALLOWERTIMEBOUND).getSI()) / timeGranularity);
245 xBins = cp.xAxisBins();
246 assertEquals("Modified xBins should be " + expectedXBins, expectedXBins, xBins);
247 expectedYBins = (int) Math.ceil(lane.getLength().getSI() / distanceGranularity);
248 yBins = cp.yAxisBins();
249 assertEquals("Modified yBins should be " + expectedYBins, expectedYBins, yBins);
250 bins = cp.getItemCount(0);
251 assertEquals("Total bin count is product of xBins * yBins", xBins * yBins, bins);
252 for (int item = 0; item < bins; item++)
253 {
254 double x = cp.getXValue(0, item);
255 assertTrue("X should be >= " + initialLowerTimeBoundString,
256 x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI());
257 assertTrue("X should be <= " + initialUpperTimeBoundString,
258 x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI());
259 Number alternateX = cp.getX(0, item);
260 assertEquals("getXValue and getX should return things that have the same value", x,
261 alternateX.doubleValue(), 0.000001);
262 double y = cp.getYValue(0, item);
263 Number alternateY = cp.getY(0, item);
264 assertEquals("getYValue and getY should return things that have the same value", y,
265 alternateY.doubleValue(), 0.000001);
266 double z = cp.getZValue(0, item);
267 if (Double.isNaN(expectedZValue))
268 {
269 assertTrue("Z value should be NaN", Double.isNaN(z));
270 }
271 else
272 {
273 assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001);
274 }
275 Number alternateZ = cp.getZ(0, item);
276 if (Double.isNaN(expectedZValue))
277 {
278 assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue()));
279 }
280 else
281 {
282 assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue,
283 alternateZ.doubleValue(), 0.0000);
284 }
285 }
286 try
287 {
288 cp.getXValue(0, -1);
289 fail("Should have thrown an Exception");
290 }
291 catch (RuntimeException e)
292 {
293
294 }
295 try
296 {
297 cp.getXValue(0, bins);
298 fail("Should have thrown an Exception");
299 }
300 catch (RuntimeException e)
301 {
302
303 }
304 try
305 {
306 cp.yAxisBin(-1);
307 fail("Should have thrown an Exception");
308 }
309 catch (RuntimeException e)
310 {
311
312 }
313 try
314 {
315 cp.yAxisBin(bins);
316 fail("Should have thrown an Exception");
317 }
318 catch (RuntimeException e)
319 {
320
321 }
322 }
323 }
324
325 try
326 {
327 cp.actionPerformed(new ActionEvent(cp, 0, "blabla"));
328 fail("Should have thrown an Exception");
329 }
330 catch (RuntimeException e)
331 {
332
333 }
334 try
335 {
336 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity -1"));
337 fail("Should have thrown an Exception");
338 }
339 catch (RuntimeException e)
340 {
341
342 }
343 try
344 {
345 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity abc"));
346 fail("Should have thrown an Exception");
347 }
348 catch (RuntimeException e)
349 {
350
351 }
352 try
353 {
354 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularitIE 10"));
355 fail("Should have thrown an Exception");
356 }
357 catch (RuntimeException e)
358 {
359
360 }
361
362 final double useTimeGranularity = 30;
363 cp.actionPerformed(new ActionEvent(cp, 0, "setTimeGranularity " + useTimeGranularity));
364 final double useDistanceGranularity =
365 ContourPlot.STANDARDDISTANCEGRANULARITIES[ContourPlot.STANDARDDISTANCEGRANULARITIES.length - 1];
366 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity " + useDistanceGranularity));
367 cp.reGraph();
368 bins = cp.getItemCount(0);
369 Time.Abs initialTime = new Time.Abs(0, SECOND);
370 Length.Rel initialPosition = new Length.Rel(100, METER);
371 Speed initialSpeed = new Speed(50, KM_PER_HOUR);
372 ContourPlotModel model = new ContourPlotModel();
373 SimpleSimulator simulator =
374 new SimpleSimulator(initialTime, new Time.Rel(0, SECOND), new Time.Rel(1800, SECOND), model);
375
376 SequentialFixedAccelerationModel gtuFollowingModel =
377 new SequentialFixedAccelerationModel(simulator, new Acceleration(2.0, AccelerationUnit.METER_PER_SECOND_2));
378
379 gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Time.Rel(60,
380 SECOND)));
381
382 gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Time.Rel(600,
383 SECOND)));
384
385 gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Time.Rel(300,
386 SECOND)));
387 LaneChangeModel laneChangeModel = new Egoistic();
388 OTSNetwork network = new OTSNetwork("network");
389 LaneBasedIndividualGTU car =
390 CarTest.makeReferenceCar("0", gtuType, lane, initialPosition, initialSpeed, simulator, gtuFollowingModel,
391 laneChangeModel, network);
392 car.getStrategicalPlanner().getDrivingCharacteristics()
393 .setForwardHeadwayDistance(new Length.Rel(10, LengthUnit.KILOMETER));
394
395 for (int item = 0; item < bins; item++)
396 {
397 double x = cp.getXValue(0, item);
398 assertTrue("X should be >= " + ContourPlot.INITIALLOWERTIMEBOUND,
399 x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI());
400 assertTrue("X should be <= " + ContourPlot.INITIALUPPERTIMEBOUND,
401 x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI());
402 Number alternateX = cp.getX(0, item);
403 assertEquals("getXValue and getX should return things that have the same value", x,
404 alternateX.doubleValue(), 0.000001);
405 double y = cp.getYValue(0, item);
406 Number alternateY = cp.getY(0, item);
407 assertEquals("getYValue and getY should return things that have the same value", y,
408 alternateY.doubleValue(), 0.000001);
409 double z = cp.getZValue(0, item);
410 if (Double.isNaN(expectedZValue))
411 {
412 assertTrue("Z value should be NaN (got " + z + ")", Double.isNaN(z));
413 }
414 else
415 {
416 assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001);
417 }
418 Number alternateZ = cp.getZ(0, item);
419 if (Double.isNaN(expectedZValue))
420 {
421 assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue()));
422 }
423 else
424 {
425 assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue, alternateZ.doubleValue(),
426 0.0000);
427 }
428 }
429
430
431 double stopTime = gtuFollowingModel.timeAfterCompletionOfStep(0).si;
432 simulator.runUpToAndIncluding(new Time.Abs(stopTime, TimeUnit.SI));
433 while (simulator.isRunning())
434 {
435 try
436 {
437 Thread.sleep(10);
438 }
439 catch (InterruptedException ie)
440 {
441 ie = null;
442 }
443 }
444
445
446
447
448 for (int item = 0; item < bins; item++)
449 {
450 double x = cp.getXValue(0, item);
451 assertTrue("X should be >= " + ContourPlot.INITIALLOWERTIMEBOUND,
452 x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI());
453 assertTrue("X should be <= " + ContourPlot.INITIALUPPERTIMEBOUND,
454 x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI());
455 Number alternateX = cp.getX(0, item);
456 assertEquals("getXValue and getX should return things that have the same value", x,
457 alternateX.doubleValue(), 0.000001);
458 double y = cp.getYValue(0, item);
459 Number alternateY = cp.getY(0, item);
460 assertEquals("getYValue and getY should return things that have the same value", y,
461 alternateY.doubleValue(), 0.000001);
462 double z = cp.getZValue(0, item);
463
464
465
466
467
468 boolean hit = false;
469 if (x + useTimeGranularity >= 0
470 && x < 60)
471 {
472
473 Time.Abs cellStartTime =
474 new Time.Abs(Math.max(car.getOperationalPlan().getStartTime().getSI(), x), SECOND);
475 Time.Abs cellEndTime =
476 new Time.Abs(Math.min(car.getOperationalPlan().getEndTime().getSI(), x + useTimeGranularity),
477 SECOND);
478
479
480
481
482
483 double xAtCellStartTime = initialPosition.si + initialSpeed.si * cellStartTime.si;
484 double xAtCellEndTime = initialPosition.si + initialSpeed.si * cellEndTime.si;
485 if (xAtCellStartTime < y + useDistanceGranularity && xAtCellEndTime >= y)
486 {
487 hit = true;
488 }
489 }
490
491
492
493
494 Number alternateZ = cp.getZ(0, item);
495 if (hit)
496 {
497 if (!Double.isNaN(expectedZValueWithTraffic))
498 {
499 if (Double.isNaN(z))
500 {
501 printMatrix(cp, 0, 10, 0, 10);
502 System.out.println("Oops - z is NaN, expected z value with traffic is "
503 + expectedZValueWithTraffic);
504 }
505 assertEquals("Z value should be " + expectedZValueWithTraffic, expectedZValueWithTraffic, z, 0.0001);
506 assertEquals("Z value should be " + expectedZValueWithTraffic, expectedZValueWithTraffic,
507 alternateZ.doubleValue(), 0.0001);
508 }
509 else
510 {
511 if (Double.isNaN(expectedZValue))
512 {
513 assertFalse("Z value should not be NaN", Double.isNaN(z));
514 }
515 }
516 }
517 else
518 {
519 if (Double.isNaN(expectedZValue))
520 {
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539 assertTrue("Z value should be NaN", Double.isNaN(z));
540 }
541 else
542 {
543 assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001);
544 }
545 if (Double.isNaN(expectedZValue))
546 {
547 assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue()));
548 }
549 else
550 {
551 assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue,
552 alternateZ.doubleValue(), 0.0000);
553 }
554 }
555 }
556
557
558 stopTime = gtuFollowingModel.timeAfterCompletionOfStep(1).si;
559 simulator.runUpToAndIncluding(new Time.Abs(stopTime, TimeUnit.SI));
560 while (simulator.isRunning())
561 {
562 try
563 {
564 Thread.sleep(10);
565 }
566 catch (InterruptedException ie)
567 {
568 ie = null;
569 }
570 }
571
572
573 xBins = cp.xAxisBins();
574 bins = cp.getItemCount(0);
575 double observedHighestTime = Double.MIN_VALUE;
576 for (int bin = 0; bin < bins; bin++)
577 {
578 double xValue = cp.getXValue(0, bin);
579 if (xValue > observedHighestTime)
580 {
581 observedHighestTime = xValue;
582 }
583 }
584 double expectedHighestTime =
585 Math.floor((car.getSimulator().getSimulatorTime().get().si - 0.001) / useTimeGranularity)
586 * useTimeGranularity;
587 assertEquals("Time range should run up to " + expectedHighestTime, expectedHighestTime, observedHighestTime,
588 0.0001);
589
590
591 JLabel hintPanel = null;
592 ChartPanel chartPanel = null;
593 for (Component c0 : cp.getComponents())
594 {
595 for (Component c1 : ((Container) c0).getComponents())
596 {
597 if (c1 instanceof Container)
598 {
599 for (Component c2 : ((Container) c1).getComponents())
600 {
601
602 if (c2 instanceof Container)
603 {
604 for (Component c3 : ((Container) c2).getComponents())
605 {
606
607 if (c3 instanceof JLabel)
608 {
609 if (null == hintPanel)
610 {
611 hintPanel = (JLabel) c3;
612 }
613 else
614 {
615 fail("There should be only one JPanel in a ContourPlot");
616 }
617 }
618 if (c3 instanceof ChartPanel)
619 {
620 if (null == chartPanel)
621 {
622 chartPanel = (ChartPanel) c3;
623 }
624 else
625 {
626 fail("There should be only one ChartPanel in a ContourPlot");
627 }
628 }
629 }
630 }
631 }
632 }
633 }
634 }
635 if (null == hintPanel)
636 {
637 fail("Could not find a JLabel in ContourPlot");
638 }
639 if (null == chartPanel)
640 {
641 fail("Could not find a ChartPanel in ContourPlot");
642 }
643 assertEquals("Initially the text should be a single space", " ", hintPanel.getText());
644 PointerHandler ph = null;
645 for (MouseListener ml : chartPanel.getMouseListeners())
646 {
647 if (ml instanceof PointerHandler)
648 {
649 if (null == ph)
650 {
651 ph = (PointerHandler) ml;
652 }
653 else
654 {
655 fail("There should be only one PointerHandler on the chartPanel");
656 }
657 }
658 }
659 if (null == ph)
660 {
661 fail("Could not find the PointerHandler for the chartPanel");
662 }
663 ph.updateHint(1, 2);
664
665 assertFalse("Hint should not be a single space", " ".equals(hintPanel.getText()));
666 ph.updateHint(Double.NaN, Double.NaN);
667 assertEquals("The text should again be a single space", " ", hintPanel.getText());
668 }
669
670
671
672
673
674
675 public static void main(final String[] args) throws Exception
676 {
677 ContourPlotTest cpt = new ContourPlotTest();
678 System.out.println("Click the OK button");
679 JOptionPane.showMessageDialog(null, "ContourPlot", "Start experiment", JOptionPane.INFORMATION_MESSAGE);
680 System.out.println("Running ...");
681 cpt.densityContourTest();
682 System.out.println("Finished");
683 }
684
685 }
686
687
688
689
690
691
692
693
694
695
696 class ContourPlotModel implements OTSModelInterface
697 {
698
699
700 private static final long serialVersionUID = 20150209L;
701
702
703 @Override
704 public void constructModel(
705 SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> simulator)
706 throws SimRuntimeException
707 {
708
709 }
710
711
712 @Override
713 public SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getSimulator()
714
715 {
716 return null;
717 }
718
719 }