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