View Javadoc
1   package org.opentrafficsim.demo.conflictAndControl;
2   
3   import static org.opentrafficsim.core.gtu.GTUType.VEHICLE;
4   import static org.opentrafficsim.road.gtu.lane.RoadGTUTypes.CAR;
5   
6   import java.awt.BorderLayout;
7   import java.awt.geom.Rectangle2D;
8   import java.awt.geom.Rectangle2D.Double;
9   import java.net.URL;
10  import java.rmi.RemoteException;
11  import java.util.ArrayList;
12  import java.util.HashSet;
13  import java.util.LinkedHashSet;
14  import java.util.Set;
15  
16  import javax.naming.NamingException;
17  import javax.swing.JPanel;
18  import javax.swing.JScrollPane;
19  import javax.swing.SwingUtilities;
20  
21  import nl.tudelft.simulation.dsol.SimRuntimeException;
22  import nl.tudelft.simulation.dsol.simulators.DEVSSimulator;
23  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
24  import nl.tudelft.simulation.event.EventInterface;
25  import nl.tudelft.simulation.event.EventListenerInterface;
26  import nl.tudelft.simulation.event.EventProducer;
27  import nl.tudelft.simulation.event.EventType;
28  import nl.tudelft.simulation.language.io.URLResource;
29  
30  import org.djunits.unit.AccelerationUnit;
31  import org.djunits.unit.LengthUnit;
32  import org.djunits.unit.TimeUnit;
33  import org.djunits.unit.SpeedUnit;
34  import org.djunits.value.vdouble.scalar.Acceleration;
35  import org.djunits.value.vdouble.scalar.Duration;
36  import org.djunits.value.vdouble.scalar.Length;
37  import org.djunits.value.vdouble.scalar.Speed;
38  import org.djunits.value.vdouble.scalar.Time;
39  import org.opentrafficsim.base.modelproperties.Property;
40  import org.opentrafficsim.base.modelproperties.PropertyException;
41  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
42  import org.opentrafficsim.core.dsol.OTSModelInterface;
43  import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
44  import org.opentrafficsim.core.geometry.OTSGeometryException;
45  import org.opentrafficsim.core.gtu.GTUDirectionality;
46  import org.opentrafficsim.core.gtu.GTUException;
47  import org.opentrafficsim.core.gtu.GTUType;
48  import org.opentrafficsim.core.gtu.RelativePosition;
49  import org.opentrafficsim.core.gtu.animation.GTUColorer;
50  import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
51  import org.opentrafficsim.core.network.NetworkException;
52  import org.opentrafficsim.core.network.OTSNetwork;
53  import org.opentrafficsim.demo.carFollowing.DefaultsFactory;
54  import org.opentrafficsim.road.animation.AnimationToggles;
55  import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
56  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
57  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlanner;
58  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
59  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
60  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
61  import org.opentrafficsim.road.network.factory.xml.XmlNetworkLaneParser;
62  import org.opentrafficsim.road.network.lane.CrossSectionLink;
63  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
64  import org.opentrafficsim.road.network.lane.Lane;
65  import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
66  import org.opentrafficsim.road.network.lane.conflict.ConflictBuilder;
67  import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
68  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
69  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
70  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
71  import org.opentrafficsim.simulationengine.OTSSimulationException;
72  import org.opentrafficsim.simulationengine.SimpleSimulatorInterface;
73  import org.opentrafficsim.trafficcontrol.TrafficController;
74  import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
75  
76  /**
77   * <p>
78   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA,
79   * Delft, the Netherlands. All rights reserved. <br>
80   * BSD-style license. See
81   * <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
82   * <p>
83   * 
84   * @version $Revision: 3439 $, $LastChangedDate: 2017-01-30 18:25:56 +0100 (Mon,
85   *          30 Jan 2017) $, by $Author: gtamminga $, initial version Dec 06,
86   *          2016 <br>
87   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander
88   *         Verbraeck</a>
89   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
90   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
91   */
92  public class DemoTrafcodAndTurbo extends AbstractWrappableAnimation {
93  
94  	/** */
95  	private static final long serialVersionUID = 20161118L;
96  
97  	/**
98  	 * Main program.
99  	 * 
100 	 * @param args
101 	 *            String[]; the command line arguments (not used)
102 	 * @throws SimRuntimeException
103 	 *             should never happen
104 	 */
105 	public static void main(final String[] args) throws SimRuntimeException {
106 		SwingUtilities.invokeLater(new Runnable() {
107 			@Override
108 			public void run() {
109 				try {
110 					DemoTrafcodAndTurbo model = new DemoTrafcodAndTurbo();
111 					// 1 hour simulation run for testing
112 					model.buildAnimator(Time.ZERO, Duration.ZERO, new Duration(60.0, TimeUnit.MINUTE),
113 							new ArrayList<Property<?>>(), null, true);
114 				} catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception) {
115 					exception.printStackTrace();
116 				}
117 			}
118 		});
119 	}
120 
121 	/** TrafCOD controller display. */
122 	private JPanel controllerDisplayPanel = new JPanel(new BorderLayout());
123 
124 	/** The TrafCOD controller. */
125 	TrafCOD trafCOD;
126 
127 	/** {@inheritDoc} */
128 	@Override
129 	public final String shortName() {
130 		return "TrafCOD demonstration 2";
131 	}
132 
133 	/** {@inheritDoc} */
134 	@Override
135 	public final String description() {
136 		return "TrafCOD demonstration";
137 	}
138 
139 	/** {@inheritDoc} */
140 	@Override
141 	protected final void addTabs(final SimpleSimulatorInterface simulator)
142 			throws OTSSimulationException, PropertyException {
143 		JScrollPane scrollPane = new JScrollPane(DemoTrafcodAndTurbo.this.controllerDisplayPanel);
144 		JPanel wrapper = new JPanel(new BorderLayout());
145 		wrapper.add(scrollPane);
146 		addTab(getTabCount() - 1, this.trafCOD.getId(), wrapper);
147 	}
148 
149 	/** {@inheritDoc} */
150 	@Override
151 	protected final OTSModelInterface makeModel(final GTUColorer colorer) throws OTSSimulationException {
152 		return new TrafCODModel();
153 	}
154 
155 	/** {@inheritDoc} */
156 	@Override
157 	protected final void addAnimationToggles() {
158 		AnimationToggles.setTextAnimationTogglesStandard(this);
159 	}
160 
161 	/** {@inheritDoc} */
162 	@Override
163 	protected final Double makeAnimationRectangle() {
164 		return new Rectangle2D.Double(-200, -200, 400, 400);
165 	}
166 
167 	/**
168 	 * The simulation model.
169 	 */
170 	class TrafCODModel extends EventProducer implements OTSModelInterface, EventListenerInterface {
171 		/** */
172 		private static final long serialVersionUID = 20161020L;
173 
174 		/** The network. */
175 		private OTSNetwork network;
176 
177 		@SuppressWarnings("synthetic-access")
178 		@Override
179 		public void constructModel(final SimulatorInterface<Time, Duration, OTSSimTimeDouble> theSimulator)
180 				throws SimRuntimeException, RemoteException {
181 			try {
182 				URL url = URLResource.getResource("/conflictAndControl/TurboRoundaboutAndSignal.xml");
183 				XmlNetworkLaneParser nlp = new XmlNetworkLaneParser((OTSDEVSSimulatorInterface) theSimulator);
184 				this.network = nlp.build(url);
185 				// add conflicts
186 				((CrossSectionLink) this.network.getLink("EBNA")).setPriority(Priority.PRIORITY);
187 				((CrossSectionLink) this.network.getLink("NBWA")).setPriority(Priority.PRIORITY);
188 				((CrossSectionLink) this.network.getLink("WBSA")).setPriority(Priority.PRIORITY);
189 				((CrossSectionLink) this.network.getLink("SBEA")).setPriority(Priority.PRIORITY);
190 				ConflictBuilder.buildConflicts(this.network, VEHICLE, (OTSDEVSSimulatorInterface) theSimulator,
191 						new ConflictBuilder.FixedWidthGenerator(new Length(2.0, LengthUnit.SI)));
192 
193 				// CrossSectionLink csLink = ((CrossSectionLink)
194 				// this.network.getLink("WWW"));
195 				// Lane lane = (Lane) csLink.getCrossSectionElement("RIGHT");
196 				// GTUColorer gtuColorer = null;
197 				// setupBlock(lane, (OTSDEVSSimulatorInterface) theSimulator,
198 				// gtuColorer );
199 
200 				String[] directions = { "E", "S", "W", "N" };
201 				// Add the traffic lights and the detectors
202 				Set<TrafficLight> trafficLights = new HashSet<>();
203 				Set<TrafficLightSensor> sensors = new HashSet<>();
204 				Length stopLineMargin = new Length(0.1, LengthUnit.METER);
205 				Length headDetectorLength = new Length(1, LengthUnit.METER);
206 				Length headDetectorMargin = stopLineMargin.plus(headDetectorLength)
207 						.plus(new Length(3, LengthUnit.METER));
208 				Length longDetectorLength = new Length(30, LengthUnit.METER);
209 				Length longDetectorMargin = stopLineMargin.plus(longDetectorLength)
210 						.plus(new Length(10, LengthUnit.METER));
211 				int stream = 1;
212 				for (String direction : directions) {
213 					for (int laneNumber = 3; laneNumber >= 1; laneNumber--) {
214 						Lane lane = (Lane) ((CrossSectionLink) this.network.getLink(direction + "S", direction + "C"))
215 								.getCrossSectionElement("FORWARD" + laneNumber);
216 						if (lane != null) {
217 							if (stream != 7) {
218 								trafficLights.add(new SimpleTrafficLight(String.format("TL%02d", stream), lane,
219 										lane.getLength().minus(stopLineMargin),
220 										(OTSDEVSSimulatorInterface) theSimulator));
221 								sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
222 										lane.getLength().minus(headDetectorMargin), lane,
223 										lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
224 										RelativePosition.FRONT, RelativePosition.REAR,
225 										(OTSDEVSSimulatorInterface) theSimulator));
226 								sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
227 										lane.getLength().minus(longDetectorMargin), lane,
228 										lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
229 										RelativePosition.FRONT, RelativePosition.REAR,
230 										(OTSDEVSSimulatorInterface) theSimulator));
231 							}
232 							else {
233 								lane = (Lane) ((CrossSectionLink) this.network.getLink("ESS1", "ESS" ))
234 										.getCrossSectionElement("FORWARD" );
235 								trafficLights.add(new SimpleTrafficLight(String.format("TL%02d", stream), lane,
236 										lane.getLength().minus(stopLineMargin),
237 										(OTSDEVSSimulatorInterface) theSimulator));
238 								sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
239 										lane.getLength().minus(headDetectorMargin), lane,
240 										lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
241 										RelativePosition.FRONT, RelativePosition.REAR,
242 										(OTSDEVSSimulatorInterface) theSimulator));
243 								sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
244 										lane.getLength().minus(longDetectorMargin), lane,
245 										lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
246 										RelativePosition.FRONT, RelativePosition.REAR,
247 										(OTSDEVSSimulatorInterface) theSimulator));
248 								
249 							}
250 							
251 						}
252 						stream++;
253 					}
254 				}
255 				String controllerName = "Not so simple TrafCOD controller";
256 				DemoTrafcodAndTurbo.this.trafCOD = new TrafCOD(controllerName,
257 						URLResource.getResource("/conflictAndControl/Intersection12Dir.tfc"), trafficLights, sensors,
258 						(DEVSSimulator<Time, Duration, OTSSimTimeDouble>) theSimulator,
259 						DemoTrafcodAndTurbo.this.controllerDisplayPanel);
260 				DemoTrafcodAndTurbo.this.trafCOD.addListener(this,
261 						TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
262 				DemoTrafcodAndTurbo.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
263 				DemoTrafcodAndTurbo.this.trafCOD.addListener(this,
264 						TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
265 				DemoTrafcodAndTurbo.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
266 				DemoTrafcodAndTurbo.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
267 				DemoTrafcodAndTurbo.this.trafCOD.addListener(this,
268 						TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
269 				// Subscribe the TrafCOD machine to trace command events that we
270 				// emit
271 				addListener(DemoTrafcodAndTurbo.this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
272 				// fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
273 				// Object[] {controllerName, "TGX", 8, true});
274 				// fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
275 				// Object[] {controllerName, "XR1", 11, true});
276 				// fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
277 				// Object[] {controllerName, "TD1", 11, true});
278 				// fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
279 				// Object[] {controllerName, "TGX", 11, true});
280 				// fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
281 				// Object[] {controllerName, "TL", 11, true});
282 				// System.out.println("demo: emitting a SET TRACING event for
283 				// all variables related to stream 11");
284 				// fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
285 				// Object[] { controllerName, "", 11, true });
286 
287 				// TrafCODDemo2.this.trafCOD.traceVariablesOfStream(TrafficController.NO_STREAM,
288 				// true);
289 				// TrafCODDemo2.this.trafCOD.traceVariablesOfStream(11, true);
290 				// TrafCODDemo2.this.trafCOD.traceVariable("MRV", 11, true);
291 			} catch (Exception exception) {
292 				exception.printStackTrace();
293 			}
294 		}
295 
296 		@SuppressWarnings("synthetic-access")
297 		@Override
298 		public SimulatorInterface<Time, Duration, OTSSimTimeDouble> getSimulator() throws RemoteException {
299 			return DemoTrafcodAndTurbo.this.trafCOD.getSimulator();
300 		}
301 
302 		/** {@inheritDoc} */
303 		@Override
304 		public final OTSNetwork getNetwork() {
305 			return this.network;
306 		}
307 
308 		/** {@inheritDoc} */
309 		@Override
310 		public void notify(final EventInterface event) throws RemoteException {
311 			EventType type = event.getType();
312 			Object[] payload = (Object[]) event.getContent();
313 			if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type)) {
314 				// System.out.println("Evaluation starts at " +
315 				// getSimulator().getSimulatorTime().getTime());
316 				return;
317 			} else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type)) {
318 				System.out.println(
319 						"Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
320 			} else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type)) {
321 				System.out.println(String.format("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]));
322 			} else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type)) {
323 				System.out.println("Warning " + payload[1]);
324 			} else {
325 				System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
326 				String separator = "";
327 				for (Object o : payload) {
328 					System.out.print(separator + o);
329 					separator = ",";
330 				}
331 				System.out.println("]");
332 			}
333 		}
334 
335 		/**
336 		 * Put a block at the end of a Lane.
337 		 * 
338 		 * @param lane
339 		 *            Lane; the lane on which the block is placed
340 		 * @param theSimulator
341 		 *            the simulator
342 		 * @param gtuColorer
343 		 *            the gtu colorer to use
344 		 * @return Lane; the lane
345 		 * @throws NamingException
346 		 *             on ???
347 		 * @throws NetworkException
348 		 *             on network inconsistency
349 		 * @throws SimRuntimeException
350 		 *             on ???
351 		 * @throws GTUException
352 		 *             when construction of the GTU (the block is a GTU) fails
353 		 * @throws OTSGeometryException
354 		 *             when the initial path is wrong
355 		 */
356 		private Lane setupBlock(final Lane lane, OTSDEVSSimulatorInterface theSimulator, GTUColorer gtuColorer)
357 				throws NamingException, NetworkException, SimRuntimeException, GTUException, OTSGeometryException {
358 			Length initialPosition = lane.getLength();
359 			Duration tSafe = new Duration(0, TimeUnit.SECOND);
360 			Acceleration ac1 = new Acceleration(1.0, AccelerationUnit.METER_PER_SECOND_2);
361 			Length l = new Length(1.0, LengthUnit.METER);
362 			IDMPlusOld carFollowingModelCars = new IDMPlusOld(ac1, ac1, l, tSafe, 1.0);
363 			Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
364 			initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
365 			GTUType gtuType = CAR;
366 			BehavioralCharacteristics behavioralCharacteristics = DefaultsFactory.getDefaultBehavioralCharacteristics();
367 			LaneBasedIndividualGTU block = new LaneBasedIndividualGTU("999999", gtuType,
368 					new Length(1, LengthUnit.METER), lane.getWidth(1), Speed.ZERO, theSimulator,
369 					(OTSNetwork) this.network);
370 			LaneBasedStrategicalPlanner strategicalPlanner = new LaneBasedStrategicalRoutePlanner(
371 					behavioralCharacteristics, new LaneBasedGTUFollowingTacticalPlanner(carFollowingModelCars, block),
372 					block);
373 			block.initWithAnimation(strategicalPlanner, initialPositions, Speed.ZERO, DefaultCarAnimation.class,
374 					gtuColorer);
375 			return lane;
376 		}
377 
378 	}
379 
380 }