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.Map;
7   import java.util.Set;
8   import java.util.function.Supplier;
9   
10  import org.djunits.unit.DurationUnit;
11  import org.djunits.unit.LengthUnit;
12  import org.djunits.unit.SpeedUnit;
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.djutils.draw.point.Point2d;
20  import org.opentrafficsim.base.parameters.ParameterException;
21  import org.opentrafficsim.base.parameters.ParameterSet;
22  import org.opentrafficsim.core.definitions.DefaultsNl;
23  import org.opentrafficsim.core.distributions.ConstantSupplier;
24  import org.opentrafficsim.core.distributions.FrequencyAndObject;
25  import org.opentrafficsim.core.distributions.ObjectDistribution;
26  import org.opentrafficsim.core.dsol.AbstractOtsModel;
27  import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
28  import org.opentrafficsim.core.gtu.GtuType;
29  import org.opentrafficsim.core.idgenerator.IdSupplier;
30  import org.opentrafficsim.core.network.NetworkException;
31  import org.opentrafficsim.core.network.Node;
32  import org.opentrafficsim.core.network.route.FixedRouteGenerator;
33  import org.opentrafficsim.core.network.route.Route;
34  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
35  import org.opentrafficsim.road.definitions.DefaultsRoadNl;
36  import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
37  import org.opentrafficsim.road.gtu.generator.LaneBasedGtuGenerator;
38  import org.opentrafficsim.road.gtu.generator.TtcRoomChecker;
39  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGtuTemplate;
40  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGtuTemplateDistribution;
41  import org.opentrafficsim.road.gtu.generator.headway.HeadwayGenerator;
42  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
43  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalRoutePlannerFactory;
44  import org.opentrafficsim.road.gtu.tactical.following.AbstractIdm;
45  import org.opentrafficsim.road.gtu.tactical.lmrs.Lmrs;
46  import org.opentrafficsim.road.gtu.tactical.lmrs.LmrsFactory;
47  import org.opentrafficsim.road.gtu.tactical.lmrs.LmrsFactory.Setting;
48  import org.opentrafficsim.road.network.CrossSectionLink;
49  import org.opentrafficsim.road.network.Lane;
50  import org.opentrafficsim.road.network.LaneGeometryUtil;
51  import org.opentrafficsim.road.network.LanePosition;
52  import org.opentrafficsim.road.network.LaneType;
53  import org.opentrafficsim.road.network.RoadNetwork;
54  import org.opentrafficsim.road.network.factory.LaneFactory;
55  import org.opentrafficsim.road.network.object.detector.SinkDetector;
56  import org.opentrafficsim.road.network.object.trafficlight.TrafficLight;
57  import org.opentrafficsim.road.network.object.trafficlight.TrafficLightColor;
58  import org.opentrafficsim.road.network.speed.LaneSpeedLimits;
59  
60  import nl.tudelft.simulation.dsol.SimRuntimeException;
61  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
62  import nl.tudelft.simulation.jstats.distributions.DistUniform;
63  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
64  import nl.tudelft.simulation.jstats.streams.StreamInterface;
65  
66  /**
67   * Simulate a single lane road of 5 km length. Vehicles are generated at a constant rate of 1500 veh/hour. At time 300s a
68   * blockade is inserted at position 4 km; this blockade is removed at time 500s. The used car following algorithm is IDM+
69   * <a href="http://opentrafficsim.org/downloads/MOTUS%20reference.pdf"><i>Integrated Lane Change Model with Relaxation and
70   * Synchronization</i>, by Wouter J. Schakel, Victor L. Knoop and Bart van Arem, 2012</a>. <br>
71   * Output is a set of block charts:
72   * <ul>
73   * <li>Traffic density</li>
74   * <li>Speed</li>
75   * <li>Flow</li>
76   * <li>Acceleration</li>
77   * </ul>
78   * All these graphs display simulation time along the horizontal axis and distance along the road along the vertical axis.
79   * <p>
80   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
81   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
82   * </p>
83   * @author Peter Knoppers
84   */
85  public class StraightModel extends AbstractOtsModel implements UNITS
86  {
87      /** The network. */
88      private final RoadNetwork network = new RoadNetwork("network", getSimulator());
89  
90      /** The probability that the next generated GTU is a passenger car. */
91      private double carProbability;
92  
93      /** The blocking, implemented as a traffic light. */
94      private TrafficLight block = null;
95  
96      /** Maximum distance. */
97      private Length maximumDistance = new Length(5000, METER);
98  
99      /** The Lane that contains the simulated Cars. */
100     private Lane lane;
101 
102     /** The random number generator used to decide what kind of GTU to generate. */
103     private StreamInterface stream = new MersenneTwister(12345);
104 
105     /** The sequence of Lanes that all vehicles will follow. */
106     private List<Lane> path = new ArrayList<>();
107 
108     /** The speed limit on all Lanes. */
109     private LaneSpeedLimits speedLimit = new LaneSpeedLimits(new Speed(120, SpeedUnit.KM_PER_HOUR),
110             Map.of(DefaultsNl.TRUCK, new Speed(80, SpeedUnit.KM_PER_HOUR)));
111 
112     /**
113      * Constructor.
114      * @param simulator the simulator for this model
115      */
116     public StraightModel(final OtsSimulatorInterface simulator)
117     {
118         super(simulator);
119         InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
120     }
121 
122     @Override
123     public final void constructModel() throws SimRuntimeException
124     {
125         try
126         {
127             Node from = new Node(this.network, "From", new Point2d(0.0, 0), Direction.ZERO);
128             Node to = new Node(this.network, "To", new Point2d(this.maximumDistance.getSI(), 0), Direction.ZERO);
129             Node end = new Node(this.network, "End", new Point2d(this.maximumDistance.getSI() + 50.0, 0), Direction.ZERO);
130             LaneType laneType = DefaultsRoadNl.TWO_WAY_LANE;
131             this.lane = LaneFactory.makeLane(this.network, "Lane", from, to, null, laneType, this.speedLimit, this.simulator);
132             this.path.add(this.lane);
133             CrossSectionLink endLink = LaneFactory.makeLink(this.network, "endLink", to, end, null, this.simulator);
134             // No overtaking, single lane
135             Lane sinkLane = LaneGeometryUtil.createStraightLane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
136                     this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0), laneType,
137                     this.speedLimit);
138             new SinkDetector(sinkLane, new Length(10.0, METER), DefaultsNl.ROAD_USERS);
139             this.path.add(sinkLane);
140 
141             this.carProbability = (double) getInputParameter("generic.carProbability");
142 
143             // Generation of a new car / truck
144             TtcRoomChecker roomChecker = new TtcRoomChecker(new Duration(10.0, DurationUnit.SI));
145             IdSupplier idGenerator = new IdSupplier("");
146             ParameterSet params = new ParameterSet();
147             params.setDefaultParameter(AbstractIdm.DELTA);
148             GtuType car = DefaultsNl.CAR;
149             GtuType truck = DefaultsNl.TRUCK;
150             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
151                     new ContinuousDistDoubleScalar.Rel<>(new DistUniform(this.stream, 90.0, 110.0), SpeedUnit.KM_PER_HOUR);
152             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
153                     new ContinuousDistDoubleScalar.Rel<>(new DistUniform(this.stream, 80, 95), SpeedUnit.KM_PER_HOUR);
154             Supplier<Route> routeGenerator = new FixedRouteGenerator(null);
155             LaneBasedStrategicalPlannerFactory<?> strategicalPlannerFactoryCars = new LaneBasedStrategicalRoutePlannerFactory(
156                     new LmrsFactory<>(Lmrs::new).setStream(this.stream).set(Setting.ACCELERATION_TRAFFIC_LIGHTS, true));
157             LaneBasedStrategicalPlannerFactory<?> strategicalPlannerFctoryTrucks = new LaneBasedStrategicalRoutePlannerFactory(
158                     new LmrsFactory<>(Lmrs::new).setStream(this.stream).set(Setting.ACCELERATION_TRAFFIC_LIGHTS, true));
159             LaneBasedGtuTemplate carTemplate = new LaneBasedGtuTemplate(car, new ConstantSupplier<>(Length.ofSI(4.0)),
160                     new ConstantSupplier<>(Length.ofSI(2.0)), speedCar, strategicalPlannerFactoryCars, routeGenerator);
161             LaneBasedGtuTemplate truckTemplate = new LaneBasedGtuTemplate(truck, new ConstantSupplier<>(Length.ofSI(15.0)),
162                     new ConstantSupplier<>(Length.ofSI(2.5)), speedTruck, strategicalPlannerFctoryTrucks, routeGenerator);
163             ObjectDistribution<LaneBasedGtuTemplate> gtuTypeDistribution = new ObjectDistribution<>(this.stream);
164             gtuTypeDistribution.add(new FrequencyAndObject<>(this.carProbability, carTemplate));
165             gtuTypeDistribution.add(new FrequencyAndObject<>(1.0 - this.carProbability, truckTemplate));
166             Supplier<Duration> headwayGenerator =
167                     new HeadwayGenerator(new Frequency(1500.0, PER_HOUR), new MersenneTwister(4L));
168             Set<LanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
169             initialLongitudinalPositions.add(new LanePosition(this.lane, new Length(5.0, LengthUnit.SI)));
170             LaneBasedGtuTemplateDistribution characteristicsGenerator =
171                     new LaneBasedGtuTemplateDistribution(gtuTypeDistribution);
172             new LaneBasedGtuGenerator("Generator", headwayGenerator, characteristicsGenerator,
173                     GeneratorPositions.create(initialLongitudinalPositions, this.stream), this.network, getSimulator(),
174                     roomChecker, idGenerator);
175             // End generation
176 
177             this.block =
178                     new TrafficLight(this.lane.getId() + "_TL", this.lane, new Length(new Length(4000.0, LengthUnit.METER)));
179             this.block.setTrafficLightColor(TrafficLightColor.GREEN);
180             // Create a block at t = 5 minutes
181             this.simulator.scheduleEventAbs(Duration.ofSI(300.0), () -> createBlock());
182             // Remove the block at t = 7 minutes
183             this.simulator.scheduleEventAbs(Duration.ofSI(420.0), () -> removeBlock());
184         }
185         catch (SimRuntimeException | NetworkException | InputParameterException | ParameterException exception)
186         {
187             exception.printStackTrace();
188         }
189     }
190 
191     /**
192      * Set up the block.
193      */
194     protected final void createBlock()
195     {
196         this.block.setTrafficLightColor(TrafficLightColor.RED);
197     }
198 
199     /**
200      * Remove the block.
201      */
202     protected final void removeBlock()
203     {
204         this.block.setTrafficLightColor(TrafficLightColor.GREEN);
205     }
206 
207     @Override
208     public RoadNetwork getNetwork()
209     {
210         return this.network;
211     }
212 
213     /**
214      * Return path.
215      * @return the path for sampling the graphs
216      */
217     public final List<Lane> getPath()
218     {
219         return this.path;
220     }
221 
222 }