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.djutils.exceptions.Try;
9 import org.opentrafficsim.base.parameters.ParameterException;
10 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
11 import org.opentrafficsim.base.parameters.ParameterTypes;
12 import org.opentrafficsim.base.parameters.Parameters;
13 import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
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.neighbors.NeighborsPerception;
20 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
21
22
23
24
25
26
27
28
29
30
31
32 public interface Tailgating
33 {
34
35
36 ParameterTypeDouble RHO = new ParameterTypeDouble("rho", "Social pressure", 0.0, ConstraintInterface.UNITINTERVAL);
37
38
39 Tailgating NONE = new Tailgating()
40 {
41
42 @Override
43 public void tailgate(final LanePerception perception, final Parameters parameters)
44 {
45
46 }
47
48
49 @Override
50 public String toString()
51 {
52 return "NONE";
53 }
54 };
55
56
57 Tailgating RHO_ONLY = new Tailgating()
58 {
59
60 @Override
61 public void tailgate(final LanePerception perception, final Parameters parameters)
62 {
63 PerceptionCollectable<HeadwayGtu, LaneBasedGtu> leaders =
64 perception.getPerceptionCategoryOrNull(NeighborsPerception.class).getLeaders(RelativeLane.CURRENT);
65 if (leaders == null || leaders.isEmpty())
66 {
67 return;
68 }
69 try
70 {
71 Speed speed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
72 Speed vCong = parameters.getParameter(ParameterTypes.VCONG);
73 Length x0 = parameters.getParameter(ParameterTypes.LOOKAHEAD);
74 Speed vGain = parameters.getParameter(LmrsParameters.VGAIN);
75 HeadwayGtu leader = leaders.first();
76 Speed desiredSpeed = Try.assign(() -> perception.getGtu().getDesiredSpeed(), "Could not obtain the GTU.");
77 double rho = socialPressure(speed, vCong, desiredSpeed, leader.getSpeed(), vGain, leader.getDistance(), x0);
78 parameters.setParameter(RHO, rho);
79 }
80 catch (ParameterException exception)
81 {
82 throw new RuntimeException("Could not obtain or set parameter value.", exception);
83 }
84 }
85
86
87 @Override
88 public String toString()
89 {
90 return "RHO_ONLY";
91 }
92 };
93
94
95 Tailgating PRESSURE = new Tailgating()
96 {
97
98 @Override
99 public void tailgate(final LanePerception perception, final Parameters parameters)
100 {
101 PerceptionCollectable<HeadwayGtu, LaneBasedGtu> leaders =
102 perception.getPerceptionCategoryOrNull(NeighborsPerception.class).getLeaders(RelativeLane.CURRENT);
103 if (leaders == null || leaders.isEmpty())
104 {
105 return;
106 }
107 try
108 {
109 Speed speed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
110 Speed vCong = parameters.getParameter(ParameterTypes.VCONG);
111 Duration t = parameters.getParameter(ParameterTypes.T);
112 Duration tMin = parameters.getParameter(ParameterTypes.TMIN);
113 Duration tMax = parameters.getParameter(ParameterTypes.TMAX);
114 Length x0 = parameters.getParameter(ParameterTypes.LOOKAHEAD);
115 Speed vGain = parameters.getParameter(LmrsParameters.VGAIN);
116 HeadwayGtu leader = leaders.first();
117 Speed desiredSpeed = Try.assign(() -> perception.getGtu().getDesiredSpeed(), "Could not obtain the GTU.");
118 double rho = socialPressure(speed, vCong, desiredSpeed, leader.getSpeed(), vGain, leader.getDistance(), x0);
119 parameters.setParameter(RHO, rho);
120 double tNew = rho * tMin.si + (1.0 - rho) * tMax.si;
121 if (tNew < t.si)
122 {
123 parameters.setParameter(ParameterTypes.T, Duration.instantiateSI(tNew));
124 }
125 }
126 catch (ParameterException exception)
127 {
128 throw new RuntimeException("Could not obtain or set parameter value.", exception);
129 }
130 }
131
132
133 @Override
134 public String toString()
135 {
136 return "PRESSURE";
137 }
138 };
139
140
141
142
143
144
145
146
147
148
149
150
151 static double socialPressure(final Speed speed, final Speed vCong, final Speed desiredSpeed, final Speed leaderSpeed,
152 final Speed vGain, final Length headway, final Length x0)
153 {
154 double dv = desiredSpeed.si - leaderSpeed.si;
155 if (dv < 0 || headway.gt(x0))
156 {
157 return 0.0;
158 }
159 return 1.0 - Math.exp(-(dv / vGain.si) * (1.0 - (headway.si / x0.si)));
160 }
161
162
163
164
165
166
167 void tailgate(LanePerception perception, Parameters parameters);
168
169 }