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 @Override
134 protected final Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
135 final Length desiredHeadway, final PerceptionIterable<? extends Headway> leaders) throws ParameterException
136 {
137 if (leaders.isEmpty() || leaders.first().getDistance().gt(desiredHeadway))
138 {
139
140 double eff = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAFF) * parameters.getParameter(SIGMAFF);
141 return new Acceleration(parameters.getParameter(LAMBDAFF) * (desiredSpeed.si - speed.si) + eff,
142 AccelerationUnit.SI);
143 }
144
145 if (leaders.first().getSpeed().ge(speed))
146 {
147
148 double eCfAcc =
149 Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMAACC) * parameters.getParameter(SIGMAACC);
150
151 return new Acceleration(
152 parameters.getParameter(CCFACC)
153 * Math.pow(speed.si, parameters.getParameter(BETAACC))
154 * Math.pow(leaders.first().getDistance().si, parameters.getParameter(GAMMAACC))
155 * Math.pow(getDensity(leaders), parameters.getParameter(RHOACC))
156 * Math.pow(leaders.first().getSpeed().si - speed.si, parameters.getParameter(LAMBDAACC))
157 + eCfAcc,
158 AccelerationUnit.SI);
159
160 }
161
162 double eCfDec = Toledo.RANDOM.nextGaussian() * parameters.getParameter(SIGMADEC) * parameters.getParameter(SIGMADEC);
163
164 return new Acceleration(
165 parameters.getParameter(CCFDEC)
166 * Math.pow(leaders.first().getDistance().si, parameters.getParameter(GAMMADEC))
167 * Math.pow(getDensity(leaders), parameters.getParameter(RHODEC))
168 * Math.pow(speed.si - leaders.first().getSpeed().si, parameters.getParameter(LAMBDADEC))
169 + eCfDec,
170 AccelerationUnit.SI);
171
172 }
173
174 @Override
175 public final String getName()
176 {
177 return "ToledoCFM";
178 }
179
180 @Override
181 public final String getLongName()
182 {
183 return "Toledo car-following model";
184 }
185
186
187
188
189
190
191 private double getDensity(final PerceptionIterable<? extends Headway> leaders)
192 {
193 if (leaders.isEmpty())
194 {
195 return 0;
196 }
197 Headway last = null;
198 int n = 0;
199 for (Headway next : leaders)
200 {
201 n++;
202 last = next;
203 }
204 return last.getDistance().getInUnit(LengthUnit.KILOMETER) / n;
205 }
206
207 }