Skip to content

Latest commit

 

History

History
330 lines (262 loc) · 10 KB

File metadata and controls

330 lines (262 loc) · 10 KB

"""Heliosail-RX Production Architecture

A NASA-grade aerospace simulation platform for multi-physics solar sail mission design.

Architecture Overview

Heliosail-RX uses a Hybrid Modular + Simulation Kernel architecture:

heliosail-rx/
├── kernel/              ← Simulation runtime core (event bus, state mgmt, scheduler)
├── models/              ← Physics modules (orbital, sail, propulsion, environment, GNC)
├── control/             ← Mission optimization & GNC decision-making
├── data/                ← Persistent state (logging, checkpointing, telemetry)
├── api/                 ← External interface (programmatic, REST, file I/O)
├── config/              ← Simulation configuration & mission profiles
├── gui/                 ← Visualization & interactive UI
└── infra/               ← Deployment (Docker, CI/CD, reproducibility)

Core Design Principles

  1. Separation of Concerns

    • Kernel handles execution & scheduling; models are completely decoupled
    • Physics modules have NO direct dependency on kernel (inverted control)
    • API consumes kernel & models; models don't know about API
  2. Temporal Consistency

    • Global simulation time managed by kernel
    • All computations stamped with epoch (absolute time, mission elapsed time)
    • Events fully ordered; replay is deterministic
  3. Interface Contracts

    • All module interactions via well-defined data models
    • Strongly typed (Python dataclasses, optional Pydantic validation)
    • Schema versioning for reproducibility
  4. Auditability & Reproducibility

    • Every state transition logged with full provenance
    • Configuration + seed stored with results
    • Checkpointing at intervals for restart & debugging
  5. Multi-Rate Integration

    • Kernel schedules tasks at different time steps (ODE, event detection, logging)
    • Sophisticated time managers (symplectic, adaptive RK, implicit stiff solvers)
    • No hardcoded dt; all configurable

Kernel Architecture

SimulationEngine

The core runtime:

engine = SimulationEngine(config=sim_config, models={...manifests...})
engine.initialize(initial_state)
engine.run(t_end=86400.0, callbacks=[...event_handlers...])
result = engine.finalize()  # → SimulationResult with telemetry, state history

Responsibilities:

  • Time stepping (fixed or adaptive)
  • State propagation (calls physics models in correct order)
  • Event detection & handling
  • Logging & checkpointing
  • Exception handling & recovery

Data Models

All data transmitted via immutable dataclasses:

  • SimulationConfig: mission parameters, solver settings, physics toggles
  • SpacecraftState: r, v, q, ω, membrane, power, attitude (single epoch)
  • PhysicsModule: interface contract (inputs → outputs)
  • Event: discrete occurrence (CME arrival, collision, maneuver trigger)
  • SimulationStep: one time step result (state, derivatives, events, diagnostics)
  • SimulationResult: full run (config, trajectory, telemetry, audit log)

Event Bus & Callbacks

The kernel fires events at key points:

  • on_step_start: beginning of time step
  • on_physics_computed: after force/acceleration
  • on_events_detected: discrete events found
  • on_step_complete: end of time step
  • on_checkpoint: periodic save
  • on_error: exception occurred

External code (plotting, early stopping, adaptive stepping) registers listeners.

Physics Module Interface

Any physics module must implement:

class PhysicsModule:
    """Interface contract for all physics computations."""
    
    @dataclass
    class Input:
        state: SpacecraftState
        t_epoch: float
        params: Dict[str, Any]
    
    @dataclass
    class Output:
        acceleration: np.ndarray  # [m/s²] in inertial frame
        diagnostics: Dict[str, float]  # e.g., {"irradiance_W_m2": 1361.0}
        events: List[Event]  # discrete occurrences
    
    def compute(self, inp: Input) -> Output:
        \"\"\"Stateless computation; no side effects.\"\"\"
        pass

Advantages:

  • No coupling to kernel internals
  • Trivial to parallelize (embarrassingly parallel over runs/scenarios)
  • Easy testing (just call .compute())
  • Composition is explicit

Coupling Strategy

Task Graph Execution:

    [Load Config, ICs]
         ↓
   [Initialize Models]
         ↓
    [Time Loop] ─────────┐
         ↓               │
   [Compute Physics]     │
   (parallel batch)      │
         ↓               │
   [Detect Events]       │
         ↓               │
   [Apply State Law]     │
   (GNC, deploy, etc)    │
         ↓               │
   [Log Telemetry]       │
         ↓               │
   [Step Time]           │
         └───→ [t < t_end?]
                    ↓ (no)
              [Postprocess]
                    ↓
              [Return Result]

Dependencies:

  • Physics models depend on: state, time, config (only)
  • State evolution depends on: accelerations, event actions
  • Event detection depends on: new state, previous state
  • Logging depends on: new state, computed derivatives
  • GNC depends on: state, guidance law (no direct feedback on physics)

API Layers

1. Programmatic API (Python)

from heliosail_rx import Mission, SimulationEngine

# High-level: mission-focused
mission = Mission.load("configs/ikaros_like.yaml")
result = mission.run()

# Mid-level: experiment-focused
engine = SimulationEngine(config, physics_models)
result = engine.run(t_end=86400.0, callbacks=[...])

# Low-level: component-focused
output = orbital_mech_module.compute(PhysicsModule.Input(...))

2. File I/O API (YAML/JSON)

# missions/ikaros_study.yaml
simulation:
  t_start: 0.0
  t_end: 15768000  # 6 months
  dt_nominal: 10.0
  solver: rk4_symplectic
  
spacecraft:
  mass_kg: 260
  sail:
    area_m2: 196
    reflectivity: 0.85
    coating: "aluminized_polyimide"
  
physics_enabled:
  - orbital_mechanics
  - sail_srp_tensor
  - sail_thermal
  - environment_solar_cycle
  - radiation_belts
  
output:
  trajectory_step_s: 100
  telemetry_step_s: 1000
  checkpoint_step_s: 86400

3. REST API (optional, for interactive dashboards)

GET    /api/v1/missions         → list missions
POST   /api/v1/missions         → create & submit run
GET    /api/v1/missions/{id}    → status & current state
GET    /api/v1/missions/{id}/trajectory  → download trajectory
POST   /api/v1/missions/{id}/pause       → pause run
POST   /api/v1/missions/{id}/resume      → resume run

Data / Logging Infrastructure

Telemetry

  • Real-time telemetry: state, accelerations, energy, diagnostics (configurable cadence)
  • Checkpoint files: full state + solver state at intervals (restart capability)
  • Audit log: every significant action (init, config change, event, exception)

Storage Options

  • HDF5: trajectory + telemetry (Pythonic; efficient compression)
  • Parquet: long-form telemetry (analytics, Pandas-friendly)
  • SQLite: audit log + metadata (queryable)
  • YAML/JSON: human-readable results summary

Reproducibility

result.config.seed                    # RNG seed for stochastic models
result.config.commit_hash             # Code version
result.config.timestamp               # When run
result.audit_log                      # All decisions made

Reproduction:

result2 = SimulationEngine(config=result.config, seed=result.config.seed).run()
assert result2.trajectoryresult.trajectory  # bit-for-bit if deterministic

Deployment Topology

Development Local

heliosail-rx/
├── [source code]
├── examples/
│   └── ikaros_study.py    ← Jupyter or script
└── tests/

Single-Machine Batch

python heliosail_rx/cli.py run --config experiments/sweep_sail_area.yaml
→ Produces: results/sweep_sail_area_2026-02-22_14-30-45/
  ├── config.yaml           (what ran)
  ├── trajectory.h5         (full result)
  ├── telemetry.parquet     (time series for plotting)
  ├── audit.db              (audit log)
  └── run.log               (stdout/stderr capture)

Cluster / Cloud

heliosail_rx/infra/
├── Dockerfile             (containerized environment)
├── slurm_submit.sh        (HPC batch submit)
└── kubernetes_job.yaml    (cloud submit)

# Usage:
sbatch heliosail_rx/infra/submit_parametric_sweep.sh \
  --config sweep.yaml \
  --jobs 64
→ Produces: results/sweep_*/

Configuration Management

Three-tier hierarchy:

1. Defaults (heliosail_rx/config/defaults.yaml)
   ↓ (overridden by)
2. User config (experiments/mission_X.yaml)
   ↓ (overridden by)
3. CLI / programmatic (engine = SimulationEngine(..., force_dt=5.0))

Validation & Testing Strategy

Unit Tests

  • Each physics module in isolation: test_orbital_mechanics.py, etc.
  • No kernel; just call .compute()

Integration Tests

  • Simple 2-body mission → known ephemeris
  • CME event → documented behavior
  • Sail deployment → energy conservation check

Regression Tests

  • Reference mission: run weekly, archive trajectory
  • New code: compute L2 distance to reference
  • Threshold: detect breaking changes

Mission Validation

  • IKAROS reference trajectory → match published data
  • LightSail 2 orbital raise → match NASA measured performance

Next Steps (Implementation)

  1. ✅ Create kernel/ package: SimulationEngine, EventBus, TimeManager
  2. ✅ Create models/core.py: dataclass definitions
  3. ✅ Reorganize physics modules → models/
  4. ✅ Create api/ package: high-level Mission, CLI
  5. ✅ Create config/ package: schema, defaults, loading
  6. ✅ Create data/ package: logging, checkpointing
  7. ✅ Create infra/ package: Docker, CI/CD templates
  8. ✅ Build end-to-end example: simple 2-body + GNC

References:

  • NASA GMAT architecture (state vector, propagator separation)
  • JPL SADen simulation framework (event bus, multi-rate scheduling)
  • OpenMDAO hierarchical approach (component composition)
  • Basilisk astrodynamics simulator (flexible task scheduling) """