BusStopConflictRule.java

  1. package org.opentrafficsim.road.network.lane.conflict;

  2. import org.djunits.value.vdouble.scalar.Length;
  3. import org.djutils.exceptions.Throw;
  4. import org.djutils.immutablecollections.ImmutableMap;
  5. import org.opentrafficsim.core.gtu.GTUDirectionality;
  6. import org.opentrafficsim.core.gtu.GTUException;
  7. import org.opentrafficsim.core.gtu.GTUType;
  8. import org.opentrafficsim.core.gtu.RelativePosition;
  9. import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
  10. import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
  11. import org.opentrafficsim.road.network.lane.Lane;

  12. import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;

  13. /**
  14.  * Conflict rule for conflicts where busses enter the lane after a stop.
  15.  * <p>
  16.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  17.  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  18.  * <p>
  19.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version 27 jan. 2017 <br>
  20.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  21.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  22.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  23.  */
  24. public class BusStopConflictRule implements ConflictRule
  25. {

  26.     /** Simulator. */
  27.     private final SimulatorInterface.TimeDoubleUnit simulator;

  28.     /**
  29.      * Constructor.
  30.      * @param simulator SimulatorInterface.TimeDoubleUnit; simulator
  31.      */
  32.     public BusStopConflictRule(final SimulatorInterface.TimeDoubleUnit simulator)
  33.     {
  34.         this.simulator = simulator;
  35.     }

  36.     /** {@inheritDoc} */
  37.     @Override
  38.     public ConflictPriority determinePriority(final Conflict conflict)
  39.     {

  40.         // determine if we request from bus stop, or not
  41.         boolean requestingFromBusStop;
  42.         Conflict busConflict;
  43.         // conflict builder enforces that only one of the two links has priority BUS_STOP
  44.         if (conflict.getLane().getParentLink().getPriority().equals(Priority.BUS_STOP))
  45.         {
  46.             Throw.when(conflict.getOtherConflict().getLane().getParentLink().getPriority().equals(Priority.BUS_STOP),
  47.                     IllegalArgumentException.class,
  48.                     "BusStopConflictRule does not support a conflict between two links with priority BUS_STOP.");
  49.             requestingFromBusStop = true;
  50.             busConflict = conflict;
  51.         }
  52.         else
  53.         {
  54.             requestingFromBusStop = false;
  55.             busConflict = conflict.getOtherConflict();
  56.         }

  57.         // find bus and determine if it has priority
  58.         // conflict forces that LongitudinalDirection is DIR_PLUS or DIR_MINUS
  59.         Lane lane = busConflict.getLane();
  60.         GTUDirectionality dir =
  61.                 busConflict.getDirection().isForward() ? GTUDirectionality.DIR_PLUS : GTUDirectionality.DIR_MINUS;
  62.         Length pos = busConflict.getLongitudinalPosition();
  63.         LaneBasedGTU gtu = null;
  64.         try
  65.         {
  66.             while (gtu == null && lane != null)
  67.             {
  68.                 gtu = lane.getGtuBehind(pos, dir, RelativePosition.FRONT, this.simulator.getSimulatorTime());
  69.                 if (gtu == null)
  70.                 {
  71.                     ImmutableMap<Lane, GTUDirectionality> map =
  72.                             lane.upstreamLanes(dir, lane.getNetwork().getGtuType(GTUType.DEFAULTS.BUS));
  73.                     if (map.size() == 1)
  74.                     {
  75.                         lane = map.keySet().iterator().next();
  76.                         // only on bus stop
  77.                         if (lane.getParentLink().getPriority().isBusStop())
  78.                         {
  79.                             dir = map.get(lane);
  80.                             pos = dir.isPlus() ? lane.getLength() : Length.ZERO;
  81.                         }
  82.                         else
  83.                         {
  84.                             lane = null;
  85.                         }
  86.                     }
  87.                     else
  88.                     {
  89.                         lane = null;
  90.                     }
  91.                 }
  92.             }
  93.         }
  94.         catch (GTUException exception)
  95.         {
  96.             throw new RuntimeException("Error while looking for GTU upstream of merge at bus stop.", exception);
  97.         }
  98.         boolean busHasPriority =
  99.                 gtu != null && gtu.getGTUType().isOfType(GTUType.DEFAULTS.BUS) && gtu.getTurnIndicatorStatus().isLeft();

  100.         // if bus has priority and bus is asking, PRIORITY
  101.         // if bus has no priority and bus is not asking (i.e. car is asking), PRIORITY
  102.         return busHasPriority == requestingFromBusStop ? ConflictPriority.PRIORITY : ConflictPriority.YIELD;

  103.     }

  104.     /** {@inheritDoc} */
  105.     @Override
  106.     public final ConflictRule clone(final SimulatorInterface.TimeDoubleUnit newSimulator)
  107.     {
  108.         return new BusStopConflictRule(newSimulator);
  109.     }

  110.     /** {@inheritDoc} */
  111.     @Override
  112.     public final String toString()
  113.     {
  114.         return "BusStopConflictRule";
  115.     }

  116. }