1 package ahfe;
2
3 import java.io.BufferedWriter;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.zip.ZipEntry;
10 import java.util.zip.ZipOutputStream;
11
12 import javax.naming.NamingException;
13 import javax.swing.SwingUtilities;
14
15 import org.djunits.unit.FrequencyUnit;
16 import org.djunits.value.vdouble.scalar.Duration;
17 import org.djunits.value.vdouble.scalar.Frequency;
18 import org.djunits.value.vdouble.scalar.Length;
19 import org.djunits.value.vdouble.scalar.Time;
20 import org.opentrafficsim.base.modelproperties.Property;
21 import org.opentrafficsim.base.modelproperties.PropertyException;
22 import org.opentrafficsim.core.dsol.OTSModelInterface;
23 import org.opentrafficsim.core.gtu.AbstractGTU;
24 import org.opentrafficsim.core.network.OTSNetwork;
25 import org.opentrafficsim.kpi.interfaces.LaneDataInterface;
26 import org.opentrafficsim.kpi.sampling.KpiGtuDirectionality;
27 import org.opentrafficsim.kpi.sampling.KpiLaneDirection;
28 import org.opentrafficsim.kpi.sampling.Sampler;
29 import org.opentrafficsim.kpi.sampling.SpaceTimeRegion;
30 import org.opentrafficsim.road.network.factory.xml.XmlNetworkLaneParser;
31 import org.opentrafficsim.road.network.lane.CrossSectionLink;
32 import org.opentrafficsim.road.network.sampling.GtuData;
33 import org.opentrafficsim.road.network.sampling.LinkData;
34 import org.opentrafficsim.road.network.sampling.RoadSampler;
35 import org.opentrafficsim.road.network.sampling.data.TimeToCollision;
36 import org.opentrafficsim.simulationengine.AbstractWrappableSimulation;
37 import org.opentrafficsim.simulationengine.OTSSimulationException;
38
39 import nl.tudelft.simulation.dsol.SimRuntimeException;
40 import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
41 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
42 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
43 import nl.tudelft.simulation.event.EventProducer;
44 import nl.tudelft.simulation.language.Throw;
45 import nl.tudelft.simulation.language.io.URLResource;
46
47
48
49
50
51
52
53
54
55
56
57
58 public class AHFESimulation extends AbstractWrappableSimulation
59 {
60
61
62 static final Time WARMUP = Time.createSI(360);
63
64
65 static final Time SIMEND = Time.createSI(360 + 3600);
66
67
68 private static Length ignoreStart = Length.createSI(2900);
69
70
71 private static Length ignoreEnd = Length.createSI(1000);
72
73
74 private static final long serialVersionUID = 20170228L;
75
76
77 private final Integer replication;
78
79
80 private final String anticipationStrategy;
81
82
83 private final Duration reactionTime;
84
85
86 private final Duration anticipationTime;
87
88
89 private final double truckFraction;
90
91
92 private final double distanceError;
93
94
95 private final double speedError;
96
97
98 private final double accelerationError;
99
100
101 private final Frequency leftDemand;
102
103
104 private final Frequency rightDemand;
105
106
107 private final double leftFraction;
108
109
110 Sampler<GtuData> sampler;
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 @SuppressWarnings("checkstyle:parameternumber")
126 public AHFESimulation(final Integer replication, final String anticipationStrategy, final Duration reactionTime,
127 final Duration anticipationTime, final double truckFraction, final double distanceError, final double speedError,
128 final double accelerationError, final Frequency leftDemand, final Frequency rightDemand, final double leftFraction)
129 {
130 super();
131 this.replication = replication;
132 this.anticipationStrategy = anticipationStrategy;
133 this.reactionTime = reactionTime;
134 this.anticipationTime = anticipationTime;
135 this.truckFraction = truckFraction;
136 this.distanceError = distanceError;
137 this.speedError = speedError;
138 this.accelerationError = accelerationError;
139 this.leftDemand = leftDemand;
140 this.rightDemand = rightDemand;
141 this.leftFraction = leftFraction;
142 }
143
144
145
146
147 public Integer getReplication()
148 {
149 return this.replication;
150 }
151
152
153
154
155 public String getAnticipationStrategy()
156 {
157 return this.anticipationStrategy;
158 }
159
160
161
162
163 public Duration getReactionTime()
164 {
165 return this.reactionTime;
166 }
167
168
169
170
171 public Duration getAnticipationTime()
172 {
173 return this.anticipationTime;
174 }
175
176
177
178
179 public double getTruckFraction()
180 {
181 return this.truckFraction;
182 }
183
184
185
186
187 public double getDistanceError()
188 {
189 return this.distanceError;
190 }
191
192
193
194
195 public double getSpeedError()
196 {
197 return this.speedError;
198 }
199
200
201
202
203 public double getAccelerationError()
204 {
205 return this.accelerationError;
206 }
207
208
209
210
211 public Frequency getLeftDemand()
212 {
213 return this.leftDemand;
214 }
215
216
217
218
219 public Frequency getRightDemand()
220 {
221 return this.rightDemand;
222 }
223
224
225
226
227 public double getLeftFraction()
228 {
229 return this.leftFraction;
230 }
231
232
233
234
235
236
237 public static void main(final String[] args) throws SimRuntimeException
238 {
239 AbstractGTU.ALIGNED = false;
240 long t1 = System.currentTimeMillis();
241 boolean autorun = false;
242 int replication = 1;
243 String anticipationStrategy = "none";
244 Duration reactionTime = Duration.createSI(0.0);
245 Duration anticipationTime = Duration.ZERO;
246 double truckFraction = 0.05;
247 double distanceError = 0.0;
248 double speedError = 0.0;
249 double accelerationError = 0.0;
250 Frequency leftDemand = new Frequency(3500.0, FrequencyUnit.PER_HOUR);
251 Frequency rightDemand = new Frequency(3200.0, FrequencyUnit.PER_HOUR);
252 double leftFraction = 0.55;
253 String scenario = "test";
254
255 for (String arg : args)
256 {
257 int equalsPos = arg.indexOf("=");
258 if (equalsPos >= 0)
259 {
260
261 String key = arg.substring(0, equalsPos);
262 String value = arg.substring(equalsPos + 1);
263 if ("autorun".equalsIgnoreCase(key))
264 {
265 if ("true".equalsIgnoreCase(value))
266 {
267 autorun = true;
268 }
269 else if ("false".equalsIgnoreCase(value))
270 {
271 autorun = false;
272 }
273 else
274 {
275 System.err.println("bad autorun value " + value + " (ignored)");
276 }
277 }
278 else if ("replication".equalsIgnoreCase(key))
279 {
280 try
281 {
282 replication = Integer.parseInt(value);
283 }
284 catch (NumberFormatException nfe)
285 {
286 System.err.println("Ignoring unparsable replication number \"" + value + "\"");
287 }
288 }
289 else if ("anticipation".equalsIgnoreCase(key))
290 {
291 if (value.equalsIgnoreCase("none") || value.equalsIgnoreCase("constant_speed")
292 || value.equalsIgnoreCase("constant_acceleration"))
293 {
294 anticipationStrategy = value;
295 }
296 else
297 {
298 System.err.println("Ignoring unparsable anticipation \"" + value + "\"");
299 }
300 }
301 else if ("reactiontime".equalsIgnoreCase(key))
302 {
303 try
304 {
305 reactionTime = Duration.createSI(java.lang.Double.parseDouble(value));
306 }
307 catch (NumberFormatException nfe)
308 {
309 System.err.println("Ignoring unparsable reaction time \"" + value + "\"");
310 }
311 }
312 else if ("anticipationtime".equalsIgnoreCase(key))
313 {
314 try
315 {
316 anticipationTime = Duration.createSI(java.lang.Double.parseDouble(value));
317 }
318 catch (NumberFormatException nfe)
319 {
320 System.err.println("Ignoring unparsable anticipation time \"" + value + "\"");
321 }
322 }
323 else if ("truckfraction".equalsIgnoreCase(key))
324 {
325 try
326 {
327 truckFraction = java.lang.Double.parseDouble(value);
328 Throw.when(truckFraction < 0.0 || truckFraction > 1.0, IllegalArgumentException.class,
329 "Truck fraction must be between 0 and 1.");
330 }
331 catch (NumberFormatException nfe)
332 {
333 System.err.println("Ignoring unparsable truck fraction \"" + value + "\"");
334 }
335 }
336 else if ("distanceerror".equalsIgnoreCase(key))
337 {
338 try
339 {
340 distanceError = java.lang.Double.parseDouble(value);
341 }
342 catch (NumberFormatException nfe)
343 {
344 System.err.println("Ignoring unparsable distance error \"" + value + "\"");
345 }
346 }
347 else if ("speederror".equalsIgnoreCase(key))
348 {
349 try
350 {
351 speedError = java.lang.Double.parseDouble(value);
352 }
353 catch (NumberFormatException nfe)
354 {
355 System.err.println("Ignoring unparsable speed error \"" + value + "\"");
356 }
357 }
358 else if ("accelerationerror".equalsIgnoreCase(key))
359 {
360 try
361 {
362 accelerationError = java.lang.Double.parseDouble(value);
363 }
364 catch (NumberFormatException nfe)
365 {
366 System.err.println("Ignoring unparsable acceleration error \"" + value + "\"");
367 }
368 }
369 else if ("leftdemand".equalsIgnoreCase(key))
370 {
371 try
372 {
373 leftDemand = new Frequency(java.lang.Double.parseDouble(value), FrequencyUnit.PER_HOUR);
374 }
375 catch (NumberFormatException nfe)
376 {
377 System.err.println("Ignoring unparsable left demand \"" + value + "\"");
378 }
379 }
380 else if ("rightdemand".equalsIgnoreCase(key))
381 {
382 try
383 {
384 rightDemand = new Frequency(java.lang.Double.parseDouble(value), FrequencyUnit.PER_HOUR);
385 }
386 catch (NumberFormatException nfe)
387 {
388 System.err.println("Ignoring unparsable right demand \"" + value + "\"");
389 }
390 }
391 else if ("leftfraction".equalsIgnoreCase(key))
392 {
393 try
394 {
395 leftFraction = java.lang.Double.parseDouble(value);
396 }
397 catch (NumberFormatException nfe)
398 {
399 System.err.println("Ignoring unparsable left fraction \"" + value + "\"");
400 }
401 }
402 else if ("scenario".equalsIgnoreCase(key))
403 {
404 scenario = value;
405 }
406 else
407 {
408 System.out.println("Ignoring unknown setting " + arg);
409 }
410 }
411 else
412 {
413
414 System.err.println("Ignoring argument " + arg);
415 }
416 }
417 final boolean finalAutoRun = autorun;
418 final int finalReplication = replication;
419 final String finalAnticipationStrategy = anticipationStrategy;
420 final Duration finalReactionTime = reactionTime;
421 final Duration finalAnticipationTime = anticipationTime;
422 final double finalTruckFraction = truckFraction;
423 final double finalDistanceError = distanceError;
424 final double finalSpeedError = speedError;
425 final double finalAccelerationError = accelerationError;
426 final Frequency finalLeftDemand = leftDemand;
427 final Frequency finalRightDemand = rightDemand;
428 final double finalLeftFraction = leftFraction;
429 final String finalScenario = scenario;
430 SwingUtilities.invokeLater(new Runnable()
431 {
432 @Override
433 public void run()
434 {
435 try
436 {
437 AHFESimulation model = new AHFESimulation(finalReplication, finalAnticipationStrategy, finalReactionTime,
438 finalAnticipationTime, finalTruckFraction, finalDistanceError, finalSpeedError,
439 finalAccelerationError, finalLeftDemand, finalRightDemand, finalLeftFraction);
440 System.out.println("Setting up replication " + finalReplication);
441 model.setNextReplication(finalReplication);
442
443 model.buildSimulator(Time.ZERO, Duration.ZERO, Duration.createSI(SIMEND.si), new ArrayList<Property<?>>());
444 if (finalAutoRun)
445 {
446 int lastReportedTime = -60;
447 int reportTimeClick = 60;
448 while (true)
449 {
450 int currentTime = (int) model.getSimulator().getSimulatorTime().si;
451 if (currentTime >= lastReportedTime + reportTimeClick)
452 {
453 lastReportedTime = currentTime / reportTimeClick * reportTimeClick;
454 System.out.println("time is " + model.getSimulator().getSimulatorTime());
455 }
456 try
457 {
458 model.getSimulator().step();
459 }
460 catch (SimRuntimeException sre)
461 {
462 if (sre.getCause() != null && sre.getCause().getCause() != null
463 && sre.getCause().getCause().getMessage().equals(
464 "Model has calcalated a negative infinite or negative max value acceleration."))
465 {
466 System.err.println("Collision detected.");
467 String file = finalScenario + ".csv.zip";
468 FileOutputStream fos = null;
469 ZipOutputStream zos = null;
470 OutputStreamWriter osw = null;
471 BufferedWriter bw = null;
472 try
473 {
474 fos = new FileOutputStream(file);
475 zos = new ZipOutputStream(fos);
476 zos.putNextEntry(new ZipEntry(finalScenario + ".csv"));
477 osw = new OutputStreamWriter(zos);
478 bw = new BufferedWriter(osw);
479 bw.write("Collision");
480 bw.write(model.getSimulator().getSimulatorTime().toString());
481 }
482 catch (IOException exception2)
483 {
484 throw new RuntimeException("Could not write to file.", exception2);
485 }
486
487 finally
488 {
489 try
490 {
491 if (bw != null)
492 {
493 bw.close();
494 }
495 if (osw != null)
496 {
497 osw.close();
498 }
499 if (zos != null)
500 {
501 zos.close();
502 }
503 if (fos != null)
504 {
505 fos.close();
506 }
507 }
508 catch (IOException ex)
509 {
510 ex.printStackTrace();
511 }
512 }
513 }
514 else
515 {
516 System.out.println("Simulation ends; time is " + model.getSimulator().getSimulatorTime());
517 if (model.sampler != null)
518 {
519 model.sampler.writeToFile(finalScenario + ".csv");
520 }
521 }
522 long t2 = System.currentTimeMillis();
523 System.out.println("Run took " + (t2 - t1) / 1000 + "s.");
524 System.exit(0);
525 break;
526 }
527 }
528
529 }
530 }
531 catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
532 {
533 exception.printStackTrace();
534 }
535 }
536 });
537 }
538
539
540 private SimulatorInterface<Time, Duration, SimTimeDoubleUnit> simulator;
541
542
543 @Override
544 public final String shortName()
545 {
546 return "AFFE Simulation";
547 }
548
549
550 @Override
551 public final String description()
552 {
553 return "Simulation for AHFE congress";
554 }
555
556
557 @Override
558 protected final OTSModelInterface makeModel() throws OTSSimulationException
559 {
560 return new AHFEModel();
561 }
562
563
564
565
566 class AHFEModel extends EventProducer implements OTSModelInterface
567 {
568
569
570 private static final long serialVersionUID = 20170228L;
571
572
573 private OTSNetwork network;
574
575
576
577 AHFEModel()
578 {
579 }
580
581
582 @SuppressWarnings("synthetic-access")
583 @Override
584 public void constructModel(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> theSimulator)
585 throws SimRuntimeException
586 {
587 AHFESimulation.this.simulator = theSimulator;
588
589 AHFESimulation.this.sampler = new RoadSampler((DEVSSimulatorInterface.TimeDoubleUnit) theSimulator);
590 AHFESimulation.this.sampler.registerExtendedDataType(new TimeToCollision());
591 try
592 {
593
594 URL stream = URLResource.getResource("./Network.xml");
595 XmlNetworkLaneParser nlp = new XmlNetworkLaneParser((DEVSSimulatorInterface.TimeDoubleUnit) theSimulator);
596 this.network = new OTSNetwork("AHFE");
597 nlp.build(stream, this.network, true);
598
599
600 LinkData linkData = new LinkData((CrossSectionLink) this.network.getLink("LEFTIN"));
601 registerLinkToSampler(linkData, ignoreStart, linkData.getLength());
602 linkData = new LinkData((CrossSectionLink) this.network.getLink("RIGHTIN"));
603 registerLinkToSampler(linkData, ignoreStart, linkData.getLength());
604 linkData = new LinkData((CrossSectionLink) this.network.getLink("CONVERGE"));
605 registerLinkToSampler(linkData, Length.ZERO, linkData.getLength());
606 linkData = new LinkData((CrossSectionLink) this.network.getLink("WEAVING"));
607 registerLinkToSampler(linkData, Length.ZERO, linkData.getLength());
608 linkData = new LinkData((CrossSectionLink) this.network.getLink("END"));
609 registerLinkToSampler(linkData, Length.ZERO, linkData.getLength().minus(ignoreEnd));
610
611
612 AHFEUtil.createDemand(this.network, null, (DEVSSimulatorInterface.TimeDoubleUnit) theSimulator,
613 getReplication(), getAnticipationStrategy(), getReactionTime(), getAnticipationTime(),
614 getTruckFraction(), SIMEND, getLeftDemand(), getRightDemand(), getLeftFraction(), getDistanceError(),
615 getSpeedError(), getAccelerationError());
616
617 }
618 catch (Exception exception)
619 {
620 exception.printStackTrace();
621 }
622 }
623
624
625
626
627
628
629
630 private void registerLinkToSampler(final LinkData linkData, final Length startDistance, final Length endDistance)
631 {
632 for (LaneDataInterface laneData : linkData.getLaneDatas())
633 {
634 Length start = laneData.getLength().multiplyBy(startDistance.si / linkData.getLength().si);
635 Length end = laneData.getLength().multiplyBy(endDistance.si / linkData.getLength().si);
636 AHFESimulation.this.sampler.registerSpaceTimeRegion(new SpaceTimeRegion(
637 new KpiLaneDirection(laneData, KpiGtuDirectionality.DIR_PLUS), start, end, WARMUP, SIMEND));
638 }
639 }
640
641
642 @SuppressWarnings("synthetic-access")
643 @Override
644 public SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
645 {
646 return AHFESimulation.this.simulator;
647 }
648
649
650 @Override
651 public OTSNetwork getNetwork()
652 {
653 return this.network;
654 }
655
656 }
657
658
659
660
661
662 public final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
663 {
664 return this.simulator;
665 }
666
667 }