-
-
Notifications
You must be signed in to change notification settings - Fork 276
ENH : Multistage mission architecture implementation #1155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aZira371
wants to merge
13
commits into
develop
Choose a base branch
from
enh/mission-architecture-implementation
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
9ff426d
ENH: mission architecture implementation on rocketpy
aZira371 227b666
MNT: remove broken mission architecture scaffold
aZira371 5efe57d
ENH: add SeparableBody and Stage to rocketpy.rocket.multistage
aZira371 72a6f79
ENH: add Deployable to rocketpy.rocket.multistage
aZira371 f15eb9d
ENH: add MultiStageRocket to rocketpy.rocket.multistage
aZira371 46f5c4b
ENH: extend flight_rocket to multiple active stages
aZira371 dd6d2a6
ENH: add Mission orchestrator, degenerate single-flight case
aZira371 9efaada
ENH: add two-stage separation and state handoff to Mission
aZira371 43c852d
ENH: add deployable ejection at apogee to Mission
aZira371 0ca5a38
BUG: populate surfaces_cp_to_cdm in flight_rocket()
aZira371 f4aa268
ENH: generalize MultiStageRocket.draw() to N stages and add Mission e…
aZira371 672d9ad
ENH: add Mission.trajectories_3d() and Mission.positions()
aZira371 02ca33f
BUG: follow the component tuple that grew a third field, and split mu…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| """Vehicle composition layer for multistage rockets and deployable payloads.""" | ||
|
|
||
| from rocketpy.rocket.multistage.deployable import Deployable | ||
| from rocketpy.rocket.multistage.geometry import axial_extent | ||
| from rocketpy.rocket.multistage.multistage_rocket import MultiStageRocket | ||
| from rocketpy.rocket.multistage.separable_body import SeparableBody | ||
| from rocketpy.rocket.multistage.stage import Stage |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| """An inert body the vehicle carries and ejects in flight.""" | ||
|
|
||
| from rocketpy.rocket.multistage.separable_body import SeparableBody | ||
|
|
||
|
|
||
| class Deployable(SeparableBody): | ||
| """An inert body carried by the vehicle and ejected in flight. | ||
|
|
||
| No aerodynamic identity while attached: contributes only mass and | ||
| inertia at a position inside the carrying stage. | ||
|
|
||
| Free-flight aerodynamics come from one of two sources, mutually | ||
| exclusive: | ||
| - ``free_rocket``: a fully built Rocket or PointMassRocket (full | ||
| control); | ||
| - surfaces added with ``add_surface()``: Mission assembles the | ||
| free-flight Rocket from the deployable's mass, inertia, radius and | ||
| the added surfaces. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| name : str | ||
| Unique body name; used to group Mission results. | ||
| mass : float | ||
| Carried mass in kg. | ||
| inertia : tuple of float | ||
| Inertia (I11, I22, I33) about the deployable's own center of | ||
| mass, in kg*m^2. | ||
| position : float | ||
| Position of the deployable's center of mass in the carrying | ||
| stage's rocket coordinate system, in meters. | ||
| radius : float, optional | ||
| The deployable's largest radius in meters. Required only when | ||
| defining its free-flight aerodynamics via add_surface(). | ||
| free_rocket : Rocket, PointMassRocket, optional | ||
| Free-flight configuration after ejection. Mutually exclusive | ||
| with add_surface(). | ||
| ejection : Event, optional | ||
| When the deployable is released, e.g. Event(trigger="apogee"). | ||
| separation_delta_v : float, optional | ||
| See SeparableBody. | ||
| """ | ||
|
|
||
| def __init__( | ||
| self, | ||
| name, | ||
| mass, | ||
| inertia, | ||
| position, | ||
| radius=None, | ||
| free_rocket=None, | ||
| ejection=None, | ||
| separation_delta_v=0.0, | ||
| ): | ||
| super().__init__(name=name, separation_delta_v=separation_delta_v) | ||
| self.mass = mass | ||
| self.inertia = inertia | ||
| self.position = position | ||
| self.radius = radius | ||
| self.free_rocket = free_rocket | ||
| self.ejection = ejection | ||
| self.surfaces = [] | ||
|
|
||
| def add_surface(self, surface, position): | ||
| """Add an aerodynamic surface to the deployable's free flight. | ||
|
|
||
| Takes effect only after ejection; while attached the deployable | ||
| still contributes only mass and inertia. ``position`` is in the | ||
| deployable's own coordinate system, in meters. Requires | ||
| ``radius`` to be set and is mutually exclusive with | ||
| ``free_rocket``. | ||
| """ | ||
| if self.free_rocket is not None: | ||
| raise ValueError( | ||
| "add_surface is mutually exclusive with free_rocket; " | ||
| "a free_rocket was already provided for this deployable." | ||
| ) | ||
| if self.radius is None: | ||
| raise ValueError("add_surface requires radius to be set on the deployable.") | ||
| self.surfaces.append((surface, position)) |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| """Axial geometry of a rocket, as the stacking of stages needs it.""" | ||
|
|
||
| from rocketpy.rocket.aero_surface.fins.fins import Fins | ||
| from rocketpy.rocket.aero_surface.nose_cone import NoseCone | ||
| from rocketpy.rocket.aero_surface.tail import Tail | ||
|
|
||
|
|
||
| def axial_extent(rocket): | ||
| """Axial extent (bottom, top) spanned by a rocket's aerodynamic | ||
| surfaces, in the rocket's own coordinate system. | ||
|
|
||
| NoseCone, Tail and Fins each occupy a span (their own ``length`` or | ||
| ``root_chord``, starting from their own reference position); every | ||
| other surface type (GenericSurface, RailButtons, individual Fin, | ||
| TubeFins, ...) is treated as a single point at its own position. This | ||
| is an approximation for those types, not an exact geometric fit. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| rocket : Rocket | ||
| Must have at least one aerodynamic surface. | ||
|
|
||
| Returns | ||
| ------- | ||
| tuple of float | ||
| (bottom, top) - the lowest and highest axial coordinates spanned. | ||
| """ | ||
| if not rocket.aerodynamic_surfaces: | ||
| raise ValueError( | ||
| "Rocket must have at least one aerodynamic surface to compute " | ||
| "its axial extent." | ||
| ) | ||
| bounds = [] | ||
| for surface, position, *_ in rocket.aerodynamic_surfaces: | ||
| z = position.z | ||
| bounds.append(z) | ||
| if isinstance(surface, NoseCone): | ||
| bounds.append(z - rocket._csys * surface.length) | ||
| elif isinstance(surface, Tail): | ||
| bounds.append(z - rocket._csys * surface.length) | ||
| elif isinstance(surface, Fins): | ||
| bounds.append(z - rocket._csys * surface.root_chord) | ||
| return min(bounds), max(bounds) |
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we should allow users to select their preferred colors. A new issue could be opened about it, so contributors can solve it.