SimpleOperationalPlan.java

  1. package org.opentrafficsim.road.gtu.lane.plan.operational;

  2. import java.io.Serializable;

  3. import org.djunits.value.vdouble.scalar.Acceleration;
  4. import org.djunits.value.vdouble.scalar.Duration;
  5. import org.djunits.value.vdouble.scalar.Length;
  6. import org.djutils.exceptions.Throw;
  7. import org.djutils.logger.CategoryLogger;
  8. import org.opentrafficsim.core.gtu.GtuException;
  9. import org.opentrafficsim.core.gtu.TurnIndicatorIntent;
  10. import org.opentrafficsim.core.gtu.TurnIndicatorStatus;
  11. import org.opentrafficsim.core.network.LateralDirectionality;
  12. import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;

  13. /**
  14.  * Simplified plan containing an acceleration value and possible lane change direction.
  15.  * <p>
  16.  * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  17.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  18.  * </p>
  19.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  20.  * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
  21.  * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
  22.  */

  23. public class SimpleOperationalPlan implements Serializable
  24. {

  25.     /** */
  26.     private static final long serialVersionUID = 20160811L;

  27.     /** Acceleration. */
  28.     private Acceleration acceleration;

  29.     /** Lane change direction. */
  30.     private final LateralDirectionality laneChangeDirection;

  31.     /** Indicator intent. */
  32.     private TurnIndicatorIntent indicatorIntent = TurnIndicatorIntent.NONE;

  33.     /** Distance to object causing turn indicator intent. */
  34.     private Length indicatorObjectDistance = null;

  35.     /** Duration of the plan. */
  36.     private final Duration duration;

  37.     /**
  38.      * @param acceleration acceleration
  39.      * @param duration duration
  40.      */
  41.     public SimpleOperationalPlan(final Acceleration acceleration, final Duration duration)
  42.     {
  43.         this(acceleration, duration, LateralDirectionality.NONE);
  44.     }

  45.     /**
  46.      * @param acceleration acceleration
  47.      * @param duration duration
  48.      * @param laneChangeDirection lane change direction, may be {@code null}.
  49.      */
  50.     public SimpleOperationalPlan(final Acceleration acceleration, final Duration duration,
  51.             final LateralDirectionality laneChangeDirection)
  52.     {
  53.         Throw.whenNull(acceleration, "Acceleration may not be null.");
  54.         Throw.whenNull(duration, "Duration may not be null.");
  55.         Throw.whenNull(laneChangeDirection, "Lane change direction may not be null.");
  56.         checkAcceleration(acceleration);
  57.         this.acceleration = Acceleration.max(Acceleration.instantiateSI(-100.0), acceleration);
  58.         this.duration = duration;
  59.         this.laneChangeDirection = laneChangeDirection;
  60.     }

  61.     /**
  62.      * @return acceleration.
  63.      */
  64.     public final Acceleration getAcceleration()
  65.     {
  66.         return this.acceleration;
  67.     }

  68.     /**
  69.      * Sets acceleration.
  70.      * @param acceleration acceleration
  71.      */
  72.     public final void setAcceleration(final Acceleration acceleration)
  73.     {
  74.         checkAcceleration(acceleration);
  75.         this.acceleration = acceleration;
  76.     }

  77.     /**
  78.      * @return duration.
  79.      */
  80.     public Duration getDuration()
  81.     {
  82.         return this.duration;
  83.     }

  84.     /**
  85.      * @return if lane change.
  86.      */
  87.     public final boolean isLaneChange()
  88.     {
  89.         return this.laneChangeDirection != LateralDirectionality.NONE;
  90.     }

  91.     /**
  92.      * @return laneChangeDirection, may be NONE if no lane change.
  93.      */
  94.     public final LateralDirectionality getLaneChangeDirection()
  95.     {
  96.         return this.laneChangeDirection;
  97.     }

  98.     /**
  99.      * Set minimum of current and given acceleration.
  100.      * @param a acceleration to set if lower than current acceleration
  101.      */
  102.     public final void minimizeAcceleration(final Acceleration a)
  103.     {
  104.         checkAcceleration(a);
  105.         // XXX: AV
  106.         this.acceleration = Acceleration.max(Acceleration.instantiateSI(-100.0), Acceleration.min(this.acceleration, a));
  107.     }

  108.     /**
  109.      * Check acceleration level.
  110.      * @param a acceleration
  111.      */
  112.     private void checkAcceleration(final Acceleration a)
  113.     {
  114.         if (a.equals(Acceleration.NEGATIVE_INFINITY) || a.equals(Acceleration.NEG_MAXVALUE))
  115.         {
  116.             // XXX: AV
  117.             CategoryLogger.always().error("Model has calculated a negative infinite or negative max value acceleration.");
  118.         }
  119.     }

  120.     /**
  121.      * @return indicatorIntent.
  122.      */
  123.     public final TurnIndicatorIntent getIndicatorIntent()
  124.     {
  125.         return this.indicatorIntent;
  126.     }

  127.     /**
  128.      * Set left indicator intent. Any intent given with distance overrules this intent.
  129.      */
  130.     public final void setIndicatorIntentLeft()
  131.     {
  132.         if (this.indicatorObjectDistance != null)
  133.         {
  134.             return;
  135.         }
  136.         if (this.indicatorIntent.isRight())
  137.         {
  138.             this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
  139.         }
  140.         else
  141.         {
  142.             this.indicatorIntent = TurnIndicatorIntent.LEFT;
  143.         }
  144.     }

  145.     /**
  146.      * Set right indicator intent. Any intent given with distance overrules this intent.
  147.      */
  148.     public final void setIndicatorIntentRight()
  149.     {
  150.         if (this.indicatorObjectDistance != null)
  151.         {
  152.             return;
  153.         }
  154.         if (this.indicatorIntent.isLeft())
  155.         {
  156.             this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
  157.         }
  158.         else
  159.         {
  160.             this.indicatorIntent = TurnIndicatorIntent.RIGHT;
  161.         }
  162.     }

  163.     /**
  164.      * Set left indicator intent. Intent with smallest provided distance has priority.
  165.      * @param distance distance to object pertaining to the turn indicator intent
  166.      */
  167.     public final void setIndicatorIntentLeft(final Length distance)
  168.     {
  169.         if (compareAndIgnore(distance))
  170.         {
  171.             return;
  172.         }
  173.         if (this.indicatorIntent.isRight())
  174.         {
  175.             this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
  176.         }
  177.         else
  178.         {
  179.             this.indicatorIntent = TurnIndicatorIntent.LEFT;
  180.         }

  181.     }

  182.     /**
  183.      * Set right indicator intent. Intent with smallest provided distance has priority.
  184.      * @param distance distance to object pertaining to the turn indicator intent
  185.      */
  186.     public final void setIndicatorIntentRight(final Length distance)
  187.     {
  188.         if (compareAndIgnore(distance))
  189.         {
  190.             return;
  191.         }
  192.         if (this.indicatorIntent.isLeft())
  193.         {
  194.             this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
  195.         }
  196.         else
  197.         {
  198.             this.indicatorIntent = TurnIndicatorIntent.RIGHT;
  199.         }
  200.     }

  201.     /**
  202.      * Compares distances and returns whether the given distance (and intent) can be ignored.
  203.      * @param distance distance to object of intent
  204.      * @return whether the given distance can be ignored
  205.      */
  206.     private boolean compareAndIgnore(final Length distance)
  207.     {
  208.         if (this.indicatorObjectDistance != null)
  209.         {
  210.             if (this.indicatorObjectDistance.lt(distance))
  211.             {
  212.                 // disregard input; the intent from larger distance
  213.                 return true;
  214.             }
  215.             if (this.indicatorObjectDistance.gt(distance))
  216.             {
  217.                 // disregard existing; the intent from larger distance
  218.                 this.indicatorIntent = TurnIndicatorIntent.NONE; // prevents a set to CONFLICTING
  219.             }
  220.         }
  221.         else
  222.         {
  223.             // disregard existing; the intent without distance
  224.             this.indicatorIntent = TurnIndicatorIntent.NONE; // prevents a set to CONFLICTING
  225.         }
  226.         return false;
  227.     }

  228.     @Override
  229.     @SuppressWarnings("checkstyle:designforextension")
  230.     public String toString()
  231.     {
  232.         return "SimpleOperationalPlan [Acceleration=" + this.acceleration + ", change=" + this.laneChangeDirection
  233.                 + ", indicator intent=" + this.indicatorIntent + "]";
  234.     }

  235.     /**
  236.      * @param gtu LaneBasedGtu to set the indicator on
  237.      * @throws GtuException if GTU does not support the indicator
  238.      */
  239.     public final void setTurnIndicator(final LaneBasedGtu gtu) throws GtuException
  240.     {
  241.         if (this.indicatorIntent.isLeft())
  242.         {
  243.             gtu.setTurnIndicatorStatus(TurnIndicatorStatus.LEFT);
  244.         }
  245.         else if (this.indicatorIntent.isRight())
  246.         {
  247.             gtu.setTurnIndicatorStatus(TurnIndicatorStatus.RIGHT);
  248.         }
  249.         else
  250.         {
  251.             gtu.setTurnIndicatorStatus(TurnIndicatorStatus.NONE);
  252.         }
  253.     }

  254. }