View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import static org.opentrafficsim.core.gtu.GTUType.CAR;
4   
5   import java.util.LinkedHashSet;
6   import java.util.Set;
7   
8   import org.djunits.unit.TimeUnit;
9   import org.djunits.unit.UNITS;
10  import org.djunits.value.vdouble.scalar.Acceleration;
11  import org.djunits.value.vdouble.scalar.Duration;
12  import org.djunits.value.vdouble.scalar.Length;
13  import org.djunits.value.vdouble.scalar.Speed;
14  import org.djunits.value.vdouble.scalar.Time;
15  import org.junit.Test;
16  import org.opentrafficsim.base.parameters.Parameters;
17  import org.opentrafficsim.core.compatibility.Compatible;
18  import org.opentrafficsim.core.dsol.OTSModelInterface;
19  import org.opentrafficsim.core.geometry.OTSPoint3D;
20  import org.opentrafficsim.core.gtu.GTUDirectionality;
21  import org.opentrafficsim.core.gtu.GTUType;
22  import org.opentrafficsim.core.gtu.RelativePosition;
23  import org.opentrafficsim.core.network.Network;
24  import org.opentrafficsim.core.network.NetworkException;
25  import org.opentrafficsim.core.network.OTSNetwork;
26  import org.opentrafficsim.core.network.OTSNode;
27  import org.opentrafficsim.road.DefaultTestParameters;
28  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
29  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
30  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlanner;
31  import org.opentrafficsim.road.gtu.lane.tactical.following.FixedAccelerationModel;
32  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
33  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
34  import org.opentrafficsim.road.network.factory.LaneFactory;
35  import org.opentrafficsim.road.network.lane.object.sensor.AbstractSensor;
36  import org.opentrafficsim.simulationengine.SimpleSimulator;
37  
38  import nl.tudelft.simulation.dsol.SimRuntimeException;
39  import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
40  import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
41  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
42  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
43  
44  /**
45   * Test sensors and scheduling of trigger.
46   * <p>
47   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
48   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
49   * <p>
50   * $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $,
51   * initial version 16 jan. 2015 <br>
52   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
53   */
54  public class SensorTest implements UNITS
55  {
56      /**
57       * Test the constructors of SensorLaneEnd and SensorLaneStart.
58       * @throws Exception when something goes wrong (should not happen)
59       */
60      @Test
61      public final void sensorTest() throws Exception
62      {
63          Network network = new OTSNetwork("sensor test network");
64          // First we need a set of Lanes
65          // To create Lanes we need Nodes and a LaneType
66          OTSNode nodeAFrom = new OTSNode(network, "AFrom", new OTSPoint3D(0, 0, 0));
67          OTSNode nodeATo = new OTSNode(network, "ATo", new OTSPoint3D(1000, 0, 0));
68          OTSNode nodeBTo = new OTSNode(network, "BTo", new OTSPoint3D(20000, 0, 0)); // so car won't run off lane B in 100 s.
69          GTUType gtuType = CAR;
70          LaneType laneType = LaneType.TWO_WAY_LANE;
71          // And a simulator, but for that we first need something that implements OTSModelInterface
72          OTSModelInterface model = new DummyModelForSensorTest();
73          final SimpleSimulator simulator = new SimpleSimulator(Time.ZERO, Duration.ZERO, new Duration(3600.0, SECOND), model);
74          Lane[] lanesA = LaneFactory.makeMultiLane(network, "A", nodeAFrom, nodeATo, null, 3, laneType,
75                  new Speed(100, KM_PER_HOUR), simulator);
76          Lane[] lanesB = LaneFactory.makeMultiLane(network, "B", nodeATo, nodeBTo, null, 3, laneType,
77                  new Speed(100, KM_PER_HOUR), simulator);
78  
79          // put a sensor on each of the lanes at the end of LaneA
80          for (Lane lane : lanesA)
81          {
82              Length longitudinalPosition = new Length(999.9999, METER);
83              TriggerSensor sensor = new TriggerSensor(lane, longitudinalPosition, RelativePosition.REFERENCE,
84                      "Trigger@" + lane.toString(), simulator);
85          }
86  
87          Length positionA = new Length(100, METER);
88          Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>(1);
89          initialLongitudinalPositions.add(new DirectedLanePosition(lanesA[1], positionA, GTUDirectionality.DIR_PLUS));
90  
91          // A Car needs an initial speed
92          Speed initialSpeed = new Speed(50, KM_PER_HOUR);
93          // Length of the Car
94          Length carLength = new Length(4, METER);
95          // Width of the Car
96          Length carWidth = new Length(1.8, METER);
97          // Maximum speed of the Car
98          Speed maximumSpeed = new Speed(100, KM_PER_HOUR);
99          // ID of the Car
100         String carID = "theCar";
101         // Create an acceleration profile for the car
102         FixedAccelerationModel fas =
103                 new FixedAccelerationModel(new Acceleration(0.5, METER_PER_SECOND_2), new Duration(100, SECOND));
104         // Now we can make a car (GTU) (and we don't even have to hold a pointer to it)
105         Parameters parameters = DefaultTestParameters.create();
106 
107         // LaneBasedBehavioralCharacteristics drivingCharacteristics =
108         // new LaneBasedBehavioralCharacteristics(fas, null);
109         LaneBasedIndividualGTU car = new LaneBasedIndividualGTU(carID, gtuType, carLength, carWidth, maximumSpeed,
110                 carLength.multiplyBy(0.5), simulator, (OTSNetwork) network);
111         LaneBasedStrategicalPlanner strategicalPlanner =
112                 new LaneBasedStrategicalRoutePlanner(new LaneBasedGTUFollowingTacticalPlanner(fas, car), car);
113         car.setParameters(parameters);
114         car.init(strategicalPlanner, initialLongitudinalPositions, initialSpeed);
115         simulator.runUpTo(new Time(1, TimeUnit.BASE_SECOND));
116         if (!simulator.isRunning())
117         {
118             simulator.start();
119         }
120         while (simulator.isRunning())
121         {
122             try
123             {
124                 Thread.sleep(1);
125             }
126             catch (InterruptedException ie)
127             {
128                 ie = null; // ignore
129             }
130         }
131         // Construction of the car scheduled a car move event at t=0
132         Set<SimEventInterface<SimTimeDoubleUnit>> eventList = simulator.getEventList();
133         SimEventInterface<SimTimeDoubleUnit> triggerEvent = null;
134         for (SimEventInterface<SimTimeDoubleUnit> event : eventList)
135         {
136             System.out.println("Scheduled Event " + event);
137             if (event.toString().contains("trigger"))
138             {
139                 triggerEvent = event;
140             }
141         }
142         // XXX this is not true anymore with OperationalPlans, Perception, etc =>
143         // XXX the number of events that should be scheduled can vary per models chosen
144         // XXX assertEquals("There should be three scheduled events (trigger, leaveLane,
145         // XXX car.move, terminate)", 4, eventList.size());
146         // The sensor should be triggered around t=38.3403 (exact value: 10 / 9 * (sqrt(3541) - 25))
147         // System.out.println("trigger event is " + triggerEvent);
148         // / TODO not triggered in next half second.
149         // XXX assertEquals("Trigger event should be around 38.3403", 38.3403,
150         // XXX triggerEvent.getAbsoluteExecutionTime().get().getSI(), 0.0001);
151     }
152 }
153 
154 /** */
155 class TriggerSensor extends AbstractSensor
156 {
157     /** */
158     private static final long serialVersionUID = 1L;
159 
160     /**
161      * @param lane lane of the sensor
162      * @param longitudinalPosition position of the sensor on the lane
163      * @param positionType trigger position of the GTU
164      * @param name name of the sensor
165      * @param simulator the simulator
166      * @throws NetworkException in case position is out of bounds
167      */
168     TriggerSensor(final Lane lane, final Length longitudinalPosition, final RelativePosition.TYPE positionType,
169             final String name, final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NetworkException
170     {
171         super(name, lane, longitudinalPosition, positionType, simulator, Compatible.EVERYTHING);
172     }
173 
174     /** {@inheritDoc} */
175     @Override
176     public void triggerResponse(final LaneBasedGTU gtu)
177     {
178         // TODO check that the sensor is triggered at the right time.
179     }
180 
181     /** {@inheritDoc} */
182     @Override
183     public AbstractSensor clone(final CrossSectionElement newCSE, final SimulatorInterface.TimeDoubleUnit newSimulator,
184             final boolean animation) throws NetworkException
185     {
186         return null;
187     }
188 
189 }
190 
191 /**
192  * Dummy OTSModelInterface.
193  * <p>
194  * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
195  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
196  * <p>
197  * $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $,
198  * initial version 4 jan. 2015 <br>
199  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
200  */
201 class DummyModelForSensorTest implements OTSModelInterface
202 {
203     /** */
204     private static final long serialVersionUID = 20150114L;
205 
206     /** The simulator. */
207     private SimulatorInterface<Time, Duration, SimTimeDoubleUnit> simulator;
208 
209     /**
210      * Register the simulator.
211      * @param simulator SimulatorInterface&lt;Time, Duration, SimTimeDoubleUnit&gt;; the simulator
212      */
213     public final void setSimulator(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> simulator)
214     {
215         this.simulator = simulator;
216     }
217 
218     /** {@inheritDoc} */
219     @Override
220     public final void constructModel(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> arg0) throws SimRuntimeException
221     {
222         // Nothing happens here
223     }
224 
225     /** {@inheritDoc} */
226     @Override
227     public SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
228 
229     {
230         if (null == this.simulator)
231         {
232             throw new Error("getSimulator called, but simulator field is null");
233         }
234         return this.simulator;
235     }
236 
237     /** {@inheritDoc} */
238     @Override
239     public OTSNetwork getNetwork()
240     {
241         return null;
242     }
243 
244 }