1 package org.opentrafficsim.demo.cacc;
2
3 import java.awt.Color;
4 import java.io.BufferedWriter;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
7 import java.rmi.RemoteException;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.LinkedHashSet;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import org.djunits.unit.DurationUnit;
16 import org.djunits.unit.FrequencyUnit;
17 import org.djunits.unit.SpeedUnit;
18 import org.djunits.unit.TimeUnit;
19 import org.djunits.value.ValueRuntimeException;
20 import org.djunits.value.storage.StorageType;
21 import org.djunits.value.vdouble.scalar.Acceleration;
22 import org.djunits.value.vdouble.scalar.Direction;
23 import org.djunits.value.vdouble.scalar.Duration;
24 import org.djunits.value.vdouble.scalar.Length;
25 import org.djunits.value.vdouble.scalar.Speed;
26 import org.djunits.value.vdouble.scalar.Time;
27 import org.djunits.value.vdouble.vector.FrequencyVector;
28 import org.djunits.value.vdouble.vector.TimeVector;
29 import org.djunits.value.vdouble.vector.base.DoubleVector;
30 import org.djunits.value.vfloat.scalar.FloatDuration;
31 import org.djutils.cli.Checkable;
32 import org.djutils.cli.CliException;
33 import org.djutils.cli.CliUtil;
34 import org.djutils.event.EventInterface;
35 import org.djutils.event.EventListenerInterface;
36 import org.opentrafficsim.base.compressedfiles.CompressionType;
37 import org.opentrafficsim.base.compressedfiles.Writer;
38 import org.opentrafficsim.core.animation.gtu.colorer.AccelerationGTUColorer;
39 import org.opentrafficsim.core.animation.gtu.colorer.IDGTUColorer;
40 import org.opentrafficsim.core.animation.gtu.colorer.SpeedGTUColorer;
41 import org.opentrafficsim.core.animation.gtu.colorer.SwitchableGTUColorer;
42 import org.opentrafficsim.core.distributions.ConstantGenerator;
43 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
44 import org.opentrafficsim.core.geometry.Bezier;
45 import org.opentrafficsim.core.geometry.OTSLine3D;
46 import org.opentrafficsim.core.geometry.OTSPoint3D;
47 import org.opentrafficsim.core.gtu.GTUDirectionality;
48 import org.opentrafficsim.core.gtu.GTUException;
49 import org.opentrafficsim.core.gtu.GTUType;
50 import org.opentrafficsim.core.gtu.TemplateGTUType;
51 import org.opentrafficsim.core.network.Link;
52 import org.opentrafficsim.core.network.LinkType;
53 import org.opentrafficsim.core.network.NetworkException;
54 import org.opentrafficsim.core.network.Node;
55 import org.opentrafficsim.core.network.OTSNode;
56 import org.opentrafficsim.core.parameters.ParameterFactory;
57 import org.opentrafficsim.core.parameters.ParameterFactoryByType;
58 import org.opentrafficsim.draw.factory.DefaultAnimationFactory;
59 import org.opentrafficsim.draw.graphs.ContourDataSource;
60 import org.opentrafficsim.draw.graphs.ContourPlotSpeed;
61 import org.opentrafficsim.draw.graphs.GraphPath;
62 import org.opentrafficsim.draw.graphs.road.GraphLaneUtil;
63 import org.opentrafficsim.kpi.sampling.KpiGtuDirectionality;
64 import org.opentrafficsim.kpi.sampling.KpiLaneDirection;
65 import org.opentrafficsim.kpi.sampling.SamplingException;
66 import org.opentrafficsim.kpi.sampling.SpaceTimeRegion;
67 import org.opentrafficsim.kpi.sampling.Trajectory;
68 import org.opentrafficsim.kpi.sampling.TrajectoryGroup;
69 import org.opentrafficsim.kpi.sampling.meta.FilterDataGtuType;
70 import org.opentrafficsim.road.gtu.colorer.DesiredSpeedColorer;
71 import org.opentrafficsim.road.gtu.colorer.FixedColor;
72 import org.opentrafficsim.road.gtu.colorer.GTUTypeColorer;
73 import org.opentrafficsim.road.gtu.colorer.SplitColorer;
74 import org.opentrafficsim.road.gtu.colorer.SynchronizationColorer;
75 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
76 import org.opentrafficsim.road.gtu.generator.Platoons;
77 import org.opentrafficsim.road.gtu.generator.od.DefaultGTUCharacteristicsGeneratorOD;
78 import org.opentrafficsim.road.gtu.generator.od.ODApplier;
79 import org.opentrafficsim.road.gtu.generator.od.ODApplier.GeneratorObjects;
80 import org.opentrafficsim.road.gtu.generator.od.ODOptions;
81 import org.opentrafficsim.road.gtu.generator.od.StrategicalPlannerFactorySupplierOD;
82 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
83 import org.opentrafficsim.road.gtu.lane.tactical.cacc.CaccController;
84 import org.opentrafficsim.road.gtu.lane.tactical.cacc.CaccControllerFactory;
85 import org.opentrafficsim.road.gtu.lane.tactical.cacc.CaccParameters;
86 import org.opentrafficsim.road.gtu.lane.tactical.cacc.CaccTacticalPlanner;
87 import org.opentrafficsim.road.gtu.lane.tactical.cacc.CaccTacticalPlannerFactory;
88 import org.opentrafficsim.road.gtu.lane.tactical.cacc.LongitudinalControllerFactory;
89 import org.opentrafficsim.road.gtu.lane.tactical.cacc.Platoon;
90 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
91 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
92 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
93 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
94 import org.opentrafficsim.road.gtu.strategical.od.Categorization;
95 import org.opentrafficsim.road.gtu.strategical.od.Category;
96 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
97 import org.opentrafficsim.road.gtu.strategical.od.ODMatrix;
98 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
99 import org.opentrafficsim.road.network.OTSRoadNetwork;
100 import org.opentrafficsim.road.network.lane.CrossSectionLink;
101 import org.opentrafficsim.road.network.lane.Lane;
102 import org.opentrafficsim.road.network.lane.LaneDirection;
103 import org.opentrafficsim.road.network.lane.LaneType;
104 import org.opentrafficsim.road.network.lane.OTSRoadNode;
105 import org.opentrafficsim.road.network.lane.Stripe;
106 import org.opentrafficsim.road.network.lane.Stripe.Permeable;
107 import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
108 import org.opentrafficsim.road.network.lane.object.sensor.Detector;
109 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
110 import org.opentrafficsim.road.network.sampling.LaneData;
111 import org.opentrafficsim.road.network.sampling.RoadSampler;
112 import org.opentrafficsim.road.network.sampling.data.TimeToCollision;
113 import org.opentrafficsim.swing.graphs.SwingContourPlot;
114 import org.opentrafficsim.swing.gui.OTSSimulationApplication;
115 import org.opentrafficsim.swing.script.AbstractSimulationScript;
116
117 import nl.tudelft.simulation.dsol.swing.gui.TablePanel;
118 import nl.tudelft.simulation.jstats.streams.StreamInterface;
119 import picocli.CommandLine;
120 import picocli.CommandLine.Option;
121
122
123
124
125
126
127
128
129
130
131
132 public class CaccSimulation extends AbstractSimulationScript implements Checkable
133 {
134
135
136 private static final long serialVersionUID = 1L;
137
138
139 private RoadSampler sampler;
140
141
142 private final TimeToCollision ttc = new TimeToCollision();
143
144
145 private final FilterDataGtuType metaGtu = new FilterDataGtuType();
146
147
148 private CaccController caccController;
149
150
151 private GTUType caccGTUType;
152
153
154 private final List<SpaceTimeRegion> regions = new ArrayList<>();
155
156
157 private List<Lane> graphLanes = new ArrayList<>();
158
159
160
161
162 @Option(names = "--nn", description = "Network name", defaultValue = "onramp")
163 private String networkName;
164
165
166 @Option(names = "--intensity", description = "Intensity factor", defaultValue = "1.00")
167 private double intensity;
168
169
170 @Option(names = "--penetration", description = "Fraction of vehicles equipped with CACC", defaultValue = "1.00")
171 private double penetration;
172
173
174 @Option(names = "--platoon", description = "Platoon size", defaultValue = "3")
175 private int platoonSize;
176
177
178 @Option(names = "--headway", description = "Platoon headway", defaultValue = "0.9")
179 private double headway;
180
181
182 @Option(names = "--synchronization", description = "Synchronization", defaultValue = "0.0")
183 private double synchronization;
184
185
186 @Option(names = "--setspeed", description = "Free flow speed of platoon vehicles", defaultValue = "80 km/h")
187 private Speed setspeed;
188
189
190 @Option(names = "--sd", description = "Simulation time", defaultValue = "5400s")
191 private Duration simulationDuration;
192
193
194 @Option(names = "--graphs", description = "Show graphs", defaultValue = "true")
195 private boolean graphs;
196
197
198 @Option(names = "--nol", description = "Number of lanes", defaultValue = "2")
199 private int numberOfLanes;
200
201
202 @Option(names = "--controller", description = "Controller", defaultValue = "CACC")
203 private String controller;
204
205
206 @Option(names = "--outputFileDets", description = "Output file for detections",
207 defaultValue = "C:\\\\Temp\\\\Journal-Platoon\\\\DetsDefault.csv")
208 private String outputFileDets;
209
210
211 @Option(names = "--outputFileTraj", description = "Output file for trajectories",
212 defaultValue = "C:\\\\Temp\\\\Journal-Platoon\\\\GenDefault")
213 private String outputFileTraj;
214
215
216 @Option(names = "--outputFileGen", description = "Output file for generators",
217 defaultValue = "C:\\Temp\\Journal-Platoon\\GenDefault")
218 private String outputFileGen;
219
220
221 @Option(names = "--startSpacing", description = "Gross equilibrium distance at 25m/s with s0=3m, l=12m and T=0.3s",
222 defaultValue = "0.5")
223 private double startSpacing;
224
225
226
227
228
229
230 protected CaccSimulation(final String[] properties) throws NoSuchFieldException, CliException
231 {
232 super("Truck CACC", "Simulation of CACC trucks");
233 CommandLine cmd = new CommandLine(this);
234 CliUtil.changeOptionDefault(AbstractSimulationScript.class, "seed", "5");
235 CliUtil.execute(cmd, properties);
236 }
237
238
239
240
241
242
243 public static void main(final String[] args) throws Exception
244 {
245 new CaccSimulation(args).start();
246 }
247
248
249 @Override
250 protected OTSRoadNetwork setupSimulation(final OTSSimulatorInterface sim) throws Exception
251 {
252 OTSRoadNetwork network = new OTSRoadNetwork(this.networkName, true, sim);
253 GTUType carGTUType = network.getGtuType(GTUType.DEFAULTS.CAR);
254 GTUType truckGTUType = network.getGtuType(GTUType.DEFAULTS.TRUCK);
255 this.caccGTUType = new GTUType("CACC", truckGTUType);
256 LinkType freewayLinkType = network.getLinkType(LinkType.DEFAULTS.FREEWAY);
257 LaneType freewayLaneType = network.getLaneType(LaneType.DEFAULTS.FREEWAY);
258 GTUType vehicle = network.getGtuType(GTUType.DEFAULTS.VEHICLE);
259 this.caccController = new CaccController();
260 this.caccController.setCACCGTUType(this.caccGTUType);
261 setGtuColorer(new SwitchableGTUColorer(0, new FixedColor(Color.BLUE, "Blue"),
262 new GTUTypeColorer().add(carGTUType, Color.BLUE).add(truckGTUType, Color.RED)
263 .add(truckGTUType, Color.GREEN),
264 new IDGTUColorer(), new SpeedGTUColorer(new Speed(150, SpeedUnit.KM_PER_HOUR)),
265 new DesiredSpeedColorer(new Speed(50, SpeedUnit.KM_PER_HOUR), new Speed(150, SpeedUnit.KM_PER_HOUR)),
266 new AccelerationGTUColorer(Acceleration.instantiateSI(-6.0), Acceleration.instantiateSI(2)), new SplitColorer(),
267 new SynchronizationColorer()));
268
269
270 ParameterFactoryByType parameters = new ParameterFactoryByType();
271
272 parameters.addParameter(CaccParameters.T_SYSTEM_CACC, new Duration(this.headway, DurationUnit.SI));
273 parameters.addParameter(CaccParameters.A_REDUCED, Acceleration.instantiateSI(this.synchronization));
274 parameters.addParameter(CaccParameters.SET_SPEED, this.setspeed);
275
276 CaccControllerFactory longitudinalControllerFactory;
277 String controllerName = this.controller;
278 if (controllerName.equals("CACC"))
279 {
280 longitudinalControllerFactory = new CaccControllerFactory();
281 }
282 else
283 {
284 throw new RuntimeException("Controller " + controllerName + " not supported.");
285 }
286
287 Length laneWidth = Length.instantiateSI(3.5);
288 Length stripeWidth = Length.instantiateSI(0.2);
289 Map<String, GeneratorObjects> odApplierOutput;
290
291 String platoonDetector1;
292
293 if (this.networkName.equals("onramp"))
294 {
295
296 OTSPoint3D pointA = new OTSPoint3D(0, 0);
297 OTSPoint3D pointB = new OTSPoint3D(2000, 0);
298 OTSPoint3D pointC = new OTSPoint3D(2330, 0);
299 OTSPoint3D pointD = new OTSPoint3D(3330, 0);
300 OTSPoint3D pointE = new OTSPoint3D(1300, -40);
301
302
303 OTSRoadNode nodeA = new OTSRoadNode(network, "A", pointA, Direction.ZERO);
304 OTSRoadNode nodeB = new OTSRoadNode(network, "B", pointB, Direction.ZERO);
305 OTSRoadNode nodeC = new OTSRoadNode(network, "C", pointC, Direction.ZERO);
306 OTSRoadNode nodeD = new OTSRoadNode(network, "D", pointD, Direction.ZERO);
307 OTSRoadNode nodeE = new OTSRoadNode(network, "E", pointE, Direction.ZERO);
308
309
310 CrossSectionLink linkAB = new CrossSectionLink(network, "AB", nodeA, nodeB, freewayLinkType,
311 new OTSLine3D(pointA, pointB), LaneKeepingPolicy.KEEPRIGHT);
312 CrossSectionLink linkBC = new CrossSectionLink(network, "BC", nodeB, nodeC, freewayLinkType,
313 new OTSLine3D(pointB, pointC), LaneKeepingPolicy.KEEPRIGHT);
314 CrossSectionLink linkCD = new CrossSectionLink(network, "CD", nodeC, nodeD, freewayLinkType,
315 new OTSLine3D(pointC, pointD), LaneKeepingPolicy.KEEPRIGHT);
316 CrossSectionLink linkEB = new CrossSectionLink(network, "EB", nodeE, nodeB, freewayLinkType,
317 Bezier.cubic(nodeE.getLocation(), nodeB.getLocation()), LaneKeepingPolicy.KEEPRIGHT);
318
319
320 int n = this.numberOfLanes;
321
322 for (int i = 0; i < n; i++)
323 {
324 for (CrossSectionLink link : new CrossSectionLink[] { linkAB, linkBC, linkCD })
325 {
326 Lane lane = new Lane(link, "Lane " + (i + 1), laneWidth.times((0.5 + i)), laneWidth, freewayLaneType,
327 new Speed(100, SpeedUnit.KM_PER_HOUR));
328 Length offset = laneWidth.times(i + 1.0);
329 Stripe stripe = new Stripe(link, offset, offset, stripeWidth);
330 if (i < n - 1)
331 {
332 if (lane.getParentLink().getId().equals("BC"))
333 {
334
335 stripe.addPermeability(vehicle, Permeable.BOTH);
336 }
337 else
338 {
339 stripe.addPermeability(vehicle, Permeable.BOTH);
340 }
341 }
342 if (lane.getParentLink().getId().equals("BC"))
343 {
344
345 new Detector(lane.getFullId(), lane, Length.instantiateSI(330.0), sim);
346 }
347
348 if (lane.getParentLink().getId().equals("CD"))
349 {
350 new SinkSensor(lane, lane.getLength().minus(Length.instantiateSI(100.0)), GTUDirectionality.DIR_PLUS,
351 sim);
352
353
354
355 }
356 if (lane.getParentLink().getId().equals("AB"))
357 {
358
359 this.graphLanes.add(lane);
360 }
361 }
362 }
363 new Stripe(linkAB, Length.ZERO, Length.ZERO, stripeWidth);
364 Stripe stripe = new Stripe(linkBC, Length.ZERO, Length.ZERO, stripeWidth);
365 stripe.addPermeability(vehicle, Permeable.LEFT);
366 new Stripe(linkCD, Length.ZERO, Length.ZERO, stripeWidth);
367 new Lane(linkBC, "Acceleration lane", laneWidth.times(-0.5), laneWidth, freewayLaneType,
368 new Speed(100, SpeedUnit.KM_PER_HOUR));
369 Lane onramp = new Lane(linkEB, "Onramp", laneWidth.times(-0.5), laneWidth, freewayLaneType,
370 new Speed(100, SpeedUnit.KM_PER_HOUR));
371 new Stripe(linkEB, Length.ZERO, Length.ZERO, stripeWidth);
372 new Stripe(linkEB, laneWidth.neg(), laneWidth.neg(), stripeWidth);
373 new Stripe(linkBC, laneWidth.neg(), laneWidth.neg(), stripeWidth);
374
375
376
377
378
379 List<OTSNode> origins = new ArrayList<>();
380 origins.add(nodeA);
381 origins.add(nodeE);
382 List<OTSNode> destinations = new ArrayList<>();
383 destinations.add(nodeD);
384 TimeVector timeVector = DoubleVector.instantiate(new double[] { 0.0, 0.25, 0.50, 0.75, 1.0, 1.25, 1.50, 1.75, 2.0 },
385 TimeUnit.BASE_HOUR, StorageType.DENSE);
386 Interpolation interpolation = Interpolation.LINEAR;
387 Categorization categorization = new Categorization("CACC", GTUType.class, Lane.class);
388
389
390 Category carCategory1 = new Category(categorization, carGTUType, this.graphLanes.get(1));
391 Category carCategory0 = new Category(categorization, carGTUType, this.graphLanes.get(0));
392 Category carCategoryR = new Category(categorization, carGTUType, onramp);
393 Category truCategory0 = new Category(categorization, truckGTUType, this.graphLanes.get(0));
394 Category truCategoryR = new Category(categorization, truckGTUType, onramp);
395 Category caccCategory = new Category(categorization, caccGTUType, this.graphLanes.get(0));
396 ODMatrix odMatrix = new ODMatrix("CACC OD", origins, destinations, categorization, timeVector, interpolation);
397
398 double intensityIncrease = this.intensity;
399 double platoonPenetration = this.penetration;
400
401
402 List<Double> demandList = new ArrayList<Double>();
403 demandList.add((double) 0);
404 demandList.add((double) 0);
405 demandList.add(180 * (1 + intensityIncrease));
406 demandList.add(180 * (1 + intensityIncrease));
407 demandList.add(180 * (1 + intensityIncrease));
408 demandList.add(180 * (1 + intensityIncrease));
409 demandList.add(180 * (1 + intensityIncrease));
410 demandList.add(180 * (1 + intensityIncrease));
411 demandList.add((double) 0);
412 demandList.add((double) 0);
413 List<Double> demandPlatoon = new ArrayList<Double>();
414
415 List<Double> demandPlatoonVehicles = new ArrayList<Double>();
416
417 for (int k = 0; k < demandList.size(); k++)
418 {
419 double platoonVehicles = (demandList.get(k) * platoonPenetration);
420 double platoonPlatoons = (Math.round(platoonVehicles / this.platoonSize)) / 4;
421
422 double newDemandVal = Math.max(demandList.get(k) - platoonVehicles, 0);
423 demandList.set(k, newDemandVal);
424 demandPlatoon.add(platoonPlatoons);
425 platoonVehicles = platoonPlatoons * this.platoonSize * 4;
426
427 demandPlatoonVehicles.add(platoonVehicles);
428 }
429
430
431 Set<LaneDirection> position = new LinkedHashSet<>();
432 position.add(new LaneDirection(this.graphLanes.get(0), GTUDirectionality.DIR_PLUS));
433 DefaultGTUCharacteristicsGeneratorOD characteristicsGenerator =
434 getCharacteristicsGenerator(longitudinalControllerFactory, sim, parameters);
435 Platoons<Category> platoons =
436 Platoons.ofCategory(characteristicsGenerator, sim, sim.getReplication().getStream("generation"), position);
437
438 platoons.fixInfo(nodeA, nodeD, caccCategory);
439
440 double dt = this.startSpacing;
441
442
443
444
445 List<Double> generationTimes = new ArrayList<Double>();
446 double previous = 0;
447
448 for (int k = 0; k < demandList.size(); k++)
449 {
450 for (int i = 0; i < demandPlatoon.get(k); i++)
451 {
452 double lambda = (demandPlatoon.get(k) * 4);
453 StreamInterface rand = sim.getReplication().getStream("generation");
454
455 double arrival = (Math.log(1 - rand.nextDouble()) / (-lambda) * 3600);
456
457
458 double startTime = (arrival + previous);
459
460 generationTimes.add(startTime);
461 previous = previous + arrival;
462 }
463 }
464
465
466 Collections.sort(generationTimes);
467
468 for (int i = 0; i < generationTimes.size() - 1; i++)
469 {
470 double diff = generationTimes.get(i + 1) - generationTimes.get(i);
471 double generationDuration = 0.5;
472 double maxDuration = (generationDuration * this.platoonSize) + 1.0;
473 if (diff <= maxDuration)
474 {
475 generationTimes.set(i + 1, generationTimes.get(i) + maxDuration);
476 }
477
478
479 double endTime = generationTimes.get(i) + (generationDuration * this.platoonSize);
480 platoons.addPlatoon(Time.instantiateSI(generationTimes.get(i)), Time.instantiateSI(endTime));
481
482 for (double t = generationTimes.get(i); t < endTime; t += dt)
483 {
484 platoons.addGtu(Time.instantiateSI(t));
485 }
486 }
487
488
489
490 odMatrix.putDemandVector(nodeA, nodeD, carCategory1,
491 freq(new double[] { 0, 0, 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
492 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease), 0,
493 0 }),
494 timeVector, interpolation, 0.5);
495 odMatrix.putDemandVector(nodeA, nodeD, carCategory0, platoons.compensate(carCategory0,
496 freq(new double[] { 0, 0, 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
497 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
498
499 0, 0 }),
500 timeVector, interpolation), timeVector, interpolation, 0.5);
501 odMatrix.putDemandVector(nodeE, nodeD, carCategoryR,
502 freq(new double[] { 0, 0, 250 * (1 + intensityIncrease), 250 * (1 + intensityIncrease),
503 250 * (1 + intensityIncrease), 250 * (1 + intensityIncrease), 250 * (1 + intensityIncrease), 0,
504 0 }));
505
506 odMatrix.putDemandVector(nodeE, nodeD, truCategoryR,
507 freq(new double[] { 0, 0, 45 * (1 + intensityIncrease), 45 * (1 + intensityIncrease),
508 45 * (1 + intensityIncrease), 45 * (1 + intensityIncrease), 45 * (1 + intensityIncrease), 0, 0 }));
509
510 if (this.penetration != 1.0)
511 {
512 odMatrix.putDemandVector(nodeA, nodeD, truCategory0,
513 platoons.compensate(truCategory0,
514 freq(new double[] { demandList.get(0), demandList.get(1), demandList.get(2), demandList.get(3),
515 demandList.get(4), demandList.get(5), demandList.get(6), demandList.get(7),
516 demandList.get(8) }),
517 timeVector, interpolation));
518 }
519 if (this.penetration != 0.0)
520 {
521 odMatrix.putDemandVector(nodeA, nodeD, caccCategory,
522 platoons.compensate(caccCategory, freq(new double[] { demandPlatoonVehicles.get(0),
523 demandPlatoonVehicles.get(1), demandPlatoonVehicles.get(2), demandPlatoonVehicles.get(3),
524 demandPlatoonVehicles.get(4), demandPlatoonVehicles.get(5), demandPlatoonVehicles.get(6),
525 demandPlatoonVehicles.get(7), demandPlatoonVehicles.get(8) }), timeVector, interpolation));
526 }
527
528 ODOptions odOptions = new ODOptions().set(ODOptions.NO_LC_DIST, Length.instantiateSI(300.0)).set(ODOptions.GTU_TYPE,
529 characteristicsGenerator);
530 odApplierOutput = ODApplier.applyOD(network, odMatrix, odOptions);
531
532
533 platoonDetector1 = "A1";
534 platoons.start(odApplierOutput.get(platoonDetector1).getGenerator());
535
536
537 BufferedWriter bw;
538 bw = new BufferedWriter(
539 new OutputStreamWriter(Writer.createOutputStream(this.outputFileGen, CompressionType.NONE)));
540 bw.write(String.format("Platoon generation times [s]: %s", generationTimes));
541 bw.close();
542 }
543 else if (this.networkName.equals("onrampMERGE"))
544 {
545
546 OTSPoint3D pointA = new OTSPoint3D(0, 0);
547 OTSPoint3D pointB = new OTSPoint3D(2000, 0);
548 OTSPoint3D pointC = new OTSPoint3D(2330, 0);
549 OTSPoint3D pointD = new OTSPoint3D(3330, 0);
550 OTSPoint3D pointE = new OTSPoint3D(1300, -40);
551
552
553 OTSRoadNode nodeA = new OTSRoadNode(network, "A", pointA, Direction.ZERO);
554 OTSRoadNode nodeB = new OTSRoadNode(network, "B", pointB, Direction.ZERO);
555 OTSRoadNode nodeC = new OTSRoadNode(network, "C", pointC, Direction.ZERO);
556 OTSRoadNode nodeD = new OTSRoadNode(network, "D", pointD, Direction.ZERO);
557 OTSRoadNode nodeE = new OTSRoadNode(network, "E", pointE, Direction.ZERO);
558
559
560 CrossSectionLink linkAB = new CrossSectionLink(network, "AB", nodeA, nodeB, freewayLinkType,
561 new OTSLine3D(pointA, pointB), LaneKeepingPolicy.KEEPRIGHT);
562 CrossSectionLink linkBC = new CrossSectionLink(network, "BC", nodeB, nodeC, freewayLinkType,
563 new OTSLine3D(pointB, pointC), LaneKeepingPolicy.KEEPRIGHT);
564 CrossSectionLink linkCD = new CrossSectionLink(network, "CD", nodeC, nodeD, freewayLinkType,
565 new OTSLine3D(pointC, pointD), LaneKeepingPolicy.KEEPRIGHT);
566 CrossSectionLink linkEB = new CrossSectionLink(network, "EB", nodeE, nodeB, freewayLinkType,
567 Bezier.cubic(nodeE.getLocation(), nodeB.getLocation()), LaneKeepingPolicy.KEEPRIGHT);
568
569
570 int n = this.numberOfLanes;
571
572 for (int i = 0; i < n; i++)
573 {
574 for (CrossSectionLink link : new CrossSectionLink[] { linkAB, linkBC, linkCD })
575 {
576 Lane lane = new Lane(link, "Lane " + (i + 1), laneWidth.times((0.5 + i)), laneWidth, freewayLaneType,
577 new Speed(100, SpeedUnit.KM_PER_HOUR));
578 Length offset = laneWidth.times(i + 1.0);
579 Stripe stripe = new Stripe(link, offset, offset, stripeWidth);
580 if (i < n - 1)
581 {
582 if (lane.getParentLink().getId().equals("BC"))
583 {
584
585 stripe.addPermeability(vehicle, Permeable.BOTH);
586
587 }
588 else
589 {
590 stripe.addPermeability(vehicle, Permeable.BOTH);
591 }
592 }
593 if (lane.getParentLink().getId().equals("BC"))
594 {
595 new Detector(lane.getFullId(), lane, Length.instantiateSI(330.0), sim);
596 }
597
598 if (lane.getParentLink().getId().equals("CD"))
599 {
600 new SinkSensor(lane, lane.getLength().minus(Length.instantiateSI(100.0)), GTUDirectionality.DIR_PLUS,
601 sim);
602
603
604
605 }
606 if (lane.getParentLink().getId().equals("AB"))
607 {
608
609 this.graphLanes.add(lane);
610 }
611 }
612 }
613 new Stripe(linkAB, Length.ZERO, Length.ZERO, stripeWidth);
614 Stripe stripe = new Stripe(linkBC, Length.ZERO, Length.ZERO, stripeWidth);
615 stripe.addPermeability(vehicle, Permeable.LEFT);
616 new Stripe(linkCD, Length.ZERO, Length.ZERO, stripeWidth);
617 new Lane(linkBC, "Acceleration lane", laneWidth.times(-0.5), laneWidth, freewayLaneType,
618 new Speed(100, SpeedUnit.KM_PER_HOUR));
619 Lane onramp = new Lane(linkEB, "Onramp", laneWidth.times(-0.5), laneWidth, freewayLaneType,
620 new Speed(100, SpeedUnit.KM_PER_HOUR));
621 new Stripe(linkEB, Length.ZERO, Length.ZERO, stripeWidth);
622 new Stripe(linkEB, laneWidth.neg(), laneWidth.neg(), stripeWidth);
623 new Stripe(linkBC, laneWidth.neg(), laneWidth.neg(), stripeWidth);
624
625
626 List<OTSNode> origins = new ArrayList<>();
627 origins.add(nodeA);
628 origins.add(nodeE);
629 List<OTSNode> destinations = new ArrayList<>();
630 destinations.add(nodeD);
631 TimeVector timeVector = DoubleVector.instantiate(new double[] { 0.0, 0.25, 0.50, 0.75, 1.0, 1.25, 1.50, 1.75, 2.0 },
632 TimeUnit.BASE_HOUR, StorageType.DENSE);
633 Interpolation interpolation = Interpolation.LINEAR;
634 Categorization categorization = new Categorization("CACC", GTUType.class, Lane.class);
635 Category carCategory1 = new Category(categorization, carGTUType, this.graphLanes.get(1));
636 Category carCategory0 = new Category(categorization, carGTUType, this.graphLanes.get(0));
637 Category carCategoryR = new Category(categorization, carGTUType, onramp);
638 Category truCategory0 = new Category(categorization, truckGTUType, this.graphLanes.get(0));
639 Category truCategoryR = new Category(categorization, truckGTUType, onramp);
640 Category caccCategory = new Category(categorization, caccGTUType, onramp);
641 ODMatrix odMatrix = new ODMatrix("CACC OD", origins, destinations, categorization, timeVector, interpolation);
642
643 double intensityIncrease = this.intensity;
644 double platoonPenetration = this.penetration;
645
646
647 List<Double> demandList = new ArrayList<Double>();
648 demandList.add((double) 0);
649 demandList.add((double) 0);
650 demandList.add(45 * (1 + intensityIncrease));
651 demandList.add(45 * (1 + intensityIncrease));
652 demandList.add(45 * (1 + intensityIncrease));
653 demandList.add(45 * (1 + intensityIncrease));
654 demandList.add(45 * (1 + intensityIncrease));
655
656 demandList.add((double) 0);
657 demandList.add((double) 0);
658 List<Double> demandPlatoon = new ArrayList<Double>();
659
660 List<Double> demandPlatoonVehicles = new ArrayList<Double>();
661
662 for (int k = 0; k < demandList.size(); k++)
663 {
664 double platoonVehicles = (demandList.get(k) * platoonPenetration);
665
666
667 double platoonPlatoons = Math.ceil(Math.abs(platoonVehicles / this.platoonSize)) / 4;
668 double newDemandVal = Math.max(demandList.get(k) - platoonVehicles, 0);
669 demandList.set(k, newDemandVal);
670 demandPlatoon.add(platoonPlatoons);
671 platoonVehicles = platoonPlatoons * this.platoonSize * 4;
672
673 demandPlatoonVehicles.add(platoonVehicles);
674 }
675
676
677 Set<LaneDirection> position = new LinkedHashSet<>();
678 position.add(new LaneDirection(onramp, GTUDirectionality.DIR_PLUS));
679 DefaultGTUCharacteristicsGeneratorOD characteristicsGenerator =
680 getCharacteristicsGenerator(longitudinalControllerFactory, sim, parameters);
681 Platoons<Category> platoons =
682 Platoons.ofCategory(characteristicsGenerator, sim, sim.getReplication().getStream("generation"), position);
683
684 platoons.fixInfo(nodeE, nodeD, caccCategory);
685
686 double dt = this.startSpacing;
687
688
689
690
691 List<Double> generationTimes = new ArrayList<Double>();
692 double previous = 0;
693
694 for (int k = 0; k < demandList.size(); k++)
695 {
696 for (int i = 0; i < demandPlatoon.get(k); i++)
697 {
698 double lambda = (demandPlatoon.get(k) * 4);
699 StreamInterface rand = sim.getReplication().getStream("generation");
700
701 double arrival = (Math.log(1 - rand.nextDouble()) / (-lambda) * 3600);
702
703
704 double startTime = (arrival + previous);
705
706 generationTimes.add(startTime);
707 previous = previous + arrival;
708 }
709 }
710
711
712 Collections.sort(generationTimes);
713
714 for (int i = 0; i < generationTimes.size() - 1; i++)
715 {
716 double diff = generationTimes.get(i + 1) - generationTimes.get(i);
717 double generationDuration = 0.5;
718 double maxDuration = (generationDuration * this.platoonSize) + 1.0;
719 if (diff <= maxDuration)
720 {
721 generationTimes.set(i + 1, generationTimes.get(i) + maxDuration);
722 }
723
724
725 double endTime = generationTimes.get(i) + (generationDuration * this.platoonSize);
726 platoons.addPlatoon(Time.instantiateSI(generationTimes.get(i)), Time.instantiateSI(endTime));
727
728 for (double t = generationTimes.get(i); t < endTime; t += dt)
729 {
730 platoons.addGtu(Time.instantiateSI(t));
731 }
732 }
733
734
735 odMatrix.putDemandVector(nodeA, nodeD, carCategory1,
736 freq(new double[] { 0, 0, 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
737 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
738
739 0, 0 }),
740 timeVector, interpolation, 0.5);
741 odMatrix.putDemandVector(nodeA, nodeD, carCategory0,
742 freq(new double[] { 0, 0, 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
743 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease), 1000 * (1 + intensityIncrease),
744
745 0, 0 }),
746 timeVector, interpolation, 0.5);
747 odMatrix.putDemandVector(nodeE, nodeD, carCategoryR,
748 platoons.compensate(carCategoryR,
749 freq(new double[] { 0, 0, 250 * (1 + intensityIncrease), 250 * (1 + intensityIncrease),
750 250 * (1 + intensityIncrease), 250 * (1 + intensityIncrease), 250 * (1 + intensityIncrease),
751
752 0, 0 }),
753 timeVector, interpolation));
754
755 odMatrix.putDemandVector(nodeA, nodeD, truCategory0,
756 platoons.compensate(truCategory0,
757 freq(new double[] { 0, 0, 180 * (1 + intensityIncrease), 180 * (1 + intensityIncrease),
758 180 * (1 + intensityIncrease), 180 * (1 + intensityIncrease), 180 * (1 + intensityIncrease),
759
760 0, 0 }),
761 timeVector, interpolation));
762
763 if (this.penetration != 1.0)
764 {
765 odMatrix.putDemandVector(nodeE, nodeD, truCategoryR,
766 freq(new double[] { demandList.get(0), demandList.get(1), demandList.get(2), demandList.get(3),
767 demandList.get(4), demandList.get(5), demandList.get(6), demandList.get(7),
768 demandList.get(8) }),
769 timeVector, interpolation);
770 }
771 if (this.penetration != 0.0)
772 {
773 odMatrix.putDemandVector(nodeE, nodeD, caccCategory,
774 platoons.compensate(caccCategory, freq(new double[] { demandPlatoonVehicles.get(0),
775 demandPlatoonVehicles.get(1), demandPlatoonVehicles.get(2), demandPlatoonVehicles.get(3),
776 demandPlatoonVehicles.get(4), demandPlatoonVehicles.get(5), demandPlatoonVehicles.get(6),
777 demandPlatoonVehicles.get(7), demandPlatoonVehicles.get(8) }), timeVector, interpolation));
778 }
779
780
781 ODOptions odOptions = new ODOptions().set(ODOptions.NO_LC_DIST, Length.instantiateSI(300.0)).set(ODOptions.GTU_TYPE,
782 characteristicsGenerator);
783 odApplierOutput = ODApplier.applyOD(network, odMatrix, odOptions);
784
785
786 platoonDetector1 = "E1";
787 platoons.start(odApplierOutput.get(platoonDetector1).getGenerator());
788
789
790 BufferedWriter bw;
791 bw = new BufferedWriter(
792 new OutputStreamWriter(Writer.createOutputStream(this.outputFileGen, CompressionType.NONE)));
793 bw.write(String.format("Platoon generation times [s]: %s", generationTimes));
794 bw.close();
795
796 }
797 else
798 {
799 throw new RuntimeException("Network " + this.networkName + " not supported.");
800 }
801
802
803 odApplierOutput.get(platoonDetector1).getGenerator().addListener(new EventListenerInterface()
804 {
805
806 private static final long serialVersionUID = 1L;
807
808
809 private Platoon platoon = null;
810
811
812 private LaneBasedGTU lastGtu;
813
814
815 @Override
816 public void notify(final EventInterface event) throws RemoteException
817 {
818 if (event.getType().equals(LaneBasedGTUGenerator.GTU_GENERATED_EVENT))
819 {
820 LaneBasedGTU gtu = (LaneBasedGTU) event.getContent();
821 if (gtu.getGTUType().equals(caccGTUType))
822 {
823
824
825
826
827 if (this.lastGtu == null || this.lastGtu.isDestroyed()
828 || this.lastGtu.getLocation().distance(gtu.getLocation()) > 3.0 * gtu.getSpeed().si
829 || this.platoon.size() >= platoonSize)
830 {
831 this.platoon = new Platoon();
832 }
833 this.platoon.addGtu(gtu.getId());
834 ((CaccTacticalPlanner) gtu.getTacticalPlanner()).setPlatoon(this.platoon);
835 this.lastGtu = gtu;
836 }
837 }
838 }
839 }, LaneBasedGTUGenerator.GTU_GENERATED_EVENT);
840
841
842 this.sampler =
843 RoadSampler.build(network).registerExtendedDataType(this.ttc).registerFilterDataType(this.metaGtu).create();
844
845
846 Time start = new Time(0.25, TimeUnit.BASE_HOUR);
847 Time end = new Time(2.00, TimeUnit.BASE_HOUR);
848 for (Link link : network.getLinkMap().values())
849 {
850 for (Lane lane : ((CrossSectionLink) link).getLanes())
851 {
852 KpiLaneDirection kpiLane = new KpiLaneDirection(new LaneData(lane), KpiGtuDirectionality.DIR_PLUS);
853 SpaceTimeRegion region = new SpaceTimeRegion(kpiLane, Length.ZERO, lane.getLength(), start, end);
854 this.regions.add(region);
855 this.sampler.registerSpaceTimeRegion(region);
856 }
857 }
858 return network;
859 }
860
861
862 @Override
863 protected void addTabs(final OTSSimulatorInterface sim, final OTSSimulationApplication<?> animation)
864 {
865 if (this.graphs)
866 {
867
868 int h = (int) Math.sqrt(this.graphLanes.size());
869 int w = (int) Math.ceil(((double) this.graphLanes.size()) / h);
870 TablePanel charts = new TablePanel(w, h);
871 animation.getAnimationPanel().getTabbedPane().addTab(animation.getAnimationPanel().getTabbedPane().getTabCount(),
872 "statistics", charts);
873
874
875
876 RoadSampler graphSampler = RoadSampler.build(getNetwork()).registerExtendedDataType(this.ttc)
877 .registerFilterDataType(this.metaGtu).create();
878
879
880 int h2 = 0;
881 int w2 = 0;
882 for (int i = 0; i < this.graphLanes.size(); i++)
883 {
884 GraphPath<KpiLaneDirection> graphPath;
885 try
886 {
887
888 graphPath = GraphLaneUtil.createPath("Lane" + (i + 1),
889 new LaneDirection(this.graphLanes.get(i), GTUDirectionality.DIR_PLUS));
890 GraphPath.initRecording(graphSampler, graphPath);
891 }
892 catch (NetworkException exception)
893 {
894 throw new RuntimeException(exception);
895 }
896 ContourDataSource<?> dataPool = new ContourDataSource<>(graphSampler.getSamplerData(), graphPath);
897 SwingContourPlot plot = new SwingContourPlot(new ContourPlotSpeed("Speed lane " + (i + 1), sim, dataPool));
898 charts.setCell(plot.getContentPane(), w2, h2);
899 w2++;
900 if (w2 > w)
901 {
902 w = 0;
903 h2++;
904 }
905 }
906 }
907 }
908
909
910 @Override
911 protected void onSimulationEnd()
912 {
913
914 Detector.writeToFile(getNetwork(), this.outputFileDets, true);
915
916
917 double tts = 0.0;
918 List<Float> ttcList = new ArrayList<>();
919 List<String> ttcListGtuType = new ArrayList<>();
920 List<Float> decList = new ArrayList<>();
921 List<String> decListGtuType = new ArrayList<>();
922 List<Float> posList = new ArrayList<>();
923 List<Float> timeList = new ArrayList<>();
924 List<String> postimeList = new ArrayList<>();
925 List<String> posListGtuType = new ArrayList<>();
926 List<Float> posupstreamList = new ArrayList<>();
927 List<Float> timeupstreamList = new ArrayList<>();
928 List<String> postimeupstreamList = new ArrayList<>();
929 List<String> posupstreamListGtuType = new ArrayList<>();
930 List<Float> posdownstreamList = new ArrayList<>();
931 List<Float> timedownstreamList = new ArrayList<>();
932 List<String> postimedownstreamList = new ArrayList<>();
933 List<String> posdownstreamListGtuType = new ArrayList<>();
934 List<Float> posrampList = new ArrayList<>();
935 List<Float> timerampList = new ArrayList<>();
936 List<String> postimerampList = new ArrayList<>();
937 List<String> posrampListGtuType = new ArrayList<>();
938 int[] counts = new int[120];
939 Length detectorPosition = Length.instantiateSI(100.0);
940 for (SpaceTimeRegion region : this.regions)
941 {
942 TrajectoryGroup<?> trajectoryGroup =
943 this.sampler.getSamplerData().getTrajectoryGroup(region.getLaneDirection()).getTrajectoryGroup(
944 region.getStartPosition(), region.getEndPosition(), region.getStartTime(), region.getEndTime());
945 for (Trajectory<?> trajectory : trajectoryGroup)
946 {
947 try
948 {
949 tts += trajectory.getTotalDuration().si;
950 String gtuTypeId = trajectory.getMetaData(this.metaGtu ).getId();
951 for (FloatDuration ttcVal : trajectory.getExtendedData(this.ttc))
952 {
953 if (!Float.isNaN(ttcVal.si) && ttcVal.si < 20)
954 {
955 ttcList.add(ttcVal.si);
956 ttcListGtuType.add(gtuTypeId);
957 }
958 }
959 for (float decVal : trajectory.getA())
960 {
961 if (decVal < -2.0)
962 {
963 decList.add(decVal);
964 decListGtuType.add(gtuTypeId);
965 }
966 }
967
968
969 if (region.getLaneDirection().getLaneData().getLinkData().getId().equals("BC")
970 && region.getLaneDirection().getLaneData().getId().equals("Lane 1"))
971 {
972 for (float xPos : trajectory.getX())
973 {
974 posList.add(xPos);
975 posListGtuType.add(trajectory.getGtuId());
976 postimeList.add(gtuTypeId);
977 }
978
979 for (float tPos : trajectory.getT())
980 {
981 timeList.add(tPos);
982 }
983 }
984
985 if (region.getLaneDirection().getLaneData().getLinkData().getId().equals("AB")
986 && region.getLaneDirection().getLaneData().getId().equals("Lane 1"))
987 {
988 for (float xPos : trajectory.getX())
989 {
990 posupstreamList.add(xPos);
991 posupstreamListGtuType.add(trajectory.getGtuId());
992 postimeupstreamList.add(gtuTypeId);
993 }
994
995 for (float tPos : trajectory.getT())
996 {
997 timeupstreamList.add(tPos);
998 }
999 }
1000
1001 if (region.getLaneDirection().getLaneData().getLinkData().getId().equals("CD")
1002 && region.getLaneDirection().getLaneData().getId().equals("Lane 1"))
1003 {
1004 for (float xPos : trajectory.getX())
1005 {
1006 posdownstreamList.add(xPos);
1007 posdownstreamListGtuType.add(trajectory.getGtuId());
1008 postimedownstreamList.add(gtuTypeId);
1009 }
1010
1011 for (float tPos : trajectory.getT())
1012 {
1013 timedownstreamList.add(tPos);
1014 }
1015 }
1016
1017 if (region.getLaneDirection().getLaneData().getLinkData().getId().equals("BC")
1018 && region.getLaneDirection().getLaneData().getId().equals("Acceleration lane"))
1019 {
1020 for (float xPos : trajectory.getX())
1021 {
1022 posrampList.add(xPos);
1023 posrampListGtuType.add(trajectory.getGtuId());
1024 postimerampList.add(gtuTypeId);
1025 }
1026
1027 for (float tPos : trajectory.getT())
1028 {
1029 timerampList.add(tPos);
1030 }
1031 }
1032 if (region.getLaneDirection().getLaneData().getLinkData().getId().equals("CD") && trajectory.size() > 1
1033 && trajectory.getX(0) < detectorPosition.si
1034 && trajectory.getX(trajectory.size() - 1) > detectorPosition.si)
1035 {
1036 double t = trajectory.getTimeAtPosition(detectorPosition).si - region.getStartTime().si;
1037 counts[(int) (t / 60.0)]++;
1038 }
1039 }
1040 catch (SamplingException exception)
1041 {
1042 throw new RuntimeException("Unexpected exception: TimeToCollission not available or index out of bounds.",
1043 exception);
1044 }
1045 }
1046 }
1047 int qMax = 0;
1048 for (int i = 0; i < counts.length - 4; i++)
1049 {
1050 int q = 0;
1051 for (int j = i; j < i + 5; j++)
1052 {
1053 q += counts[j];
1054 }
1055 qMax = qMax > q ? qMax : q;
1056 }
1057 BufferedWriter bw;
1058 try
1059 {
1060 bw = new BufferedWriter(
1061 new OutputStreamWriter(Writer.createOutputStream(this.outputFileTraj, CompressionType.NONE)));
1062 bw.write(String.format("total time spent [s]: %.0f", tts));
1063 bw.newLine();
1064 bw.write(String.format("maximum flow [veh/5min]: %d", qMax));
1065 bw.newLine();
1066 bw.write(String.format("time to collision [s]: %s", ttcList));
1067 bw.newLine();
1068 bw.write(String.format("time to collision GTU type: %s", ttcListGtuType));
1069 bw.newLine();
1070 bw.write(String.format("strong decelerations [m/s^2]: %s", decList));
1071 bw.newLine();
1072 bw.write(String.format("strong decelerations GTU type: %s", decListGtuType));
1073 bw.newLine();
1074 bw.write(String.format("X pos: %s", posList));
1075 bw.newLine();
1076 bw.write(String.format("T pos: %s", timeList));
1077 bw.newLine();
1078 bw.write(String.format("X pos GTU ID: %s", posListGtuType));
1079 bw.newLine();
1080 bw.write(String.format("X pos GTU type: %s", postimeList));
1081 bw.newLine();
1082 bw.write(String.format("X pos ramp: %s", posrampList));
1083 bw.newLine();
1084 bw.write(String.format("T pos ramp: %s", timerampList));
1085 bw.newLine();
1086 bw.write(String.format("X pos ramp GTU ID: %s", posrampListGtuType));
1087 bw.newLine();
1088 bw.write(String.format("X pos ramp GTU type: %s", postimerampList));
1089 bw.newLine();
1090 bw.write(String.format("X pos up: %s", posupstreamList));
1091 bw.newLine();
1092 bw.write(String.format("T pos up: %s", timeupstreamList));
1093 bw.newLine();
1094 bw.write(String.format("X pos up GTU ID: %s", posupstreamListGtuType));
1095 bw.newLine();
1096 bw.write(String.format("X pos up GTU type: %s", postimeupstreamList));
1097 bw.newLine();
1098 bw.write(String.format("X pos down: %s", posdownstreamList));
1099 bw.newLine();
1100 bw.write(String.format("T pos down: %s", timedownstreamList));
1101 bw.newLine();
1102 bw.write(String.format("X pos down GTU ID: %s", posdownstreamListGtuType));
1103 bw.newLine();
1104 bw.write(String.format("X pos down GTU type: %s", postimedownstreamList));
1105 bw.close();
1106 }
1107 catch (IOException exception)
1108 {
1109 throw new RuntimeException(exception);
1110 }
1111 }
1112
1113
1114
1115
1116
1117
1118
1119 private FrequencyVector freq(final double[] array) throws ValueRuntimeException
1120 {
1121 return DoubleVector.instantiate(array, FrequencyUnit.PER_HOUR, StorageType.DENSE);
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132 private DefaultGTUCharacteristicsGeneratorOD getCharacteristicsGenerator(
1133 final LongitudinalControllerFactory<? extends CaccController> longitudinalControllerFactory,
1134 final OTSSimulatorInterface simulator, final ParameterFactory parameters)
1135 {
1136
1137 Set<TemplateGTUType> templates = new LinkedHashSet<>();
1138 templates.add(new TemplateGTUType(caccGTUType, new ConstantGenerator<>(Length.instantiateSI(12.0)),
1139 new ConstantGenerator<>(Length.instantiateSI(2.55)),
1140 new ConstantGenerator<>(Speed.instantiateSI(this.setspeed.si + 2.78))));
1141
1142 return new DefaultGTUCharacteristicsGeneratorOD(templates, new StrategicalPlannerFactorySupplierOD()
1143 {
1144
1145 private LaneBasedStrategicalPlannerFactory<?> lmrsFactory = null;
1146
1147
1148 private LaneBasedStrategicalPlannerFactory<?> caccFactory = null;
1149
1150
1151 @Override
1152 public LaneBasedStrategicalPlannerFactory<?> getFactory(final Node origin, final Node destination,
1153 final Category category, final StreamInterface randomStream) throws GTUException
1154 {
1155 GTUType gtuType = category.get(GTUType.class);
1156 if (!gtuType.equals(caccGTUType))
1157 {
1158 if (this.lmrsFactory == null)
1159 {
1160 this.lmrsFactory = new LaneBasedStrategicalRoutePlannerFactory(
1161 new LMRSFactory(new IDMPlusFactory(randomStream), new DefaultLMRSPerceptionFactory()),
1162 parameters);
1163 }
1164 return this.lmrsFactory;
1165 }
1166 if (this.caccFactory == null)
1167 {
1168 this.caccFactory = new LaneBasedStrategicalRoutePlannerFactory(
1169 new CaccTacticalPlannerFactory(new IDMPlusFactory(randomStream), longitudinalControllerFactory,
1170 simulator, caccGTUType),
1171 parameters);
1172 }
1173 return this.caccFactory;
1174 }
1175 });
1176 }
1177
1178 }