Skip to content
Draft
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
080e316
ENH: first structure
MateusStano Mar 25, 2026
a927248
ENH: improve structure
MateusStano Mar 25, 2026
fae72c1
Merge remote-tracking branch 'origin/develop' into enh/events
MateusStano May 13, 2026
31952a1
ENH: Add flight phase management classes for simulation
MateusStano May 27, 2026
6e9876a
DOC: add .rst files
MateusStano Jun 2, 2026
2e86a37
ENH: adapt event affect code
MateusStano Jun 2, 2026
2ea45f3
ENH: class Event
MateusStano Jun 2, 2026
4241ff5
ENH: first final flight refactor
MateusStano Jun 2, 2026
2aabe20
DOC: improve docstrings
MateusStano Jun 7, 2026
73a9985
Merge remote-tracking branch 'origin/develop' into enh/events
MateusStano Jun 7, 2026
46b84ad
ENH: Refactor parachute trigger function and improve controller obser…
MateusStano Jun 8, 2026
4786f28
DOC: remove noise usage in docs and tests
MateusStano Jun 8, 2026
dfbba5d
ENH: optimize simulation speed
MateusStano Jun 9, 2026
33b98b0
ENH: imrpove plots and prints
MateusStano Jun 11, 2026
968dad4
DOC: improve/fix docs
MateusStano Jun 15, 2026
737bc98
MNT: pylint
MateusStano Jun 15, 2026
d954278
DOC: sensor docs
MateusStano Jun 15, 2026
97b5e90
TST: add tests
MateusStano Jun 15, 2026
7cb5b60
ENH: sensor data access via the Flight class, with prints, plots and …
MateusStano Jun 15, 2026
4cdf2b1
DOC: revert forecast.rst changes
MateusStano Jun 15, 2026
a1b4be9
MNT: ruff lint
MateusStano Jun 15, 2026
91e2130
TST: fix get_controller_observed_variables test
MateusStano Jun 15, 2026
dc12d23
MNT: pylint
MateusStano Jun 15, 2026
8f95df6
MNT: pylint
MateusStano Jun 15, 2026
5fff32c
DOC: add event class to references
MateusStano Jun 15, 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
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ max-public-methods=25
max-returns=25

# Maximum number of statements in function / method body.
max-statements=25
max-statements=50

# Minimum number of public methods for a class (see R0903).
min-public-methods=0
Expand Down Expand Up @@ -481,6 +481,7 @@ disable=raw-checker-failed,
use-symbolic-message-instead,
use-implicit-booleaness-not-comparison-to-string,
use-implicit-booleaness-not-comparison-to-zero,
use-implicit-booleaness-not-comparison, # explicit == [] is clearer, esp. in tests
no-else-return, # this is a style preference, we don't need to follow it
inconsistent-return-statements,
unspecified-encoding, # this is not a relevant issue.
Expand Down
2 changes: 0 additions & 2 deletions docs/development/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,6 @@ Consider the following integration test:
example_plain_env : rocketpy.Environment
Example environment object to be tested.
"""
# TODO:: this should be added to the set_atmospheric_model() method as a
# "file" option, instead of receiving the URL as a string.
URL = "http://weather.uwyo.edu/cgi-bin/sounding?region=samer&TYPE=TEXT%3ALIST&YEAR=2019&MONTH=02&FROM=0500&TO=0512&STNM=83779"
# give it at least 5 times to try to download the file
example_plain_env.set_atmospheric_model(type="wyoming_sounding", file=URL)
Expand Down
1 change: 0 additions & 1 deletion docs/examples/bella_lui_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=parameters.get(\"lag_rec\")[0],\n",
" noise=(0, 8.3, 0.5),\n",
")"
]
},
Expand Down
125 changes: 61 additions & 64 deletions docs/examples/camoes_flight_sim.ipynb

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions docs/examples/genesis_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=1,\n",
" noise=(0, 8.3, 0.5),\n",
")\n",
"\n",
"Main = GENESIS.add_parachute(\n",
Expand All @@ -286,7 +285,6 @@
" trigger=870,\n",
" sampling_rate=105,\n",
" lag=1,\n",
" noise=(0, 8.3, 0.5),\n",
")"
]
},
Expand Down
4 changes: 0 additions & 4 deletions docs/examples/hedy_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -804,13 +804,11 @@
"main_trigger = rocket_config[\"parachutes\"][\"main\"][\"trigger\"]\n",
"main_sampling_rate = rocket_config[\"parachutes\"][\"main\"][\"sampling_rate\"]\n",
"main_lag = rocket_config[\"parachutes\"][\"main\"][\"lag\"]\n",
"main_noise = rocket_config[\"parachutes\"][\"main\"][\"noise\"]\n",
"\n",
"drogue_cd_s = rocket_config[\"parachutes\"][\"drogue\"][\"cd_s\"]\n",
"drogue_trigger = rocket_config[\"parachutes\"][\"drogue\"][\"trigger\"]\n",
"drogue_sampling_rate = rocket_config[\"parachutes\"][\"drogue\"][\"sampling_rate\"]\n",
"drogue_lag = rocket_config[\"parachutes\"][\"drogue\"][\"lag\"]\n",
"drogue_noise = rocket_config[\"parachutes\"][\"drogue\"][\"noise\"]\n",
"\n",
"parachutes = {}\n",
"\n",
Expand All @@ -820,7 +818,6 @@
" trigger=main_trigger,\n",
" sampling_rate=main_sampling_rate,\n",
" lag=main_lag,\n",
" noise=main_noise,\n",
")\n",
"\n",
"parachutes[1] = Parachute(\n",
Expand All @@ -829,7 +826,6 @@
" trigger=drogue_trigger,\n",
" sampling_rate=drogue_sampling_rate,\n",
" lag=drogue_lag,\n",
" noise=drogue_noise,\n",
")"
]
},
Expand Down
1 change: 0 additions & 1 deletion docs/examples/juno3_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@
" cd_s=0.885,\n",
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" noise=(0, 8.3, 0.5),\n",
" lag=0.5,\n",
")"
]
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/lince_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@
"outputs": [],
"source": [
"Main = LincePreDeploy.add_parachute(\n",
" \"Main\", cd_s=3.9, trigger=\"apogee\", sampling_rate=150, lag=0, noise=(0, 0, 0)\n",
" \"Main\", cd_s=3.9, trigger=\"apogee\", sampling_rate=150, lag=0\n",
")"
]
},
Expand Down Expand Up @@ -326,7 +326,7 @@
"outputs": [],
"source": [
"Main_stage_1 = LincePostDeploy.add_parachute(\n",
" \"Main\", cd_s=3.9, trigger=\"apogee\", sampling_rate=150, lag=0, noise=(0, 0, 0)\n",
" \"Main\", cd_s=3.9, trigger=\"apogee\", sampling_rate=150, lag=0\n",
")"
]
},
Expand Down Expand Up @@ -394,7 +394,7 @@
"outputs": [],
"source": [
"Main_stage_2 = Payload.add_parachute(\n",
" \"Main\", cd_s=0.159248, trigger=\"apogee\", sampling_rate=150, lag=0, noise=(0, 0, 0)\n",
" \"Main\", cd_s=0.159248, trigger=\"apogee\", sampling_rate=150, lag=0\n",
")"
]
},
Expand Down
2 changes: 0 additions & 2 deletions docs/examples/ndrt_2020_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -377,15 +377,13 @@
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=parameters.get(\"lag_rec\")[0],\n",
" noise=(0, 8.3, 0.5),\n",
")\n",
"main = ndrt2020.add_parachute(\n",
" \"Main\",\n",
" cd_s=parameters.get(\"cd_s_main\")[0],\n",
" trigger=167.64,\n",
" sampling_rate=105,\n",
" lag=parameters.get(\"lag_rec\")[0],\n",
" noise=(0, 8.3, 0.5),\n",
")"
]
},
Expand Down
1 change: 0 additions & 1 deletion docs/examples/valetudo_flight_sim.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=parameters.get(\"lag_rec\")[0],\n",
" noise=(0, 8.3, 0.5),\n",
")"
]
},
Expand Down
890 changes: 720 additions & 170 deletions docs/notebooks/getting_started.ipynb

Large diffs are not rendered by default.

12 changes: 2 additions & 10 deletions docs/notebooks/getting_started_colab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,6 @@
" trigger=800,\n",
" sampling_rate=105,\n",
" lag=1.5,\n",
" noise=(0, 8.3, 0.5),\n",
")\n",
"\n",
"Drogue = calisto.add_parachute(\n",
Expand All @@ -500,7 +499,6 @@
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=1.5,\n",
" noise=(0, 8.3, 0.5),\n",
")"
]
},
Expand Down Expand Up @@ -588,13 +586,7 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"test_flight.export_kml(\n",
" file_name=\"trajectory.kml\",\n",
" extrude=True,\n",
" altitude_mode=\"relative_to_ground\",\n",
")"
]
"source": "test_flight.exports.kml(\n file_name=\"trajectory.kml\",\n extrude=True,\n altitude_mode=\"relative_to_ground\",\n)"
},
{
"attachments": {},
Expand Down Expand Up @@ -824,4 +816,4 @@
},
"nbformat": 4,
"nbformat_minor": 2
}
}
13 changes: 2 additions & 11 deletions docs/notebooks/monte_carlo_analysis/monte_carlo_analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
Expand Down Expand Up @@ -416,14 +416,6 @@
")\n",
"\n",
"\n",
"# Set up parachutes. This rocket, named Valetudo, only has a drogue chute.\n",
"def drogue_trigger(p, h, y):\n",
" # Check if rocket is going down, i.e. if it has passed the apogee\n",
" vertical_velocity = y[5]\n",
" # Return true to activate parachute once the vertical velocity is negative\n",
" return True if vertical_velocity < 0 else False\n",
"\n",
"\n",
"# Iterate over flight settings\n",
"out = display(\"Starting\", display_id=True)\n",
"for setting in flight_settings(analysis_parameters, number_of_simulations):\n",
Expand Down Expand Up @@ -498,10 +490,9 @@
" Drogue = Valetudo.add_parachute(\n",
" \"Drogue\",\n",
" cd_s=setting[\"cd_s_drogue\"],\n",
" trigger=drogue_trigger,\n",
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=setting[\"lag_rec\"] + setting[\"lag_se\"],\n",
" noise=(0, 8.3, 0.5),\n",
" )\n",
"\n",
" # Run trajectory simulation\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@
" trigger=800,\n",
" sampling_rate=105,\n",
" lag=1.5,\n",
" noise=(0, 8.3, 0.5),\n",
")\n",
"\n",
"Drogue = rocket.add_parachute(\n",
Expand All @@ -195,7 +194,6 @@
" trigger=\"apogee\",\n",
" sampling_rate=105,\n",
" lag=1.5,\n",
" noise=(0, 8.3, 0.5),\n",
")\n",
"\n",
"# Flight\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@
lag=analysis_parameters["parachutes_main_lag"]["mean"],
trigger=800,
sampling_rate=105,
noise=(0, 8.3, 0.5),
)

Drogue = rocket.add_parachute(
Expand All @@ -150,7 +149,6 @@
lag=analysis_parameters["parachutes_drogue_lag"]["mean"],
trigger="apogee",
sampling_rate=105,
noise=(0, 8.3, 0.5),
)

# Flight
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,14 +423,6 @@
")\n",
"\n",
"\n",
"# Set up parachutes. This rocket, named Valetudo, only has a drogue chute.\n",
"def drogueTrigger(p, h, y):\n",
" # Check if rocket is going down, i.e. if it has passed the apogee\n",
" vertical_velocity = y[5]\n",
" # Return true to activate parachute once the vertical velocity is negative\n",
" return True if vertical_velocity < 0 else False\n",
"\n",
"\n",
"# Iterate over flight settings\n",
"out = display(\"Starting\", display_id=True)\n",
"for setting in flight_settings(analysis_parameters, number_of_simulations):\n",
Expand Down Expand Up @@ -496,10 +488,9 @@
" Drogue = Valetudo.addParachute(\n",
" \"Drogue\",\n",
" CdS=setting[\"CdSDrogue\"],\n",
" trigger=drogueTrigger,\n",
" trigger=\"apogee\",\n",
" samplingRate=105,\n",
" lag=setting[\"lag_rec\"] + setting[\"lag_se\"],\n",
" noise=(0, 8.3, 0.5),\n",
" )\n",
"\n",
" # Run trajectory simulation\n",
Expand Down
783 changes: 737 additions & 46 deletions docs/notebooks/sensors.ipynb

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions docs/reference/classes/Event.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Event Class
-----------

.. autoclass:: rocketpy.Event
:members:
2 changes: 1 addition & 1 deletion docs/reference/classes/sensors/accelerometer.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Accelerometer Class
-------------------

.. autoclass:: rocketpy.sensors.Accelerometer
.. autoclass:: rocketpy.Accelerometer
:members:
2 changes: 1 addition & 1 deletion docs/reference/classes/sensors/barometer.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Barometer Class
---------------

.. autoclass:: rocketpy.sensors.Barometer
.. autoclass:: rocketpy.Barometer
:members:
2 changes: 1 addition & 1 deletion docs/reference/classes/sensors/gnss_receiver.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GNSS Receiver Class
-------------------

.. autoclass:: rocketpy.sensors.GnssReceiver
.. autoclass:: rocketpy.GnssReceiver
:members:
2 changes: 1 addition & 1 deletion docs/reference/classes/sensors/gyroscope.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Gyroscope Class
---------------

.. autoclass:: rocketpy.sensors.Gyroscope
.. autoclass:: rocketpy.Gyroscope
:members:
1 change: 1 addition & 0 deletions docs/reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This reference manual details functions, modules, methods and attributes include
classes/Parachute
classes/sensors/index.rst
classes/Flight
classes/Event
Utilities <classes/utils/index>
classes/EnvironmentAnalysis
Monte Carlo Analysis <classes/monte_carlo/index>
Expand Down
1 change: 1 addition & 0 deletions docs/technical/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ in their code.
Roll Moment <aerodynamics/roll_equations.rst>
Sensitivity Analysis <sensitivity.rst>
References <references.rst>
Simulation Loop <simulation_loop.rst>

This section is still a work in progress, however, and not everything is documented yet.
If you have any questions, please contact the maintainers of RocketPy.
73 changes: 73 additions & 0 deletions docs/technical/simulation_loop.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
Simulation Loop
===============

Overview
--------
This page gives a short overview of how the simulation loop is organized. A
``Flight`` is split into phases, each phase is advanced by its own solver, and
events are evaluated at selected time nodes along the way. The main purpose of
this structure is to keep the numerical integration, event handling, and phase
changes coordinated without making the loop hard to extend.

Key concepts
------------
- **Flight**: the top-level simulation object. It builds the phases, runs the
solver loop, and stores the final results.
- **Phase**: one segment of flight with its own solver and derivative
function.
- **Time node**: a scheduled time where the solver state is checked and events
can be evaluated.
- **Event**: a trigger/callback pair that can request simulation changes.
- **Commands**: a small result container used by events to request actions such
as enabling, disabling, adding, or redirecting simulation behavior.

Classes
-------

- ``Flight``: orchestrates the whole run.
- ``_FlightPhase``: stores the solver, derivative, and timing for one phase.
- ``_FlightPhases``: keeps the ordered list of phases.
- ``_TimeNode`` and ``_TimeNodes``: store the node schedule for a phase.
- ``Event``: evaluates trigger logic, runs callbacks, and optionally refines an
event time.
- ``Commands``: stores any actions requested by an event callback.

Simulation structure and loop
-----------------------------
At a high level the loop works like this:

1. ``Flight`` builds the phase list and the initial event set.
2. Each phase creates its solver and its ordered time nodes.
3. The solver advances to each node, then events are checked at that time.
4. Event callbacks can request changes through ``Commands``.
5. If a callback changes the phase layout, the loop updates the node schedule.
6. If an overshootable event forces a rollback, the solver is rebuilt from the
rolled-back state.

In practice, ``Flight`` owns the orchestration, ``Event`` owns the trigger and
callback logic, ``Commands`` stores requested actions, and ``_TimeNodes`` keeps
the schedule that ties everything together.

.. _time_overshoot_processing:

Time-overshoot processing (implementation detail)
-----------------------------------------------
``time_overshootable`` is only used for sampled events. RocketPy checks those
events on interpolated states between solver steps, so it can detect a trigger
without forcing a tiny step size everywhere. If a sampled event triggers in the
overshoot path, the simulation rolls back to that interpolated point and then
restarts the solver from there.

.. important::

Events that change dynamics should not rely on overshoot handling. In
those cases, the callback should request an explicit phase or solver change
instead of trying to move the trigger later.


Post-processing and derivative updates
--------------------------------------
Some callbacks mutate simulation state, such as enabling a controller or
changing a parachute condition. ``Flight`` applies those requests after the
event fires, then refreshes the derivative or phase schedule if needed so the
next solver step uses the updated setup.
Loading
Loading