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