View Javadoc
1   package org.opentrafficsim.demo;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.LinkedHashSet;
6   import java.util.List;
7   import java.util.Set;
8   
9   import org.djunits.unit.DurationUnit;
10  import org.djunits.unit.LengthUnit;
11  import org.djunits.unit.SpeedUnit;
12  import org.djunits.unit.TimeUnit;
13  import org.djunits.unit.util.UNITS;
14  import org.djunits.value.vdouble.scalar.Direction;
15  import org.djunits.value.vdouble.scalar.Duration;
16  import org.djunits.value.vdouble.scalar.Frequency;
17  import org.djunits.value.vdouble.scalar.Length;
18  import org.djunits.value.vdouble.scalar.Speed;
19  import org.djunits.value.vdouble.scalar.Time;
20  import org.opentrafficsim.base.parameters.ParameterException;
21  import org.opentrafficsim.base.parameters.ParameterSet;
22  import org.opentrafficsim.core.compatibility.Compatible;
23  import org.opentrafficsim.core.distributions.ConstantGenerator;
24  import org.opentrafficsim.core.distributions.Distribution;
25  import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
26  import org.opentrafficsim.core.distributions.Generator;
27  import org.opentrafficsim.core.distributions.ProbabilityException;
28  import org.opentrafficsim.core.dsol.AbstractOTSModel;
29  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
30  import org.opentrafficsim.core.geometry.OTSGeometryException;
31  import org.opentrafficsim.core.geometry.OTSPoint3D;
32  import org.opentrafficsim.core.gtu.GTUDirectionality;
33  import org.opentrafficsim.core.gtu.GTUException;
34  import org.opentrafficsim.core.gtu.GTUType;
35  import org.opentrafficsim.core.idgenerator.IdGenerator;
36  import org.opentrafficsim.core.network.NetworkException;
37  import org.opentrafficsim.core.network.route.FixedRouteGenerator;
38  import org.opentrafficsim.core.network.route.Route;
39  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
40  import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
41  import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
42  import org.opentrafficsim.road.gtu.generator.TTCRoomChecker;
43  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUType;
44  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUTypeDistribution;
45  import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
46  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
47  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
48  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
49  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
50  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
51  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
52  import org.opentrafficsim.road.network.OTSRoadNetwork;
53  import org.opentrafficsim.road.network.factory.LaneFactory;
54  import org.opentrafficsim.road.network.lane.CrossSectionLink;
55  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
56  import org.opentrafficsim.road.network.lane.Lane;
57  import org.opentrafficsim.road.network.lane.LaneType;
58  import org.opentrafficsim.road.network.lane.OTSRoadNode;
59  import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
60  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
61  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
62  
63  import nl.tudelft.simulation.dsol.SimRuntimeException;
64  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
65  import nl.tudelft.simulation.jstats.distributions.DistUniform;
66  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
67  import nl.tudelft.simulation.jstats.streams.StreamInterface;
68  
69  /**
70   * Simulate a single lane road of 5 km length. Vehicles are generated at a constant rate of 1500 veh/hour. At time 300s a
71   * blockade is inserted at position 4 km; this blockade is removed at time 500s. The used car following algorithm is IDM+
72   * <a href="http://opentrafficsim.org/downloads/MOTUS%20reference.pdf"><i>Integrated Lane Change Model with Relaxation and
73   * Synchronization</i>, by Wouter J. Schakel, Victor L. Knoop and Bart van Arem, 2012</a>. <br>
74   * Output is a set of block charts:
75   * <ul>
76   * <li>Traffic density</li>
77   * <li>Speed</li>
78   * <li>Flow</li>
79   * <li>Acceleration</li>
80   * </ul>
81   * All these graphs display simulation time along the horizontal axis and distance along the road along the vertical axis.
82   * <p>
83   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
84   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
85   * <p>
86   * $LastChangedDate: 2019-01-06 01:35:05 +0100 (Sun, 06 Jan 2019) $, @version $Revision: 4831 $, by $Author: averbraeck $,
87   * initial version ug 1, 2014 <br>
88   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
89   */
90  public class StraightModel extends AbstractOTSModel implements UNITS
91  {
92      /** */
93      private static final long serialVersionUID = 20140815L;
94  
95      /** The network. */
96      private final OTSRoadNetwork network = new OTSRoadNetwork("network", true, getSimulator());
97  
98      /** The probability that the next generated GTU is a passenger car. */
99      private double carProbability;
100 
101     /** The blocking, implemented as a traffic light. */
102     private SimpleTrafficLight block = null;
103 
104     /** Maximum distance. */
105     private Length maximumDistance = new Length(5000, METER);
106 
107     /** The Lane that contains the simulated Cars. */
108     private Lane lane;
109 
110     /** The random number generator used to decide what kind of GTU to generate. */
111     private StreamInterface stream = new MersenneTwister(12345);
112 
113     /** The sequence of Lanes that all vehicles will follow. */
114     private List<Lane> path = new ArrayList<>();
115 
116     /** The speed limit on all Lanes. */
117     private Speed speedLimit = new Speed(120, KM_PER_HOUR);
118 
119     /**
120      * @param simulator OTSSimulatorInterface; the simulator for this model
121      */
122     public StraightModel(final OTSSimulatorInterface simulator)
123     {
124         super(simulator);
125         InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
126     }
127 
128     /** {@inheritDoc} */
129     @Override
130     public final void constructModel() throws SimRuntimeException
131     {
132         try
133         {
134             OTSRoadNode from =
135                     new OTSRoadNode(this.network, "From", new OTSPoint3D(0.0, 0, 0), Direction.ZERO);
136             OTSRoadNode to =
137                     new OTSRoadNode(this.network, "To", new OTSPoint3D(this.maximumDistance.getSI(), 0, 0), Direction.ZERO);
138             OTSRoadNode end = new OTSRoadNode(this.network, "End", new OTSPoint3D(this.maximumDistance.getSI() + 50.0, 0, 0),
139                     Direction.ZERO);
140             LaneType laneType = this.network.getLaneType(LaneType.DEFAULTS.TWO_WAY_LANE);
141             this.lane = LaneFactory.makeLane(this.network, "Lane", from, to, null, laneType, this.speedLimit, this.simulator);
142             this.path.add(this.lane);
143             CrossSectionLink endLink = LaneFactory.makeLink(this.network, "endLink", to, end, null, this.simulator);
144             // No overtaking, single lane
145             Lane sinkLane = new Lane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
146                     this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0), laneType,
147                     this.speedLimit);
148             new SinkSensor(sinkLane, new Length(10.0, METER), Compatible.EVERYTHING, this.simulator);
149             this.path.add(sinkLane);
150 
151             this.carProbability = (double) getInputParameter("generic.carProbability");
152 
153             // Generation of a new car / truck
154             TTCRoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
155             IdGenerator idGenerator = new IdGenerator("");
156             ParameterSet params = new ParameterSet();
157             params.setDefaultParameter(AbstractIDM.DELTA);
158             GTUType car = new GTUType("car", this.network.getGtuType(GTUType.DEFAULTS.CAR));
159             GTUType truck = new GTUType("truck", this.network.getGtuType(GTUType.DEFAULTS.TRUCK));
160             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
161                     new ContinuousDistDoubleScalar.Rel<>(new DistUniform(this.stream, 90.0, 110.0), SpeedUnit.KM_PER_HOUR);
162             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
163                     new ContinuousDistDoubleScalar.Rel<>(new DistUniform(this.stream, 80, 95), SpeedUnit.KM_PER_HOUR);
164             Generator<Route> routeGenerator = new FixedRouteGenerator(null);
165             LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFactoryCars =
166                     new LaneBasedStrategicalRoutePlannerFactory(
167                             new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
168             LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFctoryTrucks =
169                     new LaneBasedStrategicalRoutePlannerFactory(
170                             new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
171             LaneBasedTemplateGTUType carTemplate = new LaneBasedTemplateGTUType(car,
172                     new ConstantGenerator<>(Length.instantiateSI(4.0)), new ConstantGenerator<>(Length.instantiateSI(2.0)),
173                     speedCar, strategicalPlannerFactoryCars, routeGenerator);
174             LaneBasedTemplateGTUType truckTemplate = new LaneBasedTemplateGTUType(truck,
175                     new ConstantGenerator<>(Length.instantiateSI(15.0)), new ConstantGenerator<>(Length.instantiateSI(2.5)),
176                     speedTruck, strategicalPlannerFctoryTrucks, routeGenerator);
177             Distribution<LaneBasedTemplateGTUType> gtuTypeDistribution = new Distribution<>(this.stream);
178             gtuTypeDistribution.add(new FrequencyAndObject<>(this.carProbability, carTemplate));
179             gtuTypeDistribution.add(new FrequencyAndObject<>(1.0 - this.carProbability, truckTemplate));
180             Generator<Duration> headwayGenerator = new HeadwayGenerator(new Frequency(1500.0, PER_HOUR));
181             Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
182             initialLongitudinalPositions
183                     .add(new DirectedLanePosition(this.lane, new Length(5.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS));
184             LaneBasedTemplateGTUTypeDistribution characteristicsGenerator =
185                     new LaneBasedTemplateGTUTypeDistribution(gtuTypeDistribution);
186             new LaneBasedGTUGenerator("Generator", headwayGenerator, characteristicsGenerator,
187                     GeneratorPositions.create(initialLongitudinalPositions, this.stream), this.network, getSimulator(),
188                     roomChecker, idGenerator);
189             // End generation
190 
191             this.block = new SimpleTrafficLight(this.lane.getId() + "_TL", this.lane,
192                     new Length(new Length(4000.0, LengthUnit.METER)), this.simulator);
193             this.block.setTrafficLightColor(TrafficLightColor.GREEN);
194             // Create a block at t = 5 minutes
195             this.simulator.scheduleEventAbs(new Time(300, TimeUnit.BASE_SECOND), this, this, "createBlock", null);
196             // Remove the block at t = 7 minutes
197             this.simulator.scheduleEventAbs(new Time(420, TimeUnit.BASE_SECOND), this, this, "removeBlock", null);
198         }
199         catch (SimRuntimeException | NetworkException | OTSGeometryException | InputParameterException | GTUException
200                 | ParameterException | ProbabilityException exception)
201         {
202             exception.printStackTrace();
203         }
204     }
205 
206     /**
207      * Set up the block.
208      */
209     protected final void createBlock()
210     {
211         this.block.setTrafficLightColor(TrafficLightColor.RED);
212     }
213 
214     /**
215      * Remove the block.
216      */
217     protected final void removeBlock()
218     {
219         this.block.setTrafficLightColor(TrafficLightColor.GREEN);
220     }
221 
222     /** {@inheritDoc} */
223     @Override
224     public OTSRoadNetwork getNetwork()
225     {
226         return this.network;
227     }
228 
229     /**
230      * @return the path for sampling the graphs
231      */
232     public final List<Lane> getPath()
233     {
234         return this.path;
235     }
236 
237     /** {@inheritDoc} */
238     @Override
239     public Serializable getSourceId()
240     {
241         return "StraightModel";
242     }
243 
244     /**
245      * <p>
246      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
247      * <br>
248      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
249      * <p>
250      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 29 jan. 2017 <br>
251      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
252      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
253      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
254      */
255     private static class HeadwayGenerator implements Generator<Duration>
256     {
257         /** Demand level. */
258         private final Frequency demand;
259 
260         /** a random stream. */
261         private StreamInterface stream = new MersenneTwister(4L);
262 
263         /**
264          * @param demand Frequency; demand
265          */
266         HeadwayGenerator(final Frequency demand)
267         {
268             this.demand = demand;
269         }
270 
271         /** {@inheritDoc} */
272         @Override
273         public Duration draw() throws ProbabilityException, ParameterException
274         {
275             return new Duration(-Math.log(this.stream.nextDouble()) / this.demand.si, DurationUnit.SI);
276         }
277 
278     }
279 
280 }