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