Skip to content

Commit 0caf343

Browse files
committed
ENH: mission architecture implementation on rocketpy
- ENH: added code architecture a new class called body - ENH: added code architecture a new class called mission aimed at deployable and stage implementation - ENH: added code architecture for flight branch class for multistage integration class to simulation
1 parent 7f85c07 commit 0caf343

15 files changed

Lines changed: 330 additions & 0 deletions

rocketpy/body/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""rocketpy.body – body abstraction layer for multistage simulation."""
2+
3+
from rocketpy.body.body_like import BodyLike
4+
from rocketpy.body.flying_body import FlightBody
5+
from rocketpy.body.rocket_adapter import RocketAdapter
6+
7+
__all__ = ["BodyLike", "FlyingBody", "RocketAdapter"]

rocketpy/body/body_like.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""BodyLike protocol for the multistage mission architecture.
2+
3+
This module defines a structural typing contract so bodies can satisfy the
4+
interface without inheriting from a shared base class.
5+
"""
6+
7+
from typing import Protocol, runtime_checkable
8+
@runtime_checkable
9+
class BodyLike(Protocol):
10+
"""Structural interface that every flight-ready body must satisfy.
11+
12+
Any object that can be integrated by the Flight simulation engine
13+
must implement this interface. Both the native :class:`FlightBody`
14+
and the :class:`RocketAdapter` (which wraps a legacy :class:`Rocket`)
15+
satisfy it, so that the simulation layer can treat them uniformly.
16+
This uses structural typing, so concrete bodies do not need to inherit
17+
from :class:`BodyLike` to be accepted by the simulation layer.
18+
19+
Attributes
20+
----------
21+
name : str
22+
Human-readable identifier for the body.
23+
"""

rocketpy/body/flying_body.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""FlyingBody – a first-class, fully configurable flight body."""
2+
3+
from copy import deepcopy
4+
5+
6+
class FlyingBody:
7+
"""A fully configurable flight body composed of interchangeable models.
8+
9+
Unlike :class:`~rocketpy.rocket.Rocket`, which is a rich user-facing
10+
builder object, :class:`FlyingBody` is designed as a clean value object
11+
that holds just enough information for the simulation engine to integrate
12+
the equations of motion. Users who need the full Rocket builder
13+
experience can convert a :class:`~rocketpy.rocket.Rocket` to a
14+
:class:`FlyingBody` via :class:`RocketAdapter`. It satisfies the
15+
:class:`~rocketpy.body.BodyLike` protocol.
16+
"""

rocketpy/body/rocket_adapter.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""RocketAdapter – wraps a legacy :class:`Rocket` as a :class:`BodyLike`.
2+
3+
This module provides a minimal adapter to allow legacy ``Rocket``
4+
instances to be consumed by code expecting a ``BodyLike`` interface.
5+
"""
6+
7+
from copy import deepcopy
8+
9+
10+
class RocketAdapter:
11+
"""Adapts a legacy :class:`~rocketpy.rocket.Rocket` to the
12+
:class:`BodyLike` interface.
13+
14+
This allows the existing :class:`~rocketpy.rocket.Rocket` builder to be
15+
consumed by the new multistage simulation infrastructure without any
16+
changes to the ``Rocket`` class itself.
17+
18+
Parameters
19+
----------
20+
rocket : :class:`~rocketpy.rocket.Rocket`
21+
The rocket instance to adapt.
22+
23+
Attributes
24+
----------
25+
rocket : :class:`~rocketpy.rocket.Rocket`
26+
The wrapped rocket instance.
27+
"""
28+
29+
def __init__(self, rocket):
30+
# store a deep copy to avoid accidental mutation of the original
31+
self.rocket = deepcopy(rocket)
32+
33+
def __repr__(self):
34+
return f"<RocketAdapter rocket={getattr(self.rocket, 'name', None)!r}>\n"

rocketpy/mission/__initi__.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""rocketpy.mission – mission architecture for multistage rockets."""
2+
3+
from rocketpy.mission.attached_item import AttachedItem
4+
from rocketpy.mission.attachment import Attachment
5+
from rocketpy.mission.deployable import Deployable
6+
from rocketpy.mission.mission import Mission
7+
from rocketpy.mission.mission_executor import MissionExecutionResult, MissionExecutor
8+
from rocketpy.mission.parent_update import NoOpParentUpdate, ParentUpdate
9+
from rocketpy.mission.separation_model import InstantaneousSeparation, SeparationModel
10+
from rocketpy.mission.stage import Stage
11+
from rocketpy.mission.stage_state import StageState
12+
13+
__all__ = [
14+
"AttachedItem",
15+
"Attachment",
16+
"Deployable",
17+
"InstantaneousSeparation",
18+
"Mission",
19+
"MissionExecutionResult",
20+
"MissionExecutor",
21+
"NoOpParentUpdate",
22+
"ParentUpdate",
23+
"RecoveryEvent",
24+
"SeparationModel",
25+
"Stage",
26+
"StageSeparationEvent",
27+
"StageState",
28+
]

rocketpy/mission/attached_item.py

Whitespace-only changes.

rocketpy/mission/attachment.py

Whitespace-only changes.

rocketpy/mission/deployable.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Deployable – a mission item that can be released during flight."""
2+
3+
from rocketpy.mission.attached_item import AttachedItem
4+
from rocketpy.mission.parent_update import NoOpParentUpdate
5+
from rocketpy.mission.separation_model import InstantaneousSeparation
6+
7+
8+
class Deployable(AttachedItem):
9+
"""A body that can be deployed (released) from its parent during flight.
10+
A :class:`Deployable` is the mission-layer wrapper around a physical
11+
body that should be released at some point in flight (e.g. a nose
12+
cone, a payload bay, or a secondary vehicle). It is *not* the physical
13+
body itself – that is held in :attr:`body`.
14+
Parameters
15+
----------
16+
name : str
17+
Human-readable identifier (e.g. ``"nose_cone_payload"``).
18+
body : :class:`~rocketpy.body.BodyLike`
19+
The physical body of the deployable.
20+
attachment : :class:`~rocketpy.mission.Attachment`
21+
Mechanical link to the parent body.
22+
deployment_event : :class:`~rocketpy.mission.DeploymentEvent`
23+
The event that triggers this deployable's release.
24+
separation : :class:`~rocketpy.mission.SeparationModel`, optional
25+
Model for the separation dynamics. Defaults to
26+
:class:`~rocketpy.mission.InstantaneousSeparation`.
27+
parent_update : :class:`~rocketpy.mission.ParentUpdate`, optional
28+
Callback that modifies the parent body after separation. Defaults
29+
to :class:`~rocketpy.mission.NoOpParentUpdate`.
30+
events : list[:class:`~rocketpy.mission.Event`], optional
31+
Additional events besides *deployment_event*.
32+
Attributes
33+
----------
34+
deployment_event : DeploymentEvent
35+
separation : SeparationModel
36+
parent_update : ParentUpdate
37+
"""
38+
39+
def __init__(
40+
self,
41+
name,
42+
body,
43+
attachment,
44+
deployment_event,
45+
separation=None,
46+
parent_update=None,
47+
events=None,
48+
):

rocketpy/mission/mission.py

Whitespace-only changes.

rocketpy/mission/mission_executor.py

Whitespace-only changes.

0 commit comments

Comments
 (0)