View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.toledo;
2   
3   import org.djunits.unit.AccelerationUnit;
4   import org.djunits.unit.DurationUnit;
5   import org.djunits.unit.LengthUnit;
6   import org.djunits.unit.SpeedUnit;
7   import org.djunits.value.vdouble.scalar.Acceleration;
8   import org.djunits.value.vdouble.scalar.Duration;
9   import org.djunits.value.vdouble.scalar.Length;
10  import org.djunits.value.vdouble.scalar.Speed;
11  import org.opentrafficsim.base.parameters.ParameterException;
12  import org.opentrafficsim.base.parameters.ParameterTypeDouble;
13  import org.opentrafficsim.base.parameters.ParameterTypeDuration;
14  import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
15  import org.opentrafficsim.base.parameters.Parameters;
16  import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
17  import org.opentrafficsim.road.gtu.lane.perception.PerceptionIterable;
18  import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
19  import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractCarFollowingModel;
20  import org.opentrafficsim.road.gtu.lane.tactical.following.DesiredHeadwayModel;
21  import org.opentrafficsim.road.gtu.lane.tactical.following.DesiredSpeedModel;
22  import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
23  
24  /**
25   * <p>
26   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
27   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
28   * <p>
29   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Jul 7, 2016 <br>
30   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
31   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
32   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
33   */
34  public class ToledoCarFollowing extends AbstractCarFollowingModel
35  {
36  
37      /** */
38      public static final ParameterTypeSpeed CDS = new ParameterTypeSpeed("C_DS", "Constant in desired speed.",
39              new Speed(17.636, SpeedUnit.SI), ConstraintInterface.POSITIVE);
40  
41      /** */
42      public static final ParameterTypeSpeed BETADS = new ParameterTypeSpeed("BETA_DS", "Reduction of desired speed for trucks.",
43              new Speed(-1.458, SpeedUnit.SI), ConstraintInterface.NEGATIVE);
44  
45      /** */
46      public static final ParameterTypeSpeed ALPHADS =
47              new ParameterTypeSpeed("ALPHA_DS", "Factor on error term of desired speed.", new Speed(-0.105, SpeedUnit.SI));
48  
49      /** */
50      public static final ParameterTypeDuration HSTAR =
51              new ParameterTypeDuration("h*", "Desired time headway.", new Duration(2.579, DurationUnit.SI));
52  
53      /** */
54      public static final ParameterTypeDouble LAMBDAFF =
55              new ParameterTypeDouble("Lambda_ff", "Free flow acceleration sensitivity.", 0.0881, ConstraintInterface.POSITIVE);
56  
57      /** */
58      public static final ParameterTypeDouble SIGMAFF =
59              new ParameterTypeDouble("Sigma_ff", "Free flow acceleration standard deviation.", Math.exp(0.169));
60  
61      /** */
62      public static final ParameterTypeDouble CCFACC = new ParameterTypeDouble("C_CF_ACC",
63              "Constant for car following acceleration.", 0.0355, ConstraintInterface.POSITIVE);
64  
65      /** */
66      public static final ParameterTypeDouble BETAACC =
67              new ParameterTypeDouble("BETA_ACC", "Power on speed for acceleration.", 0.291, ConstraintInterface.POSITIVE);
68  
69      /** */
70      public static final ParameterTypeDouble GAMMAACC = new ParameterTypeDouble("GAMMA_ACC",
71              "Power on distance headway for acceleration.", -0.166, ConstraintInterface.NEGATIVE);
72  
73      /** */
74      public static final ParameterTypeDouble RHOACC =
75              new ParameterTypeDouble("RHO_ACC", "Power on density for acceleration.", 0.550, ConstraintInterface.POSITIVE);
76  
77      /** */
78      public static final ParameterTypeDouble LAMBDAACC = new ParameterTypeDouble("LAMBDA_ACC",
79              "Power on speed difference for acceleration.", 0.520, ConstraintInterface.POSITIVE);
80  
81      /** */
82      public static final ParameterTypeDouble SIGMAACC =
83              new ParameterTypeDouble("Sigma_acc", "Car-following acceleration standard deviation.", Math.exp(0.126));
84  
85      /** */
86      public static final ParameterTypeDouble CCFDEC = new ParameterTypeDouble("C_CF_DEC",
87              "Constant for car following deceleration.", -0.860, ConstraintInterface.NEGATIVE);
88  
89      /** */
90      public static final ParameterTypeDouble GAMMADEC = new ParameterTypeDouble("GAMMA_DEC",
91              "Power on distance headway for deceleration.", -0.565, ConstraintInterface.NEGATIVE);
92  
93      /** */
94      public static final ParameterTypeDouble RHODEC =
95              new ParameterTypeDouble("RHO_DEC", "Power on density for deceleration.", 0.143, ConstraintInterface.POSITIVE);
96  
97      /** */
98      public static final ParameterTypeDouble LAMBDADEC = new ParameterTypeDouble("LAMBDA_DEC",
99              "Power on speed difference for deceleration.", 0.834, ConstraintInterface.POSITIVE);
100 
101     /** */
102     public static final ParameterTypeDouble SIGMADEC =
103             new ParameterTypeDouble("Sigma_DEC", "Car-following deceleration standard deviation.", Math.exp(0.156));
104 
105     /** Toledo desired headway model. */
106     private static final DesiredHeadwayModel HEADWAY = new DesiredHeadwayModel()
107     {
108         @Override
109         public Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
110         {
111             return parameters.getParameter(HSTAR).multiplyBy(speed);
112         }
113     };
114 
115     /** Toledo desired speed model. */
116     private static final DesiredSpeedModel DESIRED_SPEED = new DesiredSpeedModel()
117     {
118         @Override
119         public Speed desiredSpeed(final Parameters parameters, final SpeedLimitInfo speedInfo) throws ParameterException
120         {
121             return parameters.getParameter(CDS).plus(parameters.getParameter(BETADS)).plus(parameters.getParameter(ALPHADS)
122                     .multiplyBy(parameters.getParameter(ToledoLaneChangeParameters.ERROR_TERM)));
123         }
124     };
125 
126     /**
127      * Constructor using Toledo models for desired headway ans speed.
128      */
129     public ToledoCarFollowing()
130     {
131         super(HEADWAY, DESIRED_SPEED);
132     }
133 
134     /** {@inheritDoc} */
135     @Override
136     protected final Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
137             final Length desiredHeadway, final PerceptionIterable<? extends Headway> leaders) throws ParameterException
138     {
139         if (leaders.isEmpty() || leaders.first().getDistance().gt(desiredHeadway))
140         {
141             // free
142             double eff = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAFF) * parameters.getParameter(SIGMAFF);
143             return new Acceleration(parameters.getParameter(LAMBDAFF) * (desiredSpeed.si - speed.si) + eff,
144                     AccelerationUnit.SI);
145         }
146         // TODO speed difference with reaction time
147         if (leaders.first().getSpeed().ge(speed))
148         {
149             // accelerate
150             double eCfAcc =
151                     Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAACC) * parameters.getParameter(SIGMAACC);
152             // {@formatter:off}
153             return new Acceleration(
154                 parameters.getParameter(CCFACC) 
155                     * Math.pow(speed.si, parameters.getParameter(BETAACC))
156                     * Math.pow(leaders.first().getDistance().si, parameters.getParameter(GAMMAACC))
157                     * Math.pow(getDensity(leaders), parameters.getParameter(RHOACC))
158                     * Math.pow(leaders.first().getSpeed().si - speed.si, parameters.getParameter(LAMBDAACC))
159                     + eCfAcc,
160                 AccelerationUnit.SI);
161             // {@formatter:on}
162         }
163         // decelerate
164         double eCfDec = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMADEC) * parameters.getParameter(SIGMADEC);
165         // {@formatter:off}
166         return new Acceleration(
167             parameters.getParameter(CCFDEC) 
168                 * Math.pow(leaders.first().getDistance().si, parameters.getParameter(GAMMADEC))
169                 * Math.pow(getDensity(leaders), parameters.getParameter(RHODEC))
170                 * Math.pow(speed.si - leaders.first().getSpeed().si, parameters.getParameter(LAMBDADEC))
171                 + eCfDec,
172             AccelerationUnit.SI);
173         // {@formatter:on}
174     }
175 
176     /** {@inheritDoc} */
177     @Override
178     public final String getName()
179     {
180         return "ToledoCFM";
181     }
182 
183     /** {@inheritDoc} */
184     @Override
185     public final String getLongName()
186     {
187         return "Toledo car-following model";
188     }
189 
190     /**
191      * Returns the density based on the leaders in veh/km.
192      * @param leaders PerceptionIterable&lt;? extends Headway&gt;; leading vehicles
193      * @return density based on the leaders in veh/km
194      */
195     private double getDensity(final PerceptionIterable<? extends Headway> leaders)
196     {
197         if (leaders.isEmpty())
198         {
199             return 0;
200         }
201         Headway last = null;
202         int n = 0;
203         for (Headway next : leaders)
204         {
205             n++;
206             last = next;
207         }
208         return last.getDistance().getInUnit(LengthUnit.KILOMETER) / n;
209     }
210 
211 }