ENH: Controller Implementation Refactor#1065
Draft
MateusStano wants to merge 15 commits into
Draft
Conversation
- _ControllerPrints read the removed 'interactive_objects' attribute, so controller.info()/all_info() raised AttributeError; renamed to controlled_objects() reading controller.controlled_objects. - Event docstring and event_usage.rst claimed context keys are unpacked into the callback kwargs, but Event.__call__ never does that; access is via kwargs['event'].context. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… tracking A Controller is now a public Event subclass (periodic, trigger-less, changes_dynamics, priority 3) instead of a private wrapper around one. This removes the mirrored enabled/log/context state and fixes the context-lifecycle bug where the dict mutated by the controller function diverged from the event context reset between flights. - After every execution the controller snapshots the control_state of each controlled object into control_history; recorded_schedule exposes it as Functions of time for prints/plots and open-loop replay. - New ControlledObject protocol (control_state/set_control/_reset), not surface-specific so future TVC actuators can conform. - ControllableGenericSurface gains initial_control_state and _reset(); AirBrakes inherits them. Controller.reset() restores every tracked object, generalizing the airbrakes-only reset previously in Flight. - Positional controller_function signatures are now rejected with a migration error; the add_air_brakes legacy shim is the only remaining compatibility path (DeprecationWarning). - _Controller removed from the public API; new Flight.controllers property; new _ControllerPlots.control_history plot and richer controller prints. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers Event integration, callback kwargs injection, positional-signature rejection, automatic control-state history and recorded_schedule interpolation, context/history/object reset semantics, controlled-object rebinding, and to_dict/from_dict round trips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…llable_surface - SurfaceController(Controller) validates its controlled objects are ControllableGenericSurface instances and exposes .surfaces; tracking and reset stay in the base so future non-surface controllers (TVC) need no changes here. - AirBrakesController(SurfaceController) pins the 'air_brakes' friendly name, exposes .air_brakes and .deployment_level_history (Function of time), and ships deployment-focused prints/plots. - Rocket.add_air_brakes now builds an AirBrakesController; pure **kwargs controller functions are passed through unwrapped, hybrid and legacy positional signatures keep the (deprecation-warned) wrapper. - New Rocket.add_controllable_surface wires surface(s) into aerodynamic_surfaces and registers a SurfaceController, resolving the previously dangling docstring references. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Air brakes now join rocket.aerodynamic_surfaces and are summed in the standard generic-surface loop of all u_dot variants, instead of the dedicated drag-only branch in _aerodynamic_drag_force. - add_air_brakes gains a position parameter. Without it, the force application point is pinned to the center of dry mass (zero moment arm), matching historical results; the pin survives add_motor because __evaluate_single_surface_cp_to_cdm short-circuits on the sentinel. With an explicit position, deployed brakes produce proper moments at angle of attack. - The airbrake cD is now 0 at deployment level 0 unconditionally; override_rocket_drag became a body-drag suppression branch (body drag applies while brakes are retracted, is replaced by the surface-loop airbrake drag while deployed). - Result note: drag is now decomposed along the freestream like every other surface, adding small lateral components at nonzero incidence (previously pure axial). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- AirBrakes surface: deployment-0 => cD 0 (incl. override mode), curve passthrough, incidence/rate independence, clamp on/off parity with the integration tests, reset protocol, serialization round trip. - Rocket wiring: surface-loop membership, cp pinned to CDM surviving add_motor, explicit-position path, static-margin invariance, legacy signature deprecations, add_controllable_surface wiring (with surface validation moved before add_surfaces for a clear error). - Derivatives without Flight: body-drag suppression semantics and force equivalence of the surface-loop path with the legacy drag formula. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New ScheduledController replays a control schedule open-loop via set_control (clamping applies); ScheduledController.from_controller rebuilds a flight's control inputs from a recorded control_history. - Controller.to_dict now records needs and the controlled objects' names (controlled_objects_ref), plus the control_history under include_outputs; from_dict restores them, and falls back to a ScheduledController (with a warning) when the pickled controller function cannot be decoded but a history is available. - Rocket.from_dict rewires controllers to the decoded surfaces by name, replacing the dead _interactive_objects_hash path that raised AttributeError on every load of a rocket with controllers. - Air brakes are serialized once, inside aerodynamic_surfaces (the air_brakes key is dropped from Rocket.to_dict and rebuilt on load, preserving instance identity with the controller); legacy files with only the air_brakes key still load, pinned to the CDM. The pin flag round-trips via AirBrakes.to_dict. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…texts - Per-sample controllers are rebuilt as AirBrakesController with a deep copy of the base context, so nested mutables (observed-variable lists) are no longer shared across Monte Carlo samples. - Sampled air brakes are wired through Rocket._attach_air_brakes so they join the aerodynamic surface loop (a plain list append would leave them with zero drag under the unified force path); add_air_brakes accepts an optional position forwarded to each sample. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- airbrakes.rst: kwargs controller contract, deprecation of positional signatures and initial_observed_variables, position parameter, automatic deployment tracking and plots, replay section. - event_usage.rst: note that controllers are Event subclasses. - Reference stubs for Controller, SurfaceController, AirBrakesController and ScheduledController. - CHANGELOG entries for the controller refactor (also includes the pre-existing uncommitted entries for the reduced-rates change and the center_of_pressure removal from earlier branch work). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolve ScheduledController dynamically in the from_dict fallback so the module graph stays acyclic (scheduled_controller already imports controller at top level). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Introduce Effector/GenericEffector and Rocket.add_effector: a non-aerodynamic control path that injects a body-frame force and/or moment directly into the equations of motion, driven by the existing Controller. - New rocketpy/rocket/effector package (Effector base implementing the ControlledObject protocol + GenericEffector with user force/moment callables). - Rocket gains an effectors registry, effectors_cp_to_cdm moment arms, add_effector(...) (optionally wiring a Controller), and save/load support; effectors are excluded from the aerodynamic-surface / stability-margin math. - flight_derivatives sums effector force+moment in u_dot and u_dot_generalized (force only in 3-DOF); guarded so effector-free flights are unchanged. - Exports plus unit tests and a slow roll-damper integration test. Also fix compute_needs_union so a controller/event that self-enables via enable_on while declaring needs gets its expensive kwargs on the enabling node. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TBD