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