Skip to content

Orion::GroundCommsDriver Component

1. Introduction

The Orion::GroundCommsDriver component manages the simulated X-band downlink from the satellite to the ground station. It receives HIGH-priority image frames from TriageRouter, transmits them over TCP to the ground receiver (receiver.py), and manages a disk-based queue for frames that arrive outside the comm window.

The component is mode-aware via EventAction broadcasts: it only transmits in DOWNLINK mode and queues frames to disk in all other modes.

2. Requirements

Requirement Description Verification Method
ORION-GCD-001 GroundCommsDriver shall transmit HIGH-priority frames immediately when in DOWNLINK mode System test
ORION-GCD-002 GroundCommsDriver shall queue HIGH-priority frames to disk when outside DOWNLINK mode System test
ORION-GCD-003 GroundCommsDriver shall flush all queued frames when entering DOWNLINK mode System test
ORION-GCD-004 GroundCommsDriver shall periodically retry flushing queued frames during DOWNLINK mode at 1 Hz Inspection
ORION-GCD-005 GroundCommsDriver shall return all buffers to the BufferManager pool after processing Inspection
ORION-GCD-006 GroundCommsDriver shall delete queued files from disk only after successful transmission Inspection
ORION-GCD-007 GroundCommsDriver shall stop flushing the queue on the first transmit failure to avoid losing frames Inspection

3. Design

3.1 Data Flow

flowchart LR
    TR[TriageRouter] -->|HIGH frame + reason| GCD[GroundCommsDriver]
    GCD -->|TCP| RX[receiver.py :50050]
    GCD -->|buffer return| BM[BufferManager]
    GCD -.->|queue to disk| DISK[(ORION_DOWNLINK_QUEUE_DIR)]
    DISK -.->|flush on DOWNLINK| GCD
    EA[EventAction] -->|modeChangeIn| GCD
    RG[RateGroup1] -->|schedIn 1Hz| GCD

3.2 Frame Protocol

Each frame transmitted over TCP has an 8-byte header followed by the raw pixel payload:

Offset Size Field Value
0 4 bytes Magic 0x4F52494F ("ORIO") in network byte order
4 4 bytes Payload length Raw image size in bytes, network byte order
8 N bytes Payload Raw 512x512 RGB image data (786,432 bytes)

3.3 Operating Modes

DOWNLINK mode:

  1. On mode entry (modeChangeIn): immediately flush all queued files from disk
  2. On new HIGH frame arrival (fileDownlinkIn): flush queue first, then transmit the new frame
  3. On 1 Hz tick (schedIn): flush queue (catches files queued in a race between mode change and arrival)

All other modes (IDLE, MEASURE, SAFE):

  • New HIGH frames are written to disk via saveToQueue
  • Buffer is returned to pool immediately
  • No TCP connections are attempted

3.4 Queue Flush Behavior

flushQueue() scans ORION_DOWNLINK_QUEUE_DIR for files matching orion_queued_*.raw, reads each into a heap buffer, transmits via TCP, and deletes the file on success. On the first transmit failure, flushing stops — this prevents losing frames when the receiver is down.

The 1 Hz schedIn tick retries the flush, so queued frames are not abandoned on a transient failure.

3.5 TCP Connection Model

Each transmitRaw call opens a new TCP connection, sends the header + payload, and closes the socket. This one-connection-per-frame model is simple but means:

  • Connection setup overhead per frame (~1ms on LAN, more over WAN)
  • Blocking connect() if the receiver is unreachable (OS-dependent timeout, typically 75s)
  • During flushQueue, a down receiver blocks the GroundCommsDriver thread until timeout

3.6 Port Diagram

Port Direction Type Description
fileDownlinkIn async input FileDownlinkPort Receives HIGH-priority frames from TriageRouter with reason string
schedIn async input Svc.Sched 1 Hz rate group tick for periodic queue flush during DOWNLINK
modeChangeIn async input ModeChangePort Receives mode broadcasts from EventAction
bufferReturnOut output Fw.BufferSend Returns image buffers to BufferManager pool

3.7 Events

Event Severity Description
FrameDownlinked ACTIVITY_HI Logged per successful transmit with the VLM reason string
TransmitFailed WARNING_HI Logged when TCP connect or send fails
FrameQueued ACTIVITY_LO Logged when a frame is saved to disk outside comm window
QueueFlushed ACTIVITY_HI Logged with count of frames flushed during comm window
QueueWriteFailed WARNING_HI Logged when writing a frame to the disk queue fails

3.8 Telemetry

Channel Type Description
FramesDownlinked U32 Running total of frames successfully transmitted
BytesDownlinked U32 Running total of raw bytes transmitted
TransmitFailures U32 Running total of failed transmit attempts
FramesQueued U32 Running total of frames queued to disk

3.9 Environment Variables

Variable Default Description
ORION_GDS_HOST 127.0.0.1 Ground receiver IP address
ORION_GDS_PORT 50050 Ground receiver TCP port
ORION_DOWNLINK_QUEUE_DIR ./media/sd/downlink_queue/ Directory for disk-queued frames

4. Known Issues

  1. Blocking TCP connect: If the receiver is unreachable, connect() blocks for the OS default TCP timeout (typically 75s on Linux, 30s on macOS). During flushQueue, this blocks the GroundCommsDriver thread entirely, stalling all port handlers. A non-blocking connect with a short timeout would prevent this.

  2. Heap allocation in flush loop: flushQueue allocates a heap buffer per file (new U8[fileSize]). On the Pi's constrained memory, flushing many large files could fragment the heap. Using a fixed-size stack buffer (786KB matches the image size) would avoid this.

5. Change Log

Date Description
2026-04-17 Initial implementation: TCP transmit, disk queue, mode gating
2026-04-18 Fixed queue flush to preserve files on transmit failure; added QueueWriteFailed event