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