gr-apollo/CLAUDE.md

7.4 KiB
Raw Permalink Blame History

CLAUDE.md

This file provides guidance to Claude Code when working with gr-apollo.

Project Overview

GNU Radio 3.10+ out-of-tree (OOT) module for decoding Apollo Unified S-Band (USB) telecommunications signals. Based on the 1965 NAA Telecommunication Systems Study Guide (Course A-624) and Virtual AGC project.

Target signals:

  • Downlink: 2287.5 MHz (spacecraft → ground)
  • Uplink: 2106.40625 MHz (ground → spacecraft)
  • Coherent ratio: 240/221 (Tx = Rx × 240/221)

Repository Structure

gr-apollo/
├── src/apollo/              # GNU Radio Python blocks (src-layout)
│   ├── pm_demod.py              # PM demodulator (0.133 rad peak)
│   ├── bpsk_subcarrier_demod.py # 1.024 MHz BPSK subcarrier
│   ├── pcm_frame_sync.py        # 32-bit sync, 128-word frames
│   ├── pcm_demux.py             # Frame demultiplexer
│   └── voice_subcarrier_demod.py # 1.25 MHz FM voice
├── grc/                     # GRC block YAML definitions
├── docs/                    # Reference documentation
├── examples/                # Example flowgraphs
├── pyproject.toml           # Python package configuration
└── README.md

Development Commands

# Install in development mode
uv pip install -e .

# Install GRC block definitions
cp grc/*.yml ~/.local/share/gnuradio/grc/blocks/

# Test with gr-mcp (if available)
# Use protocol analysis tools to generate decoder chain

Signal Architecture

RF Input → Carrier PLL → PM Demod → Subcarrier Separation
                                            │
                    ┌───────────────────────┼───────────────────────┐
                    ↓                       ↓                       ↓
            1.024 MHz BPSK           1.25 MHz FM              Ranging
            (PCM telemetry)          (Voice)                  (PRN code)
                    ↓                       ↓
            Symbol Sync              FM Discriminator
                    ↓                       ↓
            51.2 kbps NRZ            300-3000 Hz audio
                    ↓
            Frame Sync (32-bit)
                    ↓
            128-word demux

Key Parameters

Parameter Value Notes
Downlink frequency 2287.5 MHz Coherent with uplink
PM peak deviation 0.133 rad (7.6°) Phase modulation
PCM subcarrier 1.024 MHz BPSK modulated
PCM bit rate 51.2 kbps (high) / 1.6 kbps (low) NRZ, MSB first
Voice subcarrier 1.25 MHz FM, ±29 kHz deviation
Frame length 128 words × 8 bits 50 fps high rate
Frame sync 32-bit pattern Complements on odd frames
Master clock 512 kHz All timing derived from this

PCM Frame Structure

┌─────────────────────────────────────────────────────────────┐
│  Frame Sync (32 bits = 4 words)                             │
│  [5-bit A][15-bit core][6-bit B][6-bit frame ID]           │
├─────────────────────────────────────────────────────────────┤
│  Data Words 5-128 (124 words)                               │
│  - High-level analog (0-5V, 8-bit)                          │
│  - Low-level analog (0-40mV, 8-bit with ×125 gain)         │
│  - Digital parallel/serial inputs                           │
│  - AGC downlink data (channels 34, 35, 57)                  │
└─────────────────────────────────────────────────────────────┘

50 frames = 1 subframe (1 second at high rate)

Subcarrier Oscillators (FM Mode)

SCO Center Freq Deviation Use
1 14,500 Hz ±7.5% Analog sensor
2 22,000 Hz ±7.5% Analog sensor
3 30,000 Hz ±7.5% Analog sensor
4 40,000 Hz ±7.5% Analog sensor
5 52,500 Hz ±7.5% Analog sensor
6 70,000 Hz ±7.5% Analog sensor
7 95,000 Hz ±7.5% Analog sensor
8 125,000 Hz ±7.5% Analog sensor
9 165,000 Hz ±7.5% Analog sensor

GNU Radio Blocks to Implement

Phase 1: Core Demodulation

Block Type I/O Description
pm_demod gr.sync_block complex→float PM demodulator with carrier recovery
subcarrier_extract gr.sync_block float→complex Bandpass + downconvert subcarrier
bpsk_demod gr.sync_block complex→byte BPSK demodulation with symbol sync

Phase 2: PCM Processing

Block Type I/O Description
pcm_frame_sync gr.basic_block byte→PDU 32-bit sync detection, frame extraction
pcm_demux gr.basic_block PDU→PDU Demultiplex 128-word frames by word position
downlink_decoder gr.basic_block PDU→dict Interpret AGC telemetry lists

Phase 3: Voice & Analog

Block Type I/O Description
fm_voice_demod gr.sync_block complex→float 1.25 MHz FM subcarrier → audio
sco_demod gr.sync_block float→float FM SCO demodulator (configurable)

Virtual AGC Integration

The Virtual AGC emulator communicates via TCP socket (port 19697+):

4-byte packet format:
Byte 0: [Channel bits 8-4][0x00]
Byte 1: [0x40 | Channel bits 3-1][Value bits 14-12]
Byte 2: [0x80 | Value bits 11-6]
Byte 3: [0xC0 | Value bits 5-0]

Key telecom channels:

  • Ch 45 (INLINK): Uplink data input
  • Ch 57 (OUTLINK): Downlink data output
  • Ch 34/35 (DNTM1/2): Telemetry word stream

References

Code Style

  • Python: Follow GNU Radio block patterns (numpy for DSP)
  • Use gr-mcp protocol analysis tools for decoder chain generation
  • Test blocks in Docker before integration

Docs Site Deployment

Starlight documentation site in docs/ subdirectory.

  • Production: https://gr-apollo.warehack.ing
  • Local dev: Set DOMAIN=gr-apollo.l.warehack.ing in docs/.env
  • Git: git@git.supported.systems:warehack.ing/gr-apollo.git
  • Server: ssh -A warehack-ing@warehack.ing, repo at ~/gr-apollo

Environment

Copy .env.example to .env and set:

COMPOSE_PROJECT=gr-apollo-docs
DOMAIN=gr-apollo.warehack.ing

Commands

# From docs/ directory:
make up        # Production — Caddy serves static dist/
make dev       # Development — Astro dev server with HMR
make down      # Stop all containers
make logs      # Tail container logs

Deploy to Production

# One-liner from local machine
ssh -A warehack-ing@warehack.ing "cd ~/gr-apollo && git pull && cd docs && make up"

Notes

  • Uses Docker Compose profiles (prod / dev)
  • Playwright + Chromium installed in build stage for mermaid diagram rendering
  • caddy-docker-proxy on external caddy network handles TLS automatically