Estimation.java

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

  2. import org.djunits.value.vdouble.scalar.Acceleration;
  3. import org.djunits.value.vdouble.scalar.Length;
  4. import org.djunits.value.vdouble.scalar.Speed;
  5. import org.djunits.value.vdouble.scalar.Time;
  6. import org.opentrafficsim.base.parameters.ParameterException;
  7. import org.opentrafficsim.core.gtu.perception.EgoPerception;
  8. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
  9. import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
  10. import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationSituationalAwareness;

  11. /**
  12.  * Estimation of neighbor headway, speed and acceleration.
  13.  * <p>
  14.  * Copyright (c) 2013-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  15.  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  16.  * <p>
  17.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 apr. 2018 <br>
  18.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  19.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  20.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  21.  */
  22. public interface Estimation
  23. {
  24.     /** No estimation errors. */
  25.     Estimation NONE = new Estimation()
  26.     {
  27.         @Override
  28.         public NeighborTriplet estimate(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
  29.                 final Length distance, final boolean downstream, final Time when) throws ParameterException
  30.         {
  31.             return new NeighborTriplet(getDelayedHeadway(perceivingGtu, perceivedGtu, distance, downstream, when),
  32.                     getEgoSpeed(perceivingGtu).plus(getDelayedSpeedDifference(perceivingGtu, perceivedGtu, when)),
  33.                     perceivedGtu.getAcceleration(when));
  34.         }
  35.     };

  36.     /** Underestimation based on situational awareness. */
  37.     Estimation UNDERESTIMATION = new FactorEstimation()
  38.     {
  39.         /** {@inheritDoc} */
  40.         @Override
  41.         boolean overEstimation()
  42.         {
  43.             return false;
  44.         }
  45.     };

  46.     /** OVerestimation based on situational awareness. */
  47.     Estimation OVERESTIMATION = new FactorEstimation()
  48.     {
  49.         /** {@inheritDoc} */
  50.         @Override
  51.         boolean overEstimation()
  52.         {
  53.             return true;
  54.         }
  55.     };

  56.     /**
  57.      * Estimate headway, speed and acceleration.
  58.      * @param perceivingGtu LaneBasedGTU; perceiving GTU
  59.      * @param perceivedGtu LaneBasedGTU; perceived GTU
  60.      * @param distance Length; actual headway at 'now' (i.e. not at 'when' if there is a reaction time)
  61.      * @param downstream boolean; downstream (or upstream) neighbor
  62.      * @param when Time; moment of perception, reaction time included
  63.      * @return NeighborTriplet; perceived headway, speed and acceleration
  64.      * @throws ParameterException on invalid parameter value or if parameter is not available
  65.      */
  66.     NeighborTriplet estimate(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance, boolean downstream,
  67.             Time when) throws ParameterException;

  68.     /**
  69.      * Returns a delayed headway.
  70.      * @param perceivingGtu LaneBasedGTU; perceiving GTU
  71.      * @param perceivedGtu LaneBasedGTU; perceived GTU
  72.      * @param distance Length; actual headway at 'now' (i.e. not at 'when' if there is a reaction time)
  73.      * @param downstream boolean; downstream (or upstream) neighbor
  74.      * @param when Time; moment of perception, reaction time included
  75.      * @return Length; delayed headway
  76.      */
  77.     default Length getDelayedHeadway(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu, final Length distance,
  78.             final boolean downstream, final Time when)
  79.     {
  80.         double delta = (perceivedGtu.getOdometer().si - perceivedGtu.getOdometer(when).si)
  81.                 - (perceivingGtu.getOdometer().si - perceivingGtu.getOdometer(when).si);
  82.         if (downstream)
  83.         {
  84.             delta = -delta; // faster leader increases the headway, faster follower reduces the headway
  85.         }
  86.         return Length.instantiateSI(distance.si + delta);
  87.     }

  88.     /**
  89.      * Returns the ego speed. This is the speed used in AbstractLaneBasedGTU.getCarFollowingAcceleration(), and hence this is
  90.      * the reference speed for the stimulus of speed difference.
  91.      * @param perceivingGtu LaneBasedGTU; perceiving GTU
  92.      * @return Speed; ego speed
  93.      */
  94.     default Speed getEgoSpeed(final LaneBasedGTU perceivingGtu)
  95.     {
  96.         try
  97.         {
  98.             return perceivingGtu.getTacticalPlanner().getPerception().getPerceptionCategory(EgoPerception.class).getSpeed();
  99.         }
  100.         catch (OperationalPlanException exception)
  101.         {
  102.             throw new RuntimeException("Speed difference is perceived using EgoPerception for the ego speed, but it's missing.",
  103.                     exception);
  104.         }
  105.     }

  106.     /**
  107.      * Returns a delayed speed difference (other minus ego).
  108.      * @param perceivingGtu LaneBasedGTU; perceiving GTU
  109.      * @param perceivedGtu LaneBasedGTU; perceived GTU
  110.      * @param when Time; moment of perception, reaction time included
  111.      * @return Speed; delayed speed difference (other minus ego)
  112.      */
  113.     default Speed getDelayedSpeedDifference(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu, final Time when)
  114.     {
  115.         return Speed.instantiateSI(perceivedGtu.getSpeed(when).si - perceivingGtu.getSpeed(when).si);
  116.     }

  117.     /**
  118.      * Estimation based on a factor.
  119.      * <p>
  120.      * Copyright (c) 2013-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  121.      * <br>
  122.      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  123.      * <p>
  124.      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 31 jan. 2019 <br>
  125.      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  126.      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  127.      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  128.      */
  129.     abstract class FactorEstimation implements Estimation
  130.     {

  131.         /** Sign. */
  132.         private final double sign;

  133.         /**
  134.          * Constructor.
  135.          */
  136.         FactorEstimation()
  137.         {
  138.             this.sign = overEstimation() ? 1.0 : -1.0;
  139.         }

  140.         /** {@inheritDoc} */
  141.         @Override
  142.         public NeighborTriplet estimate(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
  143.                 final Length distance, final boolean downstream, final Time when) throws ParameterException
  144.         {
  145.             double factor = 1.0 + this.sign * (perceivingGtu.getParameters().getParameter(AdaptationSituationalAwareness.SA_MAX)
  146.                     - perceivingGtu.getParameters().getParameter(AdaptationSituationalAwareness.SA));
  147.             Length headway = getDelayedHeadway(perceivingGtu, perceivedGtu, distance, downstream, when).times(factor);
  148.             Speed speed = getEgoSpeed(perceivingGtu)
  149.                     .plus(getDelayedSpeedDifference(perceivingGtu, perceivedGtu, when).times(factor));
  150.             Acceleration acceleration = perceivedGtu.getAcceleration(when);
  151.             return new NeighborTriplet(headway, speed, acceleration);
  152.         }

  153.         /**
  154.          * Returns whether this is over-estimation.
  155.          * @return boolean; whether this is over-estimation
  156.          */
  157.         abstract boolean overEstimation();
  158.     }

  159. }