View Javadoc
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 }