Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2575950
ENH: Pass Acceleration Data to Parachute Trigger Functions (RocketPy-…
ViniciusCMB Dec 4, 2025
7ec7ac9
ENH: Add acceleration-based parachute triggers with IMU sensor simula…
ViniciusCMB Dec 7, 2025
18aab57
ENH: Enable sensors+acceleration triggers in parachutes
ViniciusCMB Dec 8, 2025
0932277
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
ViniciusCMB Dec 8, 2025
916b0fc
STY: Apply ruff format to flight.py
ViniciusCMB Dec 8, 2025
8e88fa8
STY: Fix pylint for parachute triggers
ViniciusCMB Dec 9, 2025
e84df40
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
ViniciusCMB Dec 9, 2025
a7f5c3a
TST: Add comprehensive unit tests for acceleration-based parachute tr…
ViniciusCMB Dec 9, 2025
ad7e6d0
DOC: Add comprehensive documentation for acceleration-based parachute…
ViniciusCMB Dec 9, 2025
8f65022
STY: Apply ruff format to test_parachute_trigger_acceleration.py
ViniciusCMB Dec 9, 2025
d45b3a5
STY: Fix pylint warnings in test_parachute_triggers.py
ViniciusCMB Dec 9, 2025
6d79d62
FIX: Add missing u_dot parameter to direct triggerfunc calls
ViniciusCMB Dec 9, 2025
5619b3a
STY: Apply ruff format to flight.py
ViniciusCMB Dec 9, 2025
c66cffc
MNT: align acceleration trigger API with review feedback
ViniciusCMB Mar 22, 2026
56c1e51
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
ViniciusCMB Mar 22, 2026
02d344d
STY: apply ruff format fixes
ViniciusCMB Mar 22, 2026
00e94b9
STY: apply ruff format fixes to flight.py
ViniciusCMB Mar 22, 2026
a0cb73d
STY: Apply ruff check after pip update
ViniciusCMB Mar 25, 2026
aba648b
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
ViniciusCMB Mar 25, 2026
6beab3c
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
MateusStano Mar 27, 2026
aa89d50
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
MateusStano Mar 27, 2026
6a9795d
Merge branch 'develop' into enh/acceleration-data-to-trigger-parachutes
MateusStano Apr 4, 2026
0e433a6
Merge remote-tracking branch 'rocketpy/develop' into enh/acceleration…
ViniciusCMB May 5, 2026
90bbf76
MNT: address PR #911 review comments
ViniciusCMB May 5, 2026
4439a66
DOC: add Liftoff example and improve Threshold-based logic
ViniciusCMB May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/user/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ RocketPy's User Guide
:caption: Special Case Simulations

Compare Flights Class<compare_flights.rst>
Parachute Triggers (Acceleration-Based) <parachute_triggers.rst>
Deployable Payload <deployable.rst>
Air Brakes Example <airbrakes.rst>
../notebooks/sensors.ipynb
Expand Down
343 changes: 343 additions & 0 deletions docs/user/parachute_triggers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
Acceleration-Based Parachute Triggers
======================================

RocketPy supports advanced parachute deployment logic using acceleration data
from simulated IMU (Inertial Measurement Unit) sensors. This enables realistic
avionics algorithms that mimic real-world flight computers.

Overview
--------

Traditional parachute triggers rely on altitude and velocity. Acceleration-based
triggers provide additional capabilities:

- **Motor burnout detection**: Implement as a custom trigger with mission-specific thresholds
- **Apogee detection**: Use acceleration and velocity together for precise apogee
- **Freefall detection**: Identify ballistic coasting phases
- **Liftoff detection**: Confirm motor ignition via high acceleration

These triggers can optionally include sensor noise to simulate realistic IMU
behavior, making simulations more representative of actual flight conditions.

Built-in Trigger
----------------

RocketPy provides one built-in trigger string:

Apogee Detection
~~~~~~~~~~~~~~~~

Detects apogee when the rocket starts descending.

.. code-block:: python

main = Parachute(
name="Main",
cd_s=10.0,
trigger="apogee",
sampling_rate=100,
lag=0.5
)

**Detection criteria:**
- Vertical velocity becomes negative (descent starts)
Comment thread
ViniciusCMB marked this conversation as resolved.

Numeric Altitude Trigger
------------------------

You can also pass a numeric altitude (int or float) to deploy at a fixed height
while descending.

.. code-block:: python

main = Parachute(
name="Main",
cd_s=10.0,
trigger=400, # meters above ground level
sampling_rate=100,
lag=0.5
)

Custom Triggers
---------------

You can create custom triggers that use acceleration data:

.. code-block:: python

from rocketpy import Parachute

Custom Trigger: Motor Burnout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Motor burnout is highly mission-dependent, so it is recommended as a custom
trigger with user-defined thresholds:

Logic: check for a drop in vertical or total acceleration once the rocket is
above a minimum height and still ascending.

.. code-block:: python

def burnout_trigger_factory(
min_height=5.0,
min_vz=0.5,
az_threshold=-8.0,
total_acc_threshold=2.0,
):
def burnout_trigger(_pressure, height, state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False

ax, ay, az = u_dot[3], u_dot[4], u_dot[5]
total_acc = (ax**2 + ay**2 + az**2) ** 0.5
vz = state_vector[5] if len(state_vector) > 5 else 0

if height < min_height or vz <= min_vz:
return False

return az < az_threshold or total_acc < total_acc_threshold

return burnout_trigger

Usage:

.. code-block:: python

drogue = Parachute(
name="Drogue",
cd_s=1.0,
trigger=burnout_trigger_factory(
min_height=10.0,
min_vz=2.0,
az_threshold=-10.0,
total_acc_threshold=3.0,
),
sampling_rate=100,
lag=1.5,
)

Custom Trigger: Apogee by Acceleration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Logic: near-zero vertical velocity with downward acceleration.

.. code-block:: python

def apogee_acc_trigger(_pressure, _height, state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False
vz = state_vector[5]
az = u_dot[5]
# Apogee is indicated by near-zero vertical velocity and downward acceleration.
return abs(vz) < 1.0 and az < -0.1

Usage:

.. code-block:: python

main = Parachute(
name="Main",
cd_s=10.0,
trigger=apogee_acc_trigger,
sampling_rate=100,
lag=0.5
)

Custom Trigger: Free-fall
~~~~~~~~~~~~~~~~~~~~~~~~~

Logic: low total acceleration while descending above a small height.

.. code-block:: python

def freefall_trigger(_pressure, height, state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False
ax, ay, az = u_dot[3], u_dot[4], u_dot[5]
total_acc = (ax**2 + ay**2 + az**2) ** 0.5
vz = state_vector[5]
# Free-fall is a low-acceleration phase while descending.
return height > 5.0 and vz < -0.2 and total_acc < 11.5

Usage:

.. code-block:: python

drogue = Parachute(
name="Drogue",
cd_s=1.0,
trigger=freefall_trigger,
sampling_rate=100,
lag=1.5
)

Custom Trigger: Liftoff
~~~~~~~~~~~~~~~~~~~~~~

Logic: detect motor ignition by high total acceleration.

.. code-block:: python

def liftoff_trigger(_pressure, _height, _state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False

ax, ay, az = u_dot[3], u_dot[4], u_dot[5]
total_acc = (ax**2 + ay**2 + az**2) ** 0.5
return total_acc > 15.0

Usage:

.. code-block:: python

lift = Parachute(
name="Lift",
cd_s=0.5,
trigger=liftoff_trigger,
sampling_rate=100,
lag=0.1
)

Custom Trigger: Threshold-based
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Logic: this is a generic threshold example showing how to implement custom
deployment criteria based on acceleration and velocity. Adjust thresholds and
conditions to match your specific mission requirements.

.. code-block:: python

def custom_trigger(pressure, height, state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False

ax, ay, az = u_dot[3], u_dot[4], u_dot[5]
total_acc = (ax**2 + ay**2 + az**2)**0.5
vz = state_vector[5]
return total_acc < 5.0 and vz < -10.0

Usage:

.. code-block:: python

parachute = Parachute(
name="Custom",
cd_s=2.0,
trigger=custom_trigger,
sampling_rate=100,
lag=1.0
)

Custom Trigger: Sensors and Acceleration
----------------------------------------

Triggers can also accept sensor data alongside acceleration.

Logic: compare measured vertical acceleration from an Accelerometer with the
computed ``u_dot`` value.

.. code-block:: python

def advanced_trigger(pressure, height, state_vector, sensors, u_dot):
if len(sensors) == 0:
return False

acc_reading = sensors[0].measurement
if acc_reading is None or len(acc_reading) < 3:
return False

if u_dot is None or len(u_dot) < 6:
return False

meas_az = acc_reading[2]
az = u_dot[5]
return (az < -5.0) and (meas_az < -5.0)

Usage:

.. code-block:: python

parachute = Parachute(
name="Advanced",
cd_s=1.5,
trigger=advanced_trigger,
sampling_rate=100
)

.. note::

For realistic IMU behavior, use RocketPy sensors with their own noise models.
Parachute trigger functions can receive ``sensors`` and use those measurements
directly instead of injecting noise in the flight solver. See the
:doc:`Sensor Classes </reference/classes/sensors/index>` for available sensors.

Example: Simulating Drogue Deployment
-------------------------------------

Logic: in RocketPy, only one parachute is active at a time, so you can simulate
dual-deploy by treating the first trigger as a drogue event and the second as the
main deployment.

.. code-block:: python

from rocketpy import Rocket, Parachute, Flight, Environment

# Environment and rocket setup
env = Environment(latitude=32.99, longitude=-106.97, elevation=1400)
env.set_atmospheric_model(type="standard_atmosphere")

my_rocket = Rocket(...) # Define your rocket

# Drogue parachute: Deploy using a custom burnout trigger
def drogue_burnout_trigger(_pressure, height, state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False
az = u_dot[5]
vz = state_vector[5]
return height > 10 and vz > 1 and az < -8.0

drogue = Parachute(
name="Drogue",
cd_s=1.0,
trigger=drogue_burnout_trigger,
sampling_rate=100,
lag=1.5,
noise=(0, 8.3, 0.5) # Pressure sensor noise
)
my_rocket.add_parachute(drogue)

# Main parachute: Deploy at 800m using a custom trigger
def main_deploy_trigger(_pressure, height, state_vector, u_dot):
if u_dot is None or len(u_dot) < 6:
return False
vz = state_vector[5]
az = u_dot[5]
return height < 800 and vz < -5 and az > -15

main = Parachute(
name="Main",
cd_s=10.0,
trigger=main_deploy_trigger,
sampling_rate=100,
lag=0.5,
noise=(0, 8.3, 0.5)
)
my_rocket.add_parachute(main)

# Flight simulation
flight = Flight(
rocket=my_rocket,
environment=env,
rail_length=5.2,
inclination=85,
heading=0,
)

flight.all_info()

See Also
--------

- :doc:`Parachute Class Reference </reference/rocket/parachute>`
- :doc:`Flight Simulation </user/flight>`
- :doc:`Sensors and Controllers </user/sensors>`
Loading
Loading