View Javadoc
1   package org.opentrafficsim.demo;
2   
3   import java.util.ArrayList;
4   import java.util.LinkedHashSet;
5   import java.util.List;
6   import java.util.Set;
7   
8   import org.djunits.unit.LengthUnit;
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.opentrafficsim.base.parameters.ParameterException;
17  import org.opentrafficsim.base.parameters.Parameters;
18  import org.opentrafficsim.core.dsol.AbstractOTSModel;
19  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
20  import org.opentrafficsim.core.geometry.OTSGeometryException;
21  import org.opentrafficsim.core.geometry.OTSPoint3D;
22  import org.opentrafficsim.core.gtu.GTUDirectionality;
23  import org.opentrafficsim.core.gtu.GTUException;
24  import org.opentrafficsim.core.gtu.GTUType;
25  import org.opentrafficsim.core.network.NetworkException;
26  import org.opentrafficsim.core.network.OTSNode;
27  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
28  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
29  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
30  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
31  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
32  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
33  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
34  import org.opentrafficsim.road.network.OTSRoadNetwork;
35  import org.opentrafficsim.road.network.factory.LaneFactory;
36  import org.opentrafficsim.road.network.lane.CrossSectionLink;
37  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
38  import org.opentrafficsim.road.network.lane.Lane;
39  import org.opentrafficsim.road.network.lane.LaneType;
40  import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
41  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
42  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
43  
44  import nl.tudelft.simulation.dsol.SimRuntimeException;
45  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
46  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
47  import nl.tudelft.simulation.jstats.streams.StreamInterface;
48  
49  /**
50   * Simulate a single lane road of 5 km length. Vehicles are generated at a constant rate of 1500 veh/hour. At time 300s a
51   * blockade is inserted at position 4 km; this blockade is removed at time 500s. The used car following algorithm is IDM+
52   * <a href="http://opentrafficsim.org/downloads/MOTUS%20reference.pdf"><i>Integrated Lane Change Model with Relaxation and
53   * Synchronization</i>, by Wouter J. Schakel, Victor L. Knoop and Bart van Arem, 2012</a>. <br>
54   * Output is a set of block charts:
55   * <ul>
56   * <li>Traffic density</li>
57   * <li>Speed</li>
58   * <li>Flow</li>
59   * <li>Acceleration</li>
60   * </ul>
61   * All these graphs display simulation time along the horizontal axis and distance along the road along the vertical axis.
62   * <p>
63   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
64   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
65   * <p>
66   * $LastChangedDate: 2019-01-06 01:35:05 +0100 (Sun, 06 Jan 2019) $, @version $Revision: 4831 $, by $Author: averbraeck $,
67   * initial version ug 1, 2014 <br>
68   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
69   */
70  public class StraightModel extends AbstractOTSModel implements UNITS
71  {
72      /** */
73      private static final long serialVersionUID = 20140815L;
74  
75      /** The network. */
76      private final OTSRoadNetwork network = new OTSRoadNetwork("network", true);
77  
78      /** The headway (inter-vehicle time). */
79      private Duration headway;
80  
81      /** Number of cars created. */
82      private int carsCreated = 0;
83  
84      /** Strategical planner generator for cars. */
85      private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
86  
87      /** Strategical planner generator for trucks. */
88      private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
89  
90      /** Car parameters. */
91      private Parameters parametersCar;
92  
93      /** Truck parameters. */
94      private Parameters parametersTruck;
95  
96      /** The probability that the next generated GTU is a passenger car. */
97      private double carProbability;
98  
99      /** The blocking, implemented as a traffic light. */
100     private SimpleTrafficLight block = null;
101 
102     /** Minimum distance. */
103     private Length minimumDistance = new Length(0, METER);
104 
105     /** Maximum distance. */
106     private Length maximumDistance = new Length(5000, METER);
107 
108     /** The Lane that contains the simulated Cars. */
109     private Lane lane;
110 
111     /** The random number generator used to decide what kind of GTU to generate. */
112     private StreamInterface stream = new MersenneTwister(12345);
113 
114     /** The sequence of Lanes that all vehicles will follow. */
115     private List<Lane> path = new ArrayList<>();
116 
117     /** The speed limit on all Lanes. */
118     private Speed speedLimit = new Speed(100, KM_PER_HOUR);
119 
120     /**
121      * @param simulator OTSSimulatorInterface; the simulator for this model
122      */
123     public StraightModel(final OTSSimulatorInterface simulator)
124     {
125         super(simulator);
126         InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
127     }
128 
129     /** {@inheritDoc} */
130     @Override
131     public final void constructModel() throws SimRuntimeException
132     {
133         try
134         {
135             OTSNode from = new OTSNode(this.network, "From", new OTSPoint3D(getMinimumDistance().getSI(), 0, 0));
136             OTSNode to = new OTSNode(this.network, "To", new OTSPoint3D(getMaximumDistance().getSI(), 0, 0));
137             OTSNode end = new OTSNode(this.network, "End", new OTSPoint3D(getMaximumDistance().getSI() + 50.0, 0, 0));
138             LaneType laneType = this.network.getLaneType(LaneType.DEFAULTS.TWO_WAY_LANE);
139             this.lane = LaneFactory.makeLane(this.network, "Lane", from, to, null, laneType, this.speedLimit, this.simulator);
140             this.path.add(this.lane);
141             CrossSectionLink endLink = LaneFactory.makeLink(this.network, "endLink", to, end, null, this.simulator);
142             // No overtaking, single lane
143             Lane sinkLane = new Lane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
144                     this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0), laneType,
145                     this.speedLimit);
146             new SinkSensor(sinkLane, new Length(10.0, METER), this.simulator);
147             this.path.add(sinkLane);
148 
149             this.carProbability = (double) getInputParameter("generic.carProbability");
150             this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
151             this.parametersTruck = InputParameterHelper.getParametersTruck(getInputParameterMap());
152 
153             this.strategicalPlannerGeneratorCars = new LaneBasedStrategicalRoutePlannerFactory(
154                     new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
155             this.strategicalPlannerGeneratorTrucks = new LaneBasedStrategicalRoutePlannerFactory(
156                     new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
157 
158             // 1500 [veh / hour] == 2.4s headway
159             this.headway = new Duration(3600.0 / 1500.0, SECOND);
160 
161             // Schedule creation of the first car (it will re-schedule itself one headway later, etc.).
162             this.simulator.scheduleEventAbs(Time.ZERO, this, this, "generateCar", null);
163 
164             this.block = new SimpleTrafficLight(this.lane.getId() + "_TL", this.lane,
165                     new Length(new Length(4000.0, LengthUnit.METER)), this.simulator);
166             this.block.setTrafficLightColor(TrafficLightColor.GREEN);
167             // Create a block at t = 5 minutes
168             this.simulator.scheduleEventAbs(new Time(300, TimeUnit.BASE_SECOND), this, this, "createBlock", null);
169             // Remove the block at t = 7 minutes
170             this.simulator.scheduleEventAbs(new Time(420, TimeUnit.BASE_SECOND), this, this, "removeBlock", null);
171         }
172         catch (SimRuntimeException | NetworkException | OTSGeometryException | InputParameterException | GTUException
173                 | ParameterException exception)
174         {
175             exception.printStackTrace();
176         }
177     }
178 
179     /**
180      * Set up the block.
181      */
182     protected final void createBlock()
183     {
184         this.block.setTrafficLightColor(TrafficLightColor.RED);
185     }
186 
187     /**
188      * Remove the block.
189      */
190     protected final void removeBlock()
191     {
192         this.block.setTrafficLightColor(TrafficLightColor.GREEN);
193     }
194 
195     /**
196      * Generate cars at a fixed rate (implemented by re-scheduling this method).
197      */
198     protected final void generateCar()
199     {
200         try
201         {
202             boolean generateTruck = this.stream.nextDouble() > this.carProbability;
203             Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
204             LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.carsCreated),
205                     this.network.getGtuType(GTUType.DEFAULTS.CAR), vehicleLength, new Length(1.8, METER),
206                     new Speed(200, KM_PER_HOUR), vehicleLength.multiplyBy(0.5), this.simulator, this.network);
207             gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
208             gtu.setNoLaneChangeDistance(Length.ZERO);
209             gtu.setMaximumAcceleration(Acceleration.createSI(3.0));
210             gtu.setMaximumDeceleration(Acceleration.createSI(-8.0));
211 
212             // strategical planner
213             LaneBasedStrategicalPlanner strategicalPlanner =
214                     generateTruck ? this.strategicalPlannerGeneratorTrucks.create(gtu, null, null, null)
215                             : this.strategicalPlannerGeneratorCars.create(gtu, null, null, null);
216 
217             Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
218             Length initialPosition = new Length(20, METER);
219             initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
220             Speed initialSpeed = new Speed(100.0, KM_PER_HOUR);
221             gtu.init(strategicalPlanner, initialPositions, initialSpeed);
222             this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
223         }
224         catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException exception)
225         {
226             exception.printStackTrace();
227         }
228     }
229 
230     /**
231      * @return List&lt;Lane&gt;; the set of lanes for the specified index
232      */
233     public List<Lane> getPath()
234     {
235         return new ArrayList<>(this.path);
236     }
237 
238     /** {@inheritDoc} */
239     @Override
240     public OTSRoadNetwork getNetwork()
241     {
242         return this.network;
243     }
244 
245     /**
246      * @return minimumDistance
247      */
248     public final Length getMinimumDistance()
249     {
250         return this.minimumDistance;
251     }
252 
253     /**
254      * @return maximumDistance
255      */
256     public final Length getMaximumDistance()
257     {
258         return this.maximumDistance;
259     }
260 
261     /**
262      * @return lane.
263      */
264     public Lane getLane()
265     {
266         return this.lane;
267     }
268 
269 }