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 public class ToledoCarFollowing extends AbstractCarFollowingModel
34 {
35
36
37 public static final ParameterTypeSpeed CDS = new ParameterTypeSpeed("C_DS", "Constant in desired speed.",
38 new Speed(17.636, SpeedUnit.SI), ConstraintInterface.POSITIVE);
39
40
41 public static final ParameterTypeSpeed BETADS = new ParameterTypeSpeed("BETA_DS", "Reduction of desired speed for trucks.",
42 new Speed(-1.458, SpeedUnit.SI), ConstraintInterface.NEGATIVE);
43
44
45 public static final ParameterTypeSpeed ALPHADS =
46 new ParameterTypeSpeed("ALPHA_DS", "Factor on error term of desired speed.", new Speed(-0.105, SpeedUnit.SI));
47
48
49 public static final ParameterTypeDuration HSTAR =
50 new ParameterTypeDuration("h*", "Desired time headway.", new Duration(2.579, DurationUnit.SI));
51
52
53 public static final ParameterTypeDouble LAMBDAFF =
54 new ParameterTypeDouble("Lambda_ff", "Free flow acceleration sensitivity.", 0.0881, ConstraintInterface.POSITIVE);
55
56
57 public static final ParameterTypeDouble SIGMAFF =
58 new ParameterTypeDouble("Sigma_ff", "Free flow acceleration standard deviation.", Math.exp(0.169));
59
60
61 public static final ParameterTypeDouble CCFACC = new ParameterTypeDouble("C_CF_ACC",
62 "Constant for car following acceleration.", 0.0355, ConstraintInterface.POSITIVE);
63
64
65 public static final ParameterTypeDouble BETAACC =
66 new ParameterTypeDouble("BETA_ACC", "Power on speed for acceleration.", 0.291, ConstraintInterface.POSITIVE);
67
68
69 public static final ParameterTypeDouble GAMMAACC = new ParameterTypeDouble("GAMMA_ACC",
70 "Power on distance headway for acceleration.", -0.166, ConstraintInterface.NEGATIVE);
71
72
73 public static final ParameterTypeDouble RHOACC =
74 new ParameterTypeDouble("RHO_ACC", "Power on density for acceleration.", 0.550, ConstraintInterface.POSITIVE);
75
76
77 public static final ParameterTypeDouble LAMBDAACC = new ParameterTypeDouble("LAMBDA_ACC",
78 "Power on speed difference for acceleration.", 0.520, ConstraintInterface.POSITIVE);
79
80
81 public static final ParameterTypeDouble SIGMAACC =
82 new ParameterTypeDouble("Sigma_acc", "Car-following acceleration standard deviation.", Math.exp(0.126));
83
84
85 public static final ParameterTypeDouble CCFDEC = new ParameterTypeDouble("C_CF_DEC",
86 "Constant for car following deceleration.", -0.860, ConstraintInterface.NEGATIVE);
87
88
89 public static final ParameterTypeDouble GAMMADEC = new ParameterTypeDouble("GAMMA_DEC",
90 "Power on distance headway for deceleration.", -0.565, ConstraintInterface.NEGATIVE);
91
92
93 public static final ParameterTypeDouble RHODEC =
94 new ParameterTypeDouble("RHO_DEC", "Power on density for deceleration.", 0.143, ConstraintInterface.POSITIVE);
95
96
97 public static final ParameterTypeDouble LAMBDADEC = new ParameterTypeDouble("LAMBDA_DEC",
98 "Power on speed difference for deceleration.", 0.834, ConstraintInterface.POSITIVE);
99
100
101 public static final ParameterTypeDouble SIGMADEC =
102 new ParameterTypeDouble("Sigma_DEC", "Car-following deceleration standard deviation.", Math.exp(0.156));
103
104
105 private static final DesiredHeadwayModel HEADWAY = new DesiredHeadwayModel()
106 {
107 @Override
108 public Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
109 {
110 return parameters.getParameter(HSTAR).times(speed);
111 }
112 };
113
114
115 private static final DesiredSpeedModel DESIRED_SPEED = new DesiredSpeedModel()
116 {
117 @Override
118 public Speed desiredSpeed(final Parameters parameters, final SpeedLimitInfo speedInfo) throws ParameterException
119 {
120 return parameters.getParameter(CDS).plus(parameters.getParameter(BETADS)).plus(
121 parameters.getParameter(ALPHADS).times(parameters.getParameter(ToledoLaneChangeParameters.ERROR_TERM)));
122 }
123 };
124
125
126
127
128 public ToledoCarFollowing()
129 {
130 super(HEADWAY, DESIRED_SPEED);
131 }
132
133
134 @Override
135 protected final Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
136 final Length desiredHeadway, final PerceptionIterable<? extends Headway> leaders) throws ParameterException
137 {
138 if (leaders.isEmpty() || leaders.first().getDistance().gt(desiredHeadway))
139 {
140
141 double eff = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAFF) * parameters.getParameter(SIGMAFF);
142 return new Acceleration(parameters.getParameter(LAMBDAFF) * (desiredSpeed.si - speed.si) + eff,
143 AccelerationUnit.SI);
144 }
145
146 if (leaders.first().getSpeed().ge(speed))
147 {
148
149 double eCfAcc =
150 Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAACC) * parameters.getParameter(SIGMAACC);
151
152 return new Acceleration(
153 parameters.getParameter(CCFACC)
154 * Math.pow(speed.si, parameters.getParameter(BETAACC))
155 * Math.pow(leaders.first().getDistance().si, parameters.getParameter(GAMMAACC))
156 * Math.pow(getDensity(leaders), parameters.getParameter(RHOACC))
157 * Math.pow(leaders.first().getSpeed().si - speed.si, parameters.getParameter(LAMBDAACC))
158 + eCfAcc,
159 AccelerationUnit.SI);
160
161 }
162
163 double eCfDec = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMADEC) * parameters.getParameter(SIGMADEC);
164
165 return new Acceleration(
166 parameters.getParameter(CCFDEC)
167 * Math.pow(leaders.first().getDistance().si, parameters.getParameter(GAMMADEC))
168 * Math.pow(getDensity(leaders), parameters.getParameter(RHODEC))
169 * Math.pow(speed.si - leaders.first().getSpeed().si, parameters.getParameter(LAMBDADEC))
170 + eCfDec,
171 AccelerationUnit.SI);
172
173 }
174
175
176 @Override
177 public final String getName()
178 {
179 return "ToledoCFM";
180 }
181
182
183 @Override
184 public final String getLongName()
185 {
186 return "Toledo car-following model";
187 }
188
189
190
191
192
193
194 private double getDensity(final PerceptionIterable<? extends Headway> leaders)
195 {
196 if (leaders.isEmpty())
197 {
198 return 0;
199 }
200 Headway last = null;
201 int n = 0;
202 for (Headway next : leaders)
203 {
204 n++;
205 last = next;
206 }
207 return last.getDistance().getInUnit(LengthUnit.KILOMETER) / n;
208 }
209
210 }