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