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