1 package org.opentrafficsim.web.test;
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.DirectionUnit;
10 import org.djunits.unit.LengthUnit;
11 import org.djunits.unit.util.UNITS;
12 import org.djunits.value.vdouble.scalar.Acceleration;
13 import org.djunits.value.vdouble.scalar.Direction;
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.route.Route;
26 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
27 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
28 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
29 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
30 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
31 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
32 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
33 import org.opentrafficsim.road.network.OTSRoadNetwork;
34 import org.opentrafficsim.road.network.factory.LaneFactory;
35 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
36 import org.opentrafficsim.road.network.lane.Lane;
37 import org.opentrafficsim.road.network.lane.LaneType;
38 import org.opentrafficsim.road.network.lane.OTSRoadNode;
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 OTSRoadNetwork network = new OTSRoadNetwork("network", true);
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.instantiateSI(1000.0), Length.instantiateSI(500.0),
128 Length.instantiateSI(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 System.out.println("MODEL CONSTRUCTED");
155 try
156 {
157 final int laneCount = 2;
158 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
159 {
160 this.paths.add(new ArrayList<Lane>());
161 }
162
163 this.carProbability = (double) getInputParameter("generic.carProbability");
164 double radius = ((Length) getInputParameter("generic.trackLength")).si / 2 / Math.PI;
165 double headway = 1000.0 / (double) getInputParameter("generic.densityMean");
166 double headwayVariability = (double) getInputParameter("generic.densityVariability");
167
168 this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
169 this.parametersTruck = InputParameterHelper.getParametersTruck(getInputParameterMap());
170
171 this.strategicalPlannerGeneratorCars = new LaneBasedStrategicalRoutePlannerFactory(
172 new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
173 this.strategicalPlannerGeneratorTrucks = new LaneBasedStrategicalRoutePlannerFactory(
174 new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
175
176 GTUType gtuType = this.network.getGtuType(GTUType.DEFAULTS.CAR);
177 LaneType laneType = this.network.getLaneType(LaneType.DEFAULTS.TWO_WAY_LANE);
178 OTSRoadNode start = new OTSRoadNode(this.network, "Start", new OTSPoint3D(radius, 0, 0),
179 new Direction(90, DirectionUnit.EAST_DEGREE));
180 OTSRoadNode halfway = new OTSRoadNode(this.network, "Halfway", new OTSPoint3D(-radius, 0, 0),
181 new Direction(-90, DirectionUnit.EAST_DEGREE));
182
183 OTSPoint3D[] coordsHalf1 = new OTSPoint3D[127];
184 for (int i = 0; i < coordsHalf1.length; i++)
185 {
186 double angle = Math.PI * (1 + i) / (1 + coordsHalf1.length);
187 coordsHalf1[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
188 }
189 Lane[] lanes1 = LaneFactory.makeMultiLane(this.network, "FirstHalf", start, halfway, coordsHalf1, laneCount,
190 laneType, this.speedLimit, this.simulator);
191 OTSPoint3D[] coordsHalf2 = new OTSPoint3D[127];
192 for (int i = 0; i < coordsHalf2.length; i++)
193 {
194 double angle = Math.PI + Math.PI * (1 + i) / (1 + coordsHalf2.length);
195 coordsHalf2[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
196 }
197 Lane[] lanes2 = LaneFactory.makeMultiLane(this.network, "SecondHalf", halfway, start, coordsHalf2, laneCount,
198 laneType, this.speedLimit, this.simulator);
199 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
200 {
201 this.paths.get(laneIndex).add(lanes1[laneIndex]);
202 this.paths.get(laneIndex).add(lanes2[laneIndex]);
203 }
204
205 double variability = (headway - 20) * headwayVariability;
206 System.out.println("headway is " + headway + " variability limit is " + variability);
207 Random random = new Random(12345);
208 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
209 {
210 double lane1Length = lanes1[laneIndex].getLength().getSI();
211 double trackLength = lane1Length + lanes2[laneIndex].getLength().getSI();
212 for (double pos = 0; pos <= trackLength - headway - variability;)
213 {
214 Lane lane = pos >= lane1Length ? lanes2[laneIndex] : lanes1[laneIndex];
215
216 double laneRelativePos = pos > lane1Length ? pos - lane1Length : pos;
217 double actualHeadway = headway + (random.nextDouble() * 2 - 1) * variability;
218
219 generateGTU(new Length(laneRelativePos, METER), lane, gtuType);
220 pos += actualHeadway;
221 }
222 }
223 }
224 catch (Exception exception)
225 {
226 exception.printStackTrace();
227 }
228 }
229
230
231
232
233
234
235
236
237
238
239
240 protected final void generateGTU(final Length initialPosition, final Lane lane, final GTUType gtuType)
241 throws GTUException, NetworkException, SimRuntimeException, OTSGeometryException
242 {
243
244 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
245 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
246 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.carsCreated), gtuType, vehicleLength,
247 new Length(1.8, METER), new Speed(200, KM_PER_HOUR), vehicleLength.times(0.5), this.simulator, this.network);
248 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
249 gtu.setNoLaneChangeDistance(Length.ZERO);
250 gtu.setMaximumAcceleration(Acceleration.instantiateSI(3.0));
251 gtu.setMaximumDeceleration(Acceleration.instantiateSI(-8.0));
252
253
254 LaneBasedStrategicalPlanner strategicalPlanner;
255 Route route = null;
256 if (!generateTruck)
257 {
258 strategicalPlanner = this.strategicalPlannerGeneratorCars.create(gtu, route, null, null);
259 }
260 else
261 {
262 strategicalPlanner = this.strategicalPlannerGeneratorTrucks.create(gtu, route, null, null);
263 }
264
265
266 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
267 initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
268 Speed initialSpeed = new Speed(0, KM_PER_HOUR);
269 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
270 }
271
272
273 @Override
274 public OTSRoadNetwork getNetwork()
275 {
276 return this.network;
277 }
278
279
280
281
282 public final Length getMinimumDistance()
283 {
284 return this.minimumDistance;
285 }
286
287
288
289
290
291
292 public void stopSimulator(final DEVSSimulatorInterface.TimeDoubleUnit theSimulator, final String errorMessage)
293 {
294 System.out.println("Error: " + errorMessage);
295 try
296 {
297 if (theSimulator.isRunning())
298 {
299 theSimulator.stop();
300 }
301 }
302 catch (SimRuntimeException exception)
303 {
304 exception.printStackTrace();
305 }
306 throw new Error(errorMessage);
307 }
308
309 }