* 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 21 nov. 2014
* @author Peter Knoppers
*/
public class CircularLane extends AbstractWrappableAnimation implements UNITS
{
/** */
private static final long serialVersionUID = 1L;
/** The model. */
private LaneSimulationModel model;
/**
* Create a CircularLane simulation.
* @throws PropertyException when one of the properties has a non-unique tag
*/
public CircularLane() throws PropertyException
{
this.properties.add(new IntegerProperty("TrackLength", "Track length", "Circumference of the track", 2000, 500, 6000,
"Track length %dm", false, 10));
this.properties.add(new ContinuousProperty("MeanDensity", "Mean density", "Number of vehicles per km", 40.0, 5.0, 45.0,
"Density %.1f veh/km", false, 11));
this.properties.add(new ContinuousProperty("DensityVariability", "Density variability",
"Variability of the number of vehicles per km", 0.0, 0.0, 1.0, "%.1f", false, 12));
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 should never happen
*/
public static void main(final String[] args) throws SimRuntimeException
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
try
{
CircularLane circularLane = new CircularLane();
List> propertyList = circularLane.getProperties();
try
{
propertyList.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();
}
propertyList.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));
propertyList.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));
propertyList.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));
circularLane.buildAnimator(Time.ZERO, Duration.ZERO, new Duration(3600.0, SECOND), propertyList, null,
true);
}
catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
{
exception.printStackTrace();
}
}
});
}
/** {@inheritDoc} */
@Override
protected final OTSModelInterface makeModel()
{
this.model = new LaneSimulationModel(this.savedUserModifiedProperties);
return this.model;
}
/** {@inheritDoc} */
@Override
protected final void addAnimationToggles()
{
AnimationToggles.setTextAnimationTogglesStandard(this);
}
/** {@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).findSubPropertyByKey("OutputGraphs");
if (null == output)
{
throw new OTSSimulationException("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 OTSSimulationException("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.equals("TrajectoryPlot"))
{
TrajectoryPlot tp =
new TrajectoryPlot("TrajectoryPlot", new Duration(0.5, SECOND), this.model.getPath(), simulator);
tp.setTitle("Trajectory Graph");
tp.setExtendedState(Frame.MAXIMIZED_BOTH);
graph = tp;
container = tp.getContentPane();
}
else
{
ContourPlot cp;
if (graphName.equals("DensityPlot"))
{
cp = new DensityContourPlot("DensityPlot", this.model.getPath());
cp.setTitle("Density Contour Graph");
}
else if (graphName.equals("SpeedPlot"))
{
cp = new SpeedContourPlot("SpeedPlot", this.model.getPath());
cp.setTitle("Speed Contour Graph");
}
else if (graphName.equals("FlowPlot"))
{
cp = new FlowContourPlot("FlowPlot", this.model.getPath());
cp.setTitle("Flow Contour Graph");
}
else if (graphName.equals("AccelerationPlot"))
{
cp = new AccelerationContourPlot("AccelerationPlot", this.model.getPath());
cp.setTitle("Acceleration Contour Graph");
}
else
{
throw new OTSSimulationException("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 "Circular Lane simulation";
}
/** {@inheritDoc} */
@Override
public final String description()
{
return "
Circular Lane simulation
" + "Vehicles are unequally distributed over a one lane ring road. "
+ "When simulation starts, all vehicles begin driving and some shockwaves may develop (depending on "
+ "the selected track length and car following parameters). "
+ "Selected trajectory and contour plots are generated during the simulation.";
}
/**
* Simulate traffic on a circular, one-lane road.
*
* 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 1 nov. 2014
* @author Peter Knoppers
*/
class LaneSimulationModel implements OTSModelInterface, UNITS
{
/** */
private static final long serialVersionUID = 20141121L;
/** The network. */
private final OTSNetwork network = new OTSNetwork("network");
/** The simulator. */
private DEVSSimulatorInterface.TimeDoubleUnit simulator;
/** 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;
/** Minimum distance. */
private Length minimumDistance = new Length(0, METER);
/** The left Lane that contains simulated Cars. */
private Lane lane1;
/** The right Lane that contains simulated Cars. */
private Lane lane2;
/** The speed limit. */
private Speed speedLimit = new Speed(100, KM_PER_HOUR);
/** The contour plots. */
private List contourPlots = new ArrayList<>();
/** The trajectory plot. */
private List trajectoryPlots = 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);
/** The sequence of Lanes that all vehicles will follow. */
private List path = new ArrayList<>();
/**
* @param properties ArrayList<AbstractProperty<?>>; the user modified properties for the model
*/
LaneSimulationModel(final List> properties)
{
this.properties = properties;
}
/** {@inheritDoc} */
@Override
public void constructModel(final SimulatorInterface