View Javadoc
1   package org.opentrafficsim.road.gtu.lane.perception.categories.neighbors;
2   
3   import org.djunits.value.vdouble.scalar.Duration;
4   import org.djunits.value.vdouble.scalar.Length;
5   import org.djunits.value.vdouble.scalar.Time;
6   import org.djutils.exceptions.Throw;
7   import org.opentrafficsim.base.parameters.ParameterException;
8   import org.opentrafficsim.base.parameters.ParameterTypes;
9   import org.opentrafficsim.core.gtu.GTUException;
10  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
11  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation.NeighborTriplet;
12  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
13  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTUPerceived;
14  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTUReal;
15  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTURealCopy;
16  
17  /**
18   * Whether a GTU needs to be wrapped, or information should be copied for later and unaltered use.
19   * <p>
20   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
21   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
22   * <p>
23   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 24 mrt. 2017 <br>
24   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
25   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
26   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
27   */
28  public interface HeadwayGtuType
29  {
30  
31      /** The GTU is wrapped, and info is taken directly from it. */
32      HeadwayGtuType WRAP = new HeadwayGtuType()
33      {
34          @Override
35          public HeadwayGTUReal createDownstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
36                  final Length distance) throws GTUException
37          {
38              return new HeadwayGTUReal(perceivedGtu, distance, true);
39          }
40  
41          @Override
42          public HeadwayGTUReal createUpstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
43                  final Length distance) throws GTUException
44          {
45              return new HeadwayGTUReal(perceivedGtu, distance, true);
46          }
47  
48          @Override
49          public HeadwayGTUReal createParallelGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
50                  final Length overlapFront, final Length overlap, final Length overlapRear) throws GTUException
51          {
52              return new HeadwayGTUReal(perceivedGtu, overlapFront, overlap, overlapRear, true);
53          }
54      };
55  
56      /** Info regarding the GTU is copied. */
57      HeadwayGtuType COPY = new HeadwayGtuType()
58      {
59          @Override
60          public HeadwayGTURealCopy createDownstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
61                  final Length distance) throws GTUException
62          {
63              return new HeadwayGTURealCopy(perceivedGtu, distance);
64          }
65  
66          @Override
67          public HeadwayGTURealCopy createUpstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
68                  final Length distance) throws GTUException
69          {
70              return new HeadwayGTURealCopy(perceivedGtu, distance);
71          }
72  
73          @Override
74          public HeadwayGTURealCopy createParallelGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
75                  final Length overlapFront, final Length overlap, final Length overlapRear) throws GTUException
76          {
77              return new HeadwayGTURealCopy(perceivedGtu, overlapFront, overlap, overlapRear);
78          }
79      };
80  
81      /**
82       * Creates a headway object from a GTU, downstream or upstream. The default implementation figures out from possible
83       * negative distance whether a parallel GTU should be created.
84       * @param perceivingGtu LaneBasedGTU; perceiving GTU
85       * @param perceivedGtu LaneBasedGTU; perceived GTU
86       * @param distance Length; distance
87       * @param downstream boolean; downstream (or upstream) neighbor
88       * @return headway object from a gtu
89       * @throws GTUException when headway object cannot be created
90       * @throws ParameterException on invalid parameter value or missing parameter
91       */
92      default HeadwayGTU createHeadwayGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance,
93              boolean downstream) throws GTUException, ParameterException
94      {
95          if (distance.ge0())
96          {
97              if (downstream)
98              {
99                  return createDownstreamGtu(perceivingGtu, perceivedGtu, distance);
100             }
101             return createUpstreamGtu(perceivingGtu, perceivedGtu, distance);
102         }
103         Throw.when(-distance.si > perceivingGtu.getLength().si + perceivedGtu.getLength().si, IllegalStateException.class,
104                 "A GTU that is supposedly %s is actually %s.", downstream ? "downstream" : "upstream",
105                 downstream ? "upstream" : "downstream");
106         Length overlapRear = distance.plus(perceivingGtu.getLength());
107         Length overlap = distance.neg();
108         Length overlapFront = distance.plus(perceivedGtu.getLength());
109         if (overlapRear.lt0())
110         {
111             overlap = overlap.plus(overlapRear);
112         }
113         if (overlapFront.lt0())
114         {
115             overlap = overlap.plus(overlapFront);
116         }
117         return createParallelGtu(perceivingGtu, perceivedGtu, overlapFront, overlap, overlapRear);
118     }
119 
120     /**
121      * Creates a headway object from a GTU, downstream.
122      * @param perceivingGtu LaneBasedGTU; perceiving GTU
123      * @param perceivedGtu LaneBasedGTU; perceived GTU
124      * @param distance Length; distance
125      * @return headway object from a gtu
126      * @throws GTUException when headway object cannot be created
127      * @throws ParameterException on invalid parameter value or missing parameter
128      */
129     HeadwayGTU createDownstreamGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance)
130             throws GTUException, ParameterException;
131 
132     /**
133      * Creates a headway object from a GTU, downstream.
134      * @param perceivingGtu LaneBasedGTU; perceiving GTU
135      * @param perceivedGtu LaneBasedGTU; perceived GTU
136      * @param distance Length; distance
137      * @return headway object from a gtu
138      * @throws GTUException when headway object cannot be created
139      * @throws ParameterException on invalid parameter value or missing parameter
140      */
141     HeadwayGTU createUpstreamGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance)
142             throws GTUException, ParameterException;
143 
144     /**
145      * Creates a headway object from a GTU, parallel.
146      * @param perceivingGtu LaneBasedGTU; perceiving GTU
147      * @param perceivedGtu LaneBasedGTU; perceived GTU
148      * @param overlapFront Length; front overlap
149      * @param overlap Length; overlap
150      * @param overlapRear Length; rear overlap
151      * @return headway object from a gtu
152      * @throws GTUException when headway object cannot be created
153      */
154     HeadwayGTU createParallelGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length overlapFront, Length overlap,
155             Length overlapRear) throws GTUException;
156 
157     /**
158      * Class for perceived neighbors. Adjacent neighbors are perceived exactly.
159      * <p>
160      * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
161      * <br>
162      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
163      * <p>
164      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 apr. 2018 <br>
165      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
166      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
167      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
168      */
169     class PerceivedHeadwayGtuType implements HeadwayGtuType
170     {
171 
172         /** Estimation. */
173         private final Estimation estimation;
174 
175         /** Anticipation. */
176         private final Anticipation anticipation;
177 
178         /** Last update time. */
179         private Time updateTime = null;
180 
181         /** Reaction time at update time. */
182         private Duration tr;
183 
184         /** Historical moment considered at update time. */
185         private Time when;
186 
187         /** Traveled distance during reaction time at update time. */
188         private Length traveledDistance;
189 
190         /**
191          * Constructor.
192          * @param estimation Estimation; estimation
193          * @param anticipation Anticipation; anticipation
194          */
195         public PerceivedHeadwayGtuType(final Estimation estimation, final Anticipation anticipation)
196         {
197             this.estimation = estimation;
198             this.anticipation = anticipation;
199         }
200 
201         /** {@inheritDoc} */
202         @Override
203         public HeadwayGTU createHeadwayGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
204                 final Length distance, final boolean downstream) throws GTUException, ParameterException
205         {
206             Time now = perceivedGtu.getSimulator().getSimulatorTime();
207             if (this.updateTime == null || now.si > this.updateTime.si)
208             {
209                 this.updateTime = now;
210                 this.tr = perceivingGtu.getParameters().getParameter(ParameterTypes.TR);
211                 Time whenTemp = now.minus(this.tr);
212                 if (this.when == null || (this.when != null && whenTemp.si > this.when.si))
213                 {
214                     // never go backwards in time if the reaction time increases
215                     this.when = whenTemp;
216                 }
217                 this.traveledDistance = perceivingGtu.getOdometer().minus(perceivingGtu.getOdometer(this.when));
218             }
219             NeighborTriplet triplet = this.estimation.estimate(perceivingGtu, perceivedGtu, distance, downstream, this.when);
220             triplet = this.anticipation.anticipate(triplet, this.tr, this.traveledDistance, downstream);
221             return new HeadwayGTUPerceived(perceivedGtu, triplet.getHeadway(), triplet.getSpeed(), triplet.getAcceleration());
222         }
223 
224         /** {@inheritDoc} */
225         @Override
226         public HeadwayGTU createDownstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
227                 final Length distance) throws GTUException, ParameterException
228         {
229             return createHeadwayGtu(perceivingGtu, perceivedGtu, distance, true);
230         }
231 
232         /** {@inheritDoc} */
233         @Override
234         public HeadwayGTU createUpstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
235                 final Length distance) throws GTUException, ParameterException
236         {
237             return createHeadwayGtu(perceivingGtu, perceivedGtu, distance, false);
238         }
239 
240         /** {@inheritDoc} */
241         @Override
242         public HeadwayGTU createParallelGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
243                 final Length overlapFront, final Length overlap, final Length overlapRear) throws GTUException
244         {
245             return new HeadwayGTUPerceived(perceivedGtu, overlapFront, overlap, overlapRear, perceivedGtu.getSpeed(),
246                     perceivedGtu.getAcceleration());
247         }
248 
249     }
250 
251 }