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