Building a Satellite Tracker on a $250 Computer: Edge Computing in Space Tech
Professional satellite collision monitoring once required government-scale infrastructure: supercomputers, classified tracking networks, and teams of analysts. In 2026, OrbVeil screens 29,790 tracked objects for collision risks in 9.6 seconds on a $250 NVIDIA Jetson Orin Nano — a single-board computer small enough to fit in your hand.
This is the story of how edge computing is democratizing space situational awareness, the engineering choices that made it possible, and a technical guide for anyone who wants to build their own satellite tracker.
Why Edge Computing for Space Tracking?
The Traditional Approach: Cloud-First
Most satellite tracking services follow a cloud-centric model:
- Data ingestion: Fetch TLEs from Space-Track.org
- Upload to cloud: Send data to AWS, Azure, or Google Cloud
- Process at scale: Run conjunction screening on cloud compute instances
- Store and serve: Database results, serve via web APIs
This works, but it has costs:
- Compute expense: Cloud instances bill by the hour — screening 29,790 objects multiple times per day adds up
- Latency: Round-trip to cloud introduces delays (not critical for orbital timescales, but still friction)
- Internet dependency: If network is down, screening stops
- Data privacy: Some operators prefer keeping orbital data local
The Edge Alternative
Edge computing means processing data where it's generated — locally, without cloud dependencies. For satellite tracking, this offers:
- Cost: One-time hardware purchase vs. recurring cloud bills
- Speed: No network latency — results in seconds
- Autonomy: Runs offline, no internet required after initial TLE fetch
- Scalability: One device per site vs. centralized cloud bottleneck
The trade-off: you need hardware that can handle the computation. This is where GPU-accelerated single-board computers come in.
The Hardware: NVIDIA Jetson Orin Nano
Specifications
The Jetson Orin Nano (released 2023) is NVIDIA's entry-level edge AI platform:
- GPU: 1024-core Ampere architecture GPU
- CPU: 6-core ARM Cortex-A78AE @ 1.5 GHz
- RAM: 8 GB unified memory (shared between CPU and GPU)
- AI Performance: 40 TOPS (trillion operations per second)
- Power: 7-15W typical
- Size: 100mm x 79mm (credit card size)
- Price: ~$250 USD (developer kit)
Why Jetson vs. Raspberry Pi or x86?
Raspberry Pi: Great for IoT and hobbyist projects, but lacks GPU acceleration. Screening 29,790 objects on a Pi 5 would take minutes to hours, not seconds.
x86 Desktop/Server: More powerful, but also more expensive, power-hungry, and bulky. A desktop GPU setup costs $500-2000+ and draws 200-500W. Jetson hits the sweet spot for edge deployment: sufficient power, low cost, minimal footprint.
Other ARM SBCs (e.g., Rock 5, Radxa): Competitive on CPU, but lack the mature CUDA ecosystem. NVIDIA's CUDA support is critical for GPU-accelerated Python libraries like CuPy.
Storage: NVMe Over MicroSD
The Jetson Orin Nano supports NVMe SSD via M.2 slot. This is essential for two reasons:
- Speed: NVMe provides 2000+ MB/s read/write vs. 50-100 MB/s for microSD. Faster data loading means faster screening.
- Reliability: MicroSD cards wear out quickly with constant writes (logging, database updates). NVMe SSDs are rated for years of intensive use.
For OrbVeil, I'm running a 512GB NVMe SSD — overkill for TLE data (~10 MB), but useful for historical screening results and logs.
The Journey: From Drones to Satellites
Background: Fleet Management Systems
I spent several years building autonomous drone fleet management systems — coordinating swarms of UAVs for infrastructure inspection, agriculture monitoring, and mapping. The technical challenges were similar to satellite operations:
- Position propagation: Predict future UAV positions based on flight plans and wind models
- Collision avoidance: Ensure drones don't fly into each other or obstacles
- Resource optimization: Minimize battery consumption while maximizing coverage
- Edge autonomy: Drones need onboard decision-making — cloud latency is too high
The Jetson platform was ideal for drone edge computing: small, power-efficient, GPU-accelerated for computer vision and path planning. When I transitioned from drones to space tech, the hardware came with me.
The Orbital Mechanics Learning Curve
Drone flight dynamics: relatively simple. Newtonian physics in a viscous fluid (air), typically constrained to 2D paths at low altitude.
Orbital mechanics: Much harder. Kepler's laws, perturbations from Earth's oblateness (J2, J3, J4 harmonics), atmospheric drag models, solar radiation pressure, gravitational influences from Sun and Moon. And everything happens at 7-8 km/s in a vacuum where intuition breaks down.
The key breakthrough was discovering SGP4 — the Simplified General Perturbations model that handles most of the complexity analytically. With SGP4, you don't need to numerically integrate differential equations; you just plug in orbital elements and get positions. It's "good enough" for catalog-wide screening.
Why Build This?
The catalyst was reading about the 2009 Iridium-Cosmos collision — the first accidental hypervelocity collision between two intact satellites. Both were destroyed. Over 2,300 trackable fragments created. Years later, those fragments are still in orbit, still causing conjunction alerts.
I wanted to know: how often do these near-misses happen? Not "how often does the news report them," but actually — in the raw data, across the full catalog, every day. The only way to answer that was to build a screening system and run it continuously.
The constraint: it had to be cheap and open-source. Space monitoring shouldn't require a defense budget.
The Software Stack
Core Technologies
- Python 3.11+ — primary language for space libraries and data science ecosystem
- NumPy — vectorized array operations, essential for batch SGP4
- sgp4 (Brandon Rhodes' library) — Python implementation of SGP4/SDP4 propagation
- scipy.spatial.cKDTree — C-accelerated KD-tree for spatial indexing
- Optional: CuPy — GPU-accelerated NumPy drop-in replacement (CUDA required)
Data Source: Space-Track.org
The U.S. Space Surveillance Network publishes TLE data for all tracked objects via Space-Track.org. Access is free with registration (requires agreeing to terms of use).
OrbVeil fetches the full catalog once per day via the Space-Track API:
import requests
# Space-Track.org authentication
session = requests.Session()
login_data = {
'identity': 'your_username',
'password': 'your_password'
}
session.post('https://www.space-track.org/ajaxauth/login', data=login_data)
# Fetch all TLEs
tle_data = session.get(
'https://www.space-track.org/basicspacedata/query/class/gp/EPOCH/>now-1/format/3le'
).text
# tle_data is now 3-line format (name + TLE line 1 + TLE line 2)
# Parse and store for propagation
The result: ~29,790 TLE sets, totaling ~8-10 MB of text. This is small enough to store entirely in RAM.
Step 1: TLE Parsing and Validation
TLEs are ASCII text with strict formatting. Even minor corruption (e.g., incorrect checksums) causes propagation failures. Validation is essential:
from sgp4.api import Satrec
def parse_tle(line1, line2):
"""Parse and validate TLE, return Satrec object or None if invalid."""
try:
sat = Satrec.twoline2rv(line1, line2)
if sat.error != 0:
return None # Propagation error during initialization
return sat
except Exception:
return None # Parsing error
# Typical rejection rate: 0.1-0.5% due to corrupt or outdated entries
Step 2: Batch SGP4 Propagation
This is where performance matters. The naive approach — loop through 29,790 satellites and call SGP4 individually — is slow:
# SLOW: Individual propagation
positions = []
for sat in satellites:
e, r, v = sat.sgp4(jd, fr) # Julian date, fractional day
if e == 0: # No error
positions.append(r) # ECI position in km
# Runtime: ~2-5 seconds per time step on Jetson
The optimized approach: vectorized batch propagation using NumPy arrays:
from sgp4.api import jday
import numpy as np
# Convert all satellite TLEs to a vectorized array representation
# This is done once at initialization
sat_array = np.array([sat_to_array(s) for s in satellites])
# Batch propagate all satellites at once
jd, fr = jday(2026, 2, 11, 12, 0, 0) # Example: Feb 11, 2026, 12:00 UTC
errors, positions, velocities = sgp4_array(sat_array, jd, fr)
# positions is now a (29790, 3) NumPy array of ECI coordinates
# Runtime: ~0.3-0.5 seconds per time step on Jetson
The speedup: 4-10x faster by treating propagation as a matrix operation instead of 29,790 function calls. This is the difference between 9.6-second screening and 60-second screening.
Step 3: KD-Tree Spatial Filtering
With positions computed, the next challenge: find which objects are close to each other. The naive O(n²) approach checks all 443 million possible pairs — too slow.
KD-trees solve this by partitioning 3D space into a binary tree, enabling O(n log n) nearest-neighbor queries:
from scipy.spatial import cKDTree
# Build KD-tree from position array (29790 x 3)
tree = cKDTree(positions) # positions in km (ECI frame)
# Query all pairs within threshold distance (e.g., 50 km)
pairs = tree.query_pairs(r=50.0) # Returns set of (i, j) index tuples
# Typical result: 300-800 pairs out of 443 million possible
# Runtime: ~0.1-0.2 seconds per time step on Jetson
The KD-tree prunes the search space by excluding entire regions that can't possibly contain matches. The speedup is typically 100-1000x vs. brute-force distance checks.
Step 4: Close Approach Refinement
For each pair identified by the KD-tree, compute precise close approach parameters:
-
Time of closest approach (TCA): Find the exact time when miss distance is minimized
-
Miss distance: Compute minimum separation at TCA
-
Relative velocity: Vector difference of velocities at TCA
def refine_tca(sat1, sat2, coarse_time, window_seconds=300): """Find precise TCA using bisection on distance function.""" # Binary search over ±window to find minimum distance best_time = coarse_time best_distance = float('inf')
for _ in range(20): # ~1-second precision after 20 iterations # Evaluate distance at multiple points around current best # Move toward minimum # (Actual implementation uses scipy.optimize.minimize_scalar) pass return best_time, best_distance, relative_velocity
Step 5: Filtering and Classification
Raw conjunction results include many non-threats:
- Co-located formations: Starlink trains, Planet Doves — satellites intentionally close
- Same-object duplicates: Multiple catalog entries for one physical object
- High-miss-distance passes: 30-50 km separations are informational, not actionable
OrbVeil applies heuristic filters to prioritize results:
# Detect co-located formations
# Satellites with similar orbital elements (a, e, i, RAAN) and low relative velocity
formations = detect_formations(satellites, threshold_km=5, max_rel_vel=0.1)
# Filter out formation-internal conjunctions
actionable_conjunctions = [
c for c in raw_conjunctions
if not is_same_formation(c.obj1, c.obj2, formations)
]
Performance Benchmarks: Jetson vs. Cloud
Jetson Orin Nano (CPU-only mode)
- Full screening (29,790 objects, 24h window, 60-second steps): 9.6 seconds
- Breakdown: TLE parsing 0.5s, propagation 6.2s, KD-tree 2.1s, refinement 0.8s
- Memory usage: ~200 MB peak
- Power draw: ~12W during screening
Jetson Orin Nano (GPU-accelerated with CuPy)
- Full screening: 6.1 seconds (37% faster)
- GPU acceleration applies to: Batch propagation, vectorized distance calculations
- Limitation: KD-tree construction is CPU-bound (scipy doesn't support GPU), limiting speedup
AWS c6a.2xlarge (8 vCPU, 16 GB RAM)
- Full screening: 7.8 seconds
- Cost: $0.306/hour (~$220/month if running 24/7)
- Jetson advantage: Similar performance, 10x cheaper over one year
Desktop (AMD Ryzen 9 5900X, NVIDIA RTX 3080)
- Full screening: 3.2 seconds (3x faster than Jetson)
- Cost: ~$1500 hardware, 300W power draw
- Trade-off: Better for development/research; Jetson better for deployed edge use
Key insight: The Jetson hits the performance-per-watt sweet spot. It's not the fastest option, but it's fast enough for real-time screening while being deployable in power-constrained environments (remote ground stations, mobile operations, university labs).
Real-World Deployment: Lessons Learned
Thermal Management
The Jetson Orin Nano can throttle under sustained load if cooling is insufficient. For continuous operation, I added a 40mm fan (powered from the carrier board's GPIO). This keeps temperatures below 60°C even during back-to-back screening runs.
Storage: Why NVMe Matters
Initial testing used microSD for convenience. After two weeks, I encountered filesystem corruption — the card wore out from constant logging. NVMe has been rock-solid for months.
Power Supply
The Jetson requires a stable 5V supply with sufficient amperage (15W = 3A @ 5V). Cheap USB power adapters cause intermittent brownouts and crashes. Use a quality barrel jack supply or official dev kit power adapter.
Internet Dependency
OrbVeil fetches TLEs once per day from Space-Track.org. If internet is unavailable, it uses the last-fetched TLEs (with a staleness warning — TLE accuracy degrades over time). For fully offline operation, TLEs could be pre-loaded and updated manually.
The Open-Source Advantage
OrbVeil is open source under Apache 2.0 license. This means:
- Anyone can deploy it: Universities, research labs, amateur astronomers, satellite operators
- Anyone can verify it: The algorithms, data sources, and filtering logic are public
- Anyone can improve it: Contributions, forks, and derivatives are encouraged
The goal isn't to compete with government tracking systems or commercial services — those have classified data sources and higher-fidelity tracking. The goal is to democratize access to basic collision monitoring. Space situational awareness shouldn't be a black box.
Use Cases: Who Builds Their Own Tracker?
University CubeSat Teams
University satellite teams often lack access to professional conjunction screening services. Running OrbVeil locally provides:
- Free collision monitoring: Screen your CubeSat against the full catalog
- Educational value: Students learn orbital mechanics and collision prediction
- Research data: Generate conjunction statistics for papers/theses
Amateur Satellite Tracking Networks
Amateur radio operators track satellites for communication and observation. Adding conjunction screening enables:
- Alerting: Know when tracked satellites have close approaches
- Observation planning: Identify interesting conjunctions to watch visually
- Citizen science: Contribute to distributed space monitoring
Remote Ground Stations
Ground stations in remote locations (Arctic, islands, ships) need local processing due to limited/expensive internet. Edge computing enables:
- Autonomous operation: No cloud dependency
- Low bandwidth: Only TLE fetches (10 MB/day) vs. streaming position data
- Resilience: Screening continues even if network drops
Future Optimizations
GPU-Accelerated KD-Tree
The current bottleneck is KD-tree construction on CPU. Research into GPU-accelerated spatial indexing (e.g., NVIDIA RAPIDS cuSpatial) could further reduce screening time.
Multi-Node Distributed Screening
For even larger catalogs (if tracking improves to include 1-10 cm debris), screening could distribute across multiple Jetsons — each handling a subset of objects, then merging results.
Predictive Filtering
Not all objects need full-resolution screening. Objects in stable orbits with no recent conjunctions could be checked less frequently, while high-activity zones (Starlink altitude, debris clouds) get finer time steps.
Getting Started: Build Your Own
Hardware Shopping List
- NVIDIA Jetson Orin Nano Developer Kit: ~$250
- 512GB NVMe SSD (M.2 2280): ~$40
- 40mm cooling fan: ~$5
- Power supply (5V 4A barrel jack): Included with dev kit
- Total: ~$295
Software Setup
- Flash JetPack 6.x to NVMe using NVIDIA SDK Manager
- Install Python 3.11+ and dependencies:
pip install numpy scipy sgp4 requests - Clone OrbVeil:
git clone https://github.com/ncdrone/orbveil - Configure Space-Track credentials in config file
- Run initial screening:
python orbveil/screen.py
Full setup documentation is in the GitHub repository.
Frequently Asked Questions
Can I run this on a Raspberry Pi?
Technically yes, but performance suffers. Screening 29,790 objects on a Raspberry Pi 5 takes several minutes vs. 9.6 seconds on Jetson. For occasional screening this is acceptable, but for real-time monitoring the Jetson's GPU makes a huge difference.
Do I need CUDA experience?
No. The CPU-only version (using NumPy and scipy) works out of the box and achieves 9.6-second screening. GPU acceleration with CuPy is optional and provides ~30-40% speedup if you want to optimize further.
How accurate is TLE-based screening?
TLE position accuracy is typically 0.5-3 km at epoch , degrading over time. This is sufficient for identifying which conjunctions need attention, but for maneuver decisions you'd want higher-fidelity data (CDMs with covariance). See our post on collision prediction algorithms for details on TLE limitations.
Can this replace professional collision monitoring services?
No — professional services use higher-fidelity tracking data, covariance-based Pc calculations, and 24/7 analyst support. OrbVeil is for educational use, research, and situational awareness. If you're operating a satellite, use both: OrbVeil for general awareness, professional CDMs for maneuver decisions.
What about power consumption for 24/7 operation?
The Jetson Orin Nano draws ~10W idle, ~15W during screening. Running 24/7 for a year consumes ~90 kWh, costing $10-15/year at typical electricity rates. This is negligible compared to cloud compute costs.
Is the code really open source?
Yes. Apache 2.0 license — use it, fork it, modify it, deploy it commercially. The only requirement is attribution. No restrictions, no paywalls.
Ready to build your own tracker? Full source code, setup guides, and example data: github.com/ncdrone/orbveil →
Related Articles
- How Satellite Collision Prediction Works: SGP4, TLEs, and KD-Trees
- Space Debris by the Numbers: 2026 Statistics and Trends
- SGP4 vs High-Precision Orbit Propagation: What's the Difference?
DI
Daniel Isaac, OrbVeil
Builder of OrbVeil. Systems engineer transitioning from drone fleet management to space tech. GitHub →
Daily Conjunction Screening
OrbVeil screens 29,790 objects daily and delivers personalized conjunction reports. Free for university CubeSat programs. 14-day trial for operators.
Get Free Screening →