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