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.Random;
8 import java.util.Set;
9
10 import org.djunits.unit.DirectionUnit;
11 import org.djunits.unit.LengthUnit;
12 import org.djunits.unit.util.UNITS;
13 import org.djunits.value.vdouble.scalar.Acceleration;
14 import org.djunits.value.vdouble.scalar.Direction;
15 import org.djunits.value.vdouble.scalar.Length;
16 import org.djunits.value.vdouble.scalar.Speed;
17 import org.opentrafficsim.base.parameters.Parameters;
18 import org.opentrafficsim.core.dsol.AbstractOTSModel;
19 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
20 import org.opentrafficsim.core.geometry.OTSGeometryException;
21 import org.opentrafficsim.core.geometry.OTSPoint3D;
22 import org.opentrafficsim.core.gtu.GTUDirectionality;
23 import org.opentrafficsim.core.gtu.GTUException;
24 import org.opentrafficsim.core.gtu.GTUType;
25 import org.opentrafficsim.core.network.NetworkException;
26 import org.opentrafficsim.core.network.route.Route;
27 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
28 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
29 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
30 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
31 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
32 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
33 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
34 import org.opentrafficsim.road.network.OTSRoadNetwork;
35 import org.opentrafficsim.road.network.factory.LaneFactory;
36 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
37 import org.opentrafficsim.road.network.lane.Lane;
38 import org.opentrafficsim.road.network.lane.LaneType;
39 import org.opentrafficsim.road.network.lane.OTSRoadNode;
40
41 import nl.tudelft.simulation.dsol.SimRuntimeException;
42 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterDouble;
43 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterDoubleScalar;
44 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
45 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterMap;
46 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
47 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
48 import nl.tudelft.simulation.jstats.streams.StreamInterface;
49
50
51
52
53
54
55
56
57
58
59
60 public class CircularLaneModel extends AbstractOTSModel implements UNITS
61 {
62
63 private static final long serialVersionUID = 20141121L;
64
65
66 private int carsCreated = 0;
67
68
69 private double carProbability;
70
71
72 private Length minimumDistance = new Length(0, METER);
73
74
75 private Speed speedLimit = new Speed(100, KM_PER_HOUR);
76
77
78 private List<Lane> path = new ArrayList<>();
79
80
81 private Lane lane1;
82
83
84 private Lane lane2;
85
86
87 private StreamInterface stream = new MersenneTwister(12345);
88
89
90 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
91
92
93 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
94
95
96 private Parameters parametersCar;
97
98
99 private Parameters parametersTruck;
100
101
102 private final OTSRoadNetwork network;
103
104
105
106
107 public CircularLaneModel(final OTSSimulatorInterface simulator)
108 {
109 super(simulator);
110 this.network = new OTSRoadNetwork("network", true, simulator);
111 makeInputParameterMap();
112 }
113
114
115
116
117 public void makeInputParameterMap()
118 {
119 try
120 {
121 InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 4.0);
122 InputParameterMap genericMap = (InputParameterMap) this.inputParameterMap.get("generic");
123
124 genericMap.add(new InputParameterDoubleScalar<LengthUnit, Length>("trackLength", "Track length",
125 "Track length (circumfence of the track)", Length.instantiateSI(1000.0), Length.instantiateSI(500.0),
126 Length.instantiateSI(2000.0), true, true, "%.0f", 1.0));
127 genericMap.add(new InputParameterDouble("densityMean", "Mean density (veh / km)",
128 "mean density of the vehicles (vehicles per kilometer)", 30.0, 5.0, 45.0, true, true, "%.0f", 2.0));
129 genericMap.add(new InputParameterDouble("densityVariability", "Density variability",
130 "Variability of the denisty: variability * (headway - 20) meters", 0.0, 0.0, 1.0, true, true, "%.00f",
131 3.0));
132 }
133 catch (InputParameterException exception)
134 {
135 exception.printStackTrace();
136 }
137 }
138
139
140 @Override
141 public void constructModel() throws SimRuntimeException
142 {
143 try
144 {
145 this.carProbability = (double) getInputParameter("generic.carProbability");
146 double radius = ((Length) getInputParameter("generic.trackLength")).si / 2 / Math.PI;
147 double headway = 1000.0 / (double) getInputParameter("generic.densityMean");
148 double headwayVariability = (double) getInputParameter("generic.densityVariability");
149
150 this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
151 this.parametersTruck = InputParameterHelper.getParametersTruck(getInputParameterMap());
152
153 this.strategicalPlannerGeneratorCars = new LaneBasedStrategicalRoutePlannerFactory(
154 new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
155 this.strategicalPlannerGeneratorTrucks = new LaneBasedStrategicalRoutePlannerFactory(
156 new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
157
158 LaneType laneType = this.network.getLaneType(LaneType.DEFAULTS.TWO_WAY_LANE);
159 OTSRoadNode start = new OTSRoadNode(this.network, "Start", new OTSPoint3D(radius, 0, 0),
160 new Direction(90, DirectionUnit.EAST_DEGREE));
161 OTSRoadNode halfway = new OTSRoadNode(this.network, "Halfway", new OTSPoint3D(-radius, 0, 0),
162 new Direction(270, DirectionUnit.EAST_DEGREE));
163
164 OTSPoint3D[] coordsHalf1 = new OTSPoint3D[127];
165 for (int i = 0; i < coordsHalf1.length; i++)
166 {
167 double angle = Math.PI * (1 + i) / (1 + coordsHalf1.length);
168 coordsHalf1[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
169 }
170 this.lane1 = LaneFactory.makeMultiLane(this.network, "Lane1", start, halfway, coordsHalf1, 1, laneType,
171 this.speedLimit, this.simulator)[0];
172 this.path.add(this.lane1);
173
174 OTSPoint3D[] coordsHalf2 = new OTSPoint3D[127];
175 for (int i = 0; i < coordsHalf2.length; i++)
176 {
177 double angle = Math.PI + Math.PI * (1 + i) / (1 + coordsHalf2.length);
178 coordsHalf2[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
179 }
180 this.lane2 = LaneFactory.makeMultiLane(this.network, "Lane2", halfway, start, coordsHalf2, 1, laneType,
181 this.speedLimit, this.simulator)[0];
182 this.path.add(this.lane2);
183
184
185 double trackLength = this.lane1.getLength().getSI();
186 double variability = (headway - 20) * headwayVariability;
187 System.out.println("headway is " + headway + " variability limit is " + variability);
188 Random random = new Random(12345);
189 for (double pos = 0; pos <= trackLength - headway - variability;)
190 {
191
192 double actualHeadway = headway + (random.nextDouble() * 2 - 1) * variability;
193 generateCar(this.lane1, new Length(pos, METER));
194 pos += actualHeadway;
195 }
196
197 trackLength = this.lane2.getLength().getSI();
198 variability = (headway - 20) * headwayVariability;
199 System.out.println("headway is " + headway + " variability limit is " + variability);
200 random = new Random(54321);
201 for (double pos = 0; pos <= trackLength - headway - variability;)
202 {
203
204 double actualHeadway = headway + (random.nextDouble() * 2 - 1) * variability;
205 generateCar(this.lane2, new Length(pos, METER));
206 pos += actualHeadway;
207 }
208
209 }
210 catch (Exception exception)
211 {
212 exception.printStackTrace();
213 }
214 }
215
216
217
218
219
220
221
222 protected final void generateCar(final Lane lane, final Length initialPosition) throws GTUException
223 {
224
225 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
226 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
227 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.carsCreated),
228 this.network.getGtuType(GTUType.DEFAULTS.CAR), vehicleLength, new Length(1.8, METER),
229 new Speed(200, KM_PER_HOUR), vehicleLength.times(0.5), this.simulator, this.network);
230 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
231 gtu.setNoLaneChangeDistance(Length.ZERO);
232 gtu.setMaximumAcceleration(Acceleration.instantiateSI(3.0));
233 gtu.setMaximumDeceleration(Acceleration.instantiateSI(-8.0));
234
235
236 LaneBasedStrategicalPlanner strategicalPlanner;
237 Route route = null;
238 if (!generateTruck)
239 {
240 strategicalPlanner = this.strategicalPlannerGeneratorCars.create(gtu, route, null, null);
241 }
242 else
243 {
244 strategicalPlanner = this.strategicalPlannerGeneratorTrucks.create(gtu, route, null, null);
245 }
246
247
248 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
249 initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
250 Speed initialSpeed = new Speed(0, KM_PER_HOUR);
251 try
252 {
253 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
254 }
255 catch (NetworkException | SimRuntimeException | OTSGeometryException exception)
256 {
257 throw new GTUException(exception);
258 }
259 }
260
261
262
263
264 public List<Lane> getPath()
265 {
266 return new ArrayList<>(this.path);
267 }
268
269
270 @Override
271 public OTSRoadNetwork getNetwork()
272 {
273 return this.network;
274 }
275
276
277
278
279 public final Length getMinimumDistance()
280 {
281 return this.minimumDistance;
282 }
283
284
285
286
287
288
289 public void stopSimulator(final DEVSSimulatorInterface.TimeDoubleUnit theSimulator, final String errorMessage)
290 {
291 System.out.println("Error: " + errorMessage);
292 try
293 {
294 if (theSimulator.isStartingOrRunning())
295 {
296 theSimulator.stop();
297 }
298 }
299 catch (SimRuntimeException exception)
300 {
301 exception.printStackTrace();
302 }
303 throw new Error(errorMessage);
304 }
305
306
307 @Override
308 public Serializable getSourceId()
309 {
310 return "CircularLaneModel";
311 }
312
313 }