1 package org.opentrafficsim.road.gtu.lane.perception.mental;
2
3 import static org.opentrafficsim.base.parameters.constraint.NumericConstraint.POSITIVE;
4 import static org.opentrafficsim.base.parameters.constraint.NumericConstraint.POSITIVEZERO;
5
6 import java.util.LinkedHashMap;
7 import java.util.LinkedHashSet;
8 import java.util.Map;
9 import java.util.Set;
10
11 import org.djutils.exceptions.Throw;
12 import org.djutils.exceptions.Try;
13 import org.djutils.immutablecollections.Immutable;
14 import org.djutils.immutablecollections.ImmutableLinkedHashSet;
15 import org.djutils.immutablecollections.ImmutableSet;
16 import org.opentrafficsim.base.parameters.ParameterException;
17 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
18 import org.opentrafficsim.base.parameters.Parameters;
19 import org.opentrafficsim.core.gtu.GtuException;
20 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
21 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
22 import org.opentrafficsim.road.gtu.lane.perception.mental.TaskManager.SummativeTaskManager;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class Fuller implements Mental
46 {
47
48
49
50
51 public static final ParameterTypeDouble TC = new ParameterTypeDouble("TC", "Task capability", 1.0, POSITIVE);
52
53
54 public static final ParameterTypeDouble TS_CRIT =
55 new ParameterTypeDouble("TScrit", "Critical task saturation", 0.8, POSITIVEZERO)
56 {
57
58 private static final long serialVersionUID = 20180403L;
59
60 @Override
61 public void check(final Double value, final Parameters params) throws ParameterException
62 {
63 Double tsMax = params.getParameterOrNull(TS_MAX);
64 Throw.when(tsMax != null && value > tsMax, ParameterException.class,
65 "Value for TS_CRIT should not be larger than TS_MAX.");
66 }
67 };
68
69
70 public static final ParameterTypeDouble TS_MAX =
71 new ParameterTypeDouble("TSmax", "Maximum task saturation", 2.0, POSITIVEZERO)
72 {
73
74 private static final long serialVersionUID = 20180403L;
75
76 @Override
77 public void check(final Double value, final Parameters params) throws ParameterException
78 {
79 Double tsCrit = params.getParameterOrNull(TS_CRIT);
80 Throw.when(tsCrit != null && value < tsCrit, ParameterException.class,
81 "Value for TS_MAX should not be smaller than TS_CRIT.");
82 }
83 };
84
85
86 public static final ParameterTypeDouble TS = new ParameterTypeDouble("TS", "Task saturation", 0.0, POSITIVEZERO);
87
88
89
90
91 private final Set<Task> tasks;
92
93
94 private final Set<BehavioralAdaptation> behavioralAdapatations;
95
96
97 private final TaskManager taskManager;
98
99
100 private Map<String, Double> anticipationReliances = new LinkedHashMap<>();
101
102
103 private Map<String, Double> taskDemands = new LinkedHashMap<>();
104
105
106
107
108
109
110 public Fuller(final Set<? extends Task> tasks, final Set<BehavioralAdaptation> behavioralAdapatations)
111 {
112 this(tasks, behavioralAdapatations, new SummativeTaskManager());
113 }
114
115
116
117
118
119
120
121 public Fuller(final Set<? extends Task> tasks, final Set<BehavioralAdaptation> behavioralAdapatations,
122 final TaskManager taskManager)
123 {
124 Throw.whenNull(tasks, "Tasks may not be null.");
125 Throw.whenNull(behavioralAdapatations, "Behavioral adaptations may not be null.");
126 this.tasks = new LinkedHashSet<>();
127 this.tasks.addAll(tasks);
128 this.behavioralAdapatations = behavioralAdapatations;
129 this.taskManager = taskManager;
130 }
131
132
133
134
135
136 public void addTask(final Task task)
137 {
138 this.tasks.add(task);
139 }
140
141
142
143
144
145 public void removeTask(final Task task)
146 {
147 this.tasks.remove(task);
148 }
149
150
151
152
153
154 public ImmutableSet<Task> getTasks()
155 {
156 return new ImmutableLinkedHashSet<>(this.tasks, Immutable.WRAP);
157 }
158
159 @Override
160 public void apply(final LanePerception perception) throws ParameterException, GtuException
161 {
162 LaneBasedGtu gtu = Try.assign(() -> perception.getGtu(), "Could not obtain GTU.");
163 Parameters parameters = gtu.getParameters();
164 double taskDemand = 0.0;
165
166
167 this.taskManager.manage(this.tasks, perception, gtu, parameters);
168 this.anticipationReliances.clear();
169 this.taskDemands.clear();
170 for (Task task : this.tasks)
171 {
172 double ar = task.getAnticipationReliance();
173 double td = task.getTaskDemand();
174 this.anticipationReliances.put(task.getId(), ar);
175 this.taskDemands.put(task.getId(), td);
176 taskDemand += (td - ar);
177 }
178 double taskSaturation = taskDemand / parameters.getParameter(TC);
179 parameters.setParameter(TS, taskSaturation);
180
181 for (BehavioralAdaptation behavioralAdapatation : this.behavioralAdapatations)
182 {
183 behavioralAdapatation.adapt(parameters, taskSaturation);
184 }
185
186
187
188 }
189
190
191
192
193
194
195 public double getAnticipationReliance(final String taskId)
196 {
197 return this.anticipationReliances.getOrDefault(taskId, Double.NaN);
198 }
199
200
201
202
203
204
205 public double getTaskDemand(final String taskId)
206 {
207 return this.taskDemands.getOrDefault(taskId, Double.NaN);
208 }
209
210 @Override
211 public String toString()
212 {
213 return "Fuller [tasks=" + this.tasks + ", behavioralAdapatations=" + this.behavioralAdapatations + "]";
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227 @FunctionalInterface
228 public interface BehavioralAdaptation
229 {
230
231
232
233
234
235
236 void adapt(Parameters parameters, double taskSaturation) throws ParameterException;
237 }
238
239 }