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