package org.opentrafficsim.demo.conflict; import java.awt.Dimension; import java.io.Serializable; import java.net.URL; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.naming.NamingException; import org.djunits.unit.AccelerationUnit; import org.djunits.unit.DurationUnit; import org.djunits.unit.FrequencyUnit; import org.djunits.unit.LengthUnit; import org.djunits.unit.SpeedUnit; import org.djunits.value.vdouble.scalar.Acceleration; import org.djunits.value.vdouble.scalar.Duration; import org.djunits.value.vdouble.scalar.Frequency; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Speed; import org.djunits.value.vdouble.scalar.Time; import org.djutils.io.URLResource; import org.opentrafficsim.base.parameters.ParameterException; import org.opentrafficsim.base.parameters.ParameterSet; import org.opentrafficsim.base.parameters.ParameterTypes; import org.opentrafficsim.base.parameters.Parameters; import org.opentrafficsim.core.distributions.Generator; import org.opentrafficsim.core.distributions.ProbabilityException; import org.opentrafficsim.core.dsol.AbstractOTSModel; import org.opentrafficsim.core.dsol.OTSAnimator; import org.opentrafficsim.core.dsol.OTSSimulatorInterface; import org.opentrafficsim.core.gtu.GTUCharacteristics; import org.opentrafficsim.core.gtu.GTUDirectionality; import org.opentrafficsim.core.gtu.GTUException; import org.opentrafficsim.core.gtu.GTUType; import org.opentrafficsim.core.idgenerator.IdGenerator; import org.opentrafficsim.core.network.Node; import org.opentrafficsim.core.network.route.Route; import org.opentrafficsim.core.parameters.ParameterFactory; import org.opentrafficsim.demo.conflict.BusStreetDemo.BusStreetModel; import org.opentrafficsim.draw.core.OTSDrawingException; import org.opentrafficsim.road.gtu.generator.GeneratorPositions; import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator; import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker; import org.opentrafficsim.road.gtu.generator.TTCRoomChecker; import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGTUCharacteristics; import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGTUCharacteristicsGenerator; import org.opentrafficsim.road.gtu.lane.LaneBasedGTU; import org.opentrafficsim.road.gtu.lane.VehicleModel; import org.opentrafficsim.road.gtu.lane.perception.categories.DirectBusStopPerception; import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory; import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM; import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus; import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationBusStop; import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory; import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveBusStop; import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRS; import org.opentrafficsim.road.gtu.lane.tactical.pt.BusSchedule; import org.opentrafficsim.road.gtu.lane.tactical.util.ConflictUtil; import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation; import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance; import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters; import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization; import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating; import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner; import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory; import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory; import org.opentrafficsim.road.network.OTSRoadNetwork; import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser; import org.opentrafficsim.road.network.lane.CrossSectionLink; import org.opentrafficsim.road.network.lane.DirectedLanePosition; import org.opentrafficsim.road.network.lane.Lane; import org.opentrafficsim.road.network.lane.object.BusStop; import org.opentrafficsim.swing.gui.OTSAnimationPanel; import org.opentrafficsim.swing.gui.OTSSimulationApplication; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface; import nl.tudelft.simulation.dsol.simulators.SimulatorInterface; import nl.tudelft.simulation.jstats.streams.MersenneTwister; import nl.tudelft.simulation.jstats.streams.StreamInterface; import nl.tudelft.simulation.language.DSOLException; /** *

* 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. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 dec. 2016
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ public class BusStreetDemo extends OTSSimulationApplication { /** */ private static final long serialVersionUID = 20161211L; /** * Create a CrossingTrafficLights Swing application. * @param title String; the title of the Frame * @param panel OTSAnimationPanel; the tabbed panel to display * @param model BusStreetModel; the model * @throws OTSDrawingException on animation error */ public BusStreetDemo(final String title, final OTSAnimationPanel panel, final BusStreetModel model) throws OTSDrawingException { super(model, panel); OTSRoadNetwork network = model.getNetwork(); System.out.println(network.getLinkMap()); } /** * Main program. * @param args String[]; the command line arguments (not used) */ public static void main(final String[] args) { demo(true); } /** * 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("BusStreetDemo"); BusStreetModel busModel = new BusStreetModel(simulator); simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), busModel); OTSAnimationPanel animationPanel = new OTSAnimationPanel(busModel.getNetwork().getExtent(), new Dimension(800, 600), simulator, busModel, DEFAULT_COLORER, busModel.getNetwork()); BusStreetDemo app = new BusStreetDemo("Bus street demo", animationPanel, busModel); app.setExitOnClose(exitOnClose); } catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception) { exception.printStackTrace(); } } /** * The simulation model. */ public static class BusStreetModel extends AbstractOTSModel { /** */ private static final long serialVersionUID = 20161211L; /** The network. */ private OTSRoadNetwork network; /** * @param simulator OTSSimulatorInterface; the simulator for this model */ public BusStreetModel(final OTSSimulatorInterface simulator) { super(simulator); } /** {@inheritDoc} */ @Override public void constructModel() throws SimRuntimeException { Map streams = new LinkedHashMap<>(); streams.put("generation", new MersenneTwister(100L)); this.simulator.getReplication().setStreams(streams); try { URL xmlURL = URLResource.getResource("/conflict/BusStreet.xml"); this.network = new OTSRoadNetwork("BusStreet", true, getSimulator()); XmlNetworkLaneParser.build(xmlURL, this.network, true); // Add bus stops Lane lane = ((CrossSectionLink) this.network.getLink("B1B2")).getLanes().get(0); BusStop stop = new BusStop("Cafe Boszicht.1", lane, lane.getLength(), "Cafe Boszicht", this.simulator); Set lines1 = new LinkedHashSet<>(); lines1.add("1"); stop.setLines(lines1); lane = ((CrossSectionLink) this.network.getLink("C1C2")).getLanes().get(0); stop = new BusStop("Cafe Boszicht.2", lane, lane.getLength(), "Cafe Boszicht", this.simulator); Set lines2 = new LinkedHashSet<>(); lines2.add("2"); stop.setLines(lines2); lane = ((CrossSectionLink) this.network.getLink("EF")).getLanes().get(0); stop = new BusStop("Herberg De Deugd", lane, new Length(75.0, LengthUnit.SI), "Herberg De Deugd", this.simulator); stop.setLines(lines1); lane = ((CrossSectionLink) this.network.getLink("FG")).getLanes().get(1); stop = new BusStop("De Vleeshoeve", lane, new Length(75.0, LengthUnit.SI), "De Vleeshoeve", this.simulator); Set lines12 = new LinkedHashSet<>(); lines12.add("1"); lines12.add("2"); stop.setLines(lines12); lane = ((CrossSectionLink) this.network.getLink("GH")).getLanes().get(2); stop = new BusStop("Kippenboerderij De Scharrelaar", lane, new Length(50.0, LengthUnit.SI), "Kippenboerderij De Scharrelaar", this.simulator); stop.setLines(lines2); lane = ((CrossSectionLink) this.network.getLink("I1I2")).getLanes().get(0); stop = new BusStop("Dorpshuys", lane, lane.getLength(), "Dorpshuys", this.simulator); stop.setLines(lines1); lane = ((CrossSectionLink) this.network.getLink("K1K2")).getLanes().get(0); stop = new BusStop("De verkeerde afslag", lane, lane.getLength(), "De verkeerde afslag", this.simulator); stop.setLines(lines12); makeGenerator(streams.get("generation")); } catch (Exception exception) { exception.printStackTrace(); } } /** {@inheritDoc} */ @Override public OTSRoadNetwork getNetwork() { return this.network; } /** * Make the generator. * @param stream StreamInterface; random number stream * @throws GTUException on exception * @throws ParameterException on exception * @throws ProbabilityException on exception * @throws SimRuntimeException on exception */ private void makeGenerator(final StreamInterface stream) throws GTUException, SimRuntimeException, ProbabilityException, ParameterException { Lane lane = ((CrossSectionLink) this.network.getLink("AB")).getLanes().get(0); String id = lane.getId(); Set initialLongitudinalPositions = new LinkedHashSet<>(); initialLongitudinalPositions .add(new DirectedLanePosition(lane, new Length(10.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS)); Generator headwayGenerator = new HeadwayGenerator(new Frequency(800, FrequencyUnit.PER_HOUR), this.simulator); LaneBasedGTUCharacteristicsGenerator characteristicsGenerator = new CharacteristicsGenerator(this.simulator, new double[] {0.9, 0.06, 0.04}, this.network); RoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI)); LaneBasedGTUGenerator gen = new LaneBasedGTUGenerator(id, headwayGenerator, characteristicsGenerator, GeneratorPositions.create(initialLongitudinalPositions, stream), this.network, this.simulator, roomChecker, new IdGenerator("")); gen.setInstantaneousLaneChange(true); } /** {@inheritDoc} */ @Override public Serializable getSourceId() { return "BusStreetModel"; } } /** *

* 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. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version 29 jan. 2017
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ private static class HeadwayGenerator implements Generator { /** Demand level. */ private final Frequency demand; /** Simulator. */ private final SimulatorInterface.TimeDoubleUnit simulator; /** * @param demand Frequency; demand * @param simulator SimulatorInterface.TimeDoubleUnit; simulator */ HeadwayGenerator(final Frequency demand, final SimulatorInterface.TimeDoubleUnit simulator) { this.demand = demand; this.simulator = simulator; } /** {@inheritDoc} */ @Override public Duration draw() throws ProbabilityException, ParameterException { return new Duration( -Math.log(this.simulator.getReplication().getStream("generation").nextDouble()) / this.demand.si, DurationUnit.SI); } } /** *

* 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. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version 29 jan. 2017
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ public static class CharacteristicsGenerator implements LaneBasedGTUCharacteristicsGenerator { /** Simulator. */ private final DEVSSimulatorInterface.TimeDoubleUnit simulator; /** Probabilities. */ private final double[] probabilities; /** Strategical planner factory. */ private final LaneBasedStrategicalPlannerFactory plannerFactory; /** Route for car. */ private final Route carRouteN; /** Route for car. */ private final Route carRouteO; /** Nodes for bus, line 1. */ private final List busNodes1; /** Nodes for bus, line 2. */ private final List busNodes2; /** Short dwell time. */ private final Duration shortDwellTime = new Duration(15.0, DurationUnit.SI); /** Long dwell time. */ private final Duration longDwellTime = new Duration(60.0, DurationUnit.SI); /** The network. */ private OTSRoadNetwork network; /** * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; simulator * @param probabilities double[]; probabilities * @param network OTSRoadNetwork; network */ public CharacteristicsGenerator(final DEVSSimulatorInterface.TimeDoubleUnit simulator, final double[] probabilities, final OTSRoadNetwork network) { this.simulator = simulator; this.probabilities = probabilities; this.network = network; List carNodesN = new ArrayList<>(); carNodesN.add(network.getNode("A")); carNodesN.add(network.getNode("B")); carNodesN.add(network.getNode("C")); carNodesN.add(network.getNode("D")); carNodesN.add(network.getNode("E")); carNodesN.add(network.getNode("F")); carNodesN.add(network.getNode("G")); carNodesN.add(network.getNode("H")); carNodesN.add(network.getNode("I")); carNodesN.add(network.getNode("J")); carNodesN.add(network.getNode("K")); carNodesN.add(network.getNode("L")); carNodesN.add(network.getNode("M")); List carNodesO = new ArrayList<>(carNodesN); carNodesN.add(network.getNode("N")); carNodesO.add(network.getNode("O")); this.carRouteN = new Route("carN", carNodesN); this.carRouteO = new Route("carO", carNodesO); this.busNodes1 = new ArrayList<>(); this.busNodes1.add(network.getNode("A")); this.busNodes1.add(network.getNode("B")); this.busNodes1.add(network.getNode("B1")); this.busNodes1.add(network.getNode("B2")); this.busNodes1.add(network.getNode("D")); this.busNodes1.add(network.getNode("E")); this.busNodes1.add(network.getNode("F")); this.busNodes1.add(network.getNode("G")); this.busNodes1.add(network.getNode("H")); this.busNodes1.add(network.getNode("I")); this.busNodes1.add(network.getNode("I1")); this.busNodes1.add(network.getNode("I2")); this.busNodes1.add(network.getNode("J")); this.busNodes1.add(network.getNode("K")); this.busNodes1.add(network.getNode("K1")); this.busNodes1.add(network.getNode("K2")); this.busNodes1.add(network.getNode("L")); this.busNodes1.add(network.getNode("M")); this.busNodes1.add(network.getNode("N")); this.busNodes2 = new ArrayList<>(); this.busNodes2.add(network.getNode("A")); this.busNodes2.add(network.getNode("B")); this.busNodes2.add(network.getNode("C")); this.busNodes2.add(network.getNode("C1")); this.busNodes2.add(network.getNode("C2")); this.busNodes2.add(network.getNode("E")); this.busNodes2.add(network.getNode("F")); this.busNodes2.add(network.getNode("G")); this.busNodes2.add(network.getNode("H")); this.busNodes2.add(network.getNode("I")); this.busNodes2.add(network.getNode("J")); this.busNodes2.add(network.getNode("K")); this.busNodes2.add(network.getNode("K1")); this.busNodes2.add(network.getNode("K2")); this.busNodes2.add(network.getNode("K3")); this.busNodes2.add(network.getNode("L")); this.busNodes2.add(network.getNode("M")); this.busNodes2.add(network.getNode("O")); this.plannerFactory = new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactoryCarBus(), new ParameterFactoryCarBus()); } /** {@inheritDoc} */ @Override public LaneBasedGTUCharacteristics draw() throws ProbabilityException, ParameterException, GTUException { double r = this.simulator.getReplication().getStream("generation").nextDouble(); int classNum = r < this.probabilities[0] ? 0 : r < this.probabilities[0] + this.probabilities[1] ? 1 : 2; r = this.simulator.getReplication().getStream("generation").nextDouble(); GTUType gtuType; Length length; Length width; Speed maximumSpeed; Route route; switch (classNum) { case 0: { gtuType = new GTUType("CAR", this.network.getGtuType(GTUType.DEFAULTS.CAR)); length = new Length(4.0, LengthUnit.SI); width = new Length(1.8, LengthUnit.SI); maximumSpeed = new Speed(200.0, SpeedUnit.KM_PER_HOUR); route = r < 0.5 ? this.carRouteN : this.carRouteO; break; } case 1: { gtuType = new GTUType("BUS1", this.network.getGtuType(GTUType.DEFAULTS.SCHEDULED_BUS)); length = new Length(8.0, LengthUnit.SI); width = new Length(2.0, LengthUnit.SI); maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR); BusSchedule schedule = new BusSchedule("bus1." + this.simulator.getSimulatorTime(), this.busNodes1, "1"); Time now = this.simulator.getSimulatorTime(); schedule.addBusStop("Cafe Boszicht.1", now.plus(new Duration(70.0, DurationUnit.SI)), this.longDwellTime, true); schedule.addBusStop("Herberg De Deugd", now.plus(new Duration(100.0, DurationUnit.SI)), this.shortDwellTime, false); schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(120.0, DurationUnit.SI)), this.shortDwellTime, false); schedule.addBusStop("Dorpshuys", now.plus(new Duration(200.0, DurationUnit.SI)), this.longDwellTime, true); schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(270.0, DurationUnit.SI)), this.longDwellTime, true); route = schedule; break; } case 2: { gtuType = new GTUType("BUS2", this.network.getGtuType(GTUType.DEFAULTS.SCHEDULED_BUS)); length = new Length(12.0, LengthUnit.SI); width = new Length(2.0, LengthUnit.SI); maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR); BusSchedule schedule = new BusSchedule("bus2." + this.simulator.getSimulatorTime(), this.busNodes2, "2"); Time now = this.simulator.getSimulatorTime(); schedule.addBusStop("Cafe Boszicht.2", now.plus(new Duration(80.0, DurationUnit.SI)), this.longDwellTime, true); schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(110.0, DurationUnit.SI)), this.shortDwellTime, false); schedule.addBusStop("Kippenboerderij De Scharrelaar", now.plus(new Duration(180.0, DurationUnit.SI)), this.longDwellTime, false); schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(260.0, DurationUnit.SI)), this.longDwellTime, true); route = schedule; break; } default: throw new RuntimeException("Reaching default of switch case."); } GTUCharacteristics gtuCharacteristics = new GTUCharacteristics(gtuType, length, width, maximumSpeed, Acceleration.instantiateSI(3.0), Acceleration.instantiateSI(-8.0), length.times(0.5)); return new LaneBasedGTUCharacteristics(gtuCharacteristics, this.plannerFactory, route, null, null, VehicleModel.MINMAX); } } /** *

* 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. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version 29 jan. 2017
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ private static class LMRSFactoryCarBus implements LaneBasedTacticalPlannerFactory { /** */ LMRSFactoryCarBus() { } /** {@inheritDoc} */ @Override public final Parameters getParameters() { ParameterSet parameters = new ParameterSet(); parameters.setDefaultParameters(ParameterTypes.class); parameters.setDefaultParameters(LmrsParameters.class); parameters.setDefaultParameters(ConflictUtil.class); parameters.setDefaultParameters(AbstractIDM.class); return parameters; } /** {@inheritDoc} */ @Override public final LMRS create(final LaneBasedGTU gtu) throws GTUException { DefaultLMRSPerceptionFactory pFac = new DefaultLMRSPerceptionFactory(); LMRS lmrs = new LMRS(new IDMPlus(), gtu, pFac.generatePerception(gtu), Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, Tailgating.NONE); lmrs.setDefaultIncentives(); if (gtu.getGTUType().isOfType(GTUType.DEFAULTS.SCHEDULED_BUS)) { lmrs.addMandatoryIncentive(new IncentiveBusStop()); lmrs.addAccelerationIncentive(new AccelerationBusStop()); lmrs.getPerception().addPerceptionCategory(new DirectBusStopPerception(lmrs.getPerception())); } return lmrs; } } /** *

* 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. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version 29 jan. 2017
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ private static class ParameterFactoryCarBus implements ParameterFactory { /** */ ParameterFactoryCarBus() { } /** {@inheritDoc} */ @Override public void setValues(final Parameters parameters, final GTUType gtuType) throws ParameterException { parameters.setParameter(ParameterTypes.LOOKAHEAD, new Length(100.0, LengthUnit.METER)); if (gtuType.isOfType(GTUType.DEFAULTS.CAR)) { parameters.setParameter(LmrsParameters.VGAIN, new Speed(3.0, SpeedUnit.METER_PER_SECOND)); } else if (gtuType.isOfType(GTUType.DEFAULTS.SCHEDULED_BUS)) { parameters.setParameter(ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.METER_PER_SECOND_2)); } else { throw new RuntimeException("Unable to determine characteristics for GTU of type " + gtuType); } } } }