View Javadoc
1   package org.opentrafficsim.road.gtu.lane;
2   
3   import java.util.Map;
4   
5   import org.djunits.value.vdouble.scalar.Acceleration;
6   import org.djunits.value.vdouble.scalar.Direction;
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djunits.value.vdouble.scalar.Speed;
9   import org.djunits.value.vdouble.scalar.Time;
10  import org.djunits.value.vdouble.vector.PositionVector;
11  import org.djutils.event.EventType;
12  import org.djutils.event.TimedEventType;
13  import org.djutils.metadata.MetaData;
14  import org.djutils.metadata.ObjectDescriptor;
15  import org.opentrafficsim.core.gtu.GTU;
16  import org.opentrafficsim.core.gtu.GTUDirectionality;
17  import org.opentrafficsim.core.gtu.GTUException;
18  import org.opentrafficsim.core.gtu.RelativePosition;
19  import org.opentrafficsim.core.gtu.TurnIndicatorStatus;
20  import org.opentrafficsim.core.network.LateralDirectionality;
21  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlanner;
22  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
23  import org.opentrafficsim.road.network.RoadNetwork;
24  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
25  import org.opentrafficsim.road.network.lane.Lane;
26  
27  import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
28  import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
29  import nl.tudelft.simulation.language.d3.DirectedPoint;
30  
31  /**
32   * This interface defines a lane based GTU.
33   * <p>
34   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
35   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
36   * <p>
37   * @version $Revision: 1401 $, $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, by $Author: averbraeck $,
38   *          initial version Oct 22, 2014 <br>
39   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
40   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
41   */
42  public interface LaneBasedGTU extends GTU
43  {
44      /** @return the road network to which the LaneBasedGTU belongs */
45      RoadNetwork getNetwork();
46  
47      /** {@inheritDoc} */
48      @Override
49      LaneBasedStrategicalPlanner getStrategicalPlanner();
50  
51      /** {@inheritDoc} */
52      @Override
53      LaneBasedStrategicalPlanner getStrategicalPlanner(Time time);
54  
55      /** {@inheritDoc} */
56      @Override
57      default LaneBasedTacticalPlanner getTacticalPlanner()
58      {
59          return getStrategicalPlanner().getTacticalPlanner();
60      }
61  
62      /** {@inheritDoc} */
63      @Override
64      default LaneBasedTacticalPlanner getTacticalPlanner(final Time time)
65      {
66          return getStrategicalPlanner(time).getTacticalPlanner(time);
67      }
68  
69      /**
70       * Return the location without a RemoteException. {@inheritDoc}
71       */
72      @Override
73      DirectedPoint getLocation();
74  
75      /**
76       * Change lanes instantaneously.
77       * @param laneChangeDirection LateralDirectionality; the direction to change to
78       * @throws GTUException in case lane change fails
79       */
80      void changeLaneInstantaneously(LateralDirectionality laneChangeDirection) throws GTUException;
81  
82      /**
83       * Register on lanes in target lane.
84       * @param laneChangeDirection LateralDirectionality; direction of lane change
85       * @throws GTUException exception
86       */
87      void initLaneChange(LateralDirectionality laneChangeDirection) throws GTUException;
88  
89      /**
90       * Sets event to finalize lane change.
91       * @param event SimEventInterface&lt;SimTimeDoubleUnit&gt;; event
92       */
93      void setFinalizeLaneChangeEvent(SimEventInterface<SimTimeDoubleUnit> event);
94  
95      /**
96       * Get projected length on the lane.
97       * @param lane Lane; lane to project the vehicle on
98       * @return Length; the length on the lane, which is different from the actual length during deviative tactical plans
99       * @throws GTUException when the vehicle is not on the given lane
100      */
101     default Length getProjectedLength(final Lane lane) throws GTUException
102     {
103         Length front = position(lane, getFront());
104         Length rear = position(lane, getRear());
105         return getDirection(lane).isPlus() ? front.minus(rear) : rear.minus(front);
106     }
107 
108     /**
109      * Sets whether the GTU perform lane changes instantaneously or not.
110      * @param instantaneous boolean; whether the GTU perform lane changes instantaneously or not
111      */
112     void setInstantaneousLaneChange(boolean instantaneous);
113 
114     /**
115      * Returns whether the GTU perform lane changes instantaneously or not.
116      * @return boolean; whether the GTU perform lane changes instantaneously or not
117      */
118     boolean isInstantaneousLaneChange();
119 
120     /**
121      * Return the longitudinal positions of a point relative to this GTU, relative to the center line of the Lanes in which the
122      * vehicle is registered. <br>
123      * <b>Note:</b> If a GTU is registered in multiple parallel lanes, the lateralLaneChangeModel is used to determine the
124      * center line of the vehicle at this point in time. Otherwise, the average of the center positions of the lines will be
125      * taken.
126      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
127      * @return the lanes and the position on the lanes where the GTU is currently registered, for the given position of the GTU.
128      * @throws GTUException when the vehicle is not on one of the lanes on which it is registered.
129      */
130     Map<Lane, Length> positions(RelativePosition relativePosition) throws GTUException;
131 
132     /**
133      * Return the longitudinal positions of a point relative to this GTU, relative to the center line of the Lanes in which the
134      * vehicle is registered.
135      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
136      * @param when Time; the future time for which to calculate the positions.
137      * @return the lanes and the position on the lanes where the GTU will be registered at the time, for the given position of
138      *         the GTU.
139      * @throws GTUException when the vehicle is not on one of the lanes on which it is registered.
140      */
141     Map<Lane, Length> positions(RelativePosition relativePosition, Time when) throws GTUException;
142 
143     /**
144      * Return the longitudinal position of a point relative to this GTU, relative to the center line of the Lane at the current
145      * simulation time. <br>
146      * @param lane Lane; the position on this lane will be returned.
147      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
148      * @return DoubleScalarAbs&lt;LengthUnit&gt;; the position, relative to the center line of the Lane.
149      * @throws GTUException when the vehicle is not on the given lane.
150      */
151     Length position(Lane lane, RelativePosition relativePosition) throws GTUException;
152 
153     /**
154      * Return the longitudinal position of a point relative to this GTU, relative to the center line of the Lane.
155      * @param lane Lane; the position on this lane will be returned.
156      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
157      * @param when Time; the future time for which to calculate the positions.
158      * @return DoubleScalarAbs&lt;LengthUnit&gt;; the position, relative to the center line of the Lane.
159      * @throws GTUException when the vehicle is not on the given lane.
160      */
161     Length position(Lane lane, RelativePosition relativePosition, Time when) throws GTUException;
162 
163     /**
164      * Return the longitudinal positions of a point relative to this GTU, relative to the center line of the Lanes in which the
165      * vehicle is registered, as fractions of the length of the lane. This is important when we want to see if two vehicles are
166      * next to each other and we compare an 'inner' and 'outer' curve.<br>
167      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
168      * @return the lanes and the position on the lanes where the GTU is currently registered, for the given position of the GTU.
169      * @throws GTUException when the vehicle is not on one of the lanes on which it is registered.
170      */
171     Map<Lane, Double> fractionalPositions(RelativePosition relativePosition) throws GTUException;
172 
173     /**
174      * Return the longitudinal positions of a point relative to this GTU, relative to the center line of the Lanes in which the
175      * vehicle is registered, as fractions of the length of the lane. This is important when we want to see if two vehicles are
176      * next to each other and we compare an 'inner' and 'outer' curve.
177      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
178      * @param when Time; the future time for which to calculate the positions.
179      * @return the lanes and the position on the lanes where the GTU will be registered at the time, for the given position of
180      *         the GTU.
181      * @throws GTUException when the vehicle is not on one of the lanes on which it is registered.
182      */
183     Map<Lane, Double> fractionalPositions(RelativePosition relativePosition, Time when) throws GTUException;
184 
185     /**
186      * Return the longitudinal position of a point relative to this GTU, relative to the center line of the Lane, as a fraction
187      * of the length of the lane. This is important when we want to see if two vehicles are next to each other and we compare an
188      * 'inner' and 'outer' curve.
189      * @param lane Lane; the position on this lane will be returned.
190      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
191      * @param when Time; the future time for which to calculate the positions.
192      * @return the fractional relative position on the lane at the given time.
193      * @throws GTUException when the vehicle is not on the given lane.
194      */
195     double fractionalPosition(Lane lane, RelativePosition relativePosition, Time when) throws GTUException;
196 
197     /**
198      * Return the longitudinal position of a point relative to this GTU, relative to the center line of the Lane, as a fraction
199      * of the length of the lane. This is important when we want to see if two vehicles are next to each other and we compare an
200      * 'inner' and 'outer' curve.<br>
201      * @param lane Lane; the position on this lane will be returned.
202      * @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
203      * @return the fractional relative position on the lane at the given time.
204      * @throws GTUException when the vehicle is not on the given lane.
205      */
206     double fractionalPosition(Lane lane, RelativePosition relativePosition) throws GTUException;
207 
208     /**
209      * Return the current Lane, position and directionality of the GTU.
210      * @return DirectedLanePosition; the current Lane, position and directionality of the GTU
211      * @throws GTUException in case the reference position of the GTU cannot be found on the lanes in its current path
212      */
213     DirectedLanePosition getReferencePosition() throws GTUException;
214 
215     /**
216      * Return the directionality of a lane on which the GTU is registered for its current operational plan.
217      * @param lane Lane; the lane for which we want to know the direction
218      * @return GTUDirectionality; the direction on the given lane
219      * @throws GTUException in case the GTU is not registered on the Lane
220      */
221     GTUDirectionality getDirection(Lane lane) throws GTUException;
222 
223     /**
224      * Add an event to the list of lane triggers scheduled for this GTU.
225      * @param lane Lane; the lane on which the event occurs
226      * @param event SimEventInterface&lt;SimTimeDoubleUnit&gt;; SimeEvent&lt;SimTimeDoubleUnit&gt; the event
227      */
228     void addTrigger(Lane lane, SimEventInterface<SimTimeDoubleUnit> event);
229 
230     /**
231      * Set distance over which the GTU should not change lane after being created.
232      * @param distance Length; distance over which the GTU should not change lane after being created
233      */
234     void setNoLaneChangeDistance(Length distance);
235 
236     /**
237      * Returns whether a lane change is allowed.
238      * @return whether a lane change is allowed
239      */
240     boolean laneChangeAllowed();
241 
242     /**
243      * This method returns the current desired speed of the GTU. This value is required often, so implementations can cache it.
244      * @return Speed; current desired speed
245      */
246     Speed getDesiredSpeed();
247 
248     /**
249      * This method returns the current car-following acceleration of the GTU. This value is required often, so implementations
250      * can cache it.
251      * @return Acceleration; current car-following acceleration
252      */
253     Acceleration getCarFollowingAcceleration();
254 
255     /**
256      * Returns the vehicle model.
257      * @return VehicleModel; vehicle model
258      */
259     default VehicleModel getVehicleModel()
260     {
261         return VehicleModel.MINMAX;
262     }
263 
264     /**
265      * The default implementation returns {@code true} if the deceleration is larger than a speed-dependent threshold given
266      * by:<br>
267      * <br>
268      * c0 * g(v) + c1 + c3*v^2<br>
269      * <br>
270      * where c0 = 0.2, c1 = 0.15 and c3 = 0.00025 (with c2 = 0 implicit) are empirically derived averages, and g(v) is 0 below
271      * 25 km/h or 1 otherwise, representing that the engine is disengaged at low speeds.
272      * @return boolean; whether the braking lights are on
273      */
274     default boolean isBrakingLightsOn()
275     {
276         return isBrakingLightsOn(getSimulator().getSimulatorTime());
277     }
278 
279     /**
280      * The default implementation returns {@code true} if the deceleration is larger than a speed-dependent threshold given
281      * by:<br>
282      * <br>
283      * c0 * g(v) + c1 + c3*v^2<br>
284      * <br>
285      * where c0 = 0.2, c1 = 0.15 and c3 = 0.00025 (with c2 = 0 implicit) are empirically derived averages, and g(v) is 0 below
286      * 25 km/h or 1 otherwise, representing that the engine is disengaged at low speeds.
287      * @param when Time; time
288      * @return boolean; whether the braking lights are on
289      */
290     default boolean isBrakingLightsOn(final Time when)
291     {
292         double v = getSpeed(when).si;
293         double a = getAcceleration(when).si;
294         return a < (v < 6.944 ? 0.0 : -0.2) - 0.15 * v - 0.00025 * v * v;
295     }
296 
297     /**
298      * Returns the lateral position of the GTU relative to the lane center line. Negative values are towards the right.
299      * @param lane Lane; lane to consider (most important regarding left/right, not upstream downstream)
300      * @return Length; lateral position of the GTU relative to the lane center line
301      * @throws GTUException when the vehicle is not on the given lane.
302      */
303     Length getLateralPosition(Lane lane) throws GTUException;
304 
305     /** @return the status of the turn indicator */
306     TurnIndicatorStatus getTurnIndicatorStatus();
307 
308     /**
309      * @param time Time; time to obtain the turn indicator status at
310      * @return the status of the turn indicator at the given time
311      */
312     TurnIndicatorStatus getTurnIndicatorStatus(Time time);
313 
314     /**
315      * Set the status of the turn indicator.
316      * @param turnIndicatorStatus TurnIndicatorStatus; the new status of the turn indicator.
317      * @throws GTUException when GTUType does not have a turn indicator
318      */
319     void setTurnIndicatorStatus(TurnIndicatorStatus turnIndicatorStatus) throws GTUException;
320 
321     /**
322      * The lane-based event type for pub/sub indicating the initialization of a new GTU. <br>
323      * Payload: [String gtuId, PositionVector initialPosition, Direction initialDirection, Length length, Length width, String
324      * linkId, String laneId, Length positionOnReferenceLane, GTUDirectionality direction, GTUType gtuType]
325      */
326     TimedEventType LANEBASED_INIT_EVENT = new TimedEventType("LANEBASEDGTU.INIT",
327             new MetaData("Lane based GTU created", "Lane based GTU created",
328                     new ObjectDescriptor[] { new ObjectDescriptor("GTU id", "GTU id", String.class),
329                             new ObjectDescriptor("initial position", "initial position", PositionVector.class),
330                             new ObjectDescriptor("initial direction", "initial direction", Direction.class),
331                             new ObjectDescriptor("Length", "Length", Length.class),
332                             new ObjectDescriptor("Width", "Width", Length.class),
333                             new ObjectDescriptor("Link id", "Link id", String.class),
334                             new ObjectDescriptor("Lane id", "Lane id", String.class),
335                             new ObjectDescriptor("Longitudinal position on lane", "Longitudinal position on lane",
336                                     Length.class),
337                             new ObjectDescriptor("Driving direction", "Driving direction", String.class),
338                             new ObjectDescriptor("GTU type name", "GTU type name", String.class) }));
339 
340     /**
341      * The lane-based event type for pub/sub indicating a move. <br>
342      * Payload: [String gtuId, PositionVector currentPosition, Direction currentDirection, Speed speed, Acceleration
343      * acceleration, TurnIndicatorStatus turnIndicatorStatus, Length odometer, Link id of referenceLane, Lane id of
344      * referenceLane, Length positionOnReferenceLane, GTUDirectionality direction]
345      */
346     TimedEventType LANEBASED_MOVE_EVENT = new TimedEventType("LANEBASEDGTU.MOVE", new MetaData("Lane based GTU moved",
347             "Lane based GTU moved",
348             new ObjectDescriptor[] { new ObjectDescriptor("GTU id", "GTU id", String.class),
349                     new ObjectDescriptor("Position", "Position", PositionVector.class),
350                     new ObjectDescriptor("Direction", "Direction", Direction.class),
351                     new ObjectDescriptor("Speed", "Speed", Speed.class),
352                     new ObjectDescriptor("Acceleration", "Acceleration", Acceleration.class),
353                     new ObjectDescriptor("TurnIndicatorStatus", "Turn indicator status", String.class),
354                     new ObjectDescriptor("Odometer", "Odometer value", Length.class),
355                     new ObjectDescriptor("Link id", "Link id", String.class),
356                     new ObjectDescriptor("Lane id", "Lane id", String.class),
357                     new ObjectDescriptor("Longitudinal position on lane", "Longitudinal position on lane", Length.class),
358                     new ObjectDescriptor("Driving direction", "Driving direction", String.class) }));
359 
360     /**
361      * The lane-based event type for pub/sub indicating destruction of the GTU. <br>
362      * Payload: [String gtuId, PositionVector finalPosition, Direction finalDirection, Length finalOdometer, Link referenceLink,
363      * Lane referenceLane, Length positionOnReferenceLane, GTUDirectionality direction]
364      */
365     TimedEventType LANEBASED_DESTROY_EVENT = new TimedEventType("LANEBASEDGTU.DESTROY", new MetaData("Lane based GTU destroyed",
366             "Lane based GTU destroyed",
367             new ObjectDescriptor[] { new ObjectDescriptor("GTU id", "GTU id", String.class),
368                     new ObjectDescriptor("Position", "Position", PositionVector.class),
369                     new ObjectDescriptor("Direction", "Direction", Direction.class),
370                     new ObjectDescriptor("Odometer", "Odometer value", Length.class),
371                     new ObjectDescriptor("Link id", "Link id", String.class),
372                     new ObjectDescriptor("Lane id", "Lane id", String.class),
373                     new ObjectDescriptor("Longitudinal position on lane", "Longitudinal position on lane", Length.class),
374                     new ObjectDescriptor("Driving direction", "Driving direction", String.class) }));
375 
376     // TODO: the next 2 events are never fired...
377     /**
378      * The event type for pub/sub indicating that the GTU entered a new lane (with the FRONT position if driving forward; REAR
379      * if driving backward). <br>
380      * Payload: [String gtuId, String link id, String lane id]
381      */
382     EventType LANE_ENTER_EVENT = new EventType("LANE.ENTER",
383             new MetaData("Lane based GTU entered lane", "Front of lane based GTU entered lane",
384                     new ObjectDescriptor[] { new ObjectDescriptor("GTU id", "GTU id", String.class),
385                             new ObjectDescriptor("Link id", "Link id", String.class),
386                             new ObjectDescriptor("Lane id", "Lane id", String.class) }));
387 
388     /**
389      * The event type for pub/sub indicating that the GTU exited a lane (with the REAR position if driving forward; FRONT if
390      * driving backward). <br>
391      * Payload: [String gtuId, String link id, String lane id]
392      */
393     EventType LANE_EXIT_EVENT = new EventType("LANE.EXIT",
394             new MetaData("Lane based GTU exited lane", "Rear of lane based GTU exited lane",
395                     new ObjectDescriptor[] { new ObjectDescriptor("GTU id", "GTU id", String.class),
396                             new ObjectDescriptor("Link id", "Link id", String.class),
397                             new ObjectDescriptor("Lane id", "Lane id", String.class) }));
398 
399     /**
400      * The event type for pub/sub indicating that the GTU change lane. <br>
401      * Payload: [String gtuId, LateralDirectionality direction, DirectedLanePosition from]
402      */
403     TimedEventType LANE_CHANGE_EVENT = new TimedEventType("LANE.CHANGE", new MetaData("Lane based GTU changes lane",
404             "Lane based GTU changes lane",
405             new ObjectDescriptor[] { new ObjectDescriptor("GTU id", "GTU id", String.class),
406                     new ObjectDescriptor("Lateral direction of lane change", "Lateral direction of lane change", String.class),
407                     new ObjectDescriptor("Link id", "Link id", String.class),
408                     new ObjectDescriptor("Lane id of vacated lane", "Lane id of vacated lane", String.class),
409                     new ObjectDescriptor("Position along vacated lane", "Position along vacated lane", Length.class) }));
410 
411 }