View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
2   
3   import org.djunits.value.vdouble.scalar.Duration;
4   import org.djunits.value.vdouble.scalar.Length;
5   import org.djunits.value.vdouble.scalar.Speed;
6   import org.djutils.exceptions.Try;
7   import org.opentrafficsim.base.parameters.ParameterException;
8   import org.opentrafficsim.base.parameters.ParameterTypeDouble;
9   import org.opentrafficsim.base.parameters.ParameterTypes;
10  import org.opentrafficsim.base.parameters.Parameters;
11  import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
12  import org.opentrafficsim.core.gtu.perception.EgoPerception;
13  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
14  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
15  import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
16  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
17  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
18  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
19  
20  /**
21   * Interface for LMRS tailgating behavior.
22   * <p>
23   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
24   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
25   * <p>
26   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 7 mrt. 2018 <br>
27   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
28   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
29   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
30   */
31  public interface Tailgating
32  {
33  
34      /** Social pressure applied to the leader. */
35      ParameterTypeDouble RHO = new ParameterTypeDouble("rho", "Social pressure", 0.0, ConstraintInterface.UNITINTERVAL);
36  
37      /** No tailgating. */
38      Tailgating NONE = new Tailgating()
39      {
40          /** {@inheritDoc} */
41          @Override
42          public void tailgate(final LanePerception perception, final Parameters parameters)
43          {
44              //
45          }
46      };
47  
48      /** No tailgating, but social pressure exists. */
49      Tailgating RHO_ONLY = new Tailgating()
50      {
51          /** {@inheritDoc} */
52          @Override
53          public void tailgate(final LanePerception perception, final Parameters parameters)
54          {
55              PerceptionCollectable<HeadwayGTU, LaneBasedGTU> leaders =
56                      perception.getPerceptionCategoryOrNull(NeighborsPerception.class).getLeaders(RelativeLane.CURRENT);
57              if (leaders == null || leaders.isEmpty())
58              {
59                  return;
60              }
61              try
62              {
63                  Speed speed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
64                  Speed vCong = parameters.getParameter(ParameterTypes.VCONG);
65                  Length x0 = parameters.getParameter(ParameterTypes.LOOKAHEAD);
66                  Speed vGain = parameters.getParameter(LmrsParameters.VGAIN);
67                  HeadwayGTU leader = leaders.first();
68                  Speed desiredSpeed = Try.assign(() -> perception.getGtu().getDesiredSpeed(), "Could not obtain the GTU.");
69                  double rho = socialPressure(speed, vCong, desiredSpeed, leader.getSpeed(), vGain, leader.getDistance(), x0);
70                  parameters.setParameter(RHO, rho);
71              }
72              catch (ParameterException exception)
73              {
74                  throw new RuntimeException("Could not obtain or set parameter value.", exception);
75              }
76          }
77      };
78  
79      /** Tailgating based on speed pressure. */
80      Tailgating PRESSURE = new Tailgating()
81      {
82          /** {@inheritDoc} */
83          @Override
84          public void tailgate(final LanePerception perception, final Parameters parameters)
85          {
86              PerceptionCollectable<HeadwayGTU, LaneBasedGTU> leaders =
87                      perception.getPerceptionCategoryOrNull(NeighborsPerception.class).getLeaders(RelativeLane.CURRENT);
88              if (leaders == null || leaders.isEmpty())
89              {
90                  return;
91              }
92              try
93              {
94                  Speed speed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
95                  Speed vCong = parameters.getParameter(ParameterTypes.VCONG);
96                  Duration t = parameters.getParameter(ParameterTypes.T);
97                  Duration tMin = parameters.getParameter(ParameterTypes.TMIN);
98                  Duration tMax = parameters.getParameter(ParameterTypes.TMAX);
99                  Length x0 = parameters.getParameter(ParameterTypes.LOOKAHEAD);
100                 Speed vGain = parameters.getParameter(LmrsParameters.VGAIN);
101                 HeadwayGTU leader = leaders.first();
102                 Speed desiredSpeed = Try.assign(() -> perception.getGtu().getDesiredSpeed(), "Could not obtain the GTU.");
103                 double rho = socialPressure(speed, vCong, desiredSpeed, leader.getSpeed(), vGain, leader.getDistance(), x0);
104                 parameters.setParameter(RHO, rho);
105                 double tNew = rho * tMin.si + (1.0 - rho) * tMax.si;
106                 if (tNew < t.si)
107                 {
108                     parameters.setParameter(ParameterTypes.T, Duration.createSI(tNew));
109                 }
110             }
111             catch (ParameterException exception)
112             {
113                 throw new RuntimeException("Could not obtain or set parameter value.", exception);
114             }
115         }
116     };
117 
118     /**
119      * Returns a normalized social pressure, equal to (vDesired - vLead) / vGain.
120      * @param speed Speed; speed
121      * @param vCong Speed; speed indicating congestion
122      * @param desiredSpeed Speed; desired speed
123      * @param leaderSpeed Speed; leader speed
124      * @param vGain Speed; vGain parameter
125      * @param headway Length; headway to the leader
126      * @param x0 Length; anticipation distance
127      * @return normalized social pressure
128      */
129     static double socialPressure(final Speed speed, final Speed vCong, final Speed desiredSpeed, final Speed leaderSpeed,
130             final Speed vGain, final Length headway, final Length x0)
131     {
132         double dv = desiredSpeed.si - leaderSpeed.si;
133         if (dv < 0 || headway.gt(x0)) // larger headway may happen due to perception errors
134         {
135             return 0.0;
136         }
137         return 1.0 - Math.exp(-(dv / vGain.si) * (1.0 - (headway.si / x0.si)));
138     }
139 
140     /**
141      * Apply tailgating.
142      * @param perception LanePerception; perception
143      * @param parameters Parameters; parameters
144      */
145     void tailgate(LanePerception perception, Parameters parameters);
146 
147 }