AbstractLaneBasedObject.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.geometry.DirectedPoint;
  5. import org.opentrafficsim.core.geometry.OtsLine3d;
  6. import org.opentrafficsim.core.network.NetworkException;
  7. import org.opentrafficsim.core.object.StaticObject;
  8. import org.opentrafficsim.road.network.lane.Lane;
  9. import org.opentrafficsim.road.network.lane.object.detector.LaneDetector;

  10. /**
  11.  * An abstract implementation of the LaneBasedObject interface with the required fields being initialized and getters for those
  12.  * fields. All StaticObjects are EventProducers, allowing them to provide state changes to subscribers.<br>
  13.  * <br>
  14.  * Note that extending classes must use a create(...) factory method that calls init() after fully constructing the object to
  15.  * avoid "half constructed" objects to be registered in the network.
  16.  * <p>
  17.  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  18.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  19.  * </p>
  20.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  21.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  22.  * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  23.  */
  24. public abstract class AbstractLaneBasedObject extends StaticObject implements LaneBasedObject
  25. {
  26.     /** */
  27.     private static final long serialVersionUID = 20160909L;

  28.     /** The lane for which this is a sensor. */
  29.     private final Lane lane;

  30.     /** The position (between 0.0 and the length of the Lane) of the sensor on the design line of the lane. */
  31.     private final Length longitudinalPosition;

  32.     /** The DirectedPoint that indicates the location on the lane. */
  33.     private final DirectedPoint location;

  34.     /**
  35.      * Construct a new AbstractLanebasedObject with the required fields.
  36.      * @param id String; the id of the new object
  37.      * @param lane Lane; The lane on which the new object resides. If the new object is a Sensor; it is automatically registered
  38.      *            on the lane
  39.      * @param longitudinalPosition Length; The position (between 0.0 and the length of the Lane) of the sensor on the design
  40.      *            line of the lane
  41.      * @param geometry OtsLine3d; the geometry of the object, which provides its location and bounds as well
  42.      * @param height Length; the height of the object, in case it is a 3D object
  43.      * @throws NetworkException when the position on the lane is out of bounds
  44.      */
  45.     protected AbstractLaneBasedObject(final String id, final Lane lane, final Length longitudinalPosition,
  46.             final OtsLine3d geometry, final Length height) throws NetworkException
  47.     {
  48.         super(id, geometry, height);

  49.         Throw.whenNull(lane, "lane is null");
  50.         Throw.whenNull(longitudinalPosition, "longitudinal position is null");
  51.         Throw.when(longitudinalPosition.si < 0.0 || longitudinalPosition.si > lane.getCenterLine().getLengthSI(),
  52.                 NetworkException.class, "Position of the object on the lane is out of bounds");

  53.         this.lane = lane;
  54.         this.longitudinalPosition = longitudinalPosition;
  55.         DirectedPoint p = lane.getCenterLine().getLocationExtended(this.longitudinalPosition);
  56.         this.location = new DirectedPoint(p.x, p.y, p.z + 0.01, p.getRotX(), p.getRotY(), p.getRotZ());
  57.     }

  58.     /**
  59.      * Construct a new LaneBasedObject with the required fields.
  60.      * @param id String; the id of the new AbstractLaneBasedObject
  61.      * @param lane Lane; The lane for which this is a sensor
  62.      * @param longitudinalPosition Length; The position (between 0.0 and the length of the Lane) of the sensor on the design
  63.      *            line of the lane
  64.      * @param geometry OtsLine3d; the geometry of the object, which provides its location and bounds as well
  65.      * @throws NetworkException when the position on the lane is out of bounds
  66.      */
  67.     protected AbstractLaneBasedObject(final String id, final Lane lane, final Length longitudinalPosition,
  68.             final OtsLine3d geometry) throws NetworkException
  69.     {
  70.         this(id, lane, longitudinalPosition, geometry, Length.ZERO);
  71.     }

  72.     /** {@inheritDoc} */
  73.     @Override
  74.     protected void init() throws NetworkException
  75.     {
  76.         super.init();

  77.         // OTS-218: detectors register themselves.
  78.         if (!(this instanceof LaneDetector))
  79.         {
  80.             this.lane.addLaneBasedObject(this); // implements OTS-218
  81.         }
  82.     }

  83.     /** {@inheritDoc} */
  84.     @Override
  85.     public final String getFullId()
  86.     {
  87.         return getLane().getFullId() + "." + super.getId();
  88.     }

  89.     /** {@inheritDoc} */
  90.     @Override
  91.     public final Lane getLane()
  92.     {
  93.         return this.lane;
  94.     }

  95.     /** {@inheritDoc} */
  96.     @Override
  97.     public final Length getLongitudinalPosition()
  98.     {
  99.         return this.longitudinalPosition;
  100.     }

  101.     /** {@inheritDoc} */
  102.     @Override
  103.     @SuppressWarnings("checkstyle:designforextension")
  104.     public DirectedPoint getLocation()
  105.     {
  106.         return this.location;
  107.     }

  108.     /** {@inheritDoc} */
  109.     @Override
  110.     @SuppressWarnings("checkstyle:designforextension")
  111.     public String toString()
  112.     {
  113.         return "LaneBasedObject[" + getId() + "]";
  114.     }

  115. }