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
26
27
28
29
30
31
32
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
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
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
128
129 public ToledoCarFollowing()
130 {
131 super(HEADWAY, DESIRED_SPEED);
132 }
133
134
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
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
147 if (leaders.first().getSpeed().ge(speed))
148 {
149
150 double eCfAcc =
151 Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAACC) * parameters.getParameter(SIGMAACC);
152
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
162 }
163
164 double eCfDec = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMADEC) * parameters.getParameter(SIGMADEC);
165
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
174 }
175
176
177 @Override
178 public final String getName()
179 {
180 return "ToledoCFM";
181 }
182
183
184 @Override
185 public final String getLongName()
186 {
187 return "Toledo car-following model";
188 }
189
190
191
192
193
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 }