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