Architecture¶
This document provides a detailed view of Astrea's software architecture, component interactions, and design rationale. The architecture reflects the dual goals of safety and performance in aerospace engineering applications.
High-Level Architecture¶
Layered Design¶
Astrea follows a strict layered architecture where dependencies flow downward and each layer provides a specific level of abstraction:
flowchart TB
subgraph "Layer 4: Applications"
mission["Mission Planning"]
analysis["Coverage Analysis"]
validation["Benchmark Validation"]
end
subgraph "Layer 3: Domain Libraries"
trace["trace/<br/>Access Analysis"]
snapshot["snapshot/<br/>Data Management"]
end
subgraph "Layer 2: Astrodynamics Core"
astro["astro/<br/>Core Astrodynamics"]
end
subgraph "Layer 1: Foundation"
math["math/<br/>Mathematics"]
units["units/<br/>Unit System"]
utils["utilities/<br/>Cross-cutting"]
end
subgraph "Layer 0: External Dependencies"
mpunits["mp-units"]
std["C++ Standard Library"]
external["Third-party Libraries"]
end
mission -.-> trace
analysis -.-> trace
validation -.-> astro
trace --> astro
snapshot --> astro
astro --> math
astro --> units
astro --> utils
math --> units
units --> mpunits
utils --> std
snapshot --> external
Design Constraints¶
- No Circular Dependencies: Components may only depend on lower layers
- Minimal External Dependencies: Each dependency must provide clear, substantial value
- Header-Only Design: All core functionality available without separate linking
- Platform Independence: No platform-specific code in core libraries
- Exception Safety: All operations provide strong exception safety guarantees
Component Architecture¶
Layer 2: Astrodynamics Core (astro/)¶
The heart of Astrea, providing fundamental astrodynamics functionality:
flowchart TB
subgraph "astro/ Component Structure"
state["state/<br/>Orbital States"]
frames["frames/<br/>Coordinate Systems"]
time["time/<br/>Time Systems"]
systems["systems/<br/>Celestial Bodies"]
propagation["propagation/<br/>Orbit Propagation"]
platforms["platforms/<br/>Spacecraft & Sensors"]
types["types/<br/>Common Types"]
utilities["utilities/<br/>Astro Utilities"]
end
state --> types
frames --> types
time --> types
propagation --> state
propagation --> frames
propagation --> time
propagation --> systems
platforms --> state
platforms --> frames
utilities --> state
utilities --> frames
Key Abstractions¶
| Abstraction | Purpose | Implementation Strategy |
|---|---|---|
State |
Represents spacecraft position/velocity | Template-based for different coordinate systems |
Frame |
Coordinate reference frames | Type-safe compile-time frame checking |
Epoch |
Points in time with time scale info | Immutable value types with automatic conversions |
Body |
Celestial bodies with physical properties | Compile-time constants where possible |
Propagator |
Advances orbital states through time | Strategy pattern with customizable force models |
Data Flow Pattern¶
- Input Validation: All inputs validated at API boundaries
- Unit Conversion: Automatic unit conversions using mp-units
- Frame Transformation: Explicit coordinate frame handling
- Computation: Core algorithms with error checking
- Output Construction: Results in requested units/frames
Layer 3: Domain Libraries¶
Access Analysis (trace/)¶
flowchart LR
platform["Platform<br/>(Spacecraft/Ground Station)"] --> link["Link<br/>(Communication Path)"]
link --> access["Access Window<br/>(Time Period)"]
access --> stats["Statistics<br/>(Gap/Coverage Analysis)"]
subgraph "Analysis Types"
visibility["Visibility Analysis"]
interference["Interference Detection"]
coverage["Coverage Calculation"]
link_budget["Link Budget Analysis"]
end
Key Components:
- Platform: Represents spacecraft, ground stations, or targets
- Link: Models communication or observation paths between platforms
- AccessWindow: Time intervals when platforms can communicate
- Interference: Modeling of signal interference between multiple platforms
Data Management (snapshot/)¶
flowchart TB
subgraph "Data Sources"
spacetrack["Spacetrack.org"]
files["Local Files"]
spice_kernels["SPICE Kernels"]
user_data["User Input"]
end
subgraph "Storage Layer"
database["SQLite Database"]
cache["Memory Cache"]
ephemeris["Ephemeris Store"]
end
subgraph "Access Layer"
catalog["Object Catalog"]
query["Query Interface"]
sync["Data Synchronization"]
end
spacetrack --> database
files --> database
spice_kernels --> ephemeris
user_data --> cache
database --> catalog
cache --> catalog
ephemeris --> query
catalog --> sync
Key Features: - Automatic TLE downloads and updates from Spacetrack.org - Efficient storage and retrieval of large orbital datasets - SPICE kernel management and ephemeris caching - Version control and data provenance tracking
Layer 1: Foundation Libraries¶
Mathematics (math/)¶
// Unit-aware vector operations
template<typename Unit>
class Vector3 {
mp_units::quantity<Unit> x_, y_, z_;
public:
auto magnitude() const -> mp_units::quantity<Unit>;
auto normalized() const -> Vector3<mp_units::one>;
auto cross(const Vector3<Unit>& other) const -> Vector3<Unit>;
auto dot(const Vector3<Unit>& other) const -> mp_units::quantity<Unit * Unit>;
};
Design Principles: - All mathematical operations preserve unit information - Template-based for compile-time optimization - SIMD-friendly memory layout where possible - Immutable value semantics for safety
Unit System (units/)¶
// Aerospace-specific unit extensions
namespace astrea::units {
// Distance units
inline constexpr auto earth_radius = 6378.137 * si::kilometre;
inline constexpr auto astronomical_unit = 149597870.7 * si::kilometre;
// Time units
inline constexpr auto julian_day = 86400.0 * si::second;
inline constexpr auto julian_year = 365.25 * julian_day;
// Gravitational parameters
inline constexpr auto earth_mu = 398600.4418 * si::kilo<si::metre>.pow<3>() / si::second.pow<2>();
}
System Boundaries and Interfaces¶
External Integration Points¶
SPICE Integration¶
sequenceDiagram
participant App as Application
participant Astrea as Astrea Core
participant SPICE as SPICE Toolkit
participant Kernel as Kernel Files
App->>Astrea: Request planetary ephemeris
Astrea->>SPICE: Load required kernels
SPICE->>Kernel: Read ephemeris data
Kernel-->>SPICE: Chebyshev coefficients
SPICE-->>Astrea: Position/velocity vectors
Astrea->>Astrea: Convert to Astrea types
Astrea-->>App: Unit-aware State object
Database Integration¶
erDiagram
CATALOG {
string norad_id PK
string name
datetime epoch
string classification
}
TLE_DATA {
string norad_id FK
datetime epoch
string line1
string line2
datetime created
}
EPHEMERIS {
string object_id FK
datetime start_time
datetime end_time
blob state_data
string algorithm
}
CATALOG ||--o{ TLE_DATA : contains
CATALOG ||--o{ EPHEMERIS : generates
Error Handling Strategy¶
Compile-time Error Prevention¶
// This will not compile - unit mismatch detected at compile-time
auto invalid_calculation() {
auto distance = 1000.0 * units::metre;
auto time = 60.0 * units::second;
auto acceleration = distance + time; // ERROR: Cannot add length and time
return acceleration;
}
// This will not compile - frame mismatch detected
auto invalid_transformation() {
auto state_eci = state::cartesian{/* ... */};
auto position_ecef = state_eci.position(); // ERROR: Must explicitly convert frames
return position_ecef;
}
Runtime Error Handling¶
// Exception hierarchy for runtime errors
namespace astrea::exceptions {
class AstreaException : public std::exception {
// Base class for all Astrea exceptions
};
class NumericalException : public AstreaException {
// Numerical integration failures, convergence issues
};
class DataException : public AstreaException {
// Missing data, corrupted files, network failures
};
class ConfigurationException : public AstreaException {
// Invalid configurations, missing dependencies
};
}
Performance Architecture¶
Compile-time Optimization¶
// Example: Coordinate transformation matrices computed at compile-time
template<typename FromFrame, typename ToFrame>
constexpr auto transformation_matrix() {
if constexpr (std::is_same_v<FromFrame, ToFrame>) {
return math::Matrix3::identity();
} else if constexpr (is_simple_rotation_v<FromFrame, ToFrame>) {
return compute_rotation_matrix<FromFrame, ToFrame>();
} else {
return compute_full_transformation<FromFrame, ToFrame>();
}
}
Memory Layout Optimization¶
// Structure of Array (SoA) pattern for bulk operations
template<typename T>
class StateArray {
std::vector<mp_units::quantity<units::metre>> x_, y_, z_;
std::vector<mp_units::quantity<units::metre_per_second>> vx_, vy_, vz_;
public:
// SIMD-friendly bulk operations
void propagate_all(mp_units::quantity<units::second> dt);
void transform_all_to_frame(auto target_frame);
};
Extensibility Architecture¶
Plugin Interface Pattern¶
// Abstract interface for custom force models
class ForceModel {
public:
virtual ~ForceModel() = default;
virtual auto acceleration(
const state::cartesian& state,
const time::epoch& epoch
) const -> math::Vector3<units::acceleration> = 0;
virtual auto name() const -> std::string_view = 0;
};
// Registration system for custom components
template<typename T>
void register_force_model(std::string_view name) {
ForceModelRegistry::instance().register_model<T>(name);
}
Type Erasure for Runtime Flexibility¶
// Type-erased wrapper for different propagator types
class Propagator {
class PropagatorImpl {
public:
virtual ~PropagatorImpl() = default;
virtual auto propagate(
const state::cartesian& initial_state,
mp_units::quantity<units::second> duration
) const -> state::cartesian = 0;
};
template<typename ConcretePropagator>
class PropagatorWrapper : public PropagatorImpl {
ConcretePropagator impl_;
public:
// Implementation details...
};
std::unique_ptr<PropagatorImpl> impl_;
};
Quality Assurance Architecture¶
Validation Framework¶
flowchart TB
subgraph "Test Types"
unit["Unit Tests<br/>Component isolation"]
integration["Integration Tests<br/>Component interaction"]
benchmark["Benchmark Tests<br/>NASA validation data"]
performance["Performance Tests<br/>Regression prevention"]
end
subgraph "Validation Data"
nasa["NASA Test Cases"]
reference["Reference Implementations"]
analytical["Analytical Solutions"]
real_world["Real Mission Data"]
end
unit --> nasa
integration --> reference
benchmark --> nasa
benchmark --> analytical
performance --> real_world
Continuous Integration Pipeline¶
- Static Analysis: Code quality, security, and style checks
- Unit Testing: Individual component validation
- Integration Testing: Cross-component interaction testing
- Performance Testing: Benchmark comparison and regression detection
- Documentation Testing: Example code compilation and execution
- Platform Testing: Multi-platform compatibility verification
This architecture represents the evolution of aerospace software engineering practices, combining domain expertise with modern C++ techniques to create a foundation for reliable, high-performance space mission analysis.