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