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