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
60
61
62
63
64
65
66
67
68 public class CrossingTrafficLightsModel extends AbstractOTSModel implements UNITS
69 {
70
71 private static final long serialVersionUID = 20140815L;
72
73
74 private final OTSNetwork network = new OTSNetwork("network");
75
76
77 private StreamInterface stream = new MersenneTwister(555);
78
79
80 private ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> headwayDistribution =
81 new ContinuousDistDoubleScalar.Rel<>(new DistTriangular(this.stream, 7, 9, 15), DurationUnit.SECOND);
82
83
84 private ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedDistribution =
85 new ContinuousDistDoubleScalar.Rel<>(new DistTriangular(this.stream, 50, 60, 70), SpeedUnit.KM_PER_HOUR);
86
87
88 private int carsCreated = 0;
89
90
91 private GTUType gtuType = CAR;
92
93
94 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFactory;
95
96
97 private Parameters parametersCar;
98
99
100 private Speed speedLimit = new Speed(80, KM_PER_HOUR);
101
102
103 private static final Duration TGREEN = new Duration(39.0, DurationUnit.SI);
104
105
106 private static final Duration TYELLOW = new Duration(6.0, DurationUnit.SI);
107
108
109 private static final Duration TRED = new Duration(45.0, DurationUnit.SI);
110
111
112
113
114 public CrossingTrafficLightsModel(final OTSSimulatorInterface simulator)
115 {
116 super(simulator);
117 InputParameterHelper.makeInputParameterMapCar(this.inputParameterMap, 1.0);
118 }
119
120
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
210
211
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
234
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
264 @Override
265 public OTSNetwork getNetwork()
266 {
267 return this.network;
268 }
269 }