HeadwayConflict.java

  1. package org.opentrafficsim.road.gtu.lane.perception.headway;

  2. import org.djunits.unit.LengthUnit;
  3. import org.djunits.value.ValueRuntimeException;
  4. import org.djunits.value.storage.StorageType;
  5. import org.djunits.value.vdouble.scalar.Length;
  6. import org.djunits.value.vdouble.scalar.Speed;
  7. import org.djunits.value.vdouble.vector.LengthVector;
  8. import org.djunits.value.vdouble.vector.base.DoubleVector;
  9. import org.djutils.exceptions.Throw;
  10. import org.opentrafficsim.core.gtu.GTUException;
  11. import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
  12. import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
  13. import org.opentrafficsim.road.network.lane.CrossSectionLink;
  14. import org.opentrafficsim.road.network.lane.Lane;
  15. import org.opentrafficsim.road.network.lane.conflict.ConflictPriority;
  16. import org.opentrafficsim.road.network.lane.conflict.ConflictRule;
  17. import org.opentrafficsim.road.network.lane.conflict.ConflictType;

  18. /**
  19.  * <p>
  20.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  21.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
  22.  * <p>
  23.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version Jun 2, 2016 <br>
  24.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  25.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  26.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  27.  */
  28. public class HeadwayConflict extends AbstractHeadwayLaneBasedObject
  29. {

  30.     /** */
  31.     private static final long serialVersionUID = 20160602L;

  32.     /** Conflict type. */
  33.     private final ConflictType conflictType;

  34.     /** Conflict priority. */
  35.     private final ConflictPriority conflictPriority;

  36.     /** Length of the conflict in the conflicting directions. */
  37.     private final Length conflictingLength;

  38.     /**
  39.      * Set of conflicting GTU's <i>completely</i> upstream of the <i>start</i> of the conflict ordered close to far from the
  40.      * start of the conflict. Distance and overlap info concerns the conflict.
  41.      */
  42.     private final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> upstreamConflictingGTUs;

  43.     /**
  44.      * Set of conflicting GTU's (partially) downstream of the <i>start</i> of the conflict ordered close to far from the start
  45.      * of conflict. Distance and overlap info concerns the conflict.
  46.      */
  47.     private final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> downstreamConflictingGTUs;

  48.     /** Visibility on the conflicting lane within which conflicting vehicles are visible. */
  49.     private final Length conflictingVisibility;

  50.     /** Speed limit on the conflicting lane. */
  51.     private final Speed conflictingSpeedLimit;

  52.     /** Link of conflicting conflict. */
  53.     private final CrossSectionLink conflictingLink;

  54.     /** Stop line on the own lane. */
  55.     private final HeadwayStopLine stopLine;

  56.     /** Stop line on the conflicting lane. */
  57.     private final HeadwayStopLine conflictingStopLine;

  58.     /** Type of conflict rule. */
  59.     private final Class<? extends ConflictRule> conflictRuleType;

  60.     /** Distance of traffic light upstream on conflicting lane. */
  61.     private Length conflictingTrafficLightDistance = null;

  62.     /** Whether the conflict is permitted by the traffic light. */
  63.     private boolean permitted = false;

  64.     /** Width progression of conflict. */
  65.     private final Width width;

  66.     /**
  67.      * Constructor.
  68.      * @param conflictType ConflictType; conflict type
  69.      * @param conflictPriority ConflictPriority; conflict priority
  70.      * @param conflictRuleType Class&lt;? extends ConflictRule&gt;; conflict rule type
  71.      * @param id String; id
  72.      * @param distance Length; distance
  73.      * @param length Length; length of the conflict
  74.      * @param conflictingLength Length; length of the conflict on the conflicting lane
  75.      * @param upstreamConflictingGTUs PerceptionCollectable&lt;HeadwayGTU,LaneBasedGTU&gt;; conflicting GTU's upstream of the
  76.      *            &lt;i&gt;start&lt;/i&gt; of the conflict
  77.      * @param downstreamConflictingGTUs PerceptionCollectable&lt;HeadwayGTU,LaneBasedGTU&gt;; conflicting GTU's downstream of
  78.      *            the &lt;i&gt;start&lt;/i&gt; of the conflict
  79.      * @param conflictingVisibility Length; visibility on the conflicting lane within which conflicting vehicles are visible
  80.      * @param conflictingSpeedLimit Speed; speed limit on the conflicting lane
  81.      * @param conflictingLink CrossSectionLink; conflicting link
  82.      * @param width Width; width progression of conflict
  83.      * @param stopLine HeadwayStopLine; stop line on the own lane
  84.      * @param conflictingStopLine HeadwayStopLine; stop line on the conflicting lane
  85.      * @param lane Lane; the lane
  86.      * @throws GTUException when id is null, or parameters are inconsistent
  87.      */
  88.     @SuppressWarnings("checkstyle:parameternumber")
  89.     public HeadwayConflict(final ConflictType conflictType, final ConflictPriority conflictPriority,
  90.             final Class<? extends ConflictRule> conflictRuleType, final String id, final Length distance, final Length length,
  91.             final Length conflictingLength, final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> upstreamConflictingGTUs,
  92.             final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> downstreamConflictingGTUs, final Length conflictingVisibility,
  93.             final Speed conflictingSpeedLimit, final CrossSectionLink conflictingLink, final Width width,
  94.             final HeadwayStopLine stopLine, final HeadwayStopLine conflictingStopLine, final Lane lane) throws GTUException
  95.     {
  96.         super(ObjectType.CONFLICT, id, distance, length, lane);
  97.         Throw.whenNull(conflictType, "Conflict type may not be null.");
  98.         Throw.whenNull(conflictPriority, "Conflict priority may not be null.");
  99.         Throw.whenNull(conflictRuleType, "Conflict rule type may not be null.");
  100.         Throw.whenNull(id, "Conflict id may not be null.");
  101.         Throw.whenNull(distance, "Conflict distance may not be null.");
  102.         Throw.whenNull(conflictingLength, "Conflict length may not be null.");
  103.         Throw.whenNull(upstreamConflictingGTUs, "Upstreaem conflicting GTU's may not be null.");
  104.         Throw.whenNull(downstreamConflictingGTUs, "Downstream conflicting GTU's may not be null.");
  105.         Throw.whenNull(width, "Width may not be null.");
  106.         Throw.whenNull(conflictingVisibility, "Conflict visibility may not be null.");
  107.         Throw.whenNull(conflictingSpeedLimit, "Conflict speed limit may not be null.");
  108.         this.conflictType = conflictType;
  109.         this.conflictPriority = conflictPriority;
  110.         this.conflictRuleType = conflictRuleType;
  111.         this.conflictingLength = conflictingLength;
  112.         this.upstreamConflictingGTUs = upstreamConflictingGTUs;
  113.         this.downstreamConflictingGTUs = downstreamConflictingGTUs;
  114.         this.conflictingVisibility = conflictingVisibility;
  115.         this.conflictingSpeedLimit = conflictingSpeedLimit;
  116.         this.conflictingLink = conflictingLink;
  117.         this.width = width;
  118.         this.stopLine = stopLine;
  119.         this.conflictingStopLine = conflictingStopLine;
  120.     }

  121.     /**
  122.      * Constructor without stop lines.
  123.      * @param conflictType ConflictType; conflict type
  124.      * @param conflictPriority ConflictPriority; conflict priority
  125.      * @param conflictRuleType Class&lt;? extends ConflictRule&gt;; conflict rule type
  126.      * @param id String; id
  127.      * @param distance Length; distance
  128.      * @param length Length; length of the conflict
  129.      * @param conflictingLength Length; length of the conflict on the conflicting lane
  130.      * @param upstreamConflictingGTUs PerceptionCollectable&lt;HeadwayGTU,LaneBasedGTU&gt;; conflicting GTU's upstream of the
  131.      *            &lt;i&gt;start&lt;/i&gt; of the conflict
  132.      * @param downstreamConflictingGTUs PerceptionCollectable&lt;HeadwayGTU,LaneBasedGTU&gt;; conflicting GTU's downstream of
  133.      *            the &lt;i&gt;start&lt;/i&gt; of the conflict
  134.      * @param conflictingVisibility Length; visibility on the conflicting lane within which conflicting vehicles are visible
  135.      * @param conflictingSpeedLimit Speed; speed limit on the conflicting lane
  136.      * @param conflictingLink CrossSectionLink; conflicting link
  137.      * @param width Width; width progression of conflict
  138.      * @param lane Lane; the lane
  139.      * @throws GTUException when id is null, or parameters are inconsistent
  140.      */
  141.     @SuppressWarnings("checkstyle:parameternumber")
  142.     public HeadwayConflict(final ConflictType conflictType, final ConflictPriority conflictPriority,
  143.             final Class<? extends ConflictRule> conflictRuleType, final String id, final Length distance, final Length length,
  144.             final Length conflictingLength, final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> upstreamConflictingGTUs,
  145.             final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> downstreamConflictingGTUs, final Length conflictingVisibility,
  146.             final Speed conflictingSpeedLimit, final CrossSectionLink conflictingLink, final Width width, final Lane lane)
  147.             throws GTUException
  148.     {
  149.         this(conflictType, conflictPriority, conflictRuleType, id, distance, length, conflictingLength, upstreamConflictingGTUs,
  150.                 downstreamConflictingGTUs, conflictingVisibility, conflictingSpeedLimit, conflictingLink, width, null, null,
  151.                 lane);
  152.     }

  153.     /**
  154.      * Returns the conflict type.
  155.      * @return conflict type
  156.      */
  157.     public final ConflictType getConflictType()
  158.     {
  159.         return this.conflictType;
  160.     }

  161.     /**
  162.      * Returns whether this is a crossing conflict.
  163.      * @return whether this is a crossing conflict
  164.      */
  165.     public final boolean isCrossing()
  166.     {
  167.         return this.conflictType.equals(ConflictType.CROSSING);
  168.     }

  169.     /**
  170.      * Returns whether this is a merge conflict.
  171.      * @return whether this is a merge conflict
  172.      */
  173.     public final boolean isMerge()
  174.     {
  175.         return this.conflictType.equals(ConflictType.MERGE);
  176.     }

  177.     /**
  178.      * Returns whether this is a split conflict.
  179.      * @return whether this is a split conflict
  180.      */
  181.     public final boolean isSplit()
  182.     {
  183.         return this.conflictType.equals(ConflictType.SPLIT);
  184.     }

  185.     /**
  186.      * Returns the conflict priority.
  187.      * @return conflict priority
  188.      */
  189.     public final ConflictPriority getConflictPriority()
  190.     {
  191.         return this.conflictPriority;
  192.     }

  193.     /**
  194.      * Returns the length of the conflict on the conflicting lane.
  195.      * @return length of the conflict on the conflicting lane
  196.      */
  197.     public final Length getConflictingLength()
  198.     {
  199.         return this.conflictingLength;
  200.     }

  201.     /**
  202.      * Returns a set of conflicting GTU's upstream of the <i>start</i> of the conflict ordered close to far from the conflict.
  203.      * @return set of conflicting GTU's upstream of the <i>start</i> of the conflict ordered close to far from the conflict
  204.      */
  205.     public final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> getUpstreamConflictingGTUs()
  206.     {
  207.         return this.upstreamConflictingGTUs;
  208.     }

  209.     /**
  210.      * Returns a set of conflicting GTU's downstream of the <i>start</i> of the conflict ordered close to far from the conflict.
  211.      * Distance is given relative to the <i>end</i> of the conflict, or null for conflicting vehicles on the conflict. In the
  212.      * latter case the overlap is used.
  213.      * @return set of conflicting GTU's downstream of the <i>start</i> of the conflict ordered close to far from the conflict
  214.      */
  215.     public final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> getDownstreamConflictingGTUs()
  216.     {
  217.         return this.downstreamConflictingGTUs;
  218.     }

  219.     /**
  220.      * Returns the visibility on the conflicting lane within which conflicting vehicles are visible. All upstream conflicting
  221.      * GTUs have a distance smaller than the visibility. Depending on a limited visibility, a certain (lower) speed may be
  222.      * required while approaching the conflict.
  223.      * @return visibility on the conflicting lane within which conflicting vehicles are visible
  224.      */
  225.     public final Length getConflictingVisibility()
  226.     {
  227.         return this.conflictingVisibility;
  228.     }

  229.     /**
  230.      * Returns the speed limit on the conflicting lane.
  231.      * @return speed limit on the conflicting lane
  232.      */
  233.     public final Speed getConflictingSpeedLimit()
  234.     {
  235.         return this.conflictingSpeedLimit;
  236.     }

  237.     /**
  238.      * Returns the conflicting link.
  239.      * @return the conflicting link
  240.      */
  241.     public final CrossSectionLink getConflictingLink()
  242.     {
  243.         return this.conflictingLink;
  244.     }

  245.     /**
  246.      * Returns the stop line.
  247.      * @return stop line
  248.      */
  249.     public final HeadwayStopLine getStopLine()
  250.     {
  251.         return this.stopLine;
  252.     }

  253.     /**
  254.      * Returns the stop line on the conflicting lane.
  255.      * @return stop line
  256.      */
  257.     public final HeadwayStopLine getConflictingStopLine()
  258.     {
  259.         return this.conflictingStopLine;
  260.     }

  261.     /**
  262.      * Returns the conflict rule type.
  263.      * @return conflict rule type
  264.      */
  265.     public final Class<? extends ConflictRule> getConflictRuleType()
  266.     {
  267.         return this.conflictRuleType;
  268.     }

  269.     /**
  270.      * Returns the distance of a traffic light upstream on the conflicting lane.
  271.      * @return distance of a traffic light upstream on the conflicting lane, or {@code null} if no traffic light
  272.      */
  273.     public final Length getConflictingTrafficLightDistance()
  274.     {
  275.         return this.conflictingTrafficLightDistance;
  276.     }

  277.     /**
  278.      * Whether the conflict is permitted by the traffic light.
  279.      * @return whether the conflict is permitted by the traffic light
  280.      */
  281.     public final boolean isPermitted()
  282.     {
  283.         return this.permitted;
  284.     }

  285.     /**
  286.      * Set the distance of a traffic light upstream on the conflicting lane.
  287.      * @param trafficLightDistance Length; distance of a traffic light upstream on the conflicting lane.
  288.      * @param permittedConflict boolean; whether the conflict is permitted by the traffic light
  289.      */
  290.     public final void setConflictingTrafficLight(final Length trafficLightDistance, final boolean permittedConflict)
  291.     {
  292.         this.conflictingTrafficLightDistance = trafficLightDistance;
  293.         this.permitted = permittedConflict;
  294.     }

  295.     /**
  296.      * Returns the width at the given fraction.
  297.      * @param fraction double; fraction from 0 to 1
  298.      * @return Length; width at the given fraction
  299.      */
  300.     public final Length getWidthAtFraction(final double fraction)
  301.     {
  302.         try
  303.         {
  304.             return this.width.getWidth(fraction);
  305.         }
  306.         catch (ValueRuntimeException exception)
  307.         {
  308.             throw new RuntimeException("Unexpected exception: fraction could not be interpolated.", exception);
  309.         }
  310.     }

  311.     /**
  312.      * Width progression of conflict.
  313.      * <p>
  314.      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  315.      * <br>
  316.      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  317.      * <p>
  318.      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 aug. 2018 <br>
  319.      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  320.      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  321.      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  322.      */
  323.     public static class Width
  324.     {

  325.         /** Fractions, from 0 to 1. */
  326.         private final double[] fractions;

  327.         /** Vector with widths. */
  328.         private final LengthVector width;

  329.         /**
  330.          * @param fractions double[]; fractions, from 0 to 1
  331.          * @param width LengthVector; vector of equal length with widths
  332.          */
  333.         public Width(final double[] fractions, final LengthVector width)
  334.         {
  335.             Throw.whenNull(fractions, "Fractions may not be null.");
  336.             Throw.whenNull(width, "Width may not be null.");
  337.             Throw.when(fractions.length != width.size(), IllegalArgumentException.class,
  338.                     "Array and vector are not of equal length.");
  339.             Throw.when(fractions.length < 2, IllegalArgumentException.class, "Input should at least contain 2 values.");
  340.             Throw.when(fractions[0] != 0.0 || fractions[fractions.length - 1] != 1.0, IllegalArgumentException.class,
  341.                     "Fractions should range from 0 to 1.");
  342.             for (int i = 1; i < fractions.length; i++)
  343.             {
  344.                 Throw.when(fractions[i] <= fractions[i - 1], IllegalArgumentException.class, "Fractions are not increasing.");
  345.             }
  346.             this.fractions = fractions;
  347.             this.width = width;
  348.         }

  349.         /**
  350.          * Returns the width at the given fraction.
  351.          * @param fraction double; fraction from 0 to 1
  352.          * @return Length; width at the given fraction
  353.          * @throws ValueRuntimeException when index is out of bounds
  354.          */
  355.         public Length getWidth(final double fraction) throws ValueRuntimeException
  356.         {
  357.             Throw.when(fraction < 0.0 || fraction > 1.0, IllegalArgumentException.class, "Fraction should be between 0 and 1.");
  358.             if (fraction == 1.0)
  359.             {
  360.                 return this.width.get(this.width.size() - 1);
  361.             }
  362.             for (int i = 0; i < this.fractions.length - 1; i++)
  363.             {
  364.                 if (this.fractions[i] <= fraction && this.fractions[i + 1] > fraction)
  365.                 {
  366.                     double r = (fraction - this.fractions[i]) / (this.fractions[i + 1] - this.fractions[i]);
  367.                     return Length.interpolate(this.width.get(i), this.width.get(i + 1), r);
  368.                 }
  369.             }
  370.             throw new RuntimeException("Unexpected exception: fraction could not be interpolated.");
  371.         }

  372.         /**
  373.          * Returns a linear width progression.
  374.          * @param startWidth Length; start width
  375.          * @param endWidth Length; end width
  376.          * @return Width; linear width progression
  377.          */
  378.         public static Width linear(final Length startWidth, final Length endWidth)
  379.         {
  380.             Throw.whenNull(startWidth, "Start width may not be null.");
  381.             Throw.whenNull(endWidth, "End width may not be null.");
  382.             try
  383.             {
  384.                 return new Width(new double[] { 0.0, 1.0 },
  385.                         DoubleVector.instantiate(new Length[] { startWidth, endWidth }, LengthUnit.SI, StorageType.DENSE));
  386.             }
  387.             catch (ValueRuntimeException exception)
  388.             {
  389.                 throw new RuntimeException("Unexpected exception: widths could not be put in a vector.", exception);
  390.             }
  391.         }

  392.     }

  393.     /** {@inheritDoc} */
  394.     @Override
  395.     public final String toString()
  396.     {
  397.         return String.format("Headway %s to object %s of type %s", getDistance(), getId(), getObjectType());
  398.     }

  399. }