1 package org.opentrafficsim.road.gtu.lane.perception.mental;
2
3 import java.util.function.Supplier;
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.ParameterTypes;
11 import org.opentrafficsim.base.parameters.Parameters;
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.Intermediate;
16 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable.PerceptionAccumulator;
17 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable.PerceptionCollector;
18 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable.PerceptionFinalizer;
19
20
21
22
23
24
25
26
27
28
29
30
31 public abstract class TaskHeadwayBased extends AbstractTask
32 {
33
34
35
36
37
38 public TaskHeadwayBased(final String id)
39 {
40 super(id);
41 }
42
43
44 private Speed speed;
45
46
47 @Override
48 public double calculateTaskDemand(final LanePerception perception, final LaneBasedGTU gtu, final Parameters parameters)
49 throws ParameterException
50 {
51 double a = gtu.getAcceleration().si;
52 double b = parameters.getParameter(ParameterTypes.B).si;
53 double tMin = parameters.getParameter(ParameterTypes.TMIN).si;
54 double hMin = a < -b ? (1.0 - (a + b) / (8.0 - b)) * tMin : tMin;
55 EgoPerception<?, ?> ego = perception.getPerceptionCategoryOrNull(EgoPerception.class);
56 Try.execute(() -> ego.updateSpeed(), "Could not update perception of ego speed.");
57 this.speed = ego.getSpeed();
58 Duration h = getHeadway(perception, gtu, parameters);
59 if (h == null)
60 {
61 return 0.0;
62 }
63 return h.si <= hMin ? 1.0 : (h.si > 3.0 ? 0.5 : 1.0 - (1.0 - 0.5) * (h.si - hMin) / (3.0 - hMin));
64 }
65
66
67
68
69
70 protected Speed getSpeed()
71 {
72 return this.speed;
73 }
74
75
76
77
78
79
80
81
82
83 protected abstract Duration getHeadway(LanePerception perception, LaneBasedGTU gtu, Parameters parameters)
84 throws ParameterException;
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public static class TaskHeadwayCollector implements PerceptionCollector<Duration, LaneBasedGTU, Duration>
99 {
100
101
102 private final Speed speed;
103
104
105
106
107
108 public TaskHeadwayCollector(final Speed speed)
109 {
110 this.speed = speed;
111 }
112
113
114 @Override
115 public Supplier<Duration> getIdentity()
116 {
117 return new Supplier<Duration>()
118 {
119 @Override
120 public Duration get()
121 {
122 return null;
123 }
124 };
125 }
126
127
128 @Override
129 public PerceptionAccumulator<LaneBasedGTU, Duration> getAccumulator()
130 {
131 return new PerceptionAccumulator<LaneBasedGTU, Duration>()
132 {
133 @SuppressWarnings("synthetic-access")
134 @Override
135 public Intermediate<Duration> accumulate(final Intermediate<Duration> intermediate, final LaneBasedGTU object,
136 final Length distance)
137 {
138 intermediate.setObject(distance.divideBy(TaskHeadwayCollector.this.speed));
139 intermediate.stop();
140 return intermediate;
141 }
142 };
143 }
144
145
146 @Override
147 public PerceptionFinalizer<Duration, Duration> getFinalizer()
148 {
149 return new PerceptionFinalizer<Duration, Duration>()
150 {
151 @Override
152 public Duration collect(final Duration intermediate)
153 {
154 return intermediate == null ? intermediate : (intermediate.gt0() ? intermediate : Duration.ZERO);
155 }
156 };
157 }
158
159 }
160
161 }