View Javadoc
1   package org.opentrafficsim.graphs;
2   
3   import static org.junit.Assert.assertEquals;
4   
5   import java.rmi.RemoteException;
6   
7   import org.junit.Test;
8   import org.opentrafficsim.core.car.LaneBasedIndividualCar;
9   import org.opentrafficsim.core.network.NetworkException;
10  import org.opentrafficsim.core.network.lane.Lane;
11  import org.opentrafficsim.core.unit.LengthUnit;
12  import org.opentrafficsim.core.unit.TimeUnit;
13  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar;
14  
15  /**
16   * <p>
17   * Copyright (c) 2013-2014 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
18   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
19   * <p>
20   * @version Aug 22, 2014 <br>
21   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
22   */
23  public class TrajectoryPlotTest
24  {
25      /** Sample interval for the TrajectoryPlot. */
26      DoubleScalar.Rel<TimeUnit> sampleInterval = new DoubleScalar.Rel<TimeUnit>(0.25, TimeUnit.SECOND);
27  
28      /**
29       * Test the TrajectoryPlot.
30       * @throws Exception which should not happen, but will be treated as an error by the JUnit framework if it does
31       */
32      @Test
33      public final void trajectoryTest() throws Exception
34      {
35          DoubleScalar.Rel<LengthUnit> minimumDistance = new DoubleScalar.Rel<LengthUnit>(1234, LengthUnit.METER);
36          DoubleScalar.Rel<LengthUnit> maximumDistance = new DoubleScalar.Rel<LengthUnit>(12345, LengthUnit.METER);
37  
38          // TODO adapt to new path (List<Lane>) concept
39          /*-
40          TrajectoryPlot tp = new TrajectoryPlot("Trajectory", this.sampleInterval, minimumDistance, maximumDistance);
41          assertTrue("newly created DensityContourPlot should not be null", null != tp);
42          assertEquals("Number of trajectories should initially be 0", 0, tp.getSeriesCount());
43          for (int i = -10; i <= 10; i++)
44          {
45              assertEquals("SeriesKey(" + i + ") should return " + i, i, tp.getSeriesKey(i));
46          }
47          assertEquals("Domain order should be ASCENDING", DomainOrder.ASCENDING, tp.getDomainOrder());
48          // Create a car running 50 km.h
49          DoubleScalar.Rel<LengthUnit> initialPosition = new DoubleScalar.Rel<LengthUnit>(2000, LengthUnit.METER);
50          DoubleScalar.Abs<SpeedUnit> initialSpeed = new DoubleScalar.Abs<SpeedUnit>(50, SpeedUnit.KM_PER_HOUR);
51          GTUType<String> carType = new GTUType<String>("Car");
52          DoubleScalar.Rel<LengthUnit> length = new DoubleScalar.Rel<LengthUnit>(5.0, LengthUnit.METER);
53          DoubleScalar.Rel<LengthUnit> width = new DoubleScalar.Rel<LengthUnit>(2.0, LengthUnit.METER);
54          Map<Lane, DoubleScalar.Rel<LengthUnit>> initialLongitudinalPositions = new HashMap<>();
55          Lane lane = CarTest.makeLane();
56          initialLongitudinalPositions.put(lane, initialPosition);
57          OTSDEVSSimulator simulator = CarTest.makeSimulator();
58          // We want to start the car simulation at t=100s; therefore we have to advance the simulator up to that time.
59          simulateUntil(new DoubleScalar.Abs<TimeUnit>(100, TimeUnit.SECOND), simulator);
60          DoubleScalar.Abs<SpeedUnit> maxSpeed = new DoubleScalar.Abs<SpeedUnit>(120, SpeedUnit.KM_PER_HOUR);
61          Car<Integer> car =
62              new Car<Integer>(12345, carType, null, initialLongitudinalPositions, initialSpeed, length, width, maxSpeed,
63                  simulator);
64          // Make the car accelerate with constant acceleration of 0.05 m/s/s for 400 seconds
65          DoubleScalar.Rel<TimeUnit> duration = new DoubleScalar.Rel<TimeUnit>(400, TimeUnit.SECOND);
66          DoubleScalar.Abs<TimeUnit> endTime = DoubleScalar.plus(simulator.getSimulatorTime().get(), duration).immutable();
67          car.setState(new GTUFollowingModelResult(new DoubleScalar.Abs<AccelerationUnit>(0.05,
68              AccelerationUnit.METER_PER_SECOND_2), endTime));
69          // System.out.println("Car end position " + car.getPosition(car.getNextEvaluationTime()));
70          tp.addData(car);
71          assertEquals("Number of trajectories should now be 1", 1, tp.getSeriesCount());
72          verifyTrajectory(car, 0, tp);
73          simulateUntil(new DoubleScalar.Abs<TimeUnit>(150, TimeUnit.SECOND), simulator);
74          Car<Integer> secondCar =
75              new Car<Integer>(2, carType, null, initialLongitudinalPositions, initialSpeed, length, width, maxSpeed,
76                  simulator);
77          // Make the second car accelerate with constant acceleration of 0.03 m/s/s for 500 seconds
78          secondCar.setState(new GTUFollowingModelResult(new DoubleScalar.Abs<AccelerationUnit>(0.03,
79              AccelerationUnit.METER_PER_SECOND_2), endTime));
80          // System.out.println("Second car end position " + car.getPosition(secondCar.getNextEvaluationTime()));
81          tp.addData(secondCar);
82          assertEquals("Number of trajectories should now be 2", 2, tp.getSeriesCount());
83          verifyTrajectory(car, 0, tp); // first car trajectory should not change by adding the second
84          verifyTrajectory(secondCar, 1, tp);
85          // Check the updateHint method in the PointerHandler
86          // First get the panel that stores the result of updateHint (this is ugly)
87          JLabel hintPanel = null;
88          ChartPanel chartPanel = null;
89          for (Component c0 : tp.getComponents())
90          {
91              for (Component c1 : ((Container) c0).getComponents())
92              {
93                  if (c1 instanceof Container)
94                  {
95                      for (Component c2 : ((Container) c1).getComponents())
96                      {
97                          // System.out.println("c2 is " + c2);
98                          if (c2 instanceof Container)
99                          {
100                             for (Component c3 : ((Container) c2).getComponents())
101                             {
102                                 // System.out.println("c3 is " + c3);
103                                 if (c3 instanceof JLabel)
104                                 {
105                                     if (null == hintPanel)
106                                     {
107                                         hintPanel = (JLabel) c3;
108                                     }
109                                     else
110                                     {
111                                         fail("There should be only one JPanel in a ContourPlot");
112                                     }
113                                 }
114                                 if (c3 instanceof ChartPanel)
115                                 {
116                                     if (null == chartPanel)
117                                     {
118                                         chartPanel = (ChartPanel) c3;
119                                     }
120                                     else
121                                     {
122                                         fail("There should be only one ChartPanel in a ContourPlot");
123                                     }
124                                 }
125                             }
126                         }
127                     }
128                 }
129             }
130         }
131         if (null == hintPanel)
132         {
133             fail("Could not find a JLabel in ContourPlot");
134         }
135         if (null == chartPanel)
136         {
137             fail("Could not find a ChartPanel in ContourPlot");
138         }
139         assertEquals("Initially the text should be a single space", " ", hintPanel.getText());
140         PointerHandler ph = null;
141         for (MouseListener ml : chartPanel.getMouseListeners())
142         {
143             if (ml instanceof PointerHandler)
144             {
145                 if (null == ph)
146                 {
147                     ph = (PointerHandler) ml;
148                 }
149                 else
150                 {
151                     fail("There should be only one PointerHandler on the chartPanel");
152                 }
153             }
154         }
155         if (null == ph)
156         {
157             fail("Could not find the PointerHandler for the chartPanel");
158         }
159         ph.updateHint(1, 2);
160         // System.out.println("Hint text is now " + hintPanel.getText());
161         assertFalse("Hint should not be a single space", " ".equals(hintPanel.getText()));
162         ph.updateHint(Double.NaN, Double.NaN);
163         assertEquals("The text should again be a single space", " ", hintPanel.getText());
164          */
165     }
166 
167     /**
168      * Verify that a sampled trajectory matches the actual trajectory.
169      * @param car Car; the car whose trajectory was sampled
170      * @param series Integer; the series in the TrajectoryPlot that should correspond to the car
171      * @param tp TrajectoryPlot; the TrajectoryPlot that contains the samples
172      * @throws NetworkException when car is not on lane anymore
173      * @throws RemoteException on communication failure
174      */
175     private void verifyTrajectory(final LaneBasedIndividualCar<?> car, final int series, final TrajectoryPlot tp) throws NetworkException,
176         RemoteException
177     {
178         // XXX we take the first (and only) lane on which the vehicle is registered.
179         Lane lane = car.positions(car.getFront()).keySet().iterator().next();
180         DoubleScalar.Abs<TimeUnit> initialTime = car.getLastEvaluationTime();
181         DoubleScalar.Rel<TimeUnit> duration =
182             DoubleScalar.minus(car.getNextEvaluationTime(), car.getLastEvaluationTime()).immutable();
183         int expectedNumberOfSamples = (int) (duration.getSI() / this.sampleInterval.getSI());
184         assertEquals("Number of samples in trajectory should be ", expectedNumberOfSamples, tp.getItemCount(series));
185         // Check that the stored trajectory accurately matches the trajectory of the car at all sampling times
186         for (int sample = 0; sample < expectedNumberOfSamples; sample++)
187         {
188             DoubleScalar.Rel<TimeUnit> deltaTime =
189                 new DoubleScalar.Rel<TimeUnit>(this.sampleInterval.getSI() * sample, TimeUnit.SECOND);
190             DoubleScalar.Abs<TimeUnit> sampleTime = DoubleScalar.plus(initialTime, deltaTime).immutable();
191             double sampledTime = tp.getXValue(series, sample);
192             assertEquals("Sample should have been taken at " + sampleTime, sampleTime.getSI(), sampledTime, 0.0001);
193             sampledTime = tp.getX(series, sample).doubleValue();
194             assertEquals("Sample should have been taken at " + sampleTime, sampleTime.getSI(), sampledTime, 0.0001);
195             DoubleScalar.Rel<LengthUnit> actualPosition = car.position(lane, car.getFront(), sampleTime);
196             double sampledPosition = tp.getYValue(series, sample);
197             assertEquals("Sample position should have been " + actualPosition, actualPosition.getSI(), sampledPosition,
198                 0.0001);
199             sampledPosition = tp.getY(series, sample).doubleValue();
200             assertEquals("Sample position should have been " + actualPosition, actualPosition.getSI(), sampledPosition,
201                 0.0001);
202         }
203     }
204 
205 }