View Javadoc
1   package org.opentrafficsim.core.network.lane;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.fail;
5   
6   import java.awt.geom.Rectangle2D;
7   import java.rmi.RemoteException;
8   import java.util.HashMap;
9   import java.util.Map;
10  import java.util.Set;
11  
12  import javax.naming.NamingException;
13  
14  import nl.tudelft.simulation.dsol.SimRuntimeException;
15  import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
16  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
17  
18  import org.junit.Test;
19  import org.opentrafficsim.core.car.LaneBasedIndividualCar;
20  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
21  import org.opentrafficsim.core.dsol.OTSModelInterface;
22  import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
23  import org.opentrafficsim.core.gtu.GTUException;
24  import org.opentrafficsim.core.gtu.GTUType;
25  import org.opentrafficsim.core.gtu.following.FixedAccelerationModel;
26  import org.opentrafficsim.core.gtu.lane.changing.Egoistic;
27  import org.opentrafficsim.core.gtu.lane.changing.LaneChangeModel;
28  import org.opentrafficsim.core.network.NetworkException;
29  import org.opentrafficsim.core.network.factory.LaneFactory;
30  import org.opentrafficsim.core.network.geotools.NodeGeotools;
31  import org.opentrafficsim.core.unit.AccelerationUnit;
32  import org.opentrafficsim.core.unit.LengthUnit;
33  import org.opentrafficsim.core.unit.SpeedUnit;
34  import org.opentrafficsim.core.unit.TimeUnit;
35  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar;
36  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar.Abs;
37  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar.Rel;
38  import org.opentrafficsim.simulationengine.SimpleSimulator;
39  
40  import com.vividsolutions.jts.geom.Coordinate;
41  
42  /**
43   * Test SensorLaneEnd and SensorLaneStart.
44   * <p>
45   * Copyright (c) 2013-2014 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights
46   * reserved. <br>
47   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
48   * <p>
49   * @version 16 jan. 2015 <br>
50   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
51   */
52  public class SensorTest
53  {
54      /**
55       * Test the constructors of SensorLaneEnd and SensorLaneStart
56       * @throws SimRuntimeException
57       * @throws RemoteException
58       * @throws NamingException
59       * @throws NetworkException
60       * @throws GTUException
61       */
62      @Test
63      public void sensorLaneStartEndTest() throws RemoteException, SimRuntimeException, NamingException,
64              NetworkException, GTUException
65      {
66          // First we need a set of Lanes
67          // To create Lanes we need Nodes and a LaneType
68          NodeGeotools.STR nodeAFrom = new NodeGeotools.STR("AFrom", new Coordinate(0, 0, 0));
69          NodeGeotools.STR nodeATo = new NodeGeotools.STR("ATo", new Coordinate(1000, 0, 0));
70          LaneType<String> laneType = new LaneType<String>("CarLane");
71          // And a simulator, but for that we first need something that implements OTSModelInterface
72          OTSModelInterface model = new DummyModelForSensorTest();
73          final SimpleSimulator simulator =
74                  new SimpleSimulator(new DoubleScalar.Abs<TimeUnit>(0.0, TimeUnit.SECOND),
75                          new DoubleScalar.Rel<TimeUnit>(0.0, TimeUnit.SECOND), new DoubleScalar.Rel<TimeUnit>(3600.0,
76                                  TimeUnit.SECOND), model, new Rectangle2D.Double(-1000, -1000, 2000, 2000));
77          Lane[] lanes =
78                  LaneFactory.makeMultiLane("A", nodeAFrom, nodeATo, null, 3, laneType,
79                          (OTSDEVSSimulatorInterface) simulator.getSimulator());
80          // Check that there is a SensorLaneStart and a SensorLaneEnd on each Lane
81          for (Lane l : lanes)
82          {
83              int sensorsFound = 0;
84              for (Sensor sensor : l.getSensors(new DoubleScalar.Rel<LengthUnit>(0, LengthUnit.METER),
85                      new DoubleScalar.Rel<LengthUnit>(Double.MAX_VALUE, LengthUnit.METER)))
86              {
87                  sensorsFound++;
88                  if (sensor instanceof SensorLaneStart)
89                  {
90                      assertEquals("SensorLaneStart should be at beginning of the Lane", 0, sensor
91                              .getLongitudinalPosition().getSI(), 0.00001);
92                  }
93                  else if (sensor instanceof SensorLaneEnd)
94                  {
95                      assertEquals("SensorLaneEnd should be (almost) at end of the Lane", l.getLength().getSI(), sensor
96                              .getLongitudinalPosition().getSI(), 2 * Math.ulp(l.getLength().getSI()));
97                  }
98                  else
99                  {
100                     fail("Unexpected sensor: " + sensor.toString());
101                 }
102             }
103             assertEquals("There should be two sensor on each Lane", 2, sensorsFound);
104         }
105         Map<Lane, DoubleScalar.Rel<LengthUnit>> initialLongitudinalPositions =
106                 new HashMap<Lane, DoubleScalar.Rel<LengthUnit>>();
107 
108         DoubleScalar.Rel<LengthUnit> positionA = new DoubleScalar.Rel<LengthUnit>(100, LengthUnit.METER);
109         initialLongitudinalPositions.put(lanes[1], positionA);
110         // A Car needs a type
111         GTUType<String> gtuType = new GTUType<String>("Car");
112         // A Car needs an initial speed
113         DoubleScalar.Abs<SpeedUnit> initialSpeed = new DoubleScalar.Abs<SpeedUnit>(50, SpeedUnit.KM_PER_HOUR);
114         // Length of the Car
115         DoubleScalar.Rel<LengthUnit> carLength = new DoubleScalar.Rel<LengthUnit>(4, LengthUnit.METER);
116         // Width of the Car
117         DoubleScalar.Rel<LengthUnit> carWidth = new DoubleScalar.Rel<LengthUnit>(1.8, LengthUnit.METER);
118         // Maximum velocity of the Car
119         DoubleScalar.Abs<SpeedUnit> maximumVelocity = new DoubleScalar.Abs<SpeedUnit>(200, SpeedUnit.KM_PER_HOUR);
120         // ID of the Car
121         String carID = "theCar";
122         // Create an acceleration profile for the car
123         FixedAccelerationModel fas =
124                 new FixedAccelerationModel(new DoubleScalar.Abs<AccelerationUnit>(0.5,
125                         AccelerationUnit.METER_PER_SECOND_2), new DoubleScalar.Rel<TimeUnit>(100, TimeUnit.SECOND));
126         // Create a lane change model for the car
127         LaneChangeModel laneChangeModel = new Egoistic();
128         // Now we can make a GTU (and we don't even have to hold a pointer to it)
129         new LaneBasedIndividualCar<String>(carID, gtuType, fas, laneChangeModel, initialLongitudinalPositions,
130                 initialSpeed, carLength, carWidth, maximumVelocity,
131                 (OTSDEVSSimulatorInterface) simulator.getSimulator());
132         simulator.runUpTo(new DoubleScalar.Abs<TimeUnit>(1, TimeUnit.SECOND));
133         // Construction of the car scheduled a car move event at t=0
134         Set<SimEventInterface<OTSSimTimeDouble>> eventList = simulator.getSimulator().getEventList();
135         SimEventInterface<OTSSimTimeDouble> triggerEvent = null;
136         int index = 0;
137         for (SimEventInterface<OTSSimTimeDouble> event : eventList)
138         {
139             // System.out.println("Scheduled Event " + event);
140             if (0 == index)
141             {
142                 triggerEvent = event;
143             }
144             index++;
145         }
146         assertEquals("There should be three scheduled events (trigger, car.move, terminate)", 3, eventList.size());
147         // The sensor should be triggered around t=38.3403 (exact value: 10 / 9 * (sqrt(3541) - 25))
148         // System.out.println("trigger event is " + triggerEvent);
149         assertEquals("Trigger event should be around 38.3403", 38.3403, triggerEvent.getAbsoluteExecutionTime().get()
150                 .getSI(), 0.0001);
151         // TODO setup a test that verifies trigger of a SensorLaneStart; this is not (yet) possible
152     }
153 }
154 
155 /**
156  * Dummy OTSModelInterface.
157  * <p>
158  * Copyright (c) 2013-2014 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights
159  * reserved. <br>
160  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
161  * <p>
162  * @version 14 jan. 2015 <br>
163  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
164  */
165 class DummyModelForSensorTest implements OTSModelInterface
166 {
167     /** */
168     private static final long serialVersionUID = 20150114L;
169 
170     /** The simulator. */
171     private SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> simulator;
172 
173     /**
174      * Register the simulator.
175      * @param simulator SimulatorInterface&lt;DoubleScalar.Abs&lt;TimeUnit&gt;, DoubleScalar.Rel&lt;TimeUnit&gt;,
176      *            OTSSimTimeDouble&gt;; the simulator
177      */
178     public void setSimulator(
179             SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> simulator)
180     {
181         this.simulator = simulator;
182     }
183 
184     /** {@inheritDoc} */
185     @Override
186     public void constructModel(SimulatorInterface<Abs<TimeUnit>, Rel<TimeUnit>, OTSSimTimeDouble> arg0)
187             throws SimRuntimeException, RemoteException
188     {
189         // Nothing happens here
190     }
191 
192     /** {@inheritDoc} */
193     @Override
194     public SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getSimulator()
195             throws RemoteException
196     {
197         if (null == this.simulator)
198         {
199             throw new Error("getSimulator called, but simulator field is null");
200         }
201         return this.simulator;
202     }
203 
204 }