InfrastructureLaneChangeInfo.java

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

  2. import java.io.Serializable;

  3. import org.djunits.value.vdouble.scalar.Length;
  4. import org.djutils.exceptions.Throw;
  5. import org.opentrafficsim.core.gtu.RelativePosition;
  6. import org.opentrafficsim.core.network.LateralDirectionality;

  7. /**
  8.  * Contains information by which drivers know when they need to leave a lane in order to be able to stay on the infrastructure
  9.  * and follow their route.
  10.  * <p>
  11.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  12.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
  13.  * <p>
  14.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version May 2, 2016 <br>
  15.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  16.  */
  17. public class InfrastructureLaneChangeInfo implements Comparable<InfrastructureLaneChangeInfo>, Serializable
  18. {

  19.     /** */
  20.     private static final long serialVersionUID = 20160811L;

  21.     /** Required number of lane changes. */
  22.     private final int requiredNumberOfLaneChanges;

  23.     /** Record who's end defines the remaining distances. */
  24.     private final LaneStructureRecord record;

  25.     /** Available length after the start (reference on start). */
  26.     private final Length afterStartLength;

  27.     /** Whether the need to change lane comes from a dead-end. */
  28.     private boolean deadEnd;

  29.     /** Lateral directionality of required lane changes. */
  30.     private final LateralDirectionality lat;

  31.     /**
  32.      * Constructor for subclasses.
  33.      * @param requiredNumberOfLaneChanges int; required number of lane changes
  34.      * @param deadEnd boolean; whether the need to change lane comes from a dead-end
  35.      */
  36.     protected InfrastructureLaneChangeInfo(final int requiredNumberOfLaneChanges, final boolean deadEnd)
  37.     {
  38.         this.requiredNumberOfLaneChanges = requiredNumberOfLaneChanges;
  39.         this.record = null;
  40.         this.deadEnd = deadEnd;
  41.         this.afterStartLength = null;
  42.         this.lat = LateralDirectionality.NONE;
  43.     }

  44.     /**
  45.      * Constructor.
  46.      * @param requiredNumberOfLaneChanges int; required number of lane changes
  47.      * @param record LaneStructureRecord; record who's end defines the remaining distance
  48.      * @param relativePosition RelativePosition; critical relative position (i.e. nose when driving forward)
  49.      * @param deadEnd boolean; whether the need to change lane comes from a dead-end
  50.      * @param lat LateralDirectionality; lateral directionality of required lane changes
  51.      * @throws IllegalArgumentException if required number of lane changes or remaining distance is negative
  52.      * @throws NullPointerException if remaining distance is null
  53.      */
  54.     public InfrastructureLaneChangeInfo(final int requiredNumberOfLaneChanges, final LaneStructureRecord record,
  55.             final RelativePosition relativePosition, final boolean deadEnd, final LateralDirectionality lat)
  56.     {
  57.         Throw.when(requiredNumberOfLaneChanges < 0, IllegalArgumentException.class,
  58.                 "Required number of lane changes may not be negative.");
  59.         Throw.whenNull(lat, "Lateral directionality may not be null.");
  60.         Throw.when(requiredNumberOfLaneChanges != 0 && lat.equals(LateralDirectionality.NONE), IllegalArgumentException.class,
  61.                 "Lateral directionality may not be NONE for non-zero lane changes.");
  62.         Throw.whenNull(record, "Record may not be null.");
  63.         this.requiredNumberOfLaneChanges = requiredNumberOfLaneChanges;
  64.         this.record = record;
  65.         this.afterStartLength = this.record.getLane().getLength().minus(relativePosition.getDx());
  66.         this.deadEnd = deadEnd;
  67.         this.lat = lat;
  68.     }

  69.     /**
  70.      * @return requiredNumberOfLaneChanges required number of lane changes.
  71.      */
  72.     public final int getRequiredNumberOfLaneChanges()
  73.     {
  74.         return this.requiredNumberOfLaneChanges;
  75.     }

  76.     /**
  77.      * @return remainingDistance remaining distance to perform required lane changes.
  78.      */
  79.     public Length getRemainingDistance()
  80.     {
  81.         return this.record.getStartDistance().plus(this.afterStartLength);
  82.     }

  83.     /**
  84.      * @return whether this reason to change lane is due to a dead-end.
  85.      */
  86.     public final boolean isDeadEnd()
  87.     {
  88.         return this.deadEnd;
  89.     }

  90.     /**
  91.      * Sets whether this reason to change lane is due to a dead-end.
  92.      * @param deadEnd boolean; whether the need to change lane comes from a dead-end
  93.      */
  94.     public final void setDeadEnd(final boolean deadEnd)
  95.     {
  96.         this.deadEnd = deadEnd;
  97.     }

  98.     /**
  99.      * Returns the lateral directionality of the required lane changes.
  100.      * @return LateralDirectionality; lateral directionality of the required lane changes
  101.      */
  102.     public final LateralDirectionality getLateralDirectionality()
  103.     {
  104.         return this.lat;
  105.     }

  106.     /** {@inheritDoc} */
  107.     @SuppressWarnings("checkstyle:designforextension")
  108.     @Override
  109.     public String toString()
  110.     {
  111.         return "InfrastructureLaneChangeInfo [requiredNumberOfLaneChanges=" + this.requiredNumberOfLaneChanges
  112.                 + ", remainingDistance=" + getRemainingDistance() + "]";
  113.     }

  114.     /** {@inheritDoc} */
  115.     @Override
  116.     public final int compareTo(final InfrastructureLaneChangeInfo infrastructureLaneChangeInfo)
  117.     {
  118.         return this.getRemainingDistance().compareTo(infrastructureLaneChangeInfo.getRemainingDistance());
  119.     }

  120.     /**
  121.      * Returns lane change info for one lane towards the left.
  122.      * @param rec LaneStructureRecord; record who's end defines the remaining distance
  123.      * @param rel RelativePosition; critical relative position (i.e. nose when driving forward)
  124.      * @param dead boolean; whether the need to change lane comes from a dead-end
  125.      * @return InfrastructureLaneChangeInfo; lane change info for one lane towards the left
  126.      */
  127.     public final InfrastructureLaneChangeInfo left(final LaneStructureRecord rec, final RelativePosition rel,
  128.             final boolean dead)
  129.     {
  130.         return new InfrastructureLaneChangeInfo(this.requiredNumberOfLaneChanges + 1, rec, rel, dead,
  131.                 LateralDirectionality.LEFT);
  132.     }

  133.     /**
  134.      * Returns lane change info for one lane towards the right.
  135.      * @param rec LaneStructureRecord; record who's end defines the remaining distance
  136.      * @param rel RelativePosition; critical relative position (i.e. nose when driving forward)
  137.      * @param dead boolean; whether the need to change lane comes from a dead-end
  138.      * @return InfrastructureLaneChangeInfo; lane change info for one lane towards the right
  139.      */
  140.     public final InfrastructureLaneChangeInfo right(final LaneStructureRecord rec, final RelativePosition rel,
  141.             final boolean dead)
  142.     {
  143.         return new InfrastructureLaneChangeInfo(this.requiredNumberOfLaneChanges + 1, rec, rel, dead,
  144.                 LateralDirectionality.RIGHT);
  145.     }

  146.     /**
  147.      * Returns an instance for the case the entire lane is inaccessible.
  148.      * @param deadEnd boolean; dead end
  149.      * @return instance for the case the entire lane is inaccessible
  150.      */
  151.     public static InfrastructureLaneChangeInfo fromInaccessibleLane(final boolean deadEnd)
  152.     {
  153.         return new InfrastructureLaneChangeInfoInaccessibleLane(deadEnd);
  154.     }

  155.     /**
  156.      * Extension which sets the distance to 0 always, used for fully inaccessible lanes regarding the route.
  157.      * <p>
  158.      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  159.      * <br>
  160.      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  161.      * <p>
  162.      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 14 feb. 2018 <br>
  163.      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  164.      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  165.      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  166.      */
  167.     private static class InfrastructureLaneChangeInfoInaccessibleLane extends InfrastructureLaneChangeInfo
  168.     {

  169.         /** */
  170.         private static final long serialVersionUID = 20180214L;

  171.         /**
  172.          * @param deadEnd boolean; whether the need to change lane comes from a dead-end
  173.          */
  174.         InfrastructureLaneChangeInfoInaccessibleLane(final boolean deadEnd)
  175.         {
  176.             super(1, deadEnd);
  177.         }

  178.         /** {@inheritDoc} */
  179.         @Override
  180.         public Length getRemainingDistance()
  181.         {
  182.             return Length.ZERO;
  183.         }

  184.     }

  185. }