@@ -46,15 +46,22 @@ class Parachute:
4646
4747 - The string "apogee" which triggers the parachute at apogee, i.e.,
4848 when the rocket reaches its highest point and starts descending.
49-
49+
50+ - The string "launch + X" where X is a number in seconds. The parachute
51+ will be ejected X seconds after launch (t=0). This is useful for
52+ simulating delay charges that activate at a fixed time from launch.
53+
54+ - The string "burnout + X" where X is a number in seconds. The parachute
55+ will be ejected X seconds after motor burnout. This is useful for
56+ simulating delay charges in motors with delay elements.
5057
5158 Parachute.triggerfunc : function
5259 Trigger function created from the trigger used to evaluate the trigger
5360 condition for the parachute ejection system. It is a callable function
54- that takes three arguments: Freestream pressure in Pa, Height above
55- ground level in meters, and the state vector of the simulation. The
56- returns ``True`` if the parachute ejection system should be triggered
57- and ``False`` otherwise.
61+ that takes six arguments: Freestream pressure in Pa, Height above
62+ ground level in meters, the state vector of the simulation, sensors
63+ list, current time t, and rocket object. It returns ``True`` if the
64+ parachute ejection system should be triggered and ``False`` otherwise.
5865
5966 .. note:
6067
@@ -153,7 +160,14 @@ def __init__(
153160 height above ground level.
154161 - The string "apogee" which triggers the parachute at apogee, i.e., \
155162 when the rocket reaches its highest point and starts descending.
156-
163+ - The string "launch + X" where X is the delay in seconds from launch. \
164+ For example, "launch + 5" triggers 5 seconds after launch. This is \
165+ useful for simulating delay charges that activate at a fixed time \
166+ from launch.
167+ - The string "burnout + X" where X is the delay in seconds from motor \
168+ burnout. For example, "burnout + 3.5" triggers 3.5 seconds after \
169+ motor burnout. This is useful for simulating delay charges in motors \
170+ with delay elements.
157171 .. note::
158172
159173 The function will be called according to the sampling rate specified.
@@ -232,35 +246,92 @@ def __evaluate_trigger_function(self, trigger):
232246 sig = signature (triggerfunc )
233247 if len (sig .parameters ) == 3 :
234248
235- def triggerfunc (p , h , y , sensors ):
249+ def triggerfunc (p , h , y , sensors , t = None , rocket = None ):
236250 return trigger (p , h , y )
251+ elif len (sig .parameters ) == 4 :
237252
253+ def triggerfunc (p , h , y , sensors , t = None , rocket = None ):
254+ return trigger (p , h , y , sensors )
238255 self .triggerfunc = triggerfunc
239256
240257 elif isinstance (trigger , (int , float )):
241258 # The parachute is deployed at a given height
242- def triggerfunc (p , h , y , sensors ): # pylint: disable=unused-argument
259+ def triggerfunc (p , h , y , sensors , t = None , rocket = None ): # pylint: disable=unused-argument
243260 # p = pressure considering parachute noise signal
244261 # h = height above ground level considering parachute noise signal
245262 # y = [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3]
246263 return y [5 ] < 0 and h < trigger
247264
248265 self .triggerfunc = triggerfunc
249266
250- elif trigger .lower () == "apogee" :
251- # The parachute is deployed at apogee
252- def triggerfunc (p , h , y , sensors ): # pylint: disable=unused-argument
253- # p = pressure considering parachute noise signal
254- # h = height above ground level considering parachute noise signal
255- # y = [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3]
256- return y [5 ] < 0
257-
258- self .triggerfunc = triggerfunc
267+ elif isinstance (trigger , str ):
268+ trigger_lower = trigger .lower ().strip ()
269+
270+ if trigger_lower == "apogee" :
271+ # The parachute is deployed at apogee
272+ def triggerfunc (p , h , y , sensors , t = None , rocket = None ): # pylint: disable=unused-argument
273+ # p = pressure considering parachute noise signal
274+ # h = height above ground level considering parachute noise signal
275+ # y = [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3]
276+ return y [5 ] < 0
277+
278+ self .triggerfunc = triggerfunc
279+
280+ elif "+" in trigger_lower :
281+ # Time-based trigger: "launch + X" or "burnout + X"
282+ parts = trigger_lower .split ("+" )
283+ if len (parts ) != 2 :
284+ raise ValueError (
285+ f"Invalid time-based trigger format for parachute '{ self .name } '. "
286+ + "Expected format: 'launch + delay' or 'burnout + delay' "
287+ + "where delay is a number in seconds."
288+ )
289+
290+ event = parts [0 ].strip ()
291+ try :
292+ delay = float (parts [1 ].strip ())
293+ except ValueError :
294+ raise ValueError (
295+ f"Invalid delay value in trigger '{ trigger } ' for parachute '{ self .name } '. "
296+ + "Delay must be a number in seconds."
297+ )
298+
299+ if event == "launch" :
300+ # Deploy at launch time + delay
301+ def triggerfunc (p , h , y , sensors , t = None , rocket = None ): # pylint: disable=unused-argument
302+ if t is None :
303+ return False
304+ return t >= delay
305+
306+ self .triggerfunc = triggerfunc
307+
308+ elif event == "burnout" :
309+ # Deploy at motor burnout time + delay
310+ def triggerfunc (p , h , y , sensors , t = None , rocket = None ): # pylint: disable=unused-argument
311+ if t is None or rocket is None :
312+ return False
313+ burnout_time = rocket .motor .burn_out_time
314+ return t >= burnout_time + delay
315+
316+ self .triggerfunc = triggerfunc
317+
318+ else :
319+ raise ValueError (
320+ f"Invalid time-based trigger event '{ event } ' for parachute '{ self .name } '. "
321+ + "Supported events are 'launch' and 'burnout'."
322+ )
323+
324+ else :
325+ raise ValueError (
326+ f"Unable to set the trigger function for parachute '{ self .name } '. "
327+ + "Trigger string must be 'apogee', 'launch + <delay>', or 'burnout + <delay>'. "
328+ + "See the Parachute class documentation for more information."
329+ )
259330
260331 else :
261332 raise ValueError (
262333 f"Unable to set the trigger function for parachute '{ self .name } '. "
263- + "Trigger must be a callable, a float value or the string 'apogee' . "
334+ + "Trigger must be a callable, a float value or a string. "
264335 + "See the Parachute class documentation for more information."
265336 )
266337
0 commit comments