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