View Javadoc
1   package org.opentrafficsim.road.gtu.tactical.following;
2   
3   import org.djunits.unit.AccelerationUnit;
4   import org.djunits.value.vdouble.scalar.Acceleration;
5   import org.djunits.value.vdouble.scalar.Length;
6   import org.djunits.value.vdouble.scalar.Speed;
7   import org.djutils.exceptions.Throw;
8   import org.opentrafficsim.base.parameters.ParameterException;
9   import org.opentrafficsim.base.parameters.Parameters;
10  import org.opentrafficsim.road.gtu.LaneBasedGtu;
11  import org.opentrafficsim.road.gtu.perception.PerceptionIterable;
12  import org.opentrafficsim.road.gtu.perception.object.PerceivedObject;
13  import org.opentrafficsim.road.network.speed.SpeedLimits;
14  
15  /**
16   * Default implementation where desired speed and headway are pre-calculated for car-following.
17   * <p>
18   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
19   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
20   * </p>
21   * @author Wouter Schakel
22   */
23  public abstract class AbstractCarFollowingModel implements CarFollowingModel
24  {
25  
26      /** Desired headway model. */
27      private DesiredHeadwayModel desiredHeadwayModel;
28  
29      /** Desired speed model. */
30      private DesiredSpeedModel desiredSpeedModel;
31  
32      /**
33       * Constructor.
34       * @param desiredHeadwayModel desired headway model
35       * @param desiredSpeedModel desired speed model
36       */
37      public AbstractCarFollowingModel(final DesiredHeadwayModel desiredHeadwayModel, final DesiredSpeedModel desiredSpeedModel)
38      {
39          this.desiredHeadwayModel = desiredHeadwayModel;
40          this.desiredSpeedModel = desiredSpeedModel;
41      }
42  
43      @Override
44      public final Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
45      {
46          Throw.whenNull(parameters, "Parameters may not be null.");
47          Throw.whenNull(speed, "Speed may not be null.");
48          return this.desiredHeadwayModel.desiredHeadway(parameters, speed);
49      }
50  
51      @Override
52      public final Speed desiredSpeed(final Parameters parameters, final SpeedLimits speedLimits, final Speed maxVehicleSpeed)
53              throws ParameterException
54      {
55          return this.desiredSpeedModel.desiredSpeed(parameters, speedLimits, maxVehicleSpeed);
56      }
57  
58      @Override
59      public final Acceleration followingAcceleration(final Parameters parameters, final Speed speed,
60              final SpeedLimits speedLimits, final Speed maxVehicleSpeed,
61              final PerceptionIterable<? extends PerceivedObject> leaders) throws ParameterException
62      {
63          // Catch negative headway
64          if (!leaders.isEmpty() && leaders.first().getDistance().si <= 0)
65          {
66              return new Acceleration(Double.NEGATIVE_INFINITY, AccelerationUnit.SI);
67          }
68          // Forward to method with desired speed and headway predetermined by this car-following model.
69          Acceleration acc = followingAcceleration(parameters, speed, desiredSpeed(parameters, speedLimits, maxVehicleSpeed),
70                  desiredHeadway(parameters, speed), leaders);
71          return acc;
72      }
73  
74      /**
75       * Sets the desired speed model.
76       * @param model new model
77       * @return the model that was set before this method was called
78       */
79      public DesiredSpeedModel setDesiredSpeedModel(final DesiredSpeedModel model)
80      {
81          DesiredSpeedModel old = this.desiredSpeedModel;
82          this.desiredSpeedModel = model;
83          return old;
84      }
85  
86      /**
87       * Determination of car-following acceleration, possibly based on multiple leaders.
88       * @param parameters parameters
89       * @param speed current speed
90       * @param desiredSpeed desired speed
91       * @param desiredHeadway desired headway
92       * @param leaders set of leader headways (guaranteed positive) and speeds, ordered by headway (closest first)
93       * @return car-following acceleration
94       * @throws ParameterException if parameter exception occurs
95       */
96      protected abstract Acceleration followingAcceleration(Parameters parameters, Speed speed, Speed desiredSpeed,
97              Length desiredHeadway, PerceptionIterable<? extends PerceivedObject> leaders) throws ParameterException;
98  
99      @SuppressWarnings("checkstyle:designforextension")
100     @Override
101     public String toString()
102     {
103         return getLongName();
104     }
105 
106     @Override
107     public final void init(final LaneBasedGtu gtu)
108     {
109         if (this.desiredHeadwayModel instanceof Initialisable initialisable)
110         {
111             initialisable.init(gtu);
112         }
113         if (this.desiredSpeedModel instanceof Initialisable initialisable)
114         {
115             initialisable.init(gtu);
116         }
117     }
118 
119 }