Skip to main content
INS // Insights

Agile Cloud Sub Delivery for Government IT

Updated May 2026 · 7 min read

Space Domain Awareness (SDA) — tracking and characterizing all objects in Earth orbit to protect space assets and predict collisions — has moved from a niche Space Force mission to a critical national security requirement as orbital congestion increases. The software architecture requirements for modern SDA systems span real-time data ingestion, orbital mechanics computation, probabilistic conjunction analysis, and operator interface design.

What Space Domain Awareness Systems Must Do

A complete SDA architecture must:

  1. Ingest: Receive observations from diverse sensors (radar, optical, passive RF) in multiple formats at high volume
  2. Correlate: Associate new observations with known catalog objects or flag as uncorrelated tracks (UCTs)
  3. Propagate: Maintain accurate state vectors (position and velocity) for all catalog objects using orbital mechanics models
  4. Assess: Compute conjunction probabilities (probability of collision between objects) and generate alerts
  5. Display: Provide operator situational awareness — 3D visualization, alert dashboards, conjunction reports
  6. Disseminate: Share data with commercial operators, allies, and civil space agencies per policy

Data Ingestion Architecture

SDA systems receive sensor data from geographically distributed, heterogeneous sensors. A cloud-native ingestion architecture:

from dataclasses import dataclass
from datetime import datetime
from typing import Optional
import boto3
import json

@dataclass 
class RadarObservation:
    sensor_id: str
    observation_time: str     # ISO 8601 UTC
    azimuth_deg: float
    elevation_deg: float
    range_km: float
    range_rate_km_s: float
    snr_db: float
    covariance: list[list[float]]  # 3x3 measurement covariance
    object_id: Optional[str] = None  # Assigned after correlation

def ingest_observation(obs: RadarObservation, 
                        queue_url: str,
                        region: str = 'us-gov-east-1') -> str:
    """
    Route observation to SQS queue for correlation processing.
    Returns message ID for tracking.
    """
    sqs = boto3.client('sqs', region_name=region)
    
    msg = sqs.send_message(
        QueueUrl=queue_url,
        MessageBody=json.dumps({
            'observation': obs.__dict__,
            'ingested_at': datetime.utcnow().isoformat(),
            'processing_state': 'PENDING_CORRELATION'
        }),
        MessageGroupId=obs.sensor_id,  # FIFO queue by sensor
        MessageAttributes={
            'ObservationType': {
                'StringValue': 'RADAR',
                'DataType': 'String'
            }
        }
    )
    
    return msg['MessageId']

Orbital State Propagation

The Simplified General Perturbations 4 (SGP4) model is the standard for Earth-orbiting object propagation from Two-Line Element sets:

from skyfield.api import load, EarthSatellite
from skyfield.timelib import Time
import numpy as np

class CatalogObject:
    def __init__(self, norad_id: int, name: str, tle_line1: str, tle_line2: str):
        self.norad_id = norad_id
        self.name = name
        ts = load.timescale()
        self.satellite = EarthSatellite(tle_line1, tle_line2, name, ts)
        self._epoch = self.satellite.epoch
    
    def propagate_to(self, utc_time: datetime) -> dict:
        """
        Propagate to given time using SGP4.
        Returns ECI position and velocity in km and km/s.
        """
        ts = load.timescale()
        t = ts.from_datetime(utc_time)
        
        geocentric = self.satellite.at(t)
        pos = geocentric.position.km
        vel = geocentric.velocity.km_per_s
        
        return {
            'norad_id': self.norad_id,
            'epoch': utc_time.isoformat(),
            'position_eci_km': pos.tolist(),
            'velocity_eci_km_s': vel.tolist(),
            'age_days': (utc_time - self._epoch.utc_datetime()).total_seconds() / 86400
        }
    
    @property
    def needs_refresh(self) -> bool:
        """TLE accuracy degrades over time - flag for refresh after threshold."""
        ts = load.timescale()
        age_days = ts.now() - self._epoch
        return float(age_days) > 7.0  # Flag for TLE update after 7 days

Conjunction Analysis

Conjunction analysis computes the probability of collision between pairs of objects:

from scipy.stats import multivariate_normal
import numpy as np

def compute_conjunction_probability(
    primary_pos: np.ndarray,     # ECI km
    primary_cov: np.ndarray,     # 3x3 position covariance
    secondary_pos: np.ndarray,
    secondary_cov: np.ndarray,
    combined_hbr: float          # Combined hard body radius in km
) -> float:
    """
    Monte Carlo estimate of Pc (probability of collision).
    For production, use Alfano or Foster analytic methods for efficiency.
    """
    # Relative state
    rel_pos = primary_pos - secondary_pos
    rel_cov = primary_cov + secondary_cov
    
    # Miss distance
    miss_distance = np.linalg.norm(rel_pos)
    
    if miss_distance > 10 * combined_hbr:
        return 0.0  # Fast-reject for clearly non-conjunctions
    
    # Simplified 2D probability in encounter plane
    # (Production uses full 3D or encounter-plane reduction)
    try:
        rv = multivariate_normal(mean=rel_pos[:2], cov=rel_cov[:2, :2])
        # Integrate within hard body radius circle
        # This is simplified - production uses analytic methods
        return float(rv.pdf(np.array([0, 0])) * np.pi * combined_hbr**2)
    except Exception:
        return float('nan')

Alert Management and Dissemination

def evaluate_conjunction_alert(
    primary_id: str,
    secondary_id: str, 
    tca: datetime,
    miss_distance_km: float,
    probability_of_collision: float
) -> dict:
    """
    Evaluate conjunction against alert thresholds and generate 
    Conjunction Data Message (CDM) per CCSDS standards.
    """
    
    alert_level = 'GREEN'
    if probability_of_collision > 1e-4 or miss_distance_km < 1.0:
        alert_level = 'RED'
    elif probability_of_collision > 1e-5 or miss_distance_km < 5.0:
        alert_level = 'YELLOW'
    
    return {
        'cdm_version': '1.0',
        'primary_object_id': primary_id,
        'secondary_object_id': secondary_id,
        'tca': tca.isoformat(),
        'miss_distance_km': miss_distance_km,
        'probability_of_collision': probability_of_collision,
        'alert_level': alert_level,
        'generated_at': datetime.utcnow().isoformat()
    }

See Rutagon's satellite telemetry cloud processing and Space Force acquisition reform for related program and architecture context.

Explore Rutagon's aerospace capabilities.

FAQ

What is the difference between Space Situational Awareness (SSA) and Space Domain Awareness (SDA)?

SSA historically referred to tracking and characterizing objects in the space environment — conjunction analysis, collision avoidance, and reentry prediction. SDA is a broader term adopted by Space Force that adds the characterization of spacecraft behavior, intent analysis, potential threat identification, and integration of space environment effects. SDA is SSA plus the intelligence dimension.

How are Two-Line Elements (TLEs) generated and distributed?

The Space Force 18th Space Control Squadron generates and maintains the publicly available space object catalog, including TLEs distributed through Space-Track.org. TLEs are generated from observations by the Space Surveillance Network (SSN) — a global network of radar and optical sensors. The public catalog covers objects approximately 10cm and larger in LEO. Higher-accuracy, more complete catalogs are maintained for classified purposes.

What programming languages are used in SDA systems?

Python is widely used for mission analysis, algorithm development, and data pipeline work — the astropy and skyfield libraries provide mature orbital mechanics foundations. C++ is used for latency-sensitive propagation and conjunction processing. Java and C# appear in legacy ground system software. Cloud-native SDA developments increasingly use Python for processing and React/TypeScript for operator interfaces.

How does the commercial SDA market interact with government programs?

Commercial SDA providers (LeoLabs, ExoAnalytic, Slingshot Aerospace) operate sensor networks and analytics platforms that supplement government SSN data. Space Force has contracts with commercial SSA providers to access commercial data. Under Space Policy Directive-3, civil conjunction alerts go through the Commerce Department's Office of Space Commerce (LeoLabs is a provider to this program), while military functions remain with Space Force.

What accuracy is required for conjunction analysis in low Earth orbit?

Useful conjunction analysis in LEO requires object state vector accuracy in the range of hundreds of meters to a few kilometers. Below this threshold, false positives (unnecessary avoidance maneuvers) become unacceptably frequent; above this threshold, genuine high-risk conjunctions may be missed. The accuracy depends on the quality and frequency of observations, the age of the TLE, and the accuracy of the propagation model used.

Ready to discuss your project?

We deliver production-grade software for government, defense, and commercial clients. Let's talk about what you need.

Initiate Contact