HeadwayGtuReal.java

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

  2. import java.util.EnumSet;

  3. import org.djunits.value.vdouble.scalar.Acceleration;
  4. import org.djunits.value.vdouble.scalar.Length;
  5. import org.djunits.value.vdouble.scalar.Speed;
  6. import org.opentrafficsim.base.parameters.Parameters;
  7. import org.opentrafficsim.core.gtu.GtuException;
  8. import org.opentrafficsim.core.gtu.GtuType;
  9. import org.opentrafficsim.core.network.NetworkException;
  10. import org.opentrafficsim.core.network.route.Route;
  11. import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
  12. import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
  13. import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
  14. import org.opentrafficsim.road.network.speed.SpeedLimitTypes;

  15. /**
  16.  * Container for a reference to information about a (lane based) GTU and a headway. The Headway can store information about GTUs
  17.  * or objects ahead of the reference GTU, behind the reference GTU, or (partially) parallel to the reference GTU. In addition to
  18.  * the (perceived) headway, several other pieces of information can be stored, such as (perceived) speed, (perceived)
  19.  * acceleration, (perceived) turn indicators, and (perceived) braking lights. <br>
  20.  * This particular version returns behavioral information about the observed GTU objects based on their real state.<br>
  21.  * Special care must be taken in curves when perceiving headway of a GTU or object on an adjacent lane.The question is whether
  22.  * we perceive the parallel or ahead/behind based on a line perpendicular to the front/back of the GTU (rectangular), or
  23.  * perpendicular to the center line of the lane (wedge-shaped in case of a curve). The difficulty of a wedge-shaped situation is
  24.  * that reciprocity might be violated: in case of a clothoid, for instance, it is not sure that the point on the center line
  25.  * when projected from lane 1 to lane 2 is the same as the projection from lane 2 to lane 1. The same holds for shapes with
  26.  * sharp bends. Therefore, algorithms implementing headway should only project the <i>reference point</i> of the reference GTU
  27.  * on the center line of the adjacent lane, and then calculate the forward position and backward position on the adjacent lane
  28.  * based on the reference point. Still, our human perception of what is parallel and what not, is not reflected by fractional
  29.  * positions.
  30.  * <p>
  31.  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  32.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  33.  * </p>
  34.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  35.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  36.  * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  37.  */
  38. public class HeadwayGtuReal extends AbstractHeadway implements HeadwayGtu
  39. {
  40.     /** */
  41.     private static final long serialVersionUID = 20170324L;

  42.     /** Stored speed limit info of the observed GTU. */
  43.     private SpeedLimitInfo speedLimitInfo;

  44.     /** Wrapped GTU. */
  45.     private final LaneBasedGtu gtu;

  46.     /** Whether the GTU is facing the same direction. */
  47.     private final boolean facingSameDirection;

  48.     /**
  49.      * Construct a new Headway information object, for a GTU ahead of us or behind us.
  50.      * @param gtu LaneBasedGtu; the observed GTU, can not be null.
  51.      * @param distance the distance to the other object; if this constructor is used, distance cannot be null.
  52.      * @param facingSameDirection boolean; whether the GTU is facing the same direction.
  53.      * @throws GtuException when id is null, objectType is null, or parameters are inconsistent
  54.      */
  55.     public HeadwayGtuReal(final LaneBasedGtu gtu, final Length distance, final boolean facingSameDirection) throws GtuException
  56.     {
  57.         super(distance);
  58.         this.gtu = gtu;
  59.         this.facingSameDirection = facingSameDirection;
  60.     }

  61.     /**
  62.      * Construct a new Headway information object, for a GTU parallel with us.
  63.      * @param gtu LaneBasedGtu; the observed GTU, can not be null.
  64.      * @param overlapFront the front-front distance to the other Gtu; if this constructor is used, this value cannot be null.
  65.      * @param overlap the 'center' overlap with the other Gtu; if this constructor is used, this value cannot be null.
  66.      * @param overlapRear the rear-rear distance to the other Gtu; if this constructor is used, this value cannot be null.
  67.      * @param facingSameDirection boolean; whether the GTU is facing the same direction.
  68.      * @throws GtuException when id is null, or parameters are inconsistent
  69.      */
  70.     public HeadwayGtuReal(final LaneBasedGtu gtu, final Length overlapFront, final Length overlap, final Length overlapRear,
  71.             final boolean facingSameDirection) throws GtuException
  72.     {
  73.         super(overlapFront, overlap, overlapRear);
  74.         this.gtu = gtu;
  75.         this.facingSameDirection = facingSameDirection;
  76.     }

  77.     /**
  78.      * Creates speed limit prospect for given GTU.
  79.      * @param wrappedGtu LaneBasedGtu; gtu to the the speed limit prospect for
  80.      * @return speed limit prospect for given GTU
  81.      */
  82.     private SpeedLimitInfo getSpeedLimitInfo(final LaneBasedGtu wrappedGtu)
  83.     {
  84.         SpeedLimitInfo sli = new SpeedLimitInfo();
  85.         sli.addSpeedInfo(SpeedLimitTypes.MAX_VEHICLE_SPEED, wrappedGtu.getMaximumSpeed());
  86.         try
  87.         {
  88.             sli.addSpeedInfo(SpeedLimitTypes.FIXED_SIGN,
  89.                     wrappedGtu.getReferencePosition().getLane().getSpeedLimit(wrappedGtu.getType()));
  90.         }
  91.         catch (NetworkException | GtuException exception)
  92.         {
  93.             throw new RuntimeException("Could not obtain speed limit from lane for perception.", exception);
  94.         }
  95.         return sli;
  96.     }

  97.     /** {@inheritDoc} */
  98.     @Override
  99.     public final CarFollowingModel getCarFollowingModel()
  100.     {
  101.         return this.gtu.getTacticalPlanner().getCarFollowingModel();
  102.     }

  103.     /** {@inheritDoc} */
  104.     @Override
  105.     public final Parameters getParameters()
  106.     {
  107.         return this.gtu.getParameters();
  108.     }

  109.     /** {@inheritDoc} */
  110.     @Override
  111.     public final SpeedLimitInfo getSpeedLimitInfo()
  112.     {
  113.         if (this.speedLimitInfo == null)
  114.         {
  115.             this.speedLimitInfo = getSpeedLimitInfo(this.gtu);
  116.         }
  117.         return this.speedLimitInfo;
  118.     }

  119.     /** {@inheritDoc} */
  120.     @Override
  121.     public final Route getRoute()
  122.     {
  123.         return this.gtu.getStrategicalPlanner().getRoute();
  124.     }

  125.     /**
  126.      * {@inheritDoc} <br>
  127.      * <br>
  128.      * <b>Note: when moving a {@code HeadwayGtuRealDirect}, only headway, speed and acceleration may be considered to be delayed
  129.      * and anticipated. Other information is taken from the actual GTU at the time {@code moved()} is called.</b>
  130.      */
  131.     @Override
  132.     public final HeadwayGtu moved(final Length headway, final Speed speed, final Acceleration acceleration)
  133.     {
  134.         try
  135.         {
  136.             return new HeadwayGtuRealCopy(getId(), getGtuType(), headway, getLength(), getWidth(), speed, acceleration,
  137.                     getCarFollowingModel(), getParameters(), getSpeedLimitInfo(), getRoute(), getDesiredSpeed(),
  138.                     getGtuStatus());
  139.         }
  140.         catch (GtuException exception)
  141.         {
  142.             // input should be consistent
  143.             throw new RuntimeException("Exception while copying Headway GTU.", exception);
  144.         }
  145.     }

  146.     /**
  147.      * Returns an array with GTU status.
  148.      * @return array with GTU status
  149.      */
  150.     private GtuStatus[] getGtuStatus()
  151.     {
  152.         EnumSet<GtuStatus> gtuStatus = EnumSet.noneOf(GtuStatus.class);
  153.         if (isLeftTurnIndicatorOn())
  154.         {
  155.             gtuStatus.add(GtuStatus.LEFT_TURNINDICATOR);
  156.         }
  157.         if (isRightTurnIndicatorOn())
  158.         {
  159.             gtuStatus.add(GtuStatus.RIGHT_TURNINDICATOR);
  160.         }
  161.         if (isBrakingLightsOn())
  162.         {
  163.             gtuStatus.add(GtuStatus.BRAKING_LIGHTS);
  164.         }
  165.         if (isEmergencyLightsOn())
  166.         {
  167.             gtuStatus.add(GtuStatus.EMERGENCY_LIGHTS);
  168.         }
  169.         if (isHonking())
  170.         {
  171.             gtuStatus.add(GtuStatus.HONK);
  172.         }
  173.         return gtuStatus.toArray(new GtuStatus[gtuStatus.size()]);
  174.     }

  175.     /** {@inheritDoc} */
  176.     @Override
  177.     public final String getId()
  178.     {
  179.         return this.gtu.getId();
  180.     }

  181.     /** {@inheritDoc} */
  182.     @Override
  183.     public final Length getLength()
  184.     {
  185.         return this.gtu.getLength();
  186.     }

  187.     /** {@inheritDoc} */
  188.     @Override
  189.     public Length getWidth()
  190.     {
  191.         return this.gtu.getWidth();
  192.     }

  193.     /** {@inheritDoc} */
  194.     @Override
  195.     public final Speed getSpeed()
  196.     {
  197.         return this.gtu.getSpeed();
  198.     }

  199.     /** {@inheritDoc} */
  200.     @Override
  201.     public Speed getDesiredSpeed()
  202.     {
  203.         return this.gtu.getDesiredSpeed();
  204.     }

  205.     /** {@inheritDoc} */
  206.     @Override
  207.     public final ObjectType getObjectType()
  208.     {
  209.         return ObjectType.GTU;
  210.     }

  211.     /** {@inheritDoc} */
  212.     @Override
  213.     public final Acceleration getAcceleration()
  214.     {
  215.         return this.gtu.getAcceleration();
  216.     }

  217.     /** {@inheritDoc} */
  218.     @Override
  219.     public final GtuType getGtuType()
  220.     {
  221.         return this.gtu.getType();
  222.     }

  223.     /** {@inheritDoc} */
  224.     @Override
  225.     public final boolean isFacingSameDirection()
  226.     {
  227.         return this.facingSameDirection;
  228.     }

  229.     /** {@inheritDoc} */
  230.     @Override
  231.     public final boolean isBrakingLightsOn()
  232.     {
  233.         // TODO
  234.         return false;
  235.     }

  236.     /** {@inheritDoc} */
  237.     @Override
  238.     public final boolean isLeftTurnIndicatorOn()
  239.     {
  240.         return this.gtu.getTurnIndicatorStatus().isLeft();
  241.     }

  242.     /** {@inheritDoc} */
  243.     @Override
  244.     public final boolean isRightTurnIndicatorOn()
  245.     {
  246.         return this.gtu.getTurnIndicatorStatus().isRight();
  247.     }

  248.     /** {@inheritDoc} */
  249.     @Override
  250.     public final boolean isEmergencyLightsOn()
  251.     {
  252.         return this.gtu.getTurnIndicatorStatus().isHazard();
  253.     }

  254.     /** {@inheritDoc} */
  255.     @Override
  256.     public final boolean isHonking()
  257.     {
  258.         // TODO
  259.         return false;
  260.     }

  261.     /** {@inheritDoc} */
  262.     @Override
  263.     public final String toString()
  264.     {
  265.         return "HeadwayGtuReal [speedLimitInfo=" + this.speedLimitInfo + ", gtu=" + this.gtu + ", facingSameDirection="
  266.                 + this.facingSameDirection + "]";
  267.     }

  268. }