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.definitions.DefaultsNl;
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.GtuException;
23 import org.opentrafficsim.core.gtu.GtuType;
24 import org.opentrafficsim.core.network.NetworkException;
25 import org.opentrafficsim.core.network.Node;
26 import org.opentrafficsim.core.network.route.Route;
27 import org.opentrafficsim.road.definitions.DefaultsRoadNl;
28 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
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.LaneBasedStrategicalRoutePlannerFactory;
35 import org.opentrafficsim.road.network.RoadNetwork;
36 import org.opentrafficsim.road.network.factory.LaneFactory;
37 import org.opentrafficsim.road.network.lane.Lane;
38 import org.opentrafficsim.road.network.lane.LanePosition;
39 import org.opentrafficsim.road.network.lane.LaneType;
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.jstats.streams.MersenneTwister;
47 import nl.tudelft.simulation.jstats.streams.StreamInterface;
48
49
50
51
52
53
54
55
56
57 public class CircularRoadModel extends AbstractOtsModel implements UNITS
58 {
59
60 private static final long serialVersionUID = 20141121L;
61
62
63 private int carsCreated = 0;
64
65
66 private double carProbability;
67
68
69 private Length minimumDistance = new Length(0, METER);
70
71
72 private Speed speedLimit = new Speed(100, KM_PER_HOUR);
73
74
75 private List<List<Lane>> paths = new ArrayList<>();
76
77
78 private StreamInterface stream = new MersenneTwister(12345);
79
80
81 private LaneBasedStrategicalPlannerFactory<?> strategicalPlannerGeneratorCars = null;
82
83
84 private LaneBasedStrategicalPlannerFactory<?> strategicalPlannerGeneratorTrucks = null;
85
86
87 private Parameters parametersCar;
88
89
90 private Parameters parametersTruck;
91
92
93 private final RoadNetwork network;
94
95
96
97
98 public CircularRoadModel(final OtsSimulatorInterface simulator)
99 {
100 super(simulator);
101 this.network = new RoadNetwork("network", simulator);
102 makeInputParameterMap();
103 }
104
105
106
107
108 public void makeInputParameterMap()
109 {
110 try
111 {
112 InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
113
114 InputParameterMap genericMap = null;
115 if (this.inputParameterMap.getValue().containsKey("generic"))
116 {
117 genericMap = (InputParameterMap) this.inputParameterMap.get("generic");
118 }
119 else
120 {
121 genericMap = new InputParameterMap("generic", "Generic", "Generic parameters", 1.0);
122 this.inputParameterMap.add(genericMap);
123 }
124
125 genericMap.add(new InputParameterDoubleScalar<LengthUnit, Length>("trackLength", "Track length",
126 "Track length (circumfence of the track)", Length.instantiateSI(1000.0), Length.instantiateSI(500.0),
127 Length.instantiateSI(2000.0), true, true, "%.0f", 1.5));
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
142
143
144 public List<Lane> getPath(final int index)
145 {
146 return this.paths.get(index);
147 }
148
149
150 @Override
151 public void constructModel() throws SimRuntimeException
152 {
153 System.out.println("MODEL CONSTRUCTED");
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 = DefaultsNl.CAR;
176 LaneType laneType = DefaultsRoadNl.TWO_WAY_LANE;
177 Node start =
178 new Node(this.network, "Start", new OtsPoint3d(radius, 0, 0), new Direction(90, DirectionUnit.EAST_DEGREE));
179 Node halfway = new Node(this.network, "Halfway", new OtsPoint3d(-radius, 0, 0),
180 new Direction(-90, DirectionUnit.EAST_DEGREE));
181
182 OtsPoint3d[] coordsHalf1 = new OtsPoint3d[127];
183 for (int i = 0; i < coordsHalf1.length; i++)
184 {
185 double angle = Math.PI * (1 + i) / (1 + coordsHalf1.length);
186 coordsHalf1[i] = new OtsPoint3d(radius * Math.cos(angle), radius * Math.sin(angle), 0);
187 }
188 Lane[] lanes1 = LaneFactory.makeMultiLane(this.network, "FirstHalf", start, halfway, coordsHalf1, laneCount,
189 laneType, this.speedLimit, this.simulator, DefaultsNl.VEHICLE);
190 OtsPoint3d[] coordsHalf2 = new OtsPoint3d[127];
191 for (int i = 0; i < coordsHalf2.length; i++)
192 {
193 double angle = Math.PI + Math.PI * (1 + i) / (1 + coordsHalf2.length);
194 coordsHalf2[i] = new OtsPoint3d(radius * Math.cos(angle), radius * Math.sin(angle), 0);
195 }
196 Lane[] lanes2 = LaneFactory.makeMultiLane(this.network, "SecondHalf", halfway, start, coordsHalf2, laneCount,
197 laneType, this.speedLimit, this.simulator, DefaultsNl.VEHICLE);
198 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
199 {
200 this.paths.get(laneIndex).add(lanes1[laneIndex]);
201 this.paths.get(laneIndex).add(lanes2[laneIndex]);
202 }
203
204 double variability = (headway - 20) * headwayVariability;
205 System.out.println("headway is " + headway + " variability limit is " + variability);
206 Random random = new Random(12345);
207 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
208 {
209 double lane1Length = lanes1[laneIndex].getLength().getSI();
210 double trackLength = lane1Length + lanes2[laneIndex].getLength().getSI();
211 for (double pos = 0; pos <= trackLength - headway - variability;)
212 {
213 Lane lane = pos >= lane1Length ? lanes2[laneIndex] : lanes1[laneIndex];
214
215 double laneRelativePos = pos > lane1Length ? pos - lane1Length : pos;
216 double actualHeadway = headway + (random.nextDouble() * 2 - 1) * variability;
217
218 generateGTU(new Length(laneRelativePos, METER), lane, gtuType);
219 pos += actualHeadway;
220 }
221 }
222 }
223 catch (Exception exception)
224 {
225 exception.printStackTrace();
226 }
227 }
228
229
230
231
232
233
234
235
236
237
238
239 protected final void generateGTU(final Length initialPosition, final Lane lane, final GtuType gtuType)
240 throws GtuException, NetworkException, SimRuntimeException, OtsGeometryException
241 {
242
243 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
244 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
245 LaneBasedGtu gtu = new LaneBasedGtu("" + (++this.carsCreated), gtuType, vehicleLength, new Length(1.8, METER),
246 new Speed(200, KM_PER_HOUR), vehicleLength.times(0.5), this.network);
247 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
248 gtu.setNoLaneChangeDistance(Length.ZERO);
249 gtu.setMaximumAcceleration(Acceleration.instantiateSI(3.0));
250 gtu.setMaximumDeceleration(Acceleration.instantiateSI(-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<LanePosition> initialPositions = new LinkedHashSet<>(1);
266 initialPositions.add(new LanePosition(lane, initialPosition));
267 Speed initialSpeed = new Speed(0, KM_PER_HOUR);
268 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
269 }
270
271
272 @Override
273 public RoadNetwork 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 OtsSimulatorInterface theSimulator, final String errorMessage)
292 {
293 System.out.println("Error: " + errorMessage);
294 try
295 {
296 if (theSimulator.isStartingOrRunning())
297 {
298 theSimulator.stop();
299 }
300 }
301 catch (SimRuntimeException exception)
302 {
303 exception.printStackTrace();
304 }
305 throw new Error(errorMessage);
306 }
307
308 }