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-2024 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://github.com/peter-knoppers">Peter Knoppers</a>
  36.  * @author <a href="https://github.com/wjschakel">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 the observed GTU, can not be null.
  51.      * @param distance if this constructor is used, distance cannot be null.
  52.      * @param facingSameDirection 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 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 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 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().lane().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.     @Override
  98.     public final CarFollowingModel getCarFollowingModel()
  99.     {
  100.         return this.gtu.getTacticalPlanner().getCarFollowingModel();
  101.     }

  102.     @Override
  103.     public final Parameters getParameters()
  104.     {
  105.         return this.gtu.getParameters();
  106.     }

  107.     @Override
  108.     public final SpeedLimitInfo getSpeedLimitInfo()
  109.     {
  110.         if (this.speedLimitInfo == null)
  111.         {
  112.             this.speedLimitInfo = getSpeedLimitInfo(this.gtu);
  113.         }
  114.         return this.speedLimitInfo;
  115.     }

  116.     @Override
  117.     public final Route getRoute()
  118.     {
  119.         return this.gtu.getStrategicalPlanner().getRoute();
  120.     }

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

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

  180.     @Override
  181.     public final String getId()
  182.     {
  183.         return this.gtu.getId();
  184.     }

  185.     @Override
  186.     public final Length getLength()
  187.     {
  188.         return this.gtu.getLength();
  189.     }

  190.     @Override
  191.     public Length getWidth()
  192.     {
  193.         return this.gtu.getWidth();
  194.     }

  195.     @Override
  196.     public final Speed getSpeed()
  197.     {
  198.         return this.gtu.getSpeed();
  199.     }

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

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

  210.     @Override
  211.     public final Acceleration getAcceleration()
  212.     {
  213.         return this.gtu.getAcceleration();
  214.     }

  215.     @Override
  216.     public final GtuType getGtuType()
  217.     {
  218.         return this.gtu.getType();
  219.     }

  220.     @Override
  221.     public final boolean isFacingSameDirection()
  222.     {
  223.         return this.facingSameDirection;
  224.     }

  225.     @Override
  226.     public final boolean isBrakingLightsOn()
  227.     {
  228.         // TODO
  229.         return false;
  230.     }

  231.     @Override
  232.     public final boolean isLeftTurnIndicatorOn()
  233.     {
  234.         return this.gtu.getTurnIndicatorStatus().isLeft();
  235.     }

  236.     @Override
  237.     public final boolean isRightTurnIndicatorOn()
  238.     {
  239.         return this.gtu.getTurnIndicatorStatus().isRight();
  240.     }

  241.     @Override
  242.     public final boolean isEmergencyLightsOn()
  243.     {
  244.         return this.gtu.getTurnIndicatorStatus().isHazard();
  245.     }

  246.     @Override
  247.     public final boolean isHonking()
  248.     {
  249.         // TODO
  250.         return false;
  251.     }

  252.     @Override
  253.     public final String toString()
  254.     {
  255.         return "HeadwayGtuReal [speedLimitInfo=" + this.speedLimitInfo + ", gtu=" + this.gtu + ", facingSameDirection="
  256.                 + this.facingSameDirection + "]";
  257.     }

  258. }