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