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