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