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.djutils.draw.point.Point2d;
17 import org.opentrafficsim.base.parameters.Parameters;
18 import org.opentrafficsim.core.definitions.DefaultsNl;
19 import org.opentrafficsim.core.dsol.AbstractOtsModel;
20 import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
21 import org.opentrafficsim.core.geometry.OtsGeometryException;
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 = new Node(this.network, "Start", new Point2d(radius, 0), new Direction(90, DirectionUnit.EAST_DEGREE));
178 Node halfway =
179 new Node(this.network, "Halfway", new Point2d(-radius, 0), new Direction(-90, DirectionUnit.EAST_DEGREE));
180
181 Point2d[] coordsHalf1 = new Point2d[127];
182 for (int i = 0; i < coordsHalf1.length; i++)
183 {
184 double angle = Math.PI * (1 + i) / (1 + coordsHalf1.length);
185 coordsHalf1[i] = new Point2d(radius * Math.cos(angle), radius * Math.sin(angle));
186 }
187 Lane[] lanes1 = LaneFactory.makeMultiLane(this.network, "FirstHalf", start, halfway, coordsHalf1, laneCount,
188 laneType, this.speedLimit, this.simulator, DefaultsNl.VEHICLE);
189 Point2d[] coordsHalf2 = new Point2d[127];
190 for (int i = 0; i < coordsHalf2.length; i++)
191 {
192 double angle = Math.PI + Math.PI * (1 + i) / (1 + coordsHalf2.length);
193 coordsHalf2[i] = new Point2d(radius * Math.cos(angle), radius * Math.sin(angle));
194 }
195 Lane[] lanes2 = LaneFactory.makeMultiLane(this.network, "SecondHalf", halfway, start, coordsHalf2, laneCount,
196 laneType, this.speedLimit, this.simulator, DefaultsNl.VEHICLE);
197 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
198 {
199 this.paths.get(laneIndex).add(lanes1[laneIndex]);
200 this.paths.get(laneIndex).add(lanes2[laneIndex]);
201 }
202
203 double variability = (headway - 20) * headwayVariability;
204 System.out.println("headway is " + headway + " variability limit is " + variability);
205 Random random = new Random(12345);
206 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
207 {
208 double lane1Length = lanes1[laneIndex].getLength().getSI();
209 double trackLength = lane1Length + lanes2[laneIndex].getLength().getSI();
210 for (double pos = 0; pos <= trackLength - headway - variability;)
211 {
212 Lane lane = pos >= lane1Length ? lanes2[laneIndex] : lanes1[laneIndex];
213
214 double laneRelativePos = pos > lane1Length ? pos - lane1Length : pos;
215 double actualHeadway = headway + (random.nextDouble() * 2 - 1) * variability;
216
217 generateGTU(new Length(laneRelativePos, METER), lane, gtuType);
218 pos += actualHeadway;
219 }
220 }
221 }
222 catch (Exception exception)
223 {
224 exception.printStackTrace();
225 }
226 }
227
228
229
230
231
232
233
234
235
236
237
238 protected final void generateGTU(final Length initialPosition, final Lane lane, final GtuType gtuType)
239 throws GtuException, NetworkException, SimRuntimeException, OtsGeometryException
240 {
241
242 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
243 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
244 LaneBasedGtu gtu = new LaneBasedGtu("" + (++this.carsCreated), gtuType, vehicleLength, new Length(1.8, METER),
245 new Speed(200, KM_PER_HOUR), vehicleLength.times(0.5), this.network);
246 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
247 gtu.setNoLaneChangeDistance(Length.ZERO);
248 gtu.setMaximumAcceleration(Acceleration.instantiateSI(3.0));
249 gtu.setMaximumDeceleration(Acceleration.instantiateSI(-8.0));
250
251
252 LaneBasedStrategicalPlanner strategicalPlanner;
253 Route route = null;
254 if (!generateTruck)
255 {
256 strategicalPlanner = this.strategicalPlannerGeneratorCars.create(gtu, route, null, null);
257 }
258 else
259 {
260 strategicalPlanner = this.strategicalPlannerGeneratorTrucks.create(gtu, route, null, null);
261 }
262
263
264 Speed initialSpeed = new Speed(0, KM_PER_HOUR);
265 gtu.init(strategicalPlanner, new LanePosition(lane, initialPosition), initialSpeed);
266 }
267
268
269 @Override
270 public RoadNetwork 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 OtsSimulatorInterface theSimulator, final String errorMessage)
289 {
290 System.out.println("Error: " + errorMessage);
291 try
292 {
293 if (theSimulator.isStartingOrRunning())
294 {
295 theSimulator.stop();
296 }
297 }
298 catch (SimRuntimeException exception)
299 {
300 exception.printStackTrace();
301 }
302 throw new Error(errorMessage);
303 }
304
305 }