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