# nsarrazin/odessa architecture

> Architecture diagram of the GitHub repository nsarrazin/odessa, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-20). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nsarrazin/odessa
- Repository: https://github.com/nsarrazin/odessa

## Overview

1. **What ODESSA is**
   ODESSA is a Python ODE simulation framework built around a modular right-hand-side pipeline. It uses **SciPy’s ODE solvers** for integration and **Numba jitclasses** to keep modules and core state structured and fast enough for repeated RHS evaluations.

2. **Top-level runtime flow**
   The central flow is:
   **JSON config / scripted setup → `Simulation` → one or more `Phase`s → ordered module execution on a shared `Core` → SciPy integrator → solution outputs**.
   The solver repeatedly calls an RHS function that populates the `Core`, runs each module in order, and returns `Core.dy`.

3. **Simulation orchestration boundary**
   `odessa/simulation.py` is the main orchestration layer. It constructs simulations from JSON, owns the list of phases, and drives the integration run. This is the primary boundary between user-facing configuration and the internal numerical model.

4. **Phase model**
   `odessa/phase.py` represents a simulation segment. A phase contains:
   - a set of modules to execute in a fixed order,
   - a set of events that can terminate or switch behavior.
   Multiple phases allow a run to change physics mid-flight, such as powered ascent followed by ballistic flight or deployment logic.

5. **Shared state through the Core**
   The `Core` classes are the shared data bus for the simulation. They hold:
   - state variables like position and velocity,
   - derived quantities like force, acceleration, density, speed of sound, mass, inertia.
   Modules do not communicate directly with each other; they read and write through `Core`. This is the key architectural boundary that keeps the model modular.

6. **Module system**
   Modules live under `odessa/modules/` and are grouped by degree-of-freedom:
   - **3DoF**: simpler translational flight dynamics
   - **6DoF**: full translational + rotational dynamics
   Each module exposes an `id`, a `type`, and an `rhs(Core)` method. The order in the config matters, because later modules depend on values written by earlier ones.

7. **Physics subsystems**
   The main physics families are:
   - **Atmos**: atmospheric properties
   - **Mass**: mass and inertia evolution
   - **Gravity**: gravity models, including J2 and other approximations
   - **Aero**: drag and aerodynamic force/moment models
   - **Thrust**: engine force models driven by tables
   - **Tower**: launch-rail or rigid constraint behavior in 6DoF
   - **Dynamics**: final equations-of-motion assembly that turns accumulated forces/moments into derivatives
   These are the main diagram boxes for the simulation’s physical pipeline.

8. **3DoF vs 6DoF architecture**
   The repository contains two parallel simulation stacks:
   - **`odessa/modules/3dof/*`** for trajectory-style motion with fewer state variables
   - **`odessa/modules/6dof/*`** for full rigid-body flight dynamics
   They share concepts and some helper patterns, but the 6DoF stack adds orientation, moments, and rotational dynamics, plus more detailed aero/gravity/tower behavior.

9. **Events as termination or phase-control logic**
   Event modules live under `odessa/events/` and are evaluated during integration to detect conditions such as:
   - ground contact
   - fixed simulation time
   - altitude thresholds
   - apogee or distance-based conditions
   These are used both to stop a phase early and to trigger phase transitions.

10. **Helpers and numerical utilities**
   `odessa/helpers/` contains cross-cutting utilities rather than physics modules:
   - coordinate/frame transformations
   - rotation math
   - atmospheric helper functions
   - interpolation utilities for tables and grids
   - JSON/Numpy encoding support
   These support the module layer and are critical for data-driven models like drag tables, engine tables, and wind profiles.

11. **Configuration and data-driven inputs**
   Most repository examples are driven by JSON files in `scripts/configs/` and test configs under `test/`. Tables and CSVs provide real inputs such as:
   - aero coefficients
   - wind profiles
   - mass and inertia histories
   - engine/thrust curves
   This means the architecture is strongly data-driven: the same module code is reused with different parameter tables.

12. **Examples, demos, and benchmarks**
   The `scripts/` folder contains runnable demos and benchmarks that show how the framework is assembled in practice. These scripts are not a separate runtime subsystem, but they are important because they demonstrate:
   - composing phases and modules,
   - modifying a running simulation,
   - logging and plotting outputs,
   - performance comparisons for 6DoF runs.

13. **Testing and validation**
   The `test/` tree contains scenario-based regression tests for both 3DoF and 6DoF, including NASA-style atmosphere/orbit cases and a two-stage rocket scenario with external CSV fixtures. The tests validate the numerical pipeline against known outputs, which is important because architecture correctness depends on module ordering, table interpolation, and solver/event behavior.

14. **External dependencies that shape the architecture**
   The main external technologies are **Numba** and **SciPy**. Numba influences the design toward statically described module classes and jitclass specs; SciPy supplies the numerical integration engine. The architecture is therefore optimized for repeated numeric evaluation rather than request/response workloads.

Main entry points: [`odessa/modules/6dof`](https://github.com/nsarrazin/odessa/tree/master/odessa/modules/6dof) (6DoF modules), [`odessa/modules/3dof`](https://github.com/nsarrazin/odessa/tree/master/odessa/modules/3dof) (3DoF modules), [`odessa/simulation.py`](https://github.com/nsarrazin/odessa/blob/master/odessa/simulation.py) (Simulation), [`odessa/phase.py`](https://github.com/nsarrazin/odessa/blob/master/odessa/phase.py) (Phase)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime"]
  node_simulation["Simulation<br/>orchestrator<br/>[simulation.py]"]
  node_phase["Phase<br/>segment<br/>[phase.py]"]
  node_rhs(("RHS loop<br/>numeric loop"))
  node_events{{"Events<br/>termination logic"}}
  node_solver(("SciPy solver<br/>external integrator"))
end

subgraph group_physics["Physics"]
  node_core3[("Core 3DoF<br/>shared state<br/>[Core3DoF.py]")]
  node_core6[("Core 6DoF<br/>shared state<br/>[Core6DoF.py]")]
  node_modules3["3DoF modules<br/>module stack"]
  node_modules6["6DoF modules<br/>module stack"]
  node_atmos["Atmos<br/>environment<br/>[Atmos.py]"]
  node_mass["Mass<br/>propagation<br/>[Mass.py]"]
  node_gravity["Gravity<br/>force model<br/>[GravityJ2.py]"]
  node_aero["Aero<br/>force model"]
  node_thrust["Thrust<br/>propulsion<br/>[Thrust.py]"]
  node_tower["Tower<br/>constraint<br/>[Tower.py]"]
  node_dynamics["Dynamics<br/>eom assembly"]
end

subgraph group_support["Support"]
  node_helpers["Helpers<br/>utilities"]
  node_jit(("Numba JIT<br/>external runtime"))
end

subgraph group_delivery["Delivery"]
  node_config["Config<br/>json setup"]
  node_scripts["Scripts<br/>demos"]
  node_tests["Tests<br/>regression suite"]
end

node_config -->|"defines run"| node_simulation
node_simulation -->|"owns"| node_phase
node_simulation -->|"loads"| node_events
node_simulation -->|"drives"| node_solver
node_solver -->|"calls"| node_rhs
node_rhs -->|"executes"| node_phase
node_rhs -->|"writes"| node_core3
node_rhs -->|"writes"| node_core6
node_phase -->|"orders"| node_modules3
node_phase -->|"orders"| node_modules6
node_modules3 -->|"uses"| node_atmos
node_modules3 -->|"uses"| node_gravity
node_modules3 -->|"uses"| node_mass
node_modules3 -->|"uses"| node_thrust
node_modules3 -->|"finishes"| node_dynamics
node_modules6 -->|"uses"| node_atmos
node_modules6 -->|"uses"| node_gravity
node_modules6 -->|"uses"| node_mass
node_modules6 -->|"uses"| node_aero
node_modules6 -->|"uses"| node_thrust
node_modules6 -->|"uses"| node_tower
node_modules6 -->|"finishes"| node_dynamics
node_events -->|"controls"| node_phase
node_helpers -->|"supports"| node_modules3
node_helpers -->|"supports"| node_modules6
node_helpers -->|"supports"| node_simulation
node_jit -->|"structures"| node_core3
node_jit -->|"structures"| node_core6
node_jit -->|"compiles"| node_modules3
node_jit -->|"compiles"| node_modules6
node_scripts -->|"demonstrates"| node_simulation
node_tests -->|"validates"| node_simulation
node_tests -->|"validates"| node_helpers

click node_config "https://github.com/nsarrazin/odessa/tree/master/scripts/configs"
click node_simulation "https://github.com/nsarrazin/odessa/blob/master/odessa/simulation.py"
click node_phase "https://github.com/nsarrazin/odessa/blob/master/odessa/phase.py"
click node_core3 "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/3dof/core/Core3DoF.py"
click node_core6 "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/core/Core6DoF.py"
click node_modules3 "https://github.com/nsarrazin/odessa/tree/master/odessa/modules/3dof"
click node_modules6 "https://github.com/nsarrazin/odessa/tree/master/odessa/modules/6dof"
click node_atmos "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/atmos/Atmos.py"
click node_mass "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/mass/Mass.py"
click node_gravity "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/gravity/GravityJ2.py"
click node_aero "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/aero/AeroBallistic6DoF.py"
click node_thrust "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/thrust/Thrust.py"
click node_tower "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/tower/Tower.py"
click node_dynamics "https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/dynamics/DynamicsSpherical.py"
click node_events "https://github.com/nsarrazin/odessa/tree/master/odessa/events"
click node_helpers "https://github.com/nsarrazin/odessa/tree/master/odessa/helpers"
click node_scripts "https://github.com/nsarrazin/odessa/tree/master/scripts"
click node_tests "https://github.com/nsarrazin/odessa/tree/master/test"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_simulation,node_phase,node_rhs,node_events,node_solver toneBlue
class node_core3,node_core6,node_modules3,node_modules6,node_atmos,node_mass,node_gravity,node_aero,node_thrust,node_tower,node_dynamics toneAmber
class node_helpers,node_jit toneMint
class node_config,node_scripts,node_tests toneRose
```

## Components

### Runtime

Simulation orchestration and shared execution flow.

- [Simulation](https://github.com/nsarrazin/odessa/blob/master/odessa/simulation.py): orchestrator · Top-level simulation boundary that builds runs, owns phases, and drives execution. · `odessa/simulation.py`
- [Phase](https://github.com/nsarrazin/odessa/blob/master/odessa/phase.py): segment · A simulation segment with ordered modules and event conditions. · `odessa/phase.py`
- **RHS loop**: numeric loop · Repeated solver callback that populates shared state, runs modules, and returns derivatives.
- [Events](https://github.com/nsarrazin/odessa/tree/master/odessa/events): termination logic · Event modules that stop phases or trigger transitions during integration. · `odessa/events`
- **SciPy solver**: external integrator · Numerical integration engine repeatedly invoking the RHS callback.

### Physics

Core model subsystems for flight dynamics.

- [Core 3DoF](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/3dof/core/Core3DoF.py): shared state · 3DoF shared state bus for forces, mass, and derivatives. · `odessa/modules/3dof/core/Core3DoF.py`
- [Core 6DoF](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/core/Core6DoF.py): shared state · 6DoF shared state bus including translational and rotational quantities. · `odessa/modules/6dof/core/Core6DoF.py`
- [3DoF modules](https://github.com/nsarrazin/odessa/tree/master/odessa/modules/3dof): module stack · Translational flight-dynamics modules executed in fixed order. · `odessa/modules/3dof`
- [6DoF modules](https://github.com/nsarrazin/odessa/tree/master/odessa/modules/6dof): module stack · Rigid-body flight-dynamics modules with orientation, moments, and constraints. · `odessa/modules/6dof`
- [Atmos](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/atmos/Atmos.py): environment · Atmospheric property models shared by both dynamics stacks. · `odessa/modules/6dof/atmos/Atmos.py`
- [Mass](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/mass/Mass.py): propagation · Mass and inertia evolution from tables or scripted logic. · `odessa/modules/6dof/mass/Mass.py`
- [Gravity](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/gravity/GravityJ2.py): force model · Gravity models including J2 and simpler approximations. · `odessa/modules/6dof/gravity/GravityJ2.py`
- [Aero](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/aero/AeroBallistic6DoF.py): force model · Aerodynamic force and moment models driven by tables or analytic forms. · `odessa/modules/6dof/aero/AeroBallistic6DoF.py`
- [Thrust](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/thrust/Thrust.py): propulsion · Engine and thrust-table models that feed force accumulation. · `odessa/modules/6dof/thrust/Thrust.py`
- [Tower](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/tower/Tower.py): constraint · Launch-rail or rigid constraint behavior used in 6DoF scenarios. · `odessa/modules/6dof/tower/Tower.py`
- [Dynamics](https://github.com/nsarrazin/odessa/blob/master/odessa/modules/6dof/dynamics/DynamicsSpherical.py): eom assembly · Final equations-of-motion assembly that converts accumulated loads into derivatives. · `odessa/modules/6dof/dynamics/DynamicsSpherical.py`

### Support

Helpers and data-driven inputs used by the model.

- [Helpers](https://github.com/nsarrazin/odessa/tree/master/odessa/helpers): utilities · Cross-cutting math, frames, interpolation, and encoding utilities. · `odessa/helpers`
- **Numba JIT**: external runtime · JIT-compiled structured state and modules for repeated numeric evaluation.

### Delivery

Scripts and regression coverage that exercise the framework.

- [Config](https://github.com/nsarrazin/odessa/tree/master/scripts/configs): json setup · User-facing JSON and scripted setup that define runs and phases. · `scripts/configs`
- [Scripts](https://github.com/nsarrazin/odessa/tree/master/scripts): demos · Runnable examples, benchmarks, and feature demos for composing simulations. · `scripts`
- [Tests](https://github.com/nsarrazin/odessa/tree/master/test): regression suite · Scenario-based validation for 3DoF, 6DoF, and helper utilities. · `test`

## Connections

- Config → Simulation: defines run · Configuration and scripted setup are consumed to build simulations.
- Simulation → Phase: owns · A simulation is composed of one or more phases.
- Simulation → Events: loads · Simulation setup wires in phase-control events.
- Simulation → SciPy solver: drives · Simulation hands the phase runtime to the numerical integrator.
- SciPy solver → RHS loop: calls · The integrator repeatedly evaluates the RHS callback.
- RHS loop → Phase: executes · Each RHS evaluation runs the active phase logic.
- RHS loop → Core 3DoF: writes · 3DoF modules accumulate state and derivatives on shared core state.
- RHS loop → Core 6DoF: writes · 6DoF modules accumulate state and derivatives on shared core state.
- Phase → 3DoF modules: orders · A phase configures the ordered 3DoF module chain.
- Phase → 6DoF modules: orders · A phase configures the ordered 6DoF module chain.
- 3DoF modules → Atmos: uses · 3DoF model family includes atmospheric state preparation.
- 3DoF modules → Gravity: uses · 3DoF model family includes gravity contributions.
- 3DoF modules → Mass: uses · 3DoF model family includes mass evolution.
- 3DoF modules → Thrust: uses · 3DoF model family includes propulsion forcing.
- 3DoF modules → Dynamics: finishes · 3DoF dynamics assembly produces derivatives.
- 6DoF modules → Atmos: uses · 6DoF model family includes atmospheric state preparation.
- 6DoF modules → Gravity: uses · 6DoF model family includes gravity contributions.
- 6DoF modules → Mass: uses · 6DoF model family includes mass and inertia evolution.
- 6DoF modules → Aero: uses · 6DoF model family includes aerodynamic forces and moments.
- 6DoF modules → Thrust: uses · 6DoF model family includes propulsion forcing.
- 6DoF modules → Tower: uses · 6DoF model family includes launch-constraint behavior.
- 6DoF modules → Dynamics: finishes · 6DoF dynamics assembly produces derivatives.
- Events → Phase: controls · Events can terminate a phase or trigger transition behavior.
- Helpers → 3DoF modules: supports · Helper math and interpolation utilities underpin model modules.
- Helpers → 6DoF modules: supports · Helper math and interpolation utilities underpin model modules.
- Helpers → Simulation: supports · Encoding and transformation helpers support orchestration and data handling.
- Numba JIT → Core 3DoF: structures · Numba shapes the 3DoF core as structured numeric state.
- Numba JIT → Core 6DoF: structures · Numba shapes the 6DoF core as structured numeric state.
- Numba JIT → 3DoF modules: compiles · Numba accelerates module evaluation in the 3DoF stack.
- Numba JIT → 6DoF modules: compiles · Numba accelerates module evaluation in the 6DoF stack.
- Scripts → Simulation: demonstrates · Example scripts show how to compose and run simulations.
- Tests → Simulation: validates · Regression tests exercise simulation assembly and outputs.
- Tests → Helpers: validates · Helper tests cover interpolation and numeric utilities.
