View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.util.LinkedHashMap;
4   import java.util.List;
5   import java.util.Set;
6   
7   import org.djunits.value.vdouble.scalar.Speed;
8   import org.djutils.draw.line.Polygon2d;
9   import org.opentrafficsim.core.geometry.OtsLine2d;
10  import org.opentrafficsim.core.gtu.GtuType;
11  import org.opentrafficsim.core.network.LateralDirectionality;
12  import org.opentrafficsim.core.network.NetworkException;
13  import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
14  
15  /**
16   * This class is mostly the same as a Lane. But as a shoulder it can be recognized by algorithms and models to be responded to
17   * differently.
18   * <p>
19   * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
20   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
21   * </p>
22   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
23   */
24  public class Shoulder extends Lane
25  {
26  
27      /** */
28      private static final long serialVersionUID = 20240507L;
29  
30      /**
31       * Constructor specifying geometry.
32       * @param link CrossSectionLink; link.
33       * @param id String; the id of this lane within the link; should be unique within the link.
34       * @param centerLine OtsLine2d; center line.
35       * @param contour Polygon2d; contour shape.
36       * @param crossSectionSlices List&lt;CrossSectionSlice&gt;; cross-section slices.
37       * @param laneType LaneType; lane type.
38       * @throws NetworkException when no cross-section slice is defined.
39       */
40      public Shoulder(final CrossSectionLink link, final String id, final OtsLine2d centerLine, final Polygon2d contour,
41              final List<CrossSectionSlice> crossSectionSlices, final LaneType laneType) throws NetworkException
42      {
43          super(link, id, centerLine, contour, crossSectionSlices, laneType, new LinkedHashMap<>());
44      }
45  
46      /**
47       * Returns one adjacent lane.
48       * @param laneChangeDirection LateralDirectionality; lane change direction
49       * @param gtuType GtuType; GTU type.
50       * @return Lane; adjacent lane, {@code null} if none
51       */
52      @Override
53      public Lane getAdjacentLane(final LateralDirectionality laneChangeDirection, final GtuType gtuType)
54      {
55          Set<Lane> adjLanes = accessibleAdjacentLanesPhysical(laneChangeDirection, gtuType);
56          if (!adjLanes.isEmpty())
57          {
58              return adjLanes.iterator().next();
59          }
60          return null;
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public double getZ()
66      {
67          return -0.00005;
68      }
69  
70      /** {@inheritDoc} */
71      @Override
72      public Speed getSpeedLimit(final GtuType gtuType) throws NetworkException
73      {
74          LateralDirectionality[] lats = getLink().getLaneKeepingPolicy().equals(LaneKeepingPolicy.KEEPRIGHT)
75                  ? new LateralDirectionality[] {LateralDirectionality.RIGHT, LateralDirectionality.LEFT}
76                  : new LateralDirectionality[] {LateralDirectionality.LEFT, LateralDirectionality.RIGHT};
77          for (LateralDirectionality lat : lats)
78          {
79              Lane adjacentLane = getAdjacentLane(lat, gtuType);
80              if (adjacentLane != null)
81              {
82                  return adjacentLane.getSpeedLimit(gtuType);
83              }
84          }
85          return Speed.ZERO;
86      }
87  }