1 package org.opentrafficsim.road.gtu;
2
3 import org.djunits.unit.SpeedUnit;
4 import org.djunits.value.vdouble.scalar.Speed;
5
6 /**
7 * Different methods of dealing with lane bookkeeping when changing lane.
8 * <p>
9 * Copyright (c) 2024-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
10 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
11 * </p>
12 * @author Wouter Schakel
13 */
14 public enum LaneBookkeeping
15 {
16
17 /**
18 * Instantaneous lane changes. GTUs make a lateral jump. This is advised for scientific output as models are not well
19 * developed regarding lane change movement, lane change cancellation, the leader in the start lane (particularly at low
20 * speed), and how potential followers respond.
21 */
22 INSTANT(false, false, false),
23
24 /**
25 * Bookkeeping changes at the start of a lane change. The GTU has to make the lateral move with possible GTU overlap in the
26 * from lane. Trajectories are instantaneously recorded in the target lane.
27 */
28 START(false, false, false),
29
30 /**
31 * Bookkeeping changes when the reference point of the GTU enters the adjacent lane. Due to model limitations this can
32 * create dead-locks and severe decelerations at low speed in dense traffic. This is advised for control of vehicles in
33 * driver simulators due to the full continuous movement without overlap between GTUs.
34 */
35 EDGE(true, false, false),
36
37 /**
38 * The same as EDGE, but START is used when the speed drops below a low threshold. This prevents dead-locks and severe
39 * decelerations, but allows GTU overlap in the from lane at low speeds. This is advised for microscopic simulations with
40 * visual purposes. Using START only at low speeds makes the trajectories more correlated to the movement.
41 */
42 START_AND_EDGE(true, true, false),
43
44 /**
45 * The same as EDGE, but lateral crossing of an edge is only checked if something informs the bookkeeping that the GTU is
46 * changing lanes. This can for example be done by a model. In this way a model can prevent lane bookkeeping errors that its
47 * own limited modeling could produce. For example when canceling a lane change due to an adjacent GTU but still curving
48 * over the edge.
49 */
50 EDGE_INFORMED(true, false, true),
51
52 /**
53 * Combines functions of START_AND_EDGE and EDGE_INFORMED.
54 */
55 START_AND_EDGE_INFORMED(true, true, true);
56
57 /** Whether the lane bookkeeping is any type that contains edge-based logic. */
58 private final boolean edge;
59
60 /** Whether this is start-based lane bookkeeping below the start threshold, and edge-based lane bookkeeping otherwise. */
61 private final boolean startAndEdge;
62
63 /** Whether the bookkeeping is informed by an outside source, such as a model, that a lane change is occurring. */
64 private final boolean informed;
65
66 /**
67 * Constructor.
68 * @param edge whether the lane bookkeeping is any type that contains edge-based logic
69 * @param startAndEdge whether this is start-based lane bookkeeping below the start threshold, and edge-based lane
70 * bookkeeping otherwise
71 * @param informed whether the bookkeeping is informed by an outside source, such as a model, that a lane change is
72 * occurring
73 */
74 LaneBookkeeping(final boolean edge, final boolean startAndEdge, final boolean informed)
75 {
76 this.edge = edge;
77 this.startAndEdge = startAndEdge;
78 this.informed = informed;
79 }
80
81 /**
82 * Whether the lane bookkeeping is any type that contains edge-based logic.
83 * @return whether the lane bookkeeping is any type that contains edge-based logic
84 */
85 public boolean isEdge()
86 {
87 return this.edge;
88 }
89
90 /**
91 * Whether this is start-based lane bookkeeping below the start threshold, and edge-based lane bookkeeping otherwise.
92 * @return whether this is start-based lane bookkeeping below the start threshold, and edge-based lane bookkeeping otherwise
93 */
94 public boolean isStartAndEdge()
95 {
96 return this.startAndEdge;
97 }
98
99 /**
100 * Whether the bookkeeping is informed by an outside source, such as a model, that a lane change is occurring.
101 * @return whether the bookkeeping is informed by an outside source, such as a model, that a lane change is occurring
102 */
103 public boolean isInformed()
104 {
105 return this.informed;
106 }
107
108 /** Threshold speed below which START is used in START_AND_EDGE. */
109 public static final Speed START_THRESHOLD = new Speed(5.0, SpeedUnit.KM_PER_HOUR);
110
111 }