View Javadoc
1   package org.opentrafficsim.demo;
2   
3   import static org.opentrafficsim.core.gtu.GTUType.CAR;
4   
5   import java.rmi.RemoteException;
6   import java.util.HashMap;
7   import java.util.LinkedHashSet;
8   import java.util.Map;
9   import java.util.Set;
10  
11  import javax.naming.NamingException;
12  
13  import org.djunits.unit.DurationUnit;
14  import org.djunits.unit.LengthUnit;
15  import org.djunits.unit.SpeedUnit;
16  import org.djunits.unit.UNITS;
17  import org.djunits.value.vdouble.scalar.Acceleration;
18  import org.djunits.value.vdouble.scalar.Duration;
19  import org.djunits.value.vdouble.scalar.Length;
20  import org.djunits.value.vdouble.scalar.Speed;
21  import org.opentrafficsim.base.parameters.ParameterException;
22  import org.opentrafficsim.base.parameters.Parameters;
23  import org.opentrafficsim.core.dsol.AbstractOTSModel;
24  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
25  import org.opentrafficsim.core.geometry.OTSGeometryException;
26  import org.opentrafficsim.core.geometry.OTSPoint3D;
27  import org.opentrafficsim.core.gtu.GTUDirectionality;
28  import org.opentrafficsim.core.gtu.GTUException;
29  import org.opentrafficsim.core.gtu.GTUType;
30  import org.opentrafficsim.core.network.NetworkException;
31  import org.opentrafficsim.core.network.OTSNetwork;
32  import org.opentrafficsim.core.network.OTSNode;
33  import org.opentrafficsim.core.network.route.Route;
34  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
35  import org.opentrafficsim.draw.road.TrafficLightAnimation;
36  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
37  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
38  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
39  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
40  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
41  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
42  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
43  import org.opentrafficsim.road.network.factory.LaneFactory;
44  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
45  import org.opentrafficsim.road.network.lane.Lane;
46  import org.opentrafficsim.road.network.lane.LaneType;
47  import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
48  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
49  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
50  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
51  
52  import nl.tudelft.simulation.dsol.SimRuntimeException;
53  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
54  import nl.tudelft.simulation.jstats.distributions.DistTriangular;
55  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
56  import nl.tudelft.simulation.jstats.streams.StreamInterface;
57  
58  /**
59   * Simulate four double lane roads with a crossing in the middle.
60   * <p>
61   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
62   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
63   * </p>
64   * $LastChangedDate: 2016-10-28 16:34:11 +0200 (Fri, 28 Oct 2016) $, @version $Revision: 2429 $, by $Author: pknoppers $,
65   * initial version ug 1, 2014 <br>
66   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
67   */
68  public class CrossingTrafficLightsModel extends AbstractOTSModel implements UNITS
69  {
70      /** */
71      private static final long serialVersionUID = 20140815L;
72  
73      /** The network. */
74      private final OTSNetwork network = new OTSNetwork("network");
75  
76      /** the random stream for this demo. */
77      private StreamInterface stream = new MersenneTwister(555);
78  
79      /** The headway (inter-vehicle time) distribution. */
80      private ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> headwayDistribution =
81              new ContinuousDistDoubleScalar.Rel<>(new DistTriangular(this.stream, 7, 9, 15), DurationUnit.SECOND);
82  
83      /** The speed distribution. */
84      private ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedDistribution =
85              new ContinuousDistDoubleScalar.Rel<>(new DistTriangular(this.stream, 50, 60, 70), SpeedUnit.KM_PER_HOUR);
86  
87      /** Number of cars created. */
88      private int carsCreated = 0;
89  
90      /** Type of all GTUs. */
91      private GTUType gtuType = CAR;
92  
93      /** the tactical planner factory for this model. */
94      private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFactory;
95  
96      /** Car parameters. */
97      private Parameters parametersCar;
98  
99      /** The speed limit on all Lanes. */
100     private Speed speedLimit = new Speed(80, KM_PER_HOUR);
101 
102     /** Fixed green time. */
103     private static final Duration TGREEN = new Duration(39.0, DurationUnit.SI);
104 
105     /** Fixed yellow time. */
106     private static final Duration TYELLOW = new Duration(6.0, DurationUnit.SI);
107 
108     /** Fixed red time. */
109     private static final Duration TRED = new Duration(45.0, DurationUnit.SI);
110 
111     /**
112      * @param simulator OTSSimulatorInterface; the simulator for this model
113      */
114     public CrossingTrafficLightsModel(final OTSSimulatorInterface simulator)
115     {
116         super(simulator);
117         InputParameterHelper.makeInputParameterMapCar(this.inputParameterMap, 1.0);
118     }
119 
120     /** {@inheritDoc} */
121     @Override
122     public final void constructModel() throws SimRuntimeException
123     {
124         try
125         {
126             OTSNode[][] nodes = new OTSNode[4][4];
127             nodes[0][0] = new OTSNode(this.network, "sn1", new OTSPoint3D(10, -500));
128             nodes[0][1] = new OTSNode(this.network, "sn2", new OTSPoint3D(10, -20));
129             nodes[0][2] = new OTSNode(this.network, "sn3", new OTSPoint3D(10, +20));
130             nodes[0][3] = new OTSNode(this.network, "sn4", new OTSPoint3D(10, +5000));
131 
132             nodes[1][0] = new OTSNode(this.network, "we1", new OTSPoint3D(-500, -10));
133             nodes[1][1] = new OTSNode(this.network, "we2", new OTSPoint3D(-20, -10));
134             nodes[1][2] = new OTSNode(this.network, "we3", new OTSPoint3D(+20, -10));
135             nodes[1][3] = new OTSNode(this.network, "we4", new OTSPoint3D(+5000, -10));
136 
137             nodes[2][0] = new OTSNode(this.network, "ns1", new OTSPoint3D(-10, +500));
138             nodes[2][1] = new OTSNode(this.network, "ns2", new OTSPoint3D(-10, +20));
139             nodes[2][2] = new OTSNode(this.network, "ns3", new OTSPoint3D(-10, -20));
140             nodes[2][3] = new OTSNode(this.network, "ns4", new OTSPoint3D(-10, -5000));
141 
142             nodes[3][0] = new OTSNode(this.network, "ew1", new OTSPoint3D(+500, 10));
143             nodes[3][1] = new OTSNode(this.network, "ew2", new OTSPoint3D(+20, 10));
144             nodes[3][2] = new OTSNode(this.network, "ew3", new OTSPoint3D(-20, 10));
145             nodes[3][3] = new OTSNode(this.network, "ew4", new OTSPoint3D(-5000, 10));
146 
147             LaneType laneType = LaneType.TWO_WAY_LANE;
148 
149             Map<Lane, SimpleTrafficLight> trafficLights = new HashMap<>();
150 
151             for (int i = 0; i < 4; i++)
152             {
153                 for (int j = 0; j < 3; j++)
154                 {
155                     Lane[] lanes = LaneFactory.makeMultiLane(this.network,
156                             "Lane_" + nodes[i][j].getId() + "-" + nodes[i][j + 1].getId(), nodes[i][j], nodes[i][j + 1], null,
157                             2, laneType, this.speedLimit, this.simulator);
158                     if (j == 0)
159                     {
160                         for (Lane lane : lanes)
161                         {
162                             this.simulator.scheduleEventRel(this.headwayDistribution.draw(), this, this, "generateCar",
163                                     new Object[] { lane });
164                             SimpleTrafficLight tl = new SimpleTrafficLight(lane.getId() + "_TL", lane,
165                                     new Length(lane.getLength().minus(new Length(10.0, LengthUnit.METER))), this.simulator);
166                             trafficLights.put(lane, tl);
167 
168                             try
169                             {
170                                 new TrafficLightAnimation(tl, this.simulator);
171                             }
172                             catch (RemoteException | NamingException exception)
173                             {
174                                 throw new NetworkException(exception);
175                             }
176 
177                             if (i == 0 || i == 2)
178                             {
179                                 this.simulator.scheduleEventRel(Duration.ZERO, this, this, "changeTL", new Object[] { tl });
180                             }
181                             else
182                             {
183                                 this.simulator.scheduleEventRel(TRED, this, this, "changeTL", new Object[] { tl });
184                             }
185                         }
186                     }
187                     if (j == 2)
188                     {
189                         for (Lane lane : lanes)
190                         {
191                             new SinkSensor(lane, new Length(500.0, METER), this.simulator);
192                         }
193                     }
194                 }
195             }
196 
197             this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
198             this.strategicalPlannerFactory = new LaneBasedStrategicalRoutePlannerFactory(
199                     new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
200         }
201         catch (SimRuntimeException | NamingException | NetworkException | OTSGeometryException | GTUException
202                 | ParameterException | InputParameterException exception)
203         {
204             exception.printStackTrace();
205         }
206     }
207 
208     /**
209      * Change the traffic light to a new color.
210      * @param tl TrafficLight; the traffic light
211      * @throws SimRuntimeException when scheduling fails
212      */
213     protected final void changeTL(final TrafficLight tl) throws SimRuntimeException
214     {
215         if (tl.getTrafficLightColor().isRed())
216         {
217             tl.setTrafficLightColor(TrafficLightColor.GREEN);
218             this.simulator.scheduleEventRel(TGREEN, this, this, "changeTL", new Object[] { tl });
219         }
220         else if (tl.getTrafficLightColor().isGreen())
221         {
222             tl.setTrafficLightColor(TrafficLightColor.YELLOW);
223             this.simulator.scheduleEventRel(TYELLOW, this, this, "changeTL", new Object[] { tl });
224         }
225         else if (tl.getTrafficLightColor().isYellow())
226         {
227             tl.setTrafficLightColor(TrafficLightColor.RED);
228             this.simulator.scheduleEventRel(TRED, this, this, "changeTL", new Object[] { tl });
229         }
230     }
231 
232     /**
233      * Generate cars at a fixed rate (implemented by re-scheduling this method).
234      * @param lane Lane; the lane to generate the car on
235      */
236     protected final void generateCar(final Lane lane)
237     {
238         Length initialPosition = new Length(10, METER);
239         Speed initialSpeed = new Speed(10.0, KM_PER_HOUR);
240         Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
241         try
242         {
243             initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
244             Length vehicleLength = new Length(4, METER);
245             LaneBasedIndividualGTU gtu =
246                     new LaneBasedIndividualGTU("" + (++this.carsCreated), this.gtuType, vehicleLength, new Length(1.8, METER),
247                             this.speedDistribution.draw(), vehicleLength.multiplyBy(0.5), this.simulator, this.network);
248             gtu.setParameters(this.parametersCar);
249             gtu.setNoLaneChangeDistance(Length.ZERO);
250             gtu.setMaximumAcceleration(Acceleration.createSI(3.0));
251             gtu.setMaximumDeceleration(Acceleration.createSI(-8.0));
252             Route route = null;
253             LaneBasedStrategicalPlanner strategicalPlanner = this.strategicalPlannerFactory.create(gtu, route, null, null);
254             gtu.init(strategicalPlanner, initialPositions, initialSpeed);
255             this.simulator.scheduleEventRel(this.headwayDistribution.draw(), this, this, "generateCar", new Object[] { lane });
256         }
257         catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException exception)
258         {
259             exception.printStackTrace();
260         }
261     }
262 
263     /** {@inheritDoc} */
264     @Override
265     public OTSNetwork getNetwork()
266     {
267         return this.network;
268     }
269 }