* Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License.
*
* $LastChangedDate$, @version $Revision$, by $Author$,
* initial version 12 nov. 2014
* @author Peter Knoppers
*/
public class Straight extends AbstractWrappableAnimation implements UNITS
{
/** */
private static final long serialVersionUID = 1L;
/** The model. */
private StraightModel model;
/**
* Create a ContourPlots simulation.
* @throws PropertyException when the provided properties could not be handled
*/
public Straight() throws PropertyException
{
List> outputProperties = new ArrayList<>();
outputProperties.add(new BooleanProperty("DensityPlot", "Density", "Density contour plot", true, false, 0));
outputProperties.add(new BooleanProperty("FlowPlot", "Flow", "Flow contour plot", true, false, 1));
outputProperties.add(new BooleanProperty("SpeedPlot", "Speed", "Speed contour plot", true, false, 2));
outputProperties
.add(new BooleanProperty("AccelerationPlot", "Acceleration", "Acceleration contour plot", true, false, 3));
outputProperties.add(
new BooleanProperty("TrajectoryPlot", "Trajectories", "Trajectory (time/distance) diagram", true, false, 4));
this.properties.add(new CompoundProperty("OutputGraphs", "Output graphs", "Select the graphical output",
outputProperties, true, 1000));
}
/** {@inheritDoc} */
@Override
public final void stopTimersThreads()
{
super.stopTimersThreads();
this.model = null;
}
/**
* Main program.
* @param args String[]; the command line arguments (not used)
* @throws SimRuntimeException when simulation cannot be created with given parameters
*/
public static void main(final String[] args) throws SimRuntimeException
{
SwingUtilities.invokeLater(new Runnable()
{
@SuppressWarnings("synthetic-access")
@Override
public void run()
{
try
{
Straight straight = new Straight();
List> localProperties = straight.getProperties();
try
{
localProperties.add(new ProbabilityDistributionProperty("TrafficComposition", "Traffic composition",
"Mix of passenger cars and trucks", new String[] { "passenger car", "truck" },
new Double[] { 0.8, 0.2 }, false, 10));
}
catch (PropertyException exception)
{
exception.printStackTrace();
}
localProperties.add(new SelectionProperty("CarFollowingModel", "Car following model",
"The car following model determines "
+ "the acceleration that a vehicle will make taking into account "
+ "nearby vehicles, infrastructural restrictions (e.g. speed limit, "
+ "curvature of the road) capabilities of the vehicle and personality "
+ "of the driver.",
new String[] { "IDM", "IDM+" }, 1, false, 1));
localProperties.add(IDMPropertySet.makeIDMPropertySet("IDMCar", "Car",
new Acceleration(1.0, METER_PER_SECOND_2), new Acceleration(1.5, METER_PER_SECOND_2),
new Length(2.0, METER), new Duration(1.0, SECOND), 2));
localProperties.add(IDMPropertySet.makeIDMPropertySet("IDMTruck", "Truck",
new Acceleration(0.5, METER_PER_SECOND_2), new Acceleration(1.25, METER_PER_SECOND_2),
new Length(2.0, METER), new Duration(1.0, SECOND), 3));
straight.buildAnimator(Time.ZERO, Duration.ZERO, new Duration(3600.0, SECOND), localProperties, null, true);
straight.panel.getTabbedPane().addTab("info", straight.makeInfoPane());
}
catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
{
exception.printStackTrace();
}
}
});
}
/** {@inheritDoc} */
@Override
protected final void addAnimationToggles()
{
AnimationToggles.setTextAnimationTogglesStandard(this);
}
/** {@inheritDoc} */
@Override
protected final OTSModelInterface makeModel()
{
this.model = new StraightModel(this.savedUserModifiedProperties);
return this.model;
}
/**
* @return an info pane to be added to the tabbed pane.
*/
protected final JComponent makeInfoPane()
{
// Make the info tab
String helpSource = "/" + StraightModel.class.getPackage().getName().replace('.', '/') + "/IDMPlus.html";
URL page = StraightModel.class.getResource(helpSource);
if (page != null)
{
try
{
HTMLPanel htmlPanel = new HTMLPanel(page);
return new JScrollPane(htmlPanel);
}
catch (IOException exception)
{
exception.printStackTrace();
}
}
return new JPanel();
}
/** {@inheritDoc} */
@Override
protected final void addTabs(final SimpleSimulatorInterface simulator) throws OTSSimulationException, PropertyException
{
// Make the tab with the plots
Property> output = new CompoundProperty("", "", "", this.properties, false, 0).findByKey("OutputGraphs");
if (null == output)
{
throw new Error("Cannot find output properties");
}
ArrayList graphs = new ArrayList<>();
if (output instanceof CompoundProperty)
{
CompoundProperty outputProperties = (CompoundProperty) output;
for (Property> ap : outputProperties.getValue())
{
if (ap instanceof BooleanProperty)
{
BooleanProperty bp = (BooleanProperty) ap;
if (bp.getValue())
{
graphs.add(bp);
}
}
}
}
else
{
throw new Error("output properties should be compound");
}
int graphCount = graphs.size();
int columns = (int) Math.ceil(Math.sqrt(graphCount));
int rows = 0 == columns ? 0 : (int) Math.ceil(graphCount * 1.0 / columns);
TablePanel charts = new TablePanel(columns, rows);
for (int i = 0; i < graphCount; i++)
{
String graphName = graphs.get(i).getKey();
Container container = null;
LaneBasedGTUSampler graph;
if (graphName.contains("TrajectoryPlot"))
{
List path = new ArrayList<>();
path.add(this.model.getLane());
TrajectoryPlot tp = new TrajectoryPlot("Trajectory Graph", new Duration(0.5, SECOND), path, simulator);
tp.setTitle("Trajectory Graph");
tp.setExtendedState(Frame.MAXIMIZED_BOTH);
graph = tp;
container = tp.getContentPane();
}
else
{
ContourPlot cp;
if (graphName.contains("DensityPlot"))
{
cp = new DensityContourPlot("Density Graph", this.model.getPath());
cp.setTitle("Density Contour Graph");
}
else if (graphName.contains("SpeedPlot"))
{
cp = new SpeedContourPlot("Speed Graph", this.model.getPath());
cp.setTitle("Speed Contour Graph");
}
else if (graphName.contains("Flow"))
{
cp = new FlowContourPlot("Flow Graph", this.model.getPath());
cp.setTitle("Flow Contour Graph");
}
else if (graphName.contains("AccelerationPlot"))
{
cp = new AccelerationContourPlot("Acceleration Graph", this.model.getPath());
cp.setTitle("Acceleration Contour Graph");
}
else
{
throw new Error("Unhandled type of contourplot: " + graphName);
}
graph = cp;
container = cp.getContentPane();
}
// Add the container to the matrix
charts.setCell(container, i % columns, i / columns);
this.model.getPlots().add(graph);
}
addTab(getTabCount(), "statistics", charts);
}
/** {@inheritDoc} */
@Override
public final String shortName()
{
return "Straight lane";
}
/** {@inheritDoc} */
@Override
public final String description()
{
return "
Simulation of a straight one-lane road with opening bridge
"
+ "Simulation of a single lane road of 5 km length. Vehicles are generated at a constant rate of "
+ "1500 veh/hour. At time 300s a blockade is inserted at position 4km; this blockade is removed at "
+ "time 420s. This blockade simulates a bridge opening. "
+ "The blockade causes a traffic jam that slowly dissolves after the blockade is removed. "
+ "Selected trajectory and contour plots are generated during the simulation.";
}
/**
* Simulate a single lane road of 5 km length. Vehicles are generated at a constant rate of 1500 veh/hour. At time 300s a
* blockade is inserted at position 4 km; this blockade is removed at time 500s. The used car following algorithm is IDM+
* Integrated Lane Change Model with Relaxation and
* Synchronization, by Wouter J. Schakel, Victor L. Knoop and Bart van Arem, 2012.
* Output is a set of block charts:
*
*
Traffic density
*
Speed
*
Flow
*
Acceleration
*
* All these graphs display simulation time along the horizontal axis and distance along the road along the vertical axis.
*
* Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
*
* BSD-style license. See OpenTrafficSim License.
*
* $LastChangedDate$, @version $Revision$, by $Author$,
* initial version ug 1, 2014
* @author Peter Knoppers
*/
class StraightModel implements OTSModelInterface, UNITS
{
/** */
private static final long serialVersionUID = 20140815L;
/** The simulator. */
private DEVSSimulatorInterface.TimeDoubleUnit simulator;
/** The network. */
private final OTSNetwork network = new OTSNetwork("network");
/** The headway (inter-vehicle time). */
private Duration headway;
/** Number of cars created. */
private int carsCreated = 0;
/** Type of all GTUs. */
private GTUType gtuType = CAR;
/** The car following model, e.g. IDM Plus for cars. */
private GTUFollowingModelOld carFollowingModelCars;
/** The car following model, e.g. IDM Plus for trucks. */
private GTUFollowingModelOld carFollowingModelTrucks;
/** The probability that the next generated GTU is a passenger car. */
private double carProbability;
/** The blocking car. */
private LaneBasedIndividualGTU block = null;
/** Minimum distance. */
private Length minimumDistance = new Length(0, METER);
/** Maximum distance. */
private Length maximumDistance = new Length(5000, METER);
/** The Lane that contains the simulated Cars. */
private Lane lane;
/** The contour plots. */
private List plots = new ArrayList<>();
/** User settable properties. */
private List> properties = null;
/** The random number generator used to decide what kind of GTU to generate. */
private Random randomGenerator = new Random(12345);
/**
* @param properties the user settable properties
*/
StraightModel(final List> properties)
{
this.properties = properties;
}
/** The sequence of Lanes that all vehicles will follow. */
private List path = new ArrayList<>();
/** The speed limit on all Lanes. */
private Speed speedLimit = new Speed(100, KM_PER_HOUR);
/**
* @return List<Lane*gt;; the set of lanes for the specified index
*/
public List getPath()
{
return new ArrayList<>(this.path);
}
/** {@inheritDoc} */
@Override
public final void constructModel(final SimulatorInterface