# ubcaerodesign/thrust-stand-v3 architecture

> Architecture diagram of the GitHub repository ubcaerodesign/thrust-stand-v3, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ubcaerodesign/thrust-stand-v3
- Repository: https://github.com/ubcaerodesign/thrust-stand-v3
- Video tour (about a minute): https://gitdiagram.com/ubcaerodesign/thrust-stand-v3/video

## Overview

AeroThrust V3 is a desktop ground station for operating an electric propulsion test stand. Operators connect to a simulator or hardware, tare and calibrate sensors, control throttle manually or with automated sweeps, monitor live telemetry and safety status, and record runs for SQLite storage and CSV export. The graph follows the documented UI-to-API workflow into backend services and transport; sampled source supports key call paths, while several UI and router details are documented but not excerpted.

Main entry points: [`frontend/src/App.tsx`](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/App.tsx) (Test stand workspace), [`backend/app/main.py`](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/main.py) (FastAPI application), [`frontend/src/services/api.ts`](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/services/api.ts) (HTTP API client), [`backend/app/services/connection_manager.py`](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/connection_manager.py) (Connection manager)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Operator desktop"]
  node_app["Test stand workspace<br/>[App.tsx]"]
  node_stream["Telemetry stream hook"]
  node_controls["Connection and throttle controls"]
  node_calibration["Load-cell calibration"]
  node_limits["Current limits"]
  node_estop_ui["Emergency stop UI"]
  node_instruments["Telemetry instruments"]
  node_plots["Telemetry plots<br/>[TelemetryPlot.tsx]"]
  node_sequence_ui["Sweep controller"]
  node_recorder_ui["Session recorder"]
  node_api_client["HTTP API client<br/>[api.ts]"]
end

subgraph group_api["Backend API"]
  node_backend["FastAPI application<br/>[main.py]"]
  node_control_routes["Control endpoints<br/>[control.py]"]
  node_telemetry_routes["Telemetry endpoint<br/>[telemetry.py]"]
  node_session_routes["Session endpoints<br/>[session.py]"]
  node_sequence_routes["Sequence endpoints<br/>[sequence.py]"]
end

subgraph group_hardware["Control and hardware"]
  node_manager["Connection manager"]
  node_watchdog["Safety watchdog<br/>[safety_watchdog.py]"]
  node_sequence_service["Sweep execution"]
  node_protocol["Binary protocol<br/>[protocol.py]"]
  node_transports["Serial, TCP and virtual transports"]
end

subgraph group_runs["Test runs and data"]
  node_storage_service["Run storage and CSV export<br/>[storage_service.py]"]
  node_database[("SQLite run database")]
  node_csv["CSV export files"]
end

node_operator(("Operator"))
node_simulator["Physics simulator<br/>[virtual_stand.py]"]

node_operator -->|"operates"| node_app
node_app -->|"reads telemetry"| node_stream
node_app -->|"renders controls"| node_controls
node_app -->|"registers hotkey"| node_estop_ui
node_app -->|"renders readings"| node_instruments
node_app -->|"renders plots"| node_plots
node_app -->|"renders sweeps"| node_sequence_ui
node_app -->|"renders recorder"| node_recorder_ui
node_app -->|"opens calibration"| node_calibration
node_app -->|"opens limits"| node_limits
node_stream -.->|"fetches status"| node_api_client
node_controls -.->|"sends commands"| node_api_client
node_calibration -.->|"tares channels"| node_api_client
node_limits -.->|"sets thresholds"| node_api_client
node_estop_ui -.->|"requests stop"| node_api_client
node_plots -.->|"plots telemetry"| node_stream
node_sequence_ui -->|"starts sweeps"| node_api_client
node_recorder_ui -->|"manages runs"| node_api_client
node_api_client -->|"HTTP requests"| node_backend
node_stream -.->|"streams telemetry"| node_backend
node_backend -->|"registers routes"| node_control_routes
node_backend -->|"registers routes"| node_telemetry_routes
node_backend -->|"registers routes"| node_session_routes
node_backend -->|"registers routes"| node_sequence_routes
node_backend -->|"creates manager"| node_manager
node_backend -->|"starts storage"| node_storage_service
node_manager -->|"selects transport"| node_transports
node_transports -->|"encodes frames"| node_protocol
node_manager -->|"starts watchdog"| node_watchdog
node_manager -->|"creates sequencer"| node_sequence_service
node_manager -.->|"records samples"| node_storage_service
node_manager -.->|"connects TCP"| node_simulator
node_storage_service -->|"writes runs"| node_database
node_storage_service -->|"exports samples"| node_csv

click node_app "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/App.tsx"
click node_stream "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/hooks/useTelemetryStream.ts"
click node_controls "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/ConnectionSlider.tsx"
click node_calibration "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/CalibrationModal.tsx"
click node_limits "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/CurrentLimitsModal.tsx"
click node_estop_ui "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/hooks/useKeyboardEStop.ts"
click node_instruments "https://github.com/ubcaerodesign/thrust-stand-v3/tree/main/frontend/src/components/instruments"
click node_plots "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/plots/TelemetryPlot.tsx"
click node_sequence_ui "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/SequenceController.tsx"
click node_recorder_ui "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/SessionRecorder.tsx"
click node_api_client "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/services/api.ts"
click node_backend "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/main.py"
click node_control_routes "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/control.py"
click node_telemetry_routes "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/telemetry.py"
click node_session_routes "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/session.py"
click node_sequence_routes "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/sequence.py"
click node_manager "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/connection_manager.py"
click node_watchdog "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/safety_watchdog.py"
click node_sequence_service "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/sequence_service.py"
click node_protocol "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/core/protocol.py"
click node_transports "https://github.com/ubcaerodesign/thrust-stand-v3/tree/main/backend/app/hal"
click node_simulator "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/sim/virtual_stand.py"
click node_storage_service "https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/storage_service.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_stream,node_controls,node_calibration,node_limits,node_estop_ui,node_instruments,node_plots,node_sequence_ui,node_recorder_ui,node_api_client toneBlue
class node_backend,node_control_routes,node_telemetry_routes,node_session_routes,node_sequence_routes toneAmber
class node_manager,node_watchdog,node_sequence_service,node_protocol,node_transports toneMint
class node_storage_service,node_database,node_csv toneRose
class node_operator toneIndigo
class node_simulator toneTeal
```

## Components

### Operator desktop

- [Test stand workspace](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/App.tsx): `frontend/src/App.tsx`
- [Telemetry stream hook](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/hooks/useTelemetryStream.ts): `frontend/src/hooks/useTelemetryStream.ts`
- [Connection and throttle controls](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/ConnectionSlider.tsx): `frontend/src/components/controls/ConnectionSlider.tsx`
- [Load-cell calibration](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/CalibrationModal.tsx): `frontend/src/components/controls/CalibrationModal.tsx`
- [Current limits](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/CurrentLimitsModal.tsx): `frontend/src/components/controls/CurrentLimitsModal.tsx`
- [Emergency stop UI](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/hooks/useKeyboardEStop.ts): `frontend/src/hooks/useKeyboardEStop.ts`
- [Telemetry instruments](https://github.com/ubcaerodesign/thrust-stand-v3/tree/main/frontend/src/components/instruments): `frontend/src/components/instruments`
- [Telemetry plots](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/plots/TelemetryPlot.tsx): `frontend/src/components/plots/TelemetryPlot.tsx`
- [Sweep controller](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/SequenceController.tsx): `frontend/src/components/controls/SequenceController.tsx`
- [Session recorder](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/components/controls/SessionRecorder.tsx): `frontend/src/components/controls/SessionRecorder.tsx`
- [HTTP API client](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/frontend/src/services/api.ts): `frontend/src/services/api.ts`

### Backend API

- [FastAPI application](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/main.py): `backend/app/main.py`
- [Control endpoints](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/control.py): `backend/app/routers/control.py`
- [Telemetry endpoint](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/telemetry.py): `backend/app/routers/telemetry.py`
- [Session endpoints](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/session.py): `backend/app/routers/session.py`
- [Sequence endpoints](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/routers/sequence.py): `backend/app/routers/sequence.py`

### Control and hardware

- [Connection manager](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/connection_manager.py): `backend/app/services/connection_manager.py`
- [Safety watchdog](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/safety_watchdog.py): `backend/app/services/safety_watchdog.py`
- [Sweep execution](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/sequence_service.py): `backend/app/services/sequence_service.py`
- [Binary protocol](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/core/protocol.py): `backend/app/core/protocol.py`
- [Serial, TCP and virtual transports](https://github.com/ubcaerodesign/thrust-stand-v3/tree/main/backend/app/hal): `backend/app/hal`

### Test runs and data

- [Run storage and CSV export](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/backend/app/services/storage_service.py): `backend/app/services/storage_service.py`
- **SQLite run database**
- **CSV export files**

### Other components

- **Operator**
- [Physics simulator](https://github.com/ubcaerodesign/thrust-stand-v3/blob/main/sim/virtual_stand.py): `sim/virtual_stand.py`

## Connections

- Operator → Test stand workspace: operates (evidence: `README.md`)
- Test stand workspace → Telemetry stream hook: reads telemetry (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Connection and throttle controls: renders controls (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Emergency stop UI: registers hotkey (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Telemetry instruments: renders readings (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Telemetry plots: renders plots (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Sweep controller: renders sweeps (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Session recorder: renders recorder (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Load-cell calibration: opens calibration (evidence: `frontend/src/App.tsx`)
- Test stand workspace → Current limits: opens limits (evidence: `frontend/src/App.tsx`)
- Telemetry stream hook → HTTP API client: fetches status
- Connection and throttle controls → HTTP API client: sends commands
- Load-cell calibration → HTTP API client: tares channels
- Current limits → HTTP API client: sets thresholds
- Emergency stop UI → HTTP API client: requests stop
- Telemetry plots → Telemetry stream hook: plots telemetry
- Sweep controller → HTTP API client: starts sweeps (evidence: `frontend/src/components/controls/SequenceController.tsx`)
- Session recorder → HTTP API client: manages runs (evidence: `frontend/src/services/api.ts`)
- HTTP API client → FastAPI application: HTTP requests (evidence: `frontend/src/services/api.ts`)
- Telemetry stream hook → FastAPI application: streams telemetry
- FastAPI application → Control endpoints: registers routes (evidence: `backend/app/main.py`)
- FastAPI application → Telemetry endpoint: registers routes (evidence: `backend/app/main.py`)
- FastAPI application → Session endpoints: registers routes (evidence: `backend/app/main.py`)
- FastAPI application → Sequence endpoints: registers routes (evidence: `backend/app/main.py`)
- FastAPI application → Connection manager: creates manager (evidence: `backend/app/main.py`)
- FastAPI application → Run storage and CSV export: starts storage (evidence: `backend/app/main.py`)
- Connection manager → Serial, TCP and virtual transports: selects transport (evidence: `backend/app/services/connection_manager.py`)
- Serial, TCP and virtual transports → Binary protocol: encodes frames (evidence: `backend/app/hal/serial_transport.py`)
- Connection manager → Safety watchdog: starts watchdog (evidence: `backend/app/services/connection_manager.py`)
- Connection manager → Sweep execution: creates sequencer (evidence: `backend/app/services/connection_manager.py`)
- Connection manager → Run storage and CSV export: records samples (evidence: `backend/app/services/connection_manager.py`)
- Connection manager → Physics simulator: connects TCP
- Run storage and CSV export → SQLite run database: writes runs (evidence: `backend/app/services/storage_service.py`)
- Run storage and CSV export → CSV export files: exports samples (evidence: `backend/app/services/storage_service.py`)
