A satellite is only as useful as the ground system that controls it. The most sophisticated spacecraft in orbit becomes an expensive piece of space debris without software systems that can uplink commands, downlink data, process telemetry, and monitor health — all within the narrow windows when the satellite passes overhead.
Ground systems software is one of the most demanding domains in software engineering. It operates under hard real-time constraints, handles massive data throughput, requires five-nines availability, and serves operators who make split-second decisions about assets worth hundreds of millions of dollars.
At Rutagon, we build software for aerospace and defense environments where failure modes include losing contact with orbital assets. Our work in satellite data processing and high-availability systems gives us deep understanding of the architecture patterns that ground systems demand.
Ground System Architecture
A modern satellite ground system is a distributed software platform with five core subsystems:
┌────────────────────────────────────────────────────────────────┐
│ Ground System Architecture │
├────────────┬────────────┬────────────┬────────────┬────────────┤
│ Antenna │ Telemetry │ Command & │ Data │ Mission │
│ Control │ Processing │ Control │ Management │ Planning │
│ │ │ │ │ │
│ • Tracking │ • Ingest │ • Command │ • Downlink │ • Pass │
│ • Pointing │ • Decode │ Building │ Capture │ Schedule │
│ • Handoff │ • Validate │ • Uplink │ • Storage │ • Resource │
│ • Freq │ • Archive │ • Verify │ • Process │ Alloc │
│ Control │ • Alert │ • Sequence │ • Distrib │ • Conflict │
│ │ │ │ │ Resolve │
└────────────┴────────────┴────────────┴────────────┴────────────┘ Each subsystem has distinct latency, throughput, and reliability requirements. Antenna control operates in milliseconds. Telemetry processing handles sustained gigabit data rates. Command and control requires absolute correctness with no retry mechanism — a malformed command to a satellite can't be taken back.
Telemetry Processing
Telemetry is the heartbeat of satellite operations. The spacecraft continuously transmits housekeeping data — temperatures, voltages, attitude, propellant levels, subsystem status — that ground operators use to assess health and make decisions.
Ingestion Pipeline
Telemetry ingestion must handle sustained high-throughput data streams with zero data loss. The architecture uses a streaming pipeline with multiple processing stages:
from dataclasses import dataclass
from datetime import datetime, timezone
from enum import Enum
from typing import Optional
import struct
class TelemetryStatus(Enum):
NOMINAL = "nominal"
WARNING = "warning"
CRITICAL = "critical"
STALE = "stale"
@dataclass
class TelemetryPoint:
spacecraft_id: str
mnemonic: str
raw_value: bytes
timestamp: datetime
ground_receipt_time: datetime
sequence_count: int
calibrated_value: Optional[float] = None
status: TelemetryStatus = TelemetryStatus.NOMINAL
class TelemetryProcessor:
def __init__(self, calibration_db: dict, limit_db: dict):
self.calibration_db = calibration_db
self.limit_db = limit_db
self.last_sequence: dict[str, int] = {}
def process_frame(self, raw_frame: bytes, spacecraft_id: str) -> list[TelemetryPoint]:
header = self._parse_ccsds_header(raw_frame)
self._check_sequence_continuity(spacecraft_id, header['sequence_count'])
points = []
payload = raw_frame[header['header_length']:]
for mnemonic, offset, length, data_type in self._get_frame_map(header['apid']):
raw_value = payload[offset:offset + length]
point = TelemetryPoint(
spacecraft_id=spacecraft_id,
mnemonic=mnemonic,
raw_value=raw_value,
timestamp=header['timestamp'],
ground_receipt_time=datetime.now(timezone.utc),
sequence_count=header['sequence_count'],
)
point.calibrated_value = self._calibrate(mnemonic, raw_value, data_type)
point.status = self._check_limits(mnemonic, point.calibrated_value)
points.append(point)
return points
def _calibrate(self, mnemonic: str, raw_value: bytes, data_type: str) -> float:
cal = self.calibration_db.get(mnemonic)
if not cal:
return struct.unpack('>f', raw_value)[0]
raw_numeric = struct.unpack(cal['unpack_format'], raw_value)[0]
if cal['type'] == 'polynomial':
coefficients = cal['coefficients']
return sum(c * (raw_numeric ** i) for i, c in enumerate(coefficients))
elif cal['type'] == 'lookup':
return cal['table'].get(raw_numeric, raw_numeric)
return float(raw_numeric)
def _check_limits(self, mnemonic: str, value: float) -> TelemetryStatus:
limits = self.limit_db.get(mnemonic)
if not limits:
return TelemetryStatus.NOMINAL
if value < limits['critical_low'] or value > limits['critical_high']:
return TelemetryStatus.CRITICAL
elif value < limits['warning_low'] or value > limits['warning_high']:
return TelemetryStatus.WARNING
return TelemetryStatus.NOMINAL
def _check_sequence_continuity(self, spacecraft_id: str, sequence_count: int):
last = self.last_sequence.get(spacecraft_id)
if last is not None:
expected = (last + 1) % 16384
if sequence_count != expected:
gap = (sequence_count - expected) % 16384
self._report_gap(spacecraft_id, expected, sequence_count, gap)
self.last_sequence[spacecraft_id] = sequence_count Key design decisions in this pipeline:
- CCSDS packet parsing — The Consultative Committee for Space Data Systems (CCSDS) defines the standard packet format for space telemetry. Every ground system must parse these headers correctly.
- Sequence count tracking — Gaps in sequence counts indicate dropped packets. This is critical for data integrity assessment.
- Calibration and limit checking — Raw telemetry values are meaningless to operators. Calibration converts raw counts to engineering units (volts, degrees, PSI), and limit checking flags values outside expected ranges.
- Dual timestamps — Spacecraft time (when the data was generated) and ground receipt time (when it arrived) are both essential for latency analysis and anomaly investigation.
Real-Time Display
Telemetry displays are the operator's primary interface to the spacecraft. They must update in real-time, support thousands of simultaneous parameters, and provide instant visual indication of anomalies:
interface TelemetryDisplay {
mnemonic: string;
currentValue: number;
unit: string;
status: 'nominal' | 'warning' | 'critical' | 'stale';
timestamp: Date;
sparkline: number[];
}
function TelemetryPanel({ displays }: { displays: TelemetryDisplay[] }) {
return (
<div className="telemetry-grid" role="grid" aria-label="Spacecraft telemetry">
{displays.map((display) => (
<div
key={display.mnemonic}
className={`telemetry-cell telemetry-${display.status}`}
role="gridcell"
aria-label={`${display.mnemonic}: ${display.currentValue} ${display.unit}, status ${display.status}`}
>
<span className="mnemonic">{display.mnemonic}</span>
<span className="value">
{display.currentValue.toFixed(2)}
<span className="unit">{display.unit}</span>
</span>
<Sparkline data={display.sparkline} height={20} width={60} />
<span className="timestamp">
{formatUTC(display.timestamp)}
</span>
</div>
))}
</div>
);
} Status colors follow conventions deeply embedded in operator training: green for nominal, yellow for warning, red for critical, gray for stale (no recent data). Sparklines show trend data — a gradually rising temperature is more concerning than a stable one, even if both are within limits.
Command and Control
Command uplink is the most safety-critical function in ground systems. A command sent to a satellite cannot be recalled. If the wrong command is sent — or the right command with wrong parameters — the consequences range from lost data to lost spacecraft.
Command Authorization Architecture
Every command passes through multiple gates before reaching the antenna:
- Command building — Operator selects command from an authorized list, fills parameters
- Constraint checking — Software verifies the command is safe in the current spacecraft state
- Operator review — The built command is displayed for human verification
- Authorization — A second operator (for critical commands) authorizes execution
- Uplink formatting — The command is encoded per the spacecraft's command dictionary
- Transmission — The formatted command is sent through the antenna
- Verification — Telemetry confirms the command was received and executed
@dataclass
class Command:
name: str
parameters: dict
hazard_level: str
built_by: str
authorized_by: Optional[str] = None
class CommandGate:
def check_constraints(self, command: Command, spacecraft_state: dict) -> tuple[bool, str]:
constraints = self.constraint_db[command.name]
for constraint in constraints:
if not self._evaluate_constraint(constraint, spacecraft_state):
return False, f"Constraint violated: {constraint['description']}"
if command.hazard_level in ('caution', 'critical'):
if not command.authorized_by:
return False, "Critical command requires dual authorization"
if command.authorized_by == command.built_by:
return False, "Authorizer must differ from builder"
return True, "All constraints satisfied"
def _evaluate_constraint(self, constraint: dict, state: dict) -> bool:
param = state.get(constraint['telemetry_mnemonic'])
if param is None:
return False
op = constraint['operator']
threshold = constraint['value']
if op == 'gt': return param > threshold
if op == 'lt': return param < threshold
if op == 'eq': return param == threshold
if op == 'in': return param in threshold
return False The dual-authorization pattern for critical commands is non-negotiable. One operator builds the command; a different operator reviews and authorizes it. The software enforces this — there's no override, no bypass, no "just this once."
Data Downlink Management
Satellite passes are finite windows — typically 8-15 minutes for LEO satellites. Every second of contact time is valuable, and the ground system must maximize data throughput during each pass.
Pass Planning
Pass planning software calculates contact windows based on orbital mechanics and allocates ground station resources:
Pass Schedule - March 2, 2026 (UTC)
═══════════════════════════════════════════════════════════════
Pass Satellite AOS LOS Duration Max El Station
───────────────────────────────────────────────────────────────
1 SAT-Alpha 02:14:32 02:26:18 11m 46s 67.2° ALK-1
2 SAT-Beta 03:41:05 03:49:22 8m 17s 34.1° ALK-2
3 SAT-Alpha 03:52:11 04:04:45 12m 34s 82.4° ALK-1
4 SAT-Gamma 05:18:33 05:27:41 9m 08s 45.7° ALK-3
═══════════════════════════════════════════════════════════════ AOS (Acquisition of Signal) and LOS (Loss of Signal) define the contact window. Maximum elevation determines signal quality — higher elevation passes have better signal-to-noise ratios and support higher data rates.
Downlink Prioritization
When contact time is limited, the ground system must prioritize which data to download first:
- Health and safety telemetry — Always first. Operators need to know the spacecraft is healthy before downloading science data.
- Critical event data — Anomaly records, safe-mode telemetry, collision avoidance data.
- Mission data — The primary payload data the satellite exists to collect.
- Stored housekeeping — Detailed telemetry recorded between passes for trend analysis.
The prioritization is automated but operator-overridable. If an operator suspects an anomaly, they can reprioritize a pass to download diagnostic data instead of mission data.
Real-Time Monitoring Dashboards
Ground system operators manage multiple satellites simultaneously. The monitoring dashboard is their situational awareness tool — it shows the overall health of every asset, highlights anomalies, and provides drill-down capability for investigation.
Multi-Satellite Overview
┌──────────────────────────────────────────────────────────────┐
│ Constellation Status │
├──────────────┬──────────┬──────────┬──────────┬──────────────┤
│ SAT-Alpha │ SAT-Beta │ SAT-Gamma│ SAT-Delta│ SAT-Epsilon │
│ ● NOMINAL │ ● NOMINAL│ ⚠ WARN │ ● NOMINAL│ ● STANDBY │
│ Power: 28.2V │ 27.9V │ 26.1V │ 28.0V │ — │
│ Temp: 22.4°C │ 21.8°C │ 31.2°C │ 22.1°C │ — │
│ Next: 02:14 │ 03:41 │ 05:18 │ 07:33 │ 09:14 │
│ (47 min) │ (2h 14m) │ (3h 51m)│ (6h 06m) │ (7h 47m) │
└──────────────┴──────────┴──────────┴──────────┴──────────────┘ SAT-Gamma shows a warning state — elevated temperature. The operator clicks to drill down: the temperature trend shows a 3-degree rise over the last four orbits. The thermal model predicts it will enter critical range in 12 hours. The operator schedules a thermal management command for the next pass.
This kind of predictive awareness is what separates modern ground systems from legacy platforms that only alert when limits are already violated.
High Availability Requirements
Ground systems must be available when the satellite passes overhead. A missed pass might mean 90 minutes (LEO orbit period) or 24 hours (for polar orbit ground stations) without contact. For critical operations — collision avoidance maneuvers, safe-mode recovery, time-sensitive tasking — missing a pass isn't acceptable.
Architecture for Five-Nines
Five-nines availability (99.999%, roughly 5 minutes of downtime per year) requires:
- Redundant processing chains — Hot standby systems that take over within seconds
- Geographic redundancy — Multiple ground stations that can contact the same satellite
- Automated failover — No human in the loop for failover decisions (humans are too slow)
- Graceful degradation — If a subsystem fails, the rest of the system continues operating with reduced capability
- Continuous health monitoring — The ground system monitors itself as carefully as it monitors the spacecraft
The same high-availability patterns we apply to aviation systems — multi-AZ deployment, health checks, automated recovery — apply to ground systems with even tighter requirements.
Cloud Migration of Ground Systems
Legacy ground systems run on dedicated hardware in purpose-built facilities. Modern ground systems are migrating to cloud infrastructure — AWS Ground Station, Azure Orbital, and custom cloud-native architectures that maintain the reliability of dedicated hardware with the scalability and cost efficiency of cloud.
The key architectural challenge is latency. Antenna control systems require single-digit millisecond response times that cloud regions can't guarantee. The pattern is hybrid: antenna control remains on-premises at the ground station, while telemetry processing, data management, mission planning, and monitoring dashboards run in the cloud.
Ground Station (On-Premises) Cloud (AWS)
┌─────────────────────┐ ┌──────────────────────────────┐
│ Antenna Controller │ │ Telemetry Processing │
│ RF Equipment │────▶│ Data Management │
│ Front-End Processor │ │ Mission Planning │
│ Local Buffer │ │ Monitoring Dashboards │
└─────────────────────┘ │ Command Building (non-uplink)│
└──────────────────────────────┘ This hybrid architecture reduces the infrastructure footprint at each ground station while enabling centralized operations — operators at any location can monitor and command any satellite through the cloud-hosted interfaces.
Alaska's Strategic Position
Alaska's geography provides a unique advantage for ground systems. High-latitude ground stations in Alaska can contact polar-orbiting satellites on nearly every orbit — compared to mid-latitude stations that might only see the satellite on 3-4 passes per day. This makes Alaska a critical node in global satellite ground networks, as we've discussed in our analysis of Alaska's role in space and defense.
The combination of strategic ground station placement, modern software architecture, and cloud-native infrastructure is transforming how satellite operations are conducted — from dedicated facilities with 24/7 on-site staffing to distributed operations centers that manage constellation-scale assets remotely.
What is CCSDS and why does it matter for ground systems?
CCSDS (Consultative Committee for Space Data Systems) is the international standard for space communications protocols. It defines packet formats for telemetry, commands, and data transfer between spacecraft and ground systems. Every major space agency uses CCSDS standards, making it the foundation of interoperable ground systems. Building ground software that correctly parses CCSDS packets is a fundamental requirement.
How do ground systems handle multiple satellites simultaneously?
Modern ground systems use multi-mission architectures where shared infrastructure (processing, storage, displays) supports multiple satellite programs. Each satellite has its own telemetry database, command dictionary, and constraint definitions, but the underlying software platform is shared. Operators manage constellation-level awareness through overview dashboards and drill into individual satellites when needed.
What are the latency requirements for satellite ground systems?
Latency requirements vary by subsystem. Antenna control requires single-digit milliseconds for tracking accuracy. Telemetry processing targets sub-second end-to-end latency from RF reception to operator display. Command uplink has no hard latency requirement but must complete within the contact window (typically 8-15 minutes for LEO). Data downlink is throughput-limited rather than latency-limited.
Can satellite ground systems run entirely in the cloud?
Not entirely — antenna control and RF processing require on-premises hardware at the ground station with deterministic latency. However, the majority of ground system functions (telemetry processing, data management, mission planning, monitoring) can run in the cloud. AWS Ground Station and Azure Orbital provide the RF interface, while custom cloud-native software handles everything above the physical layer.
What programming languages are used in ground systems?
Ground systems use a mix of languages based on subsystem requirements. Real-time antenna control and front-end processing often use C/C++ for deterministic performance. Telemetry processing and data management increasingly use Python for its scientific computing ecosystem (NumPy, SciPy). Web-based monitoring dashboards use TypeScript/React. Mission planning and scheduling use Python or Java. The trend is toward Python and TypeScript for new development, with C/C++ reserved for hardware-adjacent components.
Discuss your project with Rutagon
Contact Us →