SOVEREIGN SATELLITE INTELLIGENCE SYSTEM

PROJECT
ARGUS

A fully containerized, event-driven satellite intelligence pipeline — ingesting raw EO imagery, geo-localizing it via a Vision Transformer, and streaming live telemetry to a terminal dashboard and real-time GUI viewer.

Go Python ViT-Base/16 Redpanda PostGIS MinIO Raylib Prometheus
874
Reference Tiles
768
Embedding Dims
~3ms
Cosine Search
100ms
Dashboard Poll
// 01 — system design

Architecture

An event-driven pipeline built on battle-tested primitives — chosen for performance, operational simplicity, and future scale.

Why Redpanda over Kafka?

Redpanda is written in C++ using the Seastar async framework. It eliminates ZooKeeper, ships as a single binary, and delivers 10× lower median produce latency. Full Kafka 3.x API compatibility — zero client code changes.

🐹

Why Go for the watcher?

Go's goroutine model makes it trivial to watch directories at kernel speed (inotify via fsnotify) while concurrently uploading to MinIO and producing events. The compiled binary is 8 MB and idles at <1% CPU.

🪣

Why MinIO?

S3-API compatible, runs on a single node with erasure-coding durability, and has a Go SDK with streaming upload support. Swapping MinIO for AWS S3 in production requires zero code changes.

🗺️

Why PostGIS?

Future spatial queries — bounding-box filtering, trajectory reconstruction, proximity alerts — require a spatial index. PostGIS gives us these for free on top of PostgreSQL, making the schema forward-compatible.

// 02 — machine learning

CV & ML Logic

How a Vision Transformer turns raw pixels into GPS coordinates — the mathematics behind the prediction.

ViT-Base/16 Embedding Pipeline

The satellite tile is resized to $224 \times 224$ and partitioned into non-overlapping patches of size $16 \times 16$, yielding:

$$N = \left(\frac{224}{16}\right)^2 = 196 \text{ patches}$$

Each patch is flattened and linearly projected to a $D = 768$-dimensional embedding. A learnable [CLS] token is prepended. With positional encodings added:

$$z_0 = \left[x_\text{cls};\, x^1_p E;\, x^2_p E;\, \ldots;\, x^N_p E\right] + E_\text{pos}, \quad E \in \mathbb{R}^{(P^2 \cdot C) \times D}$$

The sequence passes through $L = 12$ Transformer encoder layers, each consisting of Multi-Head Self-Attention (MSA) and MLP sub-layers with layer normalization:

$$z'_\ell = \text{MSA}\!\left(\text{LN}(z_{\ell-1})\right) + z_{\ell-1}$$
$$z_\ell = \text{MLP}\!\left(\text{LN}(z'_\ell)\right) + z'_\ell$$

After all $L$ layers, the CLS token output $z^0_L \in \mathbb{R}^{768}$ is extracted as the scene embedding. It is L2-normalized before storage and retrieval.

Cosine Similarity Geo-Search

Given query embedding $\mathbf{q}$ and corpus matrix $E \in \mathbb{R}^{874 \times 768}$, cosine similarity is computed for all reference tiles simultaneously:

$$\text{sim}(\mathbf{q},\, \mathbf{e}_i) = \frac{\mathbf{q} \cdot \mathbf{e}_i}{\|\mathbf{q}\|\,\|\mathbf{e}_i\|}$$

Since embeddings are pre-L2-normalized ($\|\mathbf{e}_i\| = 1$), this reduces to a dot product — vectorised as a single matrix-vector multiply completing in ~3 ms on CPU.

The top-$k = 5$ matches are selected. A softmax-temperature-weighted mean GPS coordinate is derived:

$$\hat{y} = \sum_{i \in \text{TopK}} \text{softmax}\!\left(\frac{\text{sim}(\mathbf{q}, \mathbf{e}_i)}{\tau}\right) \cdot (\text{lat}_i,\, \text{lon}_i)$$

where $\tau = 0.07$ sharpens the weight distribution, ensuring the closest match dominates the prediction.

Architecture
vit_base_patch16_224
via timm
Patch Size
16 × 16 px
196 tokens
CLS Dim
768-D float32
L2-normalized
Corpus
874 tiles
Sentinel-2, Mumbai
Search Time
~3ms CPU
dot-product matmul
Avg Error
≈ 1.2 km
at 10m GSD
// 03 — pipeline trace

Workflow Visualization

Follow a single satellite tile from raw downlink to geo-localized result.

// 04 — service catalog

Component Breakdown

Every service in the stack — its language, role, and key dependencies.

// 06 — gui mockup

Sovereign View

The Raylib GUI renders the latest processed tile with a geo-lock crosshair over the predicted GPS centroid.

ARGUS-01 ACTIVE
SENSOR: ViT-B/16
MODE: GEO-LOCK
LAT 19.0760°N
LON 72.8777°E
CONF 93.4%
GSD: 10m | SCENE: MUM-0524
SOVEREIGN VIEW v1.0
HOW IT WORKS
  • local_sync/latest_processed.jpg is written atomically by the processor worker.
  • The Raylib GUI polls the file's mod-time every frame (sub-ms overhead).
  • On change, it reloads the texture — no IPC, no network required.
  • GPS coords are painted as a crosshair overlay with confidence HUD.
HUD ELEMENTS
  • Corner brackets — viewport boundary indicators.
  • Scan-line effect — CRT aesthetic render pass.
  • Crosshair rings — pulsing geo-lock confidence indicator.
  • Coordinate overlay — LAT/LON + confidence percentage.
// 07 — quick start

Quick Start

Prerequisites: Docker + Docker Compose, WSL2 (Debian/Ubuntu recommended) or native Linux, Go 1.21+, GCC + libraylib-dev (for GUI), tmux.

terminal — clone & launch
# Clone the repository
git clone https://github.com/parthbhanti22/seopc-ground-station-epics
cd seopc-ground-station-epics

# Make scripts executable
chmod +x launch.sh feed.sh

# One-command launch (opens tmux with 4 panes)
./launch.sh

# Force rebuild Docker images
./launch.sh --rebuild
terminal — feed satellite tiles
# Drip-feed tiles every 5s (default)
bash feed.sh

# Custom interval (30s)
bash feed.sh 30

# Manually inject a single tile
sudo docker cp tiles/tile_0001.jpg \
  seopc-project-satellite-1:/downlink_buffer/
terminal — teardown
# Press Q in the dashboard pane to exit TUI, then:
sudo docker compose down
OBSERVABILITY ENDPOINTS
Prometheuslocalhost:9090
Grafanalocalhost:3000
MinIO Consolelocalhost:9001
WHAT launch.sh DOES
1.Brings up all Docker services in dependency order (Redpanda → MinIO → PostGIS → Satellite → Processor)
2.Waits for PostGIS health check to pass
3.Opens a tmux session with 4 panes: logs / dashboard / GUI / feeder
CV MODEL DETAILS
1.Architecture: vit_base_patch16_224 via timm (pretrained on ImageNet)
2.Embedding: CLS token (768-dim), L2-normalized
3.Retrieval: Cosine similarity against 874 reference tile embeddings
4.Prediction: Weighted mean of top-5 match GPS coordinates
5.Dataset: Tiles generated from Sentinel-2 satellite imagery over Mumbai/Navi Mumbai