Distraction.java

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

  2. import org.djunits.value.vdouble.scalar.Length;
  3. import org.djutils.exceptions.Throw;
  4. import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
  5. import org.opentrafficsim.core.network.NetworkException;
  6. import org.opentrafficsim.road.network.lane.Lane;

  7. /**
  8.  * Distraction following a distance profile.
  9.  * <p>
  10.  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  11.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  12.  * </p>
  13.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  14.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  15.  * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  16.  */
  17. public class Distraction extends AbstractLaneBasedObject
  18. {

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

  21.     /** Distraction profile. */
  22.     private final DistractionProfile profile;

  23.     /**
  24.      * @param id String; id
  25.      * @param lane Lane; lane
  26.      * @param longitudinalPosition Length; longitudinal position
  27.      * @param simulator OtsSimulatorInterface; simulator
  28.      * @param profile DistractionProfile; distraction profile
  29.      * @throws NetworkException on network exception
  30.      */
  31.     public Distraction(final String id, final Lane lane, final Length longitudinalPosition,
  32.             final OtsSimulatorInterface simulator, final DistractionProfile profile) throws NetworkException
  33.     {
  34.         super(id, lane, longitudinalPosition, LaneBasedObject.makeGeometry(lane, longitudinalPosition),
  35.                 Length.ZERO);
  36.         this.profile = profile;

  37.         init();
  38.     }

  39.     /**
  40.      * Returns the level of distraction at the given distance.
  41.      * @param distance Distance to distraction; negative when approaching
  42.      * @return Double; level of distraction (task-demand), or {@code null} if the distraction is no longer important
  43.      */
  44.     public Double getDistraction(final Length distance)
  45.     {
  46.         return this.profile.getDistraction(distance);
  47.     }

  48.     /**
  49.      * Describes the profile around the distraction.
  50.      * <p>
  51.      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  52.      * <br>
  53.      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  54.      * </p>
  55.      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  56.      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  57.      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  58.      */
  59.     @FunctionalInterface
  60.     public interface DistractionProfile
  61.     {
  62.         /**
  63.          * Returns the level of distraction at the given distance.
  64.          * @param distance Distance to distraction; negative when approaching
  65.          * @return Double; level of distraction (task-demand), or {@code null} if the distraction is no longer important
  66.          */
  67.         Double getDistraction(Length distance);
  68.     }

  69.     /**
  70.      * Distraction profile with trapezoid shape. The constant part is from the location of the distraction downstream.
  71.      * <p>
  72.      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  73.      * <br>
  74.      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  75.      * </p>
  76.      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  77.      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  78.      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  79.      */
  80.     public static class TrapezoidProfile implements DistractionProfile
  81.     {
  82.         /** Maximum distraction. */
  83.         private final double maxDistraction;

  84.         /** Distance before distraction where distraction starts to have effect. */
  85.         private final Length dMin;

  86.         /** Distance beyond distraction where distraction has maximum effect. */
  87.         private final Length dMed;

  88.         /** Distance beyond distraction where distraction no longer has effect. */
  89.         private final Length dMax;

  90.         /**
  91.          * @param maxDistraction double; maximum distraction (task-demand)
  92.          * @param dMin Length; distance before distraction where distraction starts to have effect (&lt;0)
  93.          * @param dMed Length; distance beyond distraction where distraction has maximum effect (&gt;0)
  94.          * @param dMax Length; distance beyond distraction where distraction no longer has effect (&gt;dMed)
  95.          */
  96.         public TrapezoidProfile(final double maxDistraction, final Length dMin, final Length dMed, final Length dMax)
  97.         {
  98.             Throw.when(dMin.si > 0 || dMed.si < 0 || dMax.si < dMed.si, IllegalArgumentException.class,
  99.                     "dMin < 0 < dMed < dMax does not hold");
  100.             Throw.when(maxDistraction < 0 || maxDistraction > 1, IllegalArgumentException.class,
  101.                     "0 <= maxDistraction <= 1 does not hold");
  102.             this.maxDistraction = maxDistraction;
  103.             this.dMin = dMin;
  104.             this.dMed = dMed;
  105.             this.dMax = dMax;
  106.         }

  107.         /** {@inheritDoc} */
  108.         @Override
  109.         public Double getDistraction(final Length distance)
  110.         {
  111.             if (distance.si < this.dMin.si)
  112.             {
  113.                 // before scope
  114.                 return 0.0;
  115.             }
  116.             else if (distance.si < 0)
  117.             {
  118.                 // increasing distraction on approach
  119.                 return this.maxDistraction * (1.0 - distance.si / this.dMin.si);
  120.             }
  121.             else if (distance.si < this.dMed.si)
  122.             {
  123.                 // max distraction at location (defined over a distance dMed)
  124.                 return this.maxDistraction;
  125.             }
  126.             else if (distance.si < this.dMax.si)
  127.             {
  128.                 // reducing distraction beyond location
  129.                 return this.maxDistraction * (1.0 - (distance.si - this.dMed.si) / (this.dMax.si - this.dMed.si));
  130.             }
  131.             else
  132.             {
  133.                 // beyond scope
  134.                 return null;
  135.             }
  136.         }
  137.     }

  138. }