Skip to content

Frame Transformations

Astrea provides a comprehensive coordinate frame transformation system that enables safe and efficient conversion between different reference frames. The transformation system is built on compile-time type safety and supports both static and dynamic frame conversions.

Transformation Framework

The frame transformation system is built around several key concepts:

  • Compile-time frame safety through template metaprogramming
  • Automatic transformation detection based on frame relationships
  • Center offset calculations for frames with different origins
  • Axis rotation matrices for frames with different orientations

Core Transformation Functions

Center Offset Calculations

For frames with different origins, the system automatically calculates position offsets:

#include <astro/frames/transformations.hpp>

// Get offset between Earth and Moon centers
CartesianVector<Distance, ECI> offset = 
    get_center_offset<earth::eci, moon::eci>(epoch);

// Frames with same origin have zero offset
CartesianVector<Distance, ECI> zeroOffset =
    get_center_offset<earth::eci, earth::ecef>(epoch); // Returns zero

Frame Concepts

The system uses C++20 concepts to enforce transformation rules:

// Frames with same origin
template<typename Frame_T, typename Frame_U>
concept HasSameOrigin = /* implementation */;

// Frames with same axis orientation
template<typename Frame_T, typename Frame_U> 
concept HasSameAxis = /* implementation */;

Transformation Types

Same Origin, Different Axes

Frames centered at the same body but with different orientations:

// Earth-centered frames with different axes
CartesianVector<Distance, ECEF> ecefPos = 
    transform<ECEF, ECI>(eciPosition, epoch);

// Requires rotation matrix calculation
// Accounts for Earth's rotation at the given epoch

Different Origin, Same Axes

Frames with the same orientation but different centers:

// Moon-centered inertial vs Earth-centered inertial
CartesianVector<Distance, moon::eci> moonPos =
    transform<moon::eci, earth::eci>(earthPos, epoch);

// Requires center offset calculation
// Uses ephemeris data for relative body positions

Different Origin and Axes

General transformation between arbitrary frames:

// Complex transformation: ECI to Moon body-fixed
CartesianVector<Distance, moon::body_fixed> moonBodyPos =
    transform<moon::body_fixed, earth::eci>(eciPos, epoch);

// Combines center offset + rotation transformation

Direction Cosine Matrices

Rotation transformations use direction cosine matrices (DCM):

#include <astro/frames/types/DirectionCosineMatrix.hpp>

// Create rotation matrix
DirectionCosineMatrix dcm = compute_rotation_matrix<ECEF, ECI>(epoch);

// Apply rotation to vector
CartesianVector<Distance, ECEF> rotatedPos = dcm * eciPosition;

Transformation Examples

Earth-Centered Transformations

// ECI to ECEF (accounts for Earth rotation)
Time epoch = epoch_to_julian_date("2024-01-01 12:00:00");

CartesianVector<Distance, ECI> eciPos(7000.0 * km, 0.0 * km, 0.0 * km);
CartesianVector<Distance, ECEF> ecefPos = 
    transform<ECEF, ECI>(eciPos, epoch);

// Velocity transformation includes Coriolis effects
CartesianVector<Velocity, ECI> eciVel(0.0 * km/s, 7.5 * km/s, 1.0 * km/s);
CartesianVector<Velocity, ECEF> ecefVel = 
    transform<ECEF, ECI>(eciVel, epoch, eciPos);

Relative Motion Frames

// Transform to Radial-Intrack-Crosstrack (RIC) frame
Keplerian referenceOrbit(7000.0 * km, 0.1, 45.0 * deg, 0.0 * deg, 0.0 * deg, 0.0 * deg);

CartesianVector<Distance, RIC> ricPosition = 
    transform<RIC, ECI>(eciPosition, epoch, referenceOrbit);

// RIC frame is centered on reference orbit
// Radial: towards/away from Earth center
// Intrack: along orbit velocity direction  
// Crosstrack: perpendicular to orbital plane

Multi-Body Transformations

// Earth to Moon center transformation
AstrodynamicsSystem system(CelestialBodyId::EARTH, {CelestialBodyId::MOON});

// Get Moon position relative to Earth
CartesianVector<Distance, earth::eci> moonPos = 
    system.get_relative_position(epoch, CelestialBodyId::EARTH, CelestialBodyId::MOON);

// Transform spacecraft position to Moon-centered frame
CartesianVector<Distance, moon::eci> moonRelativePos =
    transform<moon::eci, earth::eci>(spacecraftPos, epoch);

Performance Considerations

Compile-Time Optimization

  • Frame compatibility checked at compile time
  • Unnecessary transformations eliminated by compiler
  • Template specialization for common transformation pairs

Runtime Efficiency

  • Cached rotation matrices for repeated transformations
  • Optimized ephemeris computations using Chebyshev polynomials
  • Minimal temporary object creation
// Efficient repeated transformations
DirectionCosineMatrix cachedDCM = compute_rotation_matrix<ECEF, ECI>(epoch);
for (const auto& position : positions) {
    auto ecefPos = cachedDCM * position; // Reuse cached matrix
}

Error Handling

The transformation system provides robust error handling:

  • Compile-time errors for incompatible frame types
  • Runtime validation of transformation parameters
  • Graceful degradation for missing ephemeris data
  • Numerical stability checks for extreme cases

This comprehensive transformation framework ensures that coordinate frame conversions are both mathematically correct and computationally efficient, providing the foundation for reliable astrodynamics calculations across diverse reference frames.