package org.opentrafficsim.demo; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Window; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; import javax.naming.NamingException; import javax.swing.JButton; import org.djunits.value.vdouble.scalar.Duration; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Time; import org.opentrafficsim.core.dsol.OTSAnimator; import org.opentrafficsim.core.dsol.OTSSimulator; import org.opentrafficsim.core.dsol.OTSSimulatorInterface; import org.opentrafficsim.core.gtu.GTU; import org.opentrafficsim.core.gtu.GTUDirectionality; import org.opentrafficsim.core.network.DirectedLinkPosition; import org.opentrafficsim.core.network.NetworkException; import org.opentrafficsim.draw.core.OTSDrawingException; import org.opentrafficsim.draw.graphs.ContourDataSource; import org.opentrafficsim.draw.graphs.ContourPlotAcceleration; import org.opentrafficsim.draw.graphs.ContourPlotDensity; import org.opentrafficsim.draw.graphs.ContourPlotFlow; import org.opentrafficsim.draw.graphs.ContourPlotSpeed; import org.opentrafficsim.draw.graphs.FundamentalDiagram; import org.opentrafficsim.draw.graphs.FundamentalDiagram.Quantity; import org.opentrafficsim.draw.graphs.GraphCrossSection; import org.opentrafficsim.draw.graphs.GraphPath; import org.opentrafficsim.draw.graphs.TrajectoryPlot; import org.opentrafficsim.draw.graphs.road.GraphLaneUtil; import org.opentrafficsim.kpi.sampling.KpiLaneDirection; import org.opentrafficsim.road.network.OTSRoadNetwork; import org.opentrafficsim.road.network.lane.LaneDirection; import org.opentrafficsim.road.network.sampling.RoadSampler; import org.opentrafficsim.swing.graphs.SwingContourPlot; import org.opentrafficsim.swing.graphs.SwingFundamentalDiagram; import org.opentrafficsim.swing.graphs.SwingPlot; import org.opentrafficsim.swing.graphs.SwingTrajectoryPlot; import org.opentrafficsim.swing.gui.OTSAnimationPanel; import org.opentrafficsim.swing.gui.OTSSimulationApplication; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.dsol.swing.gui.TablePanel; import nl.tudelft.simulation.dsol.swing.gui.inputparameters.TabbedParameterDialog; import nl.tudelft.simulation.language.DSOLException; /** * Circular road simulation demo. *

* Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* $LastChangedDate: 2018-11-18 20:49:04 +0100 (Sun, 18 Nov 2018) $, @version $Revision: 4743 $, by $Author: averbraeck $, * initial version 21 nov. 2014
* @author Peter Knoppers */ public class CircularRoadSwing extends OTSSimulationApplication { /** */ private static final long serialVersionUID = 1L; /** * Create a CircularRoad Swing application. * @param title String; the title of the Frame * @param panel OTSAnimationPanel; the tabbed panel to display * @param model CircularRoadModel; the model * @throws OTSDrawingException on animation error */ public CircularRoadSwing(final String title, final OTSAnimationPanel panel, final CircularRoadModel model) throws OTSDrawingException { super(model, panel); // NetworkAnimation networkAnimation = new NetworkAnimation(model.getNetwork()); // networkAnimation.addDrawingInfoClass(Lane.class, new DrawingInfoShape<>(Color.GRAY)); OTSRoadNetwork network = model.getNetwork(); System.out.println(network.getLinkMap()); } /** {@inheritDoc} */ @Override protected void addTabs() { addStatisticsTabs(getModel().getSimulator()); } /** * Main program. * @param args String[]; the command line arguments (not used) */ public static void main(final String[] args) { // simulatorDemo(); demo(true); } /** * Run the simulation without animation. */ public static void simulatorDemo() { try { OTSSimulator simulator = new OTSSimulator("CircularRoadSwing"); final CircularRoadModel otsModel = new CircularRoadModel(simulator); System.out.println(otsModel.getInputParameterMap()); TabbedParameterDialog.process(otsModel.getInputParameterMap()); simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), otsModel); Thread getLocationThread = new Thread() { @Override public void run() { System.out.println("getLocationThread starts up"); int iteration = 0; int getLocationCalls = 0; while (simulator.isStartingOrRunning()) { iteration++; for (GTU gtu : otsModel.getNetwork().getGTUs()) { try { gtu.getLocation(); getLocationCalls++; } catch (RemoteException e) { e.printStackTrace(); } } try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("getLocationThread exits after " + iteration + " iterations and " + getLocationCalls + " getLocation calls"); } }; simulator.start(); getLocationThread.start(); while (simulator.isStartingOrRunning()) { Thread.sleep(1000); // System.out.println("Simulator time is " + simulator.getSimulatorTime()); } } catch (Exception e) { e.printStackTrace(); } System.exit(0); } /** * Find the start simulation button and click it. * @param component Component; some component that could be the start button, or a container that contains the start button * @return boolean; true if the start button was found (and clicked); false otherwise */ public static boolean clickStart(final Component component) { if (component instanceof JButton) { JButton button = (JButton) component; if (button.getText().contains("Start simulation model")) { button.doClick(); System.out.println("Auto clicked the start button"); return true; } } else if (component instanceof Container) { for (Component comp : ((Container) component).getComponents()) { if (clickStart(comp)) { return true; } } } return false; } /** * Click the button that starts the animated simulation. * @param component Component; some component that (hopefully) is, or contains the start button * @return boolean; true if the button was found (and clicked); false if the start button was not found */ public static boolean clickRunPause(final Component component) { if (component instanceof JButton) { JButton button = (JButton) component; // System.out.println("Found button with name " + button.getName()); if (button.getName().equals("runPauseButton")) { button.doClick(); System.out.println("Auto clicked the run button"); return true; } } else if (component instanceof Container) { for (Component comp : ((Container) component).getComponents()) { if (clickRunPause(comp)) { return true; } } } return false; } /** * Start the demo. * @param exitOnClose boolean; when running stand-alone: true; when running as part of a demo: false */ public static void demo(final boolean exitOnClose) { try { OTSAnimator simulator = new OTSAnimator("CircularRoadSwing"); final CircularRoadModel otsModel = new CircularRoadModel(simulator); // Thread buttonClick = new Thread() // { // @Override // public void run() // { // try // { // Thread.sleep(1000); // } // catch (InterruptedException e) // { // e.printStackTrace(); // } // wait for the TabbedParameterDialog to start up // // Find the window // for (Window window : Window.getWindows()) // { // // System.out.println("Name of window is " + window.getName()); // if (window.getName().startsWith("dialog")) // { // for (Component comp : window.getComponents()) // { // if (clickStart(comp)) // { // return; // } // } // } // } // // } // }; // buttonClick.start(); // start the thread that will try to click on the start button if (TabbedParameterDialog.process(otsModel.getInputParameterMap())) { simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), otsModel); OTSAnimationPanel animationPanel = new OTSAnimationPanel(otsModel.getNetwork().getExtent(), new Dimension(800, 600), simulator, otsModel, DEFAULT_COLORER, otsModel.getNetwork()); CircularRoadSwing app = new CircularRoadSwing("Circular Road", animationPanel, otsModel); app.setExitOnClose(exitOnClose); // simulator.setSpeedFactor(Double.MAX_VALUE, true); // simulator.setSpeedFactor(1000.0, true); // for (Component component : app.getComponents()) // { // if (clickRunPause(component)) // { // break; // } // } } else { if (exitOnClose) { System.exit(0); } } } catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception) { exception.printStackTrace(); } } /** * Add the statistics tabs. * @param simulator OTSSimulatorInterface; the simulator on which sampling can be scheduled */ protected final void addStatisticsTabs(final OTSSimulatorInterface simulator) { GraphPath path01; GraphPath path0; GraphPath path1; try { List names = new ArrayList<>(); names.add("Left lane"); names.add("Right lane"); List start = new ArrayList<>(); start.add(new LaneDirection(getModel().getPath(0).get(0), GTUDirectionality.DIR_PLUS)); start.add(new LaneDirection(getModel().getPath(1).get(0), GTUDirectionality.DIR_PLUS)); path01 = GraphLaneUtil.createPath(names, start); path0 = GraphLaneUtil.createPath(names.get(0), start.get(0)); path1 = GraphLaneUtil.createPath(names.get(1), start.get(1)); } catch (NetworkException exception) { throw new RuntimeException("Could not create a path as a lane has no set speed limit.", exception); } RoadSampler sampler = new RoadSampler(getModel().getNetwork()); GraphPath.initRecording(sampler, path01); GraphPath.initRecording(sampler, path0); GraphPath.initRecording(sampler, path1); ContourDataSource dataPool0 = new ContourDataSource<>(sampler.getSamplerData(), path0); ContourDataSource dataPool1 = new ContourDataSource<>(sampler.getSamplerData(), path1); Duration updateInterval = Duration.instantiateSI(10.0); SwingPlot plot = null; GraphPath path = null; ContourDataSource dataPool = null; TablePanel trajectoryChart = new TablePanel(2, 2); plot = new SwingTrajectoryPlot( new TrajectoryPlot("Trajectory all lanes", updateInterval, simulator, sampler.getSamplerData(), path01)); trajectoryChart.setCell(plot.getContentPane(), 0, 0); List lanes = new ArrayList<>(); List positions = new ArrayList<>(); lanes.add(path01.get(0).getSource(0)); lanes.add(path1.get(0).getSource(0)); positions.add(Length.ZERO); positions.add(Length.ZERO); List names = new ArrayList<>(); names.add("Left lane"); names.add("Right lane"); DirectedLinkPosition linkPosition = new DirectedLinkPosition(getModel().getPath(0).get(0).getParentLink(), 0.0, GTUDirectionality.DIR_PLUS); GraphCrossSection crossSection; try { crossSection = GraphLaneUtil.createCrossSection(names, linkPosition); } catch (NetworkException exception) { throw new RuntimeException(exception); } plot = new SwingFundamentalDiagram(new FundamentalDiagram("Fundamental diagram Density-Flow", Quantity.DENSITY, Quantity.FLOW, simulator, FundamentalDiagram.sourceFromSampler(sampler, crossSection, true, Duration.instantiateSI(60.0), false), null)); trajectoryChart.setCell(plot.getContentPane(), 1, 0); plot = new SwingFundamentalDiagram(new FundamentalDiagram("Fundamental diagram Flow-Speed", Quantity.FLOW, Quantity.SPEED, simulator, FundamentalDiagram.sourceFromSampler(sampler, crossSection, false, Duration.instantiateSI(60.0), false), null)); trajectoryChart.setCell(plot.getContentPane(), 1, 1); getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount(), "Trajectories", trajectoryChart); for (int lane : new int[] { 0, 1 }) { TablePanel charts = new TablePanel(3, 2); path = lane == 0 ? path0 : path1; dataPool = lane == 0 ? dataPool0 : dataPool1; plot = new SwingTrajectoryPlot( new TrajectoryPlot("Trajectory lane " + lane, updateInterval, simulator, sampler.getSamplerData(), path)); charts.setCell(plot.getContentPane(), 0, 0); plot = new SwingContourPlot(new ContourPlotDensity("Density lane " + lane, simulator, dataPool)); charts.setCell(plot.getContentPane(), 1, 0); plot = new SwingContourPlot(new ContourPlotSpeed("Speed lane " + lane, simulator, dataPool)); charts.setCell(plot.getContentPane(), 1, 1); plot = new SwingContourPlot(new ContourPlotFlow("Flow lane " + lane, simulator, dataPool)); charts.setCell(plot.getContentPane(), 2, 0); plot = new SwingContourPlot(new ContourPlotAcceleration("Accceleration lane " + lane, simulator, dataPool)); charts.setCell(plot.getContentPane(), 2, 1); getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount(), "stats lane " + lane, charts); } } }