View Javadoc
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   * Task class that translates a (composite) headway in to a task demand.
22   * <p>
23   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
24   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
25   * <p>
26   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 25 jun. 2018 <br>
27   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
28   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
29   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
30   */
31  public abstract class TaskHeadwayBased extends AbstractTask
32  {
33  
34      /**
35       * Constructor.
36       * @param id String; id
37       */
38      public TaskHeadwayBased(final String id)
39      {
40          super(id);
41      }
42  
43      /** Current speed. */
44      private Speed speed;
45  
46      /** {@inheritDoc} */
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; // no task demand
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       * Returns the current speed to translate a distance headway to a time headway.
68       * @return Speed; speed
69       */
70      protected Speed getSpeed()
71      {
72          return this.speed;
73      }
74  
75      /**
76       * Returns a collector for the task demand.
77       * @param perception LanePerception; perception
78       * @param gtu LaneBasedGTU; gtu
79       * @param parameters Parameters; parameters
80       * @return Duration; headway, {@code null} of none.
81       * @throws ParameterException on invalid parameter
82       */
83      protected abstract Duration getHeadway(LanePerception perception, LaneBasedGTU gtu, Parameters parameters)
84              throws ParameterException;
85  
86      /**
87       * Simple collector implementation to obtain time headway.
88       * <p>
89       * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
90       * <br>
91       * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
92       * <p>
93       * @version $Revision$, $LastChangedDate$, by $Author$, initial version 3 apr. 2018 <br>
94       * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
95       * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
96       * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
97       */
98      public static class TaskHeadwayCollector implements PerceptionCollector<Duration, LaneBasedGTU, Duration>
99      {
100 
101         /** Own speed. */
102         private final Speed speed;
103 
104         /**
105          * Constructor.
106          * @param speed Speed; speed
107          */
108         public TaskHeadwayCollector(final Speed speed)
109         {
110             this.speed = speed;
111         }
112 
113         /** {@inheritDoc} */
114         @Override
115         public Supplier<Duration> getIdentity()
116         {
117             return new Supplier<Duration>()
118             {
119                 @Override
120                 public Duration get()
121                 {
122                     return null; // if no leader
123                 }
124             };
125         }
126 
127         /** {@inheritDoc} */
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(); // need only 1 leader
140                     return intermediate;
141                 }
142             };
143         }
144 
145         /** {@inheritDoc} */
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 }