Skip to content

ENH: Discrete and Continuous Controllers#946

Open
Malmahrouqi3 wants to merge 9 commits into
RocketPy-Team:developfrom
Malmahrouqi3:enh/discrete_and_contrinuous_control
Open

ENH: Discrete and Continuous Controllers#946
Malmahrouqi3 wants to merge 9 commits into
RocketPy-Team:developfrom
Malmahrouqi3:enh/discrete_and_contrinuous_control

Conversation

@Malmahrouqi3
Copy link
Copy Markdown
Member

@Malmahrouqi3 Malmahrouqi3 commented Mar 30, 2026

Pull request type

  • Code changes (bugfix, features)

Checklist

  • Tests for the changes have been added (if needed)
  • Lint (black rocketpy/ tests/) has passed locally

Current behavior

#274

New behavior

Tested on the Airbrakes Example (docs/user/airbrakes.rst)

(Discrete 10 Hz sampling)
378 Calls
Apogee State
Apogee Time: 22.777 s
Apogee Altitude: 4303.058 m (ASL) | 2903.058 m (AGL)
Apogee Freestream Speed: 15.592 m/s
Apogee X position: -3.803 m
Apogee Y position: 465.747 m
Apogee latitude: 32.9944420°
Apogee longitude: -106.9750388°

Maximum altitude: 2903.06 m
(Discrete 100 Hz sampling)
3776 Calls
Apogee State
Apogee Time: 22.777 s
Apogee Altitude: 4303.008 m (ASL) | 2903.008 m (AGL)
Apogee Freestream Speed: 15.592 m/s
Apogee X position: -3.802 m
Apogee Y position: 465.738 m
Apogee latitude: 32.9944419°
Apogee longitude: -106.9750388°

Maximum altitude: 2903.01 m
(Discrete 1000 Hz sampling)
37758 Calls
Apogee State
Apogee Time: 22.779 s
Apogee Altitude: 4303.448 m (ASL) | 2903.448 m (AGL)
Apogee Freestream Speed: 15.593 m/s
Apogee X position: -3.803 m
Apogee Y position: 465.819 m
Apogee latitude: 32.9944427°
Apogee longitude: -106.9750388°

Maximum altitude: 2903.45 m
(Continuous inf sampling)
744 Calls

Apogee State
Apogee Time: 23.369 s
Apogee Altitude: 4401.779 m (ASL) | 3001.779 m (AGL)
Apogee Freestream Speed: 16.157 m/s
Apogee X position: -4.104 m
Apogee Y position: 488.409 m
Apogee latitude: 32.9946458°
Apogee longitude: -106.9750420°

Maximum altitude: 3001.78 m
(No Controller)
0 Calls
Apogee State
Apogee Time: 25.886 s
Apogee Altitude: 4705.474 m (ASL) | 3305.474 m (AGL)
Apogee Freestream Speed: 20.662 m/s
Apogee X position: -5.543 m
Apogee Y position: 588.779 m
Apogee latitude: 32.9955483°
Apogee longitude: -106.9750574°

Maximum altitude: 3305.47 m

Breaking change

  • Yes
  • No

Additional information

There is no node creation for continuous controllers hence this step is skipped in flight.py. Instead, they are called in each of the ODE solver step, hence not relying on fixed sampling rate.

@Malmahrouqi3 Malmahrouqi3 self-assigned this Mar 30, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 46.15385% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.07%. Comparing base (9cf3dd4) to head (ccce75d).
⚠️ Report is 72 commits behind head on develop.

Files with missing lines Patch % Lines
rocketpy/rocket/rocket.py 28.57% 5 Missing ⚠️
rocketpy/simulation/flight.py 60.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #946      +/-   ##
===========================================
+ Coverage    80.27%   81.07%   +0.80%     
===========================================
  Files          104      113       +9     
  Lines        12769    14555    +1786     
===========================================
+ Hits         10250    11801    +1551     
- Misses        2519     2754     +235     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Malmahrouqi3 Malmahrouqi3 force-pushed the enh/discrete_and_contrinuous_control branch from 538aca0 to a4de476 Compare May 11, 2026 21:23
@Malmahrouqi3 Malmahrouqi3 marked this pull request as ready for review May 11, 2026 21:47
@Malmahrouqi3 Malmahrouqi3 requested a review from a team as a code owner May 11, 2026 21:47
@Malmahrouqi3 Malmahrouqi3 requested a review from Copilot May 11, 2026 21:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for discrete (fixed refresh rate) and continuous (called every solver step) controllers to RocketPy’s flight simulation, aligning with the controller architecture discussed in issue #274.

Changes:

  • Invoke continuous controllers during the solver stepping loop (instead of via fixed time nodes).
  • Add Rocket.add_discrete_controller and Rocket.add_continuous_controller helpers that build _Controller objects with finite vs inf sampling rates.
  • Update _Controller to default sampling_rate to math.inf and document the “infinite sampling” behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.

File Description
rocketpy/simulation/flight.py Calls continuous controllers each solver step and skips time-node creation for sampling_rate=inf.
rocketpy/rocket/rocket.py Adds Rocket-level APIs to register discrete vs continuous controllers.
rocketpy/control/controller.py Defaults controller sampling rate to infinity and updates documentation accordingly.
Comments suppressed due to low confidence (1)

rocketpy/control/controller.py:81

  • The added note in the docstring exceeds the typical line-length used elsewhere in the project (and likely will be reformatted by Ruff/Black). Please wrap this note to keep docstring formatting consistent/readable, and consider clarifying how sampling_rate=inf interacts with the existing 1/sampling_rate wording in the sampling_rate parameter description.
            .. note:: The function will be called according to the sampling rate
            specified. If unspecified, the default sampling rate is set to infinity, meaning that the
            controller function will be called at every step of the simulation.
        sampling_rate : float
            The sampling rate of the controller function in Hertz (Hz). This
            means that the controller function will be called every
            `1/sampling_rate` seconds.

Comment thread rocketpy/simulation/flight.py
Comment thread rocketpy/simulation/flight.py
Comment thread rocketpy/simulation/flight.py Outdated
Comment thread rocketpy/simulation/flight.py
Comment thread rocketpy/rocket/rocket.py
Comment thread rocketpy/rocket/rocket.py Outdated
Comment thread rocketpy/rocket/rocket.py
Comment thread rocketpy/rocket/rocket.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants