View Javadoc
1   package org.opentrafficsim.road.gtu.perception.mental;
2   
3   import static org.opentrafficsim.base.parameters.constraint.NumericConstraint.POSITIVEZERO;
4   
5   import java.util.LinkedHashMap;
6   import java.util.LinkedHashSet;
7   import java.util.Map;
8   import java.util.Optional;
9   import java.util.Set;
10  
11  import org.djutils.exceptions.Throw;
12  import org.djutils.immutablecollections.Immutable;
13  import org.djutils.immutablecollections.ImmutableLinkedHashSet;
14  import org.djutils.immutablecollections.ImmutableSet;
15  import org.opentrafficsim.base.parameters.ParameterException;
16  import org.opentrafficsim.base.parameters.ParameterTypeDouble;
17  import org.opentrafficsim.base.parameters.Parameters;
18  import org.opentrafficsim.road.gtu.perception.LanePerception;
19  
20  /**
21   * Task-capability interface in accordance to Fuller (2011). Task demand is the sum of demands described by individual
22   * {@code Task}s. These take exogenous information to describe the workload in fundamental relations. Task demand is divided by
23   * task capability to arrive at a task saturation. Task saturation is input to {@code BehavioralAdaptation}s which alter
24   * parameters describing personal traits, such as desired headway and desired speed. In this way, task demand is kept at an
25   * equilibrium as described by Fuller.
26   * <p>
27   * A {@code BehavioralAdaptation} may also determine what the level of situational awareness is, which includes determining
28   * reaction time. Both situational awareness and reaction time parameters can be used in perception to model deteriorated
29   * perception due to a task demand imbalance.
30   * <p>
31   * Fuller, R., Driver control theory: From task difficulty homeostasis to risk allostasis, in Handbook of Traffic Psychology.
32   * 2011. p. 13-26
33   * <p>
34   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
35   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
36   * </p>
37   * @author Alexander Verbraeck
38   * @author Peter Knoppers
39   * @author Wouter Schakel
40   * @param <T> task type
41   */
42  public class SumFuller<T extends Task> extends Fuller
43  {
44  
45      /** Critical task saturation. */
46      public static final ParameterTypeDouble TS_CRIT =
47              new ParameterTypeDouble("TScrit", "Critical task saturation", 0.8, POSITIVEZERO)
48              {
49                  @Override
50                  public void check(final Double value, final Parameters params) throws ParameterException
51                  {
52                      Optional<Double> tsMax = params.getOptionalParameter(TS_MAX);
53                      Throw.when(tsMax.isPresent() && value > tsMax.get(), ParameterException.class,
54                              "Value for TS_CRIT should not be larger than TS_MAX.");
55                  }
56              };
57  
58      /** Maximum task saturation, pertaining to maximum deterioration. */
59      public static final ParameterTypeDouble TS_MAX =
60              new ParameterTypeDouble("TSmax", "Maximum task saturation", 2.0, POSITIVEZERO)
61              {
62                  @Override
63                  public void check(final Double value, final Parameters params) throws ParameterException
64                  {
65                      Optional<Double> tsCrit = params.getOptionalParameter(TS_CRIT);
66                      Throw.when(tsCrit.isPresent() && value < tsCrit.get(), ParameterException.class,
67                              "Value for TS_MAX should not be smaller than TS_CRIT.");
68                  }
69              };
70  
71      /** Tasks causing task demand. */
72      private final Set<T> tasks;
73  
74      /** Map of tasks as derived from suppliers. */
75      private final Map<String, T> taskMap;
76  
77      /**
78       * Constructor with custom situational awareness.
79       * @param tasks tasks
80       * @param behavioralAdapatations behavioralAdapatations
81       */
82      public SumFuller(final Set<T> tasks, final Set<BehavioralAdaptation> behavioralAdapatations)
83      {
84          super(behavioralAdapatations);
85          Throw.whenNull(tasks, "Tasks may not be null.");
86          this.tasks = new LinkedHashSet<>();
87          this.tasks.addAll(tasks);
88          this.taskMap = new LinkedHashMap<>();
89          tasks.forEach((t) -> this.taskMap.put(t.getId(), t));
90      }
91  
92      @Override
93      protected double getTotalTaskDemand(final LanePerception perception) throws ParameterException
94      {
95          double taskDemand = 0.0;
96          for (T task : this.tasks)
97          {
98              taskDemand += task.getTaskDemand(perception);
99          }
100         return taskDemand;
101     }
102 
103     /**
104      * Adds a task.
105      * @param task task to add
106      */
107     public void addTask(final T task)
108     {
109         this.tasks.add(task);
110     }
111 
112     /**
113      * Removes a task.
114      * @param task task to remove
115      */
116     public void removeTask(final T task)
117     {
118         this.tasks.remove(task);
119     }
120 
121     @Override
122     public ImmutableSet<T> getTasks()
123     {
124         return new ImmutableLinkedHashSet<>(this.tasks, Immutable.WRAP);
125     }
126 
127     @Override
128     public Optional<Task> getTask(final String taskId)
129     {
130         return Optional.ofNullable(this.taskMap.get(taskId));
131     }
132 
133     @Override
134     public String toString()
135     {
136         return "SumFuller [tasks=" + this.tasks + "]";
137     }
138 
139 }