Skip to content

ENH: Controller Implementation Refactor - #1065

Draft
MateusStano wants to merge 26 commits into
enh/eventsfrom
enh/control-refactor
Draft

MateusStano wants to merge 26 commits into
enh/eventsfrom
enh/control-refactor

Conversation

@MateusStano

Copy link
Copy Markdown
Member

TBD

MateusStano and others added 8 commits June 22, 2026 21:55
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every aerodynamic surface is now rooted in GenericSurface and stores its
force coefficients in the body frame (cN/cY/cA) plus the cm/cn/cl moments,
exposing all nine coefficients (cL/cD/cQ/cN/cY/cA/cm/cn/cl) with the wind
trio lazily derived. A force_convention argument lets users supply wind- or
body-frame coefficients. Barrowman surfaces (nose, tail, fin sets) keep the
classic geometric normal-force/moment method, report the force at the
geometric center of pressure via the classic 180-degree surface rotation,
and expose cN_alpha/cY_beta stability slopes (the old clalpha relabelled).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the poorly defined calisto_linear_generic fixture, which kept the
Barrowman nose cone and tail and swapped only the fins for a
LinearGenericSurface with arbitrary made-up coefficients. The new fixture is a
standalone Calisto whose nose cone, tail and fins are all LinearGenericSurfaces
built from coefficient curves extracted off the standard Barrowman surfaces
(normal-force-curve slope, center of pressure, fin roll damping).

Each linear surface applies its force at its own origin and is placed at the
source surface's center-of-pressure station, so both the static-margin path and
the flight-moment path land at the same point as calisto_robust. The resulting
flight matches the standard Calisto (identical apogee, out-of-rail time and
ascent angle of attack), so the fixture now exercises the linear
generic-surface path against a known-good reference.

Also fix test_linear_generic_surface_flight_is_stable to check the angle of
attack only during the ascent off the rail: on the rail the freestream speed is
~0 and the angle of attack is reported as a degenerate 90 degrees for any
launcher, which previously failed the < 45 assertion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MateusStano MateusStano self-assigned this Jul 11, 2026
MateusStano and others added 18 commits July 23, 2026 13:05
Conflicts were resolved toward the event context design of enh/events:

- controller.py, rocket.py: the controller save/load fix from 3260573 is
  ported to the context convention. The controlled-object hashes are still
  saved so a loaded rocket reconnects its controllers, controller_needs is
  dropped since the context works values out when first read, and the
  legacy air brakes wrapper keeps the 7-argument form but passes the live
  context["controlled_objects"] instead of the captured air brakes.
- event.py, event_builders.py, event_calling.py, event_commands.py,
  flight_phase.py: docstrings follow the new signatures (no needs or
  kwargs), keeping the reworded text where the parameter still exists.
- tests/unit/simulation/test_flight.py: both import additions kept.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Rocket.stability_margin takes (mach, time) again, at zero angle of attack
- aerodynamic center counts each surface's whole moment (pure couples, axial
  force at a sideways offset, canted individual fins)
- Rocket.disturbance_response and Flight.disturbance_response, built on
  attitude oscillator helpers shared with the flight's dynamic stability
- GenericSurface: data against alpha_total is split between the pitch and yaw
  planes from the variable name alone, also for lift and drag; force_convention
  is only "body" or "wind"
- LinearGenericSurface(axisymmetric=True) fills in the yaw-plane derivatives;
  add_full_body_aerodynamics no longer takes symmetric
- remove angular_position from GenericSurface
- stability guide: simpler center of pressure section, displayed C1 and C2
  equations, disturbance response section, parts 6 and 7 removed
- generic surface guide: full list of variable names, total angle of attack
  by variable name, axisymmetric linear surfaces
- rocket usage: drag curve at an angle of attack, stability_margin(mach, time)
A GenericSurface takes a rate derivative such as cm_q next to a coefficient,
to add damping to tabulated data: it is multiplied by its reduced rate and
added to the coefficient. Documented in the generic surface guide.
Brings in the attribute-style event context (`context.state.vz`,
`context.state_dot.az`, `context.controlled`) and the move of the event
code from `simulation/helpers` to `simulation/events`.

Conflict in `rocketpy/control/controller.py`: kept the `enh/events`
side, where `__build_controlled` replaces
`__verify_controlled_objects_name`.

Ported two places that merged cleanly but still used what that commit
removed:

- `_Controller.rebind_controlled_objects` now rebuilds
  `context.controlled` from the reconnected objects.
- The wrapper for legacy positional air brake controllers reads the
  air brakes from `context["controlled"][0]` instead of
  `context["controlled_objects"]`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A surface's `active_during` now accepts only "always", "power_on" and
"power_off". The function form `active_during(t, flight)` is removed:
to switch a surface at any other moment, an event calls one of two new
commands from its callback,

    context.event.commands.activate_surface(surface)
    context.event.commands.deactivate_surface(surface)

and the solver restarts at the switch. A surface that only appears
later in the flight is built with the new `active=False` argument, so
that it starts each flight switched off.

The flight stores each switch with its time, so `surface.is_active(t,
flight)` is still a plain question about time and the outputs computed
after the flight see the surfaces that were on at each moment. The
surfaces themselves are not modified, so another flight of the same
rocket starts from their own `active` setting.

The stability analysis leaves out a surface built with `active=False`.
… name

GenericSurface, LinearGenericSurface and ControllableGenericSurface now
take their shared arguments in the same order, with each class's own
argument last (`axisymmetric`, `controls`). ControllableGenericSurface
had `interpolation`/`extrapolation` and `force_convention`/
`active_during` swapped relative to the other two.

Every argument after `name` is keyword-only. The first five arguments
are the ones released on master and can still be passed by position.
Add a "Which drag is used" section to the generic surfaces guide: the
rocket's own drag curves always apply, every surface's axial force is
added on top, and `overwrite=True` in `add_full_body_aerodynamics`
removes the existing surfaces and zeroes both drag curves. Warn that
full-vehicle data that already includes drag is counted twice otherwise.

Also fix a typo ("collapses" to "collapse").
- Remove unused imports and the unused `plane` argument of
  `_draw_center_of_mass_and_pressure`.
- Give every `to_dict` override the `include_outputs` argument of its
  base class.
- Explain and disable the warnings that misread a deliberate pattern:
  `_BaseFin` initializes `GenericSurface` later, `Fin` and `Fins` are
  still abstract, and `u_dot_parachute` keeps the shared `t` argument.
- Disable too-many-lines in `rocket.py` and `flight.py`, too-many-locals
  in `full_body_coefficients` and too-many-statements in
  `AeroCoefficient.__init__`.
- Allow names like `M1_cm` in `.pylintrc`.
- Tests: move imports to the top, use dict literals, drop unused
  variables and arguments.
# Conflicts:
#	rocketpy/plots/aero_surface_plots.py
#	rocketpy/rocket/aero_surface/fins/fin.py
#	rocketpy/rocket/aero_surface/fins/fins.py
#	rocketpy/simulation/helpers/flight_derivatives.py
#	tests/unit/simulation/test_dynamics.py
#	tests/unit/simulation/test_event.py
#	tests/unit/simulation/test_solution.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MateusStano
MateusStano force-pushed the enh/control-refactor branch from 433b75c to 17d32fe Compare October 5, 2026 23:50
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.

1 participant