View Javadoc
1   package org.opentrafficsim.aimsun;
2   
3   import java.awt.Dimension;
4   import java.awt.Frame;
5   import java.awt.event.ActionEvent;
6   import java.io.ByteArrayInputStream;
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.io.OutputStream;
10  import java.io.PrintWriter;
11  import java.io.Serializable;
12  import java.net.ServerSocket;
13  import java.net.Socket;
14  import java.net.URISyntaxException;
15  import java.nio.charset.StandardCharsets;
16  import java.rmi.RemoteException;
17  import java.util.LinkedHashMap;
18  import java.util.Map;
19  
20  import javax.naming.NamingException;
21  import javax.swing.JFrame;
22  import javax.xml.bind.JAXBException;
23  import javax.xml.parsers.ParserConfigurationException;
24  
25  import org.djunits.unit.DurationUnit;
26  import org.djunits.unit.TimeUnit;
27  import org.djunits.value.ValueRuntimeException;
28  import org.djunits.value.vdouble.scalar.Duration;
29  import org.djunits.value.vdouble.scalar.Length;
30  import org.djunits.value.vdouble.scalar.Time;
31  import org.djutils.event.EventInterface;
32  import org.djutils.event.EventListenerInterface;
33  import org.djutils.logger.CategoryLogger;
34  import org.djutils.logger.LogCategory;
35  import org.opentrafficsim.aimsun.proto.AimsunControlProtoBuf;
36  import org.opentrafficsim.aimsun.proto.AimsunControlProtoBuf.GTUPositions;
37  import org.opentrafficsim.base.parameters.ParameterException;
38  import org.opentrafficsim.core.animation.gtu.colorer.DefaultSwitchableGTUColorer;
39  import org.opentrafficsim.core.dsol.AbstractOTSModel;
40  import org.opentrafficsim.core.dsol.OTSAnimator;
41  import org.opentrafficsim.core.dsol.OTSLoggingAnimator;
42  import org.opentrafficsim.core.dsol.OTSModelInterface;
43  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
44  import org.opentrafficsim.core.geometry.OTSGeometryException;
45  import org.opentrafficsim.core.gtu.GTU;
46  import org.opentrafficsim.core.gtu.GTUException;
47  import org.opentrafficsim.core.gtu.GTUType;
48  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
49  import org.opentrafficsim.core.network.NetworkException;
50  import org.opentrafficsim.core.network.OTSNetwork;
51  import org.opentrafficsim.draw.core.OTSDrawingException;
52  import org.opentrafficsim.draw.factory.DefaultAnimationFactory;
53  import org.opentrafficsim.road.network.OTSRoadNetwork;
54  import org.opentrafficsim.road.network.factory.xml.XmlParserException;
55  import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
56  import org.opentrafficsim.road.network.lane.CrossSectionLink;
57  import org.opentrafficsim.road.network.lane.conflict.ConflictBuilder;
58  import org.opentrafficsim.road.network.lane.conflict.LaneCombinationList;
59  import org.opentrafficsim.swing.gui.OTSAnimationPanel;
60  import org.opentrafficsim.swing.gui.OTSSimulationApplication;
61  import org.opentrafficsim.swing.gui.OTSSwingApplication;
62  import org.opentrafficsim.trafficcontrol.TrafficControlException;
63  import org.pmw.tinylog.Level;
64  import org.xml.sax.SAXException;
65  
66  import nl.tudelft.simulation.dsol.SimRuntimeException;
67  import nl.tudelft.simulation.dsol.simulators.DEVSRealTimeClock;
68  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
69  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
70  import nl.tudelft.simulation.jstats.streams.StreamInterface;
71  import nl.tudelft.simulation.language.DSOLException;
72  import nl.tudelft.simulation.language.d3.DirectedPoint;
73  
74  /**
75   * <p>
76   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
77   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
78   * <p>
79   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 18, 2017 <br>
80   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
81   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
82   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
83   */
84  public class AimsunControl
85  {
86      /** Currently active Aimsun model. */
87      private AimsunModel model = null;
88  
89      /**
90       * Program entry point.
91       * @param args String[]; the command line arguments
92       * @throws OTSGeometryException on error
93       * @throws NetworkException on error
94       * @throws NamingException on error
95       * @throws ValueRuntimeException on error
96       * @throws SimRuntimeException on error
97       * @throws ParameterException on error
98       */
99      public static void main(final String[] args) throws NetworkException, OTSGeometryException, NamingException,
100             ValueRuntimeException, ParameterException, SimRuntimeException
101     {
102         // TODO: LaneOperationalPlanBuilder.INSTANT_LANE_CHANGES = false;
103         CategoryLogger.setAllLogLevel(Level.WARNING);
104         CategoryLogger.setLogCategories(LogCategory.ALL);
105 
106         String ip = null;
107         Integer port = null;
108 
109         for (String arg : args)
110         {
111             int equalsPos = arg.indexOf("=");
112             if (equalsPos < 0)
113             {
114                 System.err.println("Unhandled argument \"" + arg + "\"");
115             }
116             String key = arg.substring(0, equalsPos);
117             String value = arg.substring(equalsPos + 1);
118             switch (key.toUpperCase())
119             {
120                 case "IP":
121                     ip = value;
122                     break;
123                 case "PORT":
124                     try
125                     {
126                         port = Integer.parseInt(value);
127                     }
128                     catch (NumberFormatException exception)
129                     {
130                         System.err.println("Bad port number \"" + value + "\"");
131                         System.exit(1);
132                     }
133                     break;
134                 default:
135                     System.err.println("Unhandled argument \"" + arg + "\"");
136             }
137         }
138         if (null == ip || null == port)
139         {
140             System.err.println("Missing required argument(s) ip=<ip-number_or_hostname> port=<port-number>");
141             System.exit(1);
142         }
143         try
144         {
145             System.out.println("Creating server socket for port " + port);
146             ServerSocket serverSocket = new ServerSocket(port);
147             serverSocket.setReuseAddress(true); // Ensure we can be restarted without the normal 2 minute delay
148             System.out.println("Waiting for client to connect");
149             Socket clientSocket = serverSocket.accept();
150             System.out.println("Client connected; closing server socket");
151             serverSocket.close(); // don't accept any other connections
152             System.out.println("Socket time out is " + clientSocket.getSoTimeout());
153             clientSocket.setSoTimeout(0);
154             System.out.println("Constructing animation/simulation");
155             AimsunControlAimsunControl">AimsunControl aimsunControl = new AimsunControl();
156             aimsunControl.commandLoop(clientSocket);
157         }
158         catch (IOException exception)
159         {
160             exception.printStackTrace();
161         }
162         System.exit(0);
163     }
164 
165     /** Shared between sendGTUPositionsToAimsun and the commandLoop methods. */
166     private Time simulateUntil = null;
167 
168     /** Shared between sendGTUPositionsToAimsun and the commandLoop methods. */
169     private Boolean waitingForSimulator = false;
170 
171     /**
172      * Construct a GTU positions message, clear the simulateUntil value, transmit all GTU positions to Aimsun and wait for the
173      * simulateUntil value to be set again.
174      * @param outputStream OutputStream;
175      */
176     protected void sendGTUPositionsToAimsun(final OutputStream outputStream)
177     {
178         OTSSimulatorInterface simulator = this.model.getSimulator();
179         Time stopTime = simulator.getSimulatorTime();
180         // System.err.println("Entering sendGTUPositionsToAimsun: simulator time is " + stopTime);
181         AimsunControlProtoBuf.GTUPositions.Builder builder = AimsunControlProtoBuf.GTUPositions.newBuilder();
182         for (GTU gtu : this.model.getNetwork().getGTUs())
183         {
184             AimsunControlProtoBuf.GTUPositions.GTUPosition.Builder gpb =
185                     AimsunControlProtoBuf.GTUPositions.GTUPosition.newBuilder();
186             gpb.setGtuId(gtu.getId());
187             DirectedPoint dp;
188             try
189             {
190                 dp = gtu.getOperationalPlan().getLocation(stopTime);
191                 gpb.setX(dp.x);
192                 gpb.setY(dp.y);
193                 gpb.setZ(dp.z);
194                 gpb.setAngle(dp.getRotZ());
195                 gpb.setLength(gtu.getLength().si);
196                 gpb.setWidth(gtu.getWidth().si);
197                 gpb.setGtuTypeId(Integer.parseInt(gtu.getGTUType().getId().split("\\.")[1]));
198                 gpb.setSpeed(gtu.getSpeed().si);
199                 builder.addGtuPos(gpb.build());
200             }
201             catch (OperationalPlanException exception)
202             {
203                 exception.printStackTrace();
204             }
205         }
206         builder.setStatus("OK");
207         GTUPositions gtuPositions = builder.build();
208         AimsunControlProtoBuf.OTSMessage.Builder resultBuilder = AimsunControlProtoBuf.OTSMessage.newBuilder();
209         resultBuilder.setGtuPositions(gtuPositions);
210         AimsunControlProtoBuf.OTSMessage result = resultBuilder.build();
211         this.simulateUntil = null;
212         try
213         {
214             transmitMessage(result, outputStream);
215         }
216         catch (IOException exception)
217         {
218             exception.printStackTrace();
219         }
220         // System.err.println("sendGTUPositionsToAimsun: GTU positions sent; setting wait for next Aimsun message flag");
221         waitingForSimulator = false;
222         // System.err.println("sendGTUPositionsToAimsun: polling simulateUntil value to become non null");
223         while (this.simulateUntil == null)
224         {
225             try
226             {
227                 Thread.sleep(1);
228             }
229             catch (InterruptedException exception)
230             {
231                 System.err.println("Interrupted exception (sendGTUPositionsToAimsun)");
232                 // exception.printStackTrace();
233             }
234         }
235         try
236         {
237             simulator.scheduleEventAbs(this.simulateUntil, this, this, "sendGTUPositionsToAimsun", new Object[] {outputStream});
238         }
239         catch (SimRuntimeException exception)
240         {
241             exception.printStackTrace();
242         }
243         // System.err.println("Simulator resuming from sendGTUPositionsToAimsun event");
244     }
245 
246     /**
247      * Process incoming commands.
248      * @param socket Socket; the communications channel to Aimsun
249      * @throws IOException when communication with Aimsun fails
250      * @throws OTSGeometryException on error
251      * @throws NetworkException on error
252      * @throws NamingException on error
253      * @throws ValueRuntimeException on error
254      * @throws SimRuntimeException on error
255      * @throws ParameterException on error
256      */
257     private void commandLoop(final Socket socket) throws IOException, NetworkException, OTSGeometryException, NamingException,
258             ValueRuntimeException, ParameterException, SimRuntimeException
259     {
260         System.out.println("Entering command loop");
261         InputStream inputStream = socket.getInputStream();
262         OutputStream outputStream = socket.getOutputStream();
263         String error = null;
264         boolean simulatorStarted = false;
265         while (null == error)
266         {
267             try
268             {
269                 if (waitingForSimulator)
270                 {
271                     // System.err.println("Polling waitingForSimulator");
272                     // System.err.println("Simulator running status is " + this.model.getSimulator().isStartingOrRunning());
273                     while (waitingForSimulator)
274                     {
275                         if (!this.model.getSimulator().isStartingOrRunning())
276                         {
277                             System.out.println("Simulator has stopped; constructing GTUPositions message with error status");
278                             Time stopTime = this.model.getSimulator().getSimulatorTime();
279                             AimsunControlProtoBuf.GTUPositions.Builder builder =
280                                     AimsunControlProtoBuf.GTUPositions.newBuilder();
281                             for (GTU gtu : this.model.getNetwork().getGTUs())
282                             {
283                                 AimsunControlProtoBuf.GTUPositions.GTUPosition.Builder gpb =
284                                         AimsunControlProtoBuf.GTUPositions.GTUPosition.newBuilder();
285                                 gpb.setGtuId(gtu.getId());
286                                 DirectedPoint dp;
287                                 try
288                                 {
289                                     dp = gtu.getOperationalPlan().getLocation(stopTime);
290                                     gpb.setX(dp.x);
291                                     gpb.setY(dp.y);
292                                     gpb.setZ(dp.z);
293                                     gpb.setAngle(dp.getRotZ());
294                                     gpb.setLength(gtu.getLength().si);
295                                     gpb.setWidth(gtu.getWidth().si);
296                                     gpb.setGtuTypeId(Integer.parseInt(gtu.getGTUType().getId().split("\\.")[1]));
297                                     gpb.setSpeed(gtu.getSpeed().si);
298                                     builder.addGtuPos(gpb.build());
299                                 }
300                                 catch (OperationalPlanException exception)
301                                 {
302                                     exception.printStackTrace();
303                                 }
304                             }
305                             builder.setStatus("ERROR");
306                             GTUPositions gtuPositions = builder.build();
307                             AimsunControlProtoBuf.OTSMessage.Builder resultBuilder =
308                                     AimsunControlProtoBuf.OTSMessage.newBuilder();
309                             resultBuilder.setGtuPositions(gtuPositions);
310                             AimsunControlProtoBuf.OTSMessage result = resultBuilder.build();
311                             this.simulateUntil = null;
312                             try
313                             {
314                                 transmitMessage(result, outputStream);
315                             }
316                             catch (IOException exception)
317                             {
318                                 exception.printStackTrace();
319                             }
320                             System.out.println("Error message sent");
321                             // System.err.println("Clearing waitingForSimulator flag");
322                             waitingForSimulator = false;
323                             break;
324                         }
325                         try
326                         {
327                             Thread.sleep(1);
328                         }
329                         catch (InterruptedException exception)
330                         {
331                             System.err.println("Interrupted exception (command loop)");
332                             // exception.printStackTrace();
333                         }
334                     }
335                     // System.err.println("waitingForSimulator flag became false");
336                     // System.err.println("Simulator running status is " + this.model.getSimulator().isStartingOrRunning());
337                 }
338                 byte[] sizeBytes = new byte[4];
339                 // System.err.println("CommandLoop: request fillBuffer to read 4 bytes");
340                 fillBuffer(inputStream, sizeBytes);
341                 int size = ((sizeBytes[0] & 0xff) << 24) + ((sizeBytes[1] & 0xff) << 16) + ((sizeBytes[2] & 0xff) << 8)
342                         + (sizeBytes[3] & 0xff);
343                 // System.err.println("CommandLoop: requesting fillBuffer to read " + size + " bytes");
344                 byte[] buffer = new byte[size];
345                 fillBuffer(inputStream, buffer);
346                 AimsunControlProtoBuf.OTSMessage message = AimsunControlProtoBuf.OTSMessage.parseFrom(buffer);
347 
348                 if (null == message)
349                 {
350                     System.out.println("Connection terminated; exiting");
351                     break;
352                 }
353                 switch (message.getMsgCase())
354                 {
355                     case CREATESIMULATION:
356                         System.out.println("Received CREATESIMULATION message");
357                         AimsunControlProtoBuf.CreateSimulation createSimulation = message.getCreateSimulation();
358                         String networkXML = createSimulation.getNetworkXML();
359                         try (PrintWriter pw = new PrintWriter("c:/Temp/AimsunOtsNetwork.xml"))
360                         {
361                             pw.print(networkXML);
362                         }
363                         Duration runDuration = new Duration(3600, DurationUnit.SECOND);
364                         System.out.println("runDuration " + runDuration);
365                         Duration warmupDuration = new Duration(0, DurationUnit.SECOND);
366                         try
367                         {
368                             OTSAnimator animator = new OTSLoggingAnimator("C:/Temp/AimsunEventlog.txt", "AimsunControl");
369                             this.model = new AimsunModel(animator, "Aimsun generated model", "Aimsun model", networkXML);
370                             Map<String, StreamInterface> map = new LinkedHashMap<>();
371                             // TODO: This seed is Aimsun specific.
372                             map.put("generation", new MersenneTwister(6L));
373                             animator.initialize(Time.ZERO, warmupDuration, runDuration, this.model, map);
374                             OTSAnimationPanel animationPanel =
375                                     new OTSAnimationPanel(this.model.getNetwork().getExtent(), new Dimension(1100, 1000),
376                                             animator, this.model, OTSSwingApplication.DEFAULT_COLORER, this.model.getNetwork());
377                             DefaultAnimationFactory.animateXmlNetwork(this.model.getNetwork(), new DefaultSwitchableGTUColorer());
378                             new AimsunSwingApplication(this.model, animationPanel);
379                             JFrame frame = (JFrame) animationPanel.getParent().getParent().getParent();
380                             frame.setExtendedState(Frame.NORMAL);
381                             frame.setSize(new Dimension(1100, 1000));
382                             frame.setBounds(0, 25, 1100, 1000);
383                             animator.setSpeedFactor(Double.MAX_VALUE, true);
384                             animator.setSpeedFactor(1000.0, true);
385                             try
386                             {
387                                 Thread.sleep(300);
388                             }
389                             catch (InterruptedException e)
390                             {
391                                 e.printStackTrace();
392                             }
393                             animationPanel.actionPerformed(new ActionEvent(this, 0, "ZoomAll"));
394                         }
395                         catch (SimRuntimeException | NamingException | OTSDrawingException | DSOLException exception1)
396                         {
397                             exception1.printStackTrace();
398                             // Stop the simulation
399                             error = "XML ERROR";
400                         }
401                         break;
402 
403                     case SIMULATEUNTIL:
404                     {
405                         AimsunControlProtoBuf.SimulateUntil simulateUntilThing = message.getSimulateUntil();
406                         Time stopTime = new Time(simulateUntilThing.getTime(), TimeUnit.BASE_SECOND);
407                         System.out.println("Received SIMULATEUNTIL " + stopTime + " message");
408                         OTSSimulatorInterface simulator = this.model.getSimulator();
409                         if (!simulatorStarted)
410                         {
411                             simulatorStarted = true;
412                             simulator.scheduleEventAbs(stopTime, this, this, "sendGTUPositionsToAimsun",
413                                     new Object[] {outputStream});
414                             System.out.println("Starting simulator");
415                             this.simulateUntil = stopTime;
416                             simulator.start();
417                         }
418                         else if (!simulator.isStartingOrRunning())
419                         {
420                             // Whoops: simulator has stopped
421                             error = "HMM Simulator stopped";
422                         }
423                         else
424                         {
425                             // System.out.println("Resuming simulator by setting simulateUntil to " + stopTime);
426                             waitingForSimulator = true;
427                             this.simulateUntil = stopTime;
428                         }
429                         break;
430                     }
431 
432                     case GTUPOSITIONS:
433                         System.out.println("Received GTUPOSITIONS message SHOULD NOT HAPPEN");
434                         socket.close();
435                         return;
436 
437                     case MSG_NOT_SET:
438                         System.out.println("Received MSG_NOT_SET message SHOULD NOT HAPPEN");
439                         socket.close();
440                         return;
441 
442                     default:
443                         System.out.println("Received unknown message SHOULD NOT HAPPEN");
444                         socket.close();
445                         break;
446                 }
447             }
448             catch (IOException exception)
449             {
450                 exception.printStackTrace();
451                 break;
452             }
453         }
454     }
455 
456     /**
457      * Transmit a message.
458      * @param message AimsunControlProtoBuf.OTSMessage; the message
459      * @param outputStream OutputStream; the output stream
460      * @throws IOException when transmission fails
461      */
462     private void transmitMessage(final AimsunControlProtoBuf.OTSMessage message, final OutputStream outputStream)
463             throws IOException
464     {
465         int size = message.getSerializedSize();
466         // System.out.print("Transmitting " + message.getGtuPositions().getGtuPosCount() + " GTU positions and status \""
467         // + message.getGtuPositions().getStatus() + "\" encoded in " + size + " bytes ... ");
468         byte[] sizeBytes = new byte[4];
469         sizeBytes[0] = (byte) ((size >> 24) & 0xff);
470         sizeBytes[1] = (byte) ((size >> 16) & 0xff);
471         sizeBytes[2] = (byte) ((size >> 8) & 0xff);
472         sizeBytes[3] = (byte) (size & 0xff);
473         outputStream.write(sizeBytes);
474         byte[] buffer = new byte[size];
475         buffer = message.toByteArray();
476         outputStream.write(buffer);
477         // System.out.println("Message sent");
478     }
479 
480     /**
481      * Fill a buffer from a stream; retry until the buffer is entirely filled.
482      * @param in InputStream; the input stream for the data
483      * @param buffer byte[]; the buffer
484      * @throws IOException when it is not possible to fill the entire buffer
485      */
486     static void fillBuffer(final InputStream in, final byte[] buffer) throws IOException
487     {
488         // System.err.println("fillBuffer: attempting to read " + buffer.length + " bytes ... ");
489         int offset = 0;
490         while (true)
491         {
492             int bytesRead = in.read(buffer, offset, buffer.length - offset);
493             if (-1 == bytesRead)
494             {
495                 break;
496             }
497             offset += bytesRead;
498             if (buffer.length == offset)
499             {
500                 // System.err.println("fillBuffer: got all " + buffer.length + " requested bytes");
501                 break;
502             }
503             if (buffer.length < offset)
504             {
505                 System.err.println("fillBuffer: Oops: Got more than " + buffer.length + " requested bytes");
506                 break;
507             }
508             // System.err.println(
509             // "fillBuffer: now got " + offset + " bytes; need to read " + (buffer.length - offset) + " more bytes ... ");
510         }
511         if (offset != buffer.length)
512         {
513             throw new IOException("Got only " + offset + " of expected " + buffer.length + " bytes");
514         }
515     }
516 
517     /**
518      * The application.
519      */
520     class AimsunSwingApplication extends OTSSimulationApplication<OTSModelInterface>
521     {
522         /** */
523         private static final long serialVersionUID = 1L;
524 
525         /**
526          * @param model OTSModelInterface; the model
527          * @param panel OTSAnimationPanel; the panel of the main screen
528          * @throws OTSDrawingException on animation error
529          */
530         AimsunSwingApplication(final OTSModelInterface model, final OTSAnimationPanel panel) throws OTSDrawingException
531         {
532             super(model, panel);
533         }
534     }
535 
536     /**
537      * The Model.
538      */
539     class AimsunModel extends AbstractOTSModel implements EventListenerInterface
540     {
541         /** */
542         private static final long serialVersionUID = 20170419L;
543 
544         /** The network. */
545         private OTSRoadNetwork network;
546 
547         /** The XML. */
548         private final String xml;
549 
550         /**
551          * @param simulator OTSSimulatorInterface; the simulator
552          * @param shortName String; the model name
553          * @param description String; the model description
554          * @param xml String; the XML description of the simulation model
555          */
556         AimsunModel(final OTSSimulatorInterface simulator, final String shortName, final String description, final String xml)
557         {
558             super(simulator, shortName, description);
559             this.xml = xml;
560         }
561 
562         /** {@inheritDoc} */
563         @Override
564         public void notify(final EventInterface event) throws RemoteException
565         {
566             System.err.println("Received event " + event);
567         }
568 
569         /** {@inheritDoc} */
570         @Override
571         public void constructModel() throws SimRuntimeException
572         {
573             try
574             {
575                 this.simulator.addListener(this, DEVSRealTimeClock.CHANGE_SPEED_FACTOR_EVENT);
576                 this.simulator.addListener(this, SimulatorInterface.TIME_CHANGED_EVENT);
577             }
578             catch (RemoteException exception1)
579             {
580                 exception1.printStackTrace();
581             }
582             this.network = new OTSRoadNetwork(getShortName(), true, getSimulator());
583             try
584             {
585                 XmlNetworkLaneParser.build(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)), this.network,
586                         false);
587                 LaneCombinationList ignoreList = new LaneCombinationList();
588                 try
589                 {
590                     // TODO: These links are Aimsun Barcelona network specific.
591                     ignoreList.addLinkCombination((CrossSectionLink) this.network.getLink("928_J5"),
592                             (CrossSectionLink) this.network.getLink("928_J6"));
593                     ignoreList.addLinkCombination((CrossSectionLink) this.network.getLink("925_J1"),
594                             (CrossSectionLink) this.network.getLink("925_J2"));
595                 }
596                 catch (NullPointerException npe)
597                 {
598                     // Ignore exception that is expected to happen when the network is NOT the Barcelona test network
599                 }
600                 LaneCombinationList permittedList = new LaneCombinationList();
601                 ConflictBuilder.buildConflictsParallel(this.network, this.network.getGtuType(GTUType.DEFAULTS.VEHICLE),
602                         getSimulator(), new ConflictBuilder.FixedWidthGenerator(Length.instantiateSI(2.0)), ignoreList,
603                         permittedList);
604                 // new GTUDumper(simulator, Time.ZERO, Duration.instantiateSI(60), network, "C:/Temp/aimsun");
605             }
606             catch (NetworkException | OTSGeometryException | JAXBException | URISyntaxException | XmlParserException
607                     | SAXException | ParserConfigurationException | GTUException | IOException
608                     | TrafficControlException exception)
609             {
610                 exception.printStackTrace();
611                 // Abusing the SimRuntimeException to propagate the message to the main method (the problem could actually be a
612                 // parsing problem)
613                 throw new SimRuntimeException(exception);
614             }
615         }
616 
617         /** {@inheritDoc} */
618         @Override
619         public OTSNetwork getNetwork()
620         {
621             return this.network;
622         }
623 
624         /** {@inheritDoc} */
625         @Override
626         public Serializable getSourceId()
627         {
628             return "AimsunModel";
629         }
630 
631     }
632 
633 }