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