View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.util.LinkedHashSet;
4   import java.util.Set;
5   
6   import org.djunits.unit.DurationUnit;
7   import org.djunits.unit.TimeUnit;
8   import org.djunits.unit.util.UNITS;
9   import org.djunits.value.vdouble.scalar.Acceleration;
10  import org.djunits.value.vdouble.scalar.Direction;
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.definitions.DefaultsNl;
18  import org.opentrafficsim.core.dsol.AbstractOtsModel;
19  import org.opentrafficsim.core.dsol.OtsModelInterface;
20  import org.opentrafficsim.core.dsol.OtsSimulator;
21  import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
22  import org.opentrafficsim.core.geometry.OtsPoint3d;
23  import org.opentrafficsim.core.gtu.GtuType;
24  import org.opentrafficsim.core.gtu.RelativePosition;
25  import org.opentrafficsim.core.network.NetworkException;
26  import org.opentrafficsim.core.network.Node;
27  import org.opentrafficsim.road.DefaultTestParameters;
28  import org.opentrafficsim.road.definitions.DefaultsRoadNl;
29  import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
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.LaneBasedStrategicalRoutePlanner;
34  import org.opentrafficsim.road.network.RoadNetwork;
35  import org.opentrafficsim.road.network.factory.LaneFactory;
36  import org.opentrafficsim.road.network.lane.object.detector.LaneDetector;
37  
38  import nl.tudelft.simulation.dsol.SimRuntimeException;
39  import nl.tudelft.simulation.dsol.eventlists.EventListInterface;
40  import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
41  
42  /**
43   * Test detectors and scheduling of trigger.
44   * <p>
45   * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
46   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
47   * </p>
48   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
49   */
50  public class DetectorTest implements UNITS
51  {
52      /**
53       * Test the constructors of SensorLaneEnd and SensorLaneStart.
54       * @throws Exception when something goes wrong (should not happen)
55       */
56      @Test
57      public final void sensorTest() throws Exception
58      {
59          // We need a simulator, but for that we first need something that implements OtsModelInterface
60          OtsSimulatorInterface simulator = new OtsSimulator("SensorTest");
61          OtsModelInterface model = new DummyModelForSensorTest(simulator);
62          simulator.initialize(Time.ZERO, Duration.ZERO, new Duration(3600.0, DurationUnit.SECOND), model);
63          RoadNetwork network = new RoadNetwork("sensor test network", simulator);
64          // Now we need a set of Lanes
65          // To create Lanes we need Nodes and a LaneType
66          Node nodeAFrom = new Node(network, "AFrom", new OtsPoint3d(0, 0, 0), Direction.ZERO);
67          Node nodeATo = new Node(network, "ATo", new OtsPoint3d(1000, 0, 0), Direction.ZERO);
68          Node nodeBTo = new Node(network, "BTo", new OtsPoint3d(20000, 0, 0), Direction.ZERO);
69          // so car won't run off lane B in 100 s.
70          GtuType gtuType = DefaultsNl.CAR;
71          LaneType laneType = DefaultsRoadNl.TWO_WAY_LANE;
72          Lane[] lanesA = LaneFactory.makeMultiLane(network, "A", nodeAFrom, nodeATo, null, 3, laneType,
73                  new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
74          Lane[] lanesB = LaneFactory.makeMultiLane(network, "B", nodeATo, nodeBTo, null, 3, laneType,
75                  new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
76  
77          // put a sensor on each of the lanes at the end of LaneA
78          for (Lane lane : lanesA)
79          {
80              Length longitudinalPosition = new Length(999.9999, METER);
81              TriggerDetector sensor = new TriggerDetector(lane, longitudinalPosition, RelativePosition.REFERENCE,
82                      "Trigger@" + lane.toString(), simulator);
83          }
84  
85          Length positionA = new Length(100, METER);
86          Set<LanePosition> initialLongitudinalPositions = new LinkedHashSet<>(1);
87          initialLongitudinalPositions.add(new LanePosition(lanesA[1], positionA));
88  
89          // A Car needs an initial speed
90          Speed initialSpeed = new Speed(50, KM_PER_HOUR);
91          // Length of the Car
92          Length carLength = new Length(4, METER);
93          // Width of the Car
94          Length carWidth = new Length(1.8, METER);
95          // Maximum speed of the Car
96          Speed maximumSpeed = new Speed(100, KM_PER_HOUR);
97          // ID of the Car
98          String carID = "theCar";
99          // Create an acceleration profile for the car
100         FixedAccelerationModel fas =
101                 new FixedAccelerationModel(new Acceleration(0.5, METER_PER_SECOND_2), new Duration(100, SECOND));
102         // Now we can make a car (GTU) (and we don't even have to hold a pointer to it)
103         Parameters parameters = DefaultTestParameters.create();
104 
105         // LaneBasedBehavioralCharacteristics drivingCharacteristics =
106         // new LaneBasedBehavioralCharacteristics(fas, null);
107         LaneBasedGtu car = new LaneBasedGtu(carID, gtuType, carLength, carWidth, maximumSpeed, carLength.times(0.5),
108                 (RoadNetwork) network);
109         LaneBasedStrategicalPlanner strategicalPlanner =
110                 new LaneBasedStrategicalRoutePlanner(new LaneBasedGtuFollowingTacticalPlanner(fas, car), car);
111         car.setParameters(parameters);
112         car.init(strategicalPlanner, initialLongitudinalPositions, initialSpeed);
113         simulator.runUpTo(new Time(1, TimeUnit.BASE_SECOND));
114         if (!simulator.isStartingOrRunning())
115         {
116             simulator.start();
117         }
118         while (simulator.isStartingOrRunning())
119         {
120             try
121             {
122                 Thread.sleep(1);
123             }
124             catch (InterruptedException ie)
125             {
126                 ie = null; // ignore
127             }
128         }
129         // Construction of the car scheduled a car move event at t=0
130         EventListInterface<Duration> eventList = simulator.getEventList();
131         SimEventInterface<Duration> triggerEvent = null;
132         for (SimEventInterface<Duration> event : eventList)
133         {
134             System.out.println("Scheduled Event " + event);
135             if (event.toString().contains("trigger"))
136             {
137                 triggerEvent = event;
138             }
139         }
140         // XXX this is not true anymore with OperationalPlans, Perception, etc =>
141         // XXX the number of events that should be scheduled can vary per models chosen
142         // XXX assertEquals("There should be three scheduled events (trigger, leaveLane,
143         // XXX car.move, terminate)", 4, eventList.size());
144         // The sensor should be triggered around t=38.3403 (exact value: 10 / 9 * (sqrt(3541) - 25))
145         // System.out.println("trigger event is " + triggerEvent);
146         // / TODO not triggered in next half second.
147         // XXX assertEquals("Trigger event should be around 38.3403", 38.3403,
148         // XXX triggerEvent.getAbsoluteExecutionTime().get().getSI(), 0.0001);
149     }
150 }
151 
152 /** */
153 class TriggerDetector extends LaneDetector
154 {
155     /** */
156     private static final long serialVersionUID = 1L;
157 
158     /**
159      * @param lane lane of the sensor
160      * @param longitudinalPosition position of the sensor on the lane
161      * @param positionType trigger position of the GTU
162      * @param name name of the sensor
163      * @param simulator the simulator
164      * @throws NetworkException in case position is out of bounds
165      */
166     TriggerDetector(final Lane lane, final Length longitudinalPosition, final RelativePosition.TYPE positionType,
167             final String name, final OtsSimulatorInterface simulator) throws NetworkException
168     {
169         super(name, lane, longitudinalPosition, positionType, simulator, DefaultsRoadNl.ROAD_USERS);
170     }
171 
172     /** {@inheritDoc} */
173     @Override
174     public void triggerResponse(final LaneBasedGtu gtu)
175     {
176         // TODO check that the sensor is triggered at the right time.
177     }
178 
179 }
180 
181 /**
182  * Dummy OtsModelInterface.
183  * <p>
184  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
185  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
186  * </p>
187  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
188  */
189 class DummyModelForSensorTest extends AbstractOtsModel
190 {
191     /** */
192     private static final long serialVersionUID = 20150114L;
193 
194     /**
195      * @param simulator the simulator to use
196      */
197     DummyModelForSensorTest(final OtsSimulatorInterface simulator)
198     {
199         super(simulator);
200     }
201 
202     /** {@inheritDoc} */
203     @Override
204     public final void constructModel() throws SimRuntimeException
205     {
206         //
207     }
208 
209     /** {@inheritDoc} */
210     @Override
211     public final RoadNetwork getNetwork()
212     {
213         return null;
214     }
215 }