1 package org.opentrafficsim.road.gtu;
2
3 import org.djutils.exceptions.Try;
4 import org.opentrafficsim.base.logger.Logger;
5 import org.opentrafficsim.core.gtu.Gtu;
6 import org.opentrafficsim.core.gtu.perception.Perception;
7 import org.opentrafficsim.road.gtu.tactical.TacticalContextEgo;
8
9 /**
10 * Utility to make debugging on a specific GTU more convenient. There is a method {@code on()} for a GTU and for perception.
11 * Should neither be available within the context of a method that needs to be debugged, {@code onSub()} can be used in
12 * combination with {@code onSuper()} at a higher-level method with a GTU or perception. <i>This class requires the user to set
13 * a break point in the method {@code trigger()}.</i>
14 * <p>
15 * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
16 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
17 * </p>
18 * @author Alexander Verbraeck
19 * @author Peter Knoppers
20 * @author Wouter Schakel
21 */
22 public final class Break
23 {
24
25 /** Condition to allow or prevent breaking in lower-level functionality. */
26 private static boolean superCondition = false;
27
28 /**
29 * Constructor.
30 */
31 private Break()
32 {
33 //
34 }
35
36 /**
37 * Sets a break condition to true which is triggered by {@code onSub()} at a lower level where context is insufficient to
38 * determine the break condition.
39 * @param perception perception to obtain gtu from
40 * @param id GTU id to break on
41 * @param time time to break at (or after)
42 * @param additionalCondition additional condition
43 */
44 public static void onSuper(final Perception<?> perception, final String id, final double time,
45 final boolean additionalCondition)
46 {
47 Try.execute(() -> onSuper(perception.getGtu(), id, time, additionalCondition),
48 "Trying to break on gtu, but gtu could not be obtained from perception.");
49 }
50
51 /**
52 * Sets a break condition to true which is triggered by {@code onSub()} at a lower level where context is insufficient to
53 * determine the break condition.
54 * @param gtu GTU
55 * @param id GTU id to break on
56 * @param time time to break at (or after)
57 * @param additionalCondition additional condition
58 */
59 public static void onSuper(final Gtu gtu, final String id, final double time, final boolean additionalCondition)
60 {
61 superCondition = gtu.getId().equals(id) && gtu.getSimulator().getSimulatorTime().si >= time && additionalCondition;
62 }
63
64 /**
65 * This method can be used if the context of a lower-level function does not contain the information on which to break. This
66 * method will only trigger a break if at a higher-level function where the context was sufficient, the break condition was
67 * set to true using {@code onSuper()}.
68 */
69 public static void onSub()
70 {
71 if (superCondition)
72 {
73 trigger();
74 }
75 }
76
77 /**
78 * This method can be used if the context of a lower-level function does not contain the information on which to break. This
79 * method will only trigger a break if at a higher-level function where the context was sufficient, the break condition was
80 * set to true using {@code onSuper()}.
81 * @param additionalCondition additional condition
82 */
83 public static void onSub(final boolean additionalCondition)
84 {
85 if (superCondition && additionalCondition)
86 {
87 trigger();
88 }
89 }
90
91 /**
92 * Break on perception and String of time.
93 * @param perception perception to obtain gtu from
94 * @param id GTU id to break on
95 * @param time time to break at (or after), in format ss, mm:ss or hh:mm:ss
96 * @param additionalCondition additional condition
97 */
98 public static void on(final Perception<?> perception, final String id, final String time, final boolean additionalCondition)
99 {
100 on(perception, id, timeFromString(time), additionalCondition);
101 }
102
103 /**
104 * Returns a double representation of a String time.
105 * @param time string format, ss, mm:ss or hh:mm:ss
106 * @return double representation of a String time
107 */
108 private static double timeFromString(final String time)
109 {
110 int index = time.indexOf(":");
111 if (index < 0)
112 {
113 return Double.valueOf(time) - 1e-6;
114 }
115 int index2 = time.indexOf(":", index + 1);
116 double h;
117 double m;
118 double s;
119 if (index2 < 0)
120 {
121 h = 0;
122 m = Double.valueOf(time.substring(0, index));
123 s = Double.valueOf(time.substring(index + 1));
124 }
125 else
126 {
127 h = Double.valueOf(time.substring(0, index));
128 m = Double.valueOf(time.substring(index + 1, index2));
129 s = Double.valueOf(time.substring(index2 + 1));
130 }
131 return h * 3600.0 + m * 60.0 + s - 1e-6;
132 }
133
134 /**
135 * Break on perception and double time.
136 * @param perception perception to obtain gtu from
137 * @param id GTU id to break on
138 * @param time time to break at (or after)
139 * @param additionalCondition additional condition
140 */
141 public static void on(final Perception<?> perception, final String id, final double time, final boolean additionalCondition)
142 {
143 Try.execute(() -> on(perception.getGtu(), id, time, additionalCondition),
144 "Trying to break on gtu, but gtu could not be obtained from perception.");
145 }
146
147 /**
148 * Break on perception and double time.
149 * @param context tactical information such as parameters and car-following model
150 * @param id GTU id to break on
151 * @param time time to break at (or after)
152 * @param additionalCondition additional condition
153 */
154 public static void on(final TacticalContextEgo context, final String id, final double time,
155 final boolean additionalCondition)
156 {
157 on(context.getUnsafeGtu(), id, time, additionalCondition);
158 }
159
160 /**
161 * Break on GTU and String of time.
162 * @param gtu GTU
163 * @param id GTU id to break on
164 * @param time time to break at (or after), in format ss, mm:ss or hh:mm:ss
165 * @param additionalCondition additional condition
166 */
167 public static void on(final Gtu gtu, final String id, final String time, final boolean additionalCondition)
168 {
169 on(gtu, id, timeFromString(time), additionalCondition);
170 }
171
172 /**
173 * Break on GTU and double time.
174 * @param gtu GTU
175 * @param id GTU id to break on
176 * @param time time to break at (or after)
177 * @param additionalCondition additional condition
178 */
179 public static void on(final Gtu gtu, final String id, final double time, final boolean additionalCondition)
180 {
181 if (gtu.getId().equals(id) && gtu.getSimulator().getSimulatorTime().si >= time && additionalCondition)
182 {
183 trigger();
184 }
185 }
186
187 /**
188 * Method that is invoked on a break condition. A break-point here allows the user to debug specific situations.
189 */
190 private static void trigger()
191 {
192 Logger.ots().error("Break condition for debugging is true."); // SET BREAK POINT ON THIS LINE
193 }
194
195 }