Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

root3315/unisat

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

189 Commits
189 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

UniSat β€” universal modular satellite platform

Verify AX.25 C tests Python tests Latest release Stars Open issues Coverage ARM License Python STM32 Platforms

Version 1.5.1 β€” Universal Platform (CanSat + CubeSat 1U–12U + HAB + Rocket + Drone + Rover)
Professional open-source flight software for any small-satellite class

UniSat key capabilities


60-second tour

git clone https://github.com/root3315/unisat.git && cd unisat
./scripts/verify.sh                                # full green pipeline (Docker)
cp mission_templates/cubesat_3u.json mission_config.json
make target-cubesat_3u                             # β†’ firmware/build-arm-cubesat_3u/
cd ground-station && streamlit run app.py          # β†’ http://localhost:8501

Prefer CanSat? Replace cubesat_3u with cansat_standard. Going to a specific competition? Pick the preset that matches its rulebook β€” e.g. cansat_uzcansat.json for πŸ‡ΊπŸ‡Ώ UzCanSat 2026. The firmware, flight-software, and ground-station all reconfigure themselves from mission_config.json.

Full step-by-step: docs/guides/USAGE_GUIDE.md Β· per-profile playbooks: docs/ops/ Β· full docs index: docs/README.md Β· mission templates: mission_templates/.


Overview

UniSat is a complete, modular flight-software platform that targets the full spectrum of student and research vehicles in a single codebase:

  • CanSat β€” minimal / standard / advanced (≀350 g, ≀500 g)
  • CubeSat β€” 1U, 1.5U, 2U, 3U, 6U, 12U
  • Suborbital rockets, high-altitude balloons, drones and rovers

The same STM32 firmware, the same Python flight controller, and the same Streamlit ground station reconfigure themselves automatically from mission_config.json. A form-factor registry enforces mass/volume/power envelopes (CDS Rev. 14 for CubeSats, ESA CanSat regulations for CanSats), and a deterministic feature-flag resolver gates every optional subsystem so the build contains only what the mission actually needs.


ΠžΠ±Π·ΠΎΡ€ (Русский)

UniSat β€” ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ программная ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°, которая ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ рСпозитория запускаСт:

  • CanSat β€” minimal / standard / advanced (≀350 Π³ ΠΈ ≀500 Π³);
  • CubeSat β€” 1U, 1.5U, 2U, 3U, 6U, 12U;
  • ΡΡƒΠ±ΠΎΡ€Π±ΠΈΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°ΠΊΠ΅Ρ‚Ρ‹, стратосфСрныС Π·ΠΎΠ½Π΄Ρ‹, Π‘ΠŸΠ›Π ΠΈ Ρ€ΠΎΠ²Π΅Ρ€Ρ‹.

Одна ΠΈ Ρ‚Π° ΠΆΠ΅ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΠ° STM32, ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΏΠΎΠ»Ρ‘Ρ‚Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ Π½Π° Python ΠΈ ΠΎΠ΄Π½Π° ΠΈ Ρ‚Π° ΠΆΠ΅ назСмная станция Π½Π° Streamlit сами ΠΏΠΎΠ΄ΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΠΎΠ΄ Π°ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ миссию Ρ‡Π΅Ρ€Π΅Π· mission_config.json. РССстр Ρ„ΠΎΡ€ΠΌ-Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΎΠ² провСряСт массу/ΠΎΠ±ΡŠΡ‘ΠΌ/энСргСтику (CDS Rev. 14 для CubeSat, ΠΏΡ€Π°Π²ΠΈΠ»Π° ESA для CanSat), Π° Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΠΎΠ»Π²Π΅Ρ€ Ρ„ΠΈΡ‡-Ρ„Π»Π°Π³ΠΎΠ² Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ подсистСмы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½Ρ‹ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Ρƒ.


πŸ”’ What's new in v1.2.0 β€” TRL-5 hardening

Version 1.2.0 landed an eight-phase hardening sweep (75 commits on feat/trl5-hardening) that promotes UniSat from "competition- ready template" to TRL-5-capable software platform. Full details in CHANGELOG.md β€” summary:

Phase 1 β€” Real ARM target build

  • STM32F446RE LD script, startup.s, SystemInit/clock at 168 MHz
  • FreeRTOS kernel + CMSIS-RTOSv2 + HAL autodetect in CMake
  • make setup-all && make target produces a real .elf
  • Verified footprint: 31.6 KB flash (6 %) / 36.3 KB RAM (28 %)

Phase 2 β€” Security (T1 + T2 both closed)

  • T1 (injection): HMAC-SHA256 + constant-time verify
  • T2 (replay): 32-bit counter + 64-bit sliding-window bitmap
  • Persistent key store (A/B flash slots + CRC + monotonic gen)
  • Python CounterSender β€” thread-safe ground-side pair

Phase 3 β€” FDIR (NASA-style three-tier)

  • 12 fault IDs + 60s escalation window + 6-level severity ladder
  • Advisor (fdir.c) / commander (mode_manager.c) split (ADR-005)
  • Persistent fault log in .noinit SRAM β€” survives warm reboot

Phase 4 β€” Tboard + mission scenario

  • Live TMP117 reading in beacon bytes 14-15 (was zero-padded)
  • End-to-end mission lifecycle test (startup β†’ nominal β†’ safe β†’ recovery) + 48-hour soak harness

Phase 5 β€” Quality gates

  • make cppcheck (CI-blocking) + MISRA advisory
  • make coverage β€” 85.3 % C lines
  • make sanitizers β€” ASAN + UBSAN clean
  • cmake -DSTRICT=ON β€” -Werror -Wshadow -Wconversion clean

Phase 6 β€” Documentation (CDR-level)

  • SRS with 44 REQ + traceability CSV
  • 8 ADRs for architectural decisions
  • HIL test plan + characterization templates
  • Threat model v2 with T1+T2 closed

Phase 7 β€” Python + release plumbing

  • make coverage-py β€” 85.15 % Python lines (gate β‰₯ 80 % MUST)
  • make lint-py β€” mypy strict clean across 21 files
  • make sbom β€” auto-generated SPDX bill of materials
  • make pin-docker β€” release-engineering digest pin

Phase 8 β€” Final polish

  • ARM build fully verified end-to-end
  • Zero warnings in any build profile
  • Total tests: 27 C + 329 Python = 356 checks
  • Migrated MIT β†’ Apache 2.0 for patent-grant protection (Β§3)

Test + coverage progression

Before (v1.1.0) After (v1.2.0)
C test executables 16 27
Python tests 34 329
C line coverage not measured 85.3 %
Python line coverage not measured 85.15 %
ARM target .elf not verified 6 % flash / 28 % RAM
ADRs 2 8
Quality gates 1 9 (all green)
License MIT Apache 2.0

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GROUND STATION (Python/Streamlit)         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚Dashboard β”‚ β”‚Telemetry β”‚ β”‚  Orbit   β”‚ β”‚Command Center β”‚  β”‚
β”‚  β”‚          β”‚ β”‚  Charts  β”‚ β”‚ Tracker  β”‚ β”‚  (HMAC-AUTH)  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚ UHF 437 MHz / S-band 2.4 GHz
                          β”‚ AX.25 / CCSDS Protocol
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CUBESAT (1U-6U)                         β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚         FLIGHT CONTROLLER (Raspberry Pi Zero 2 W)     β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚
β”‚  β”‚  β”‚Camera  β”‚ β”‚Orbit   β”‚ β”‚Health  β”‚ β”‚  Scheduler   β”‚  β”‚   β”‚
β”‚  β”‚  β”‚Handler β”‚ β”‚Predict β”‚ β”‚Monitor β”‚ β”‚  (asyncio)   β”‚  β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                         β”‚ UART                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚              OBC FIRMWARE (STM32F4 + FreeRTOS)        β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚
β”‚  β”‚  β”‚ADCS  β”‚ β”‚EPS   β”‚ β”‚COMM  β”‚ β”‚GNSS  β”‚ β”‚Telemetry β”‚  β”‚   β”‚
β”‚  β”‚  β”‚B-dot β”‚ β”‚MPPT  β”‚ β”‚UHF   β”‚ β”‚u-bloxβ”‚ β”‚  CCSDS   β”‚  β”‚   β”‚
β”‚  β”‚  β”‚Sun   β”‚ β”‚BatMgrβ”‚ β”‚S-bandβ”‚ β”‚      β”‚ β”‚          β”‚  β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   SOLAR PANELS     β”‚  β”‚      PAYLOAD (swappable)      β”‚  β”‚
β”‚  β”‚   GaAs 29.5% eff.  β”‚  β”‚  Radiation / Camera / IoT /   β”‚  β”‚
β”‚  β”‚   6 panels (3U)    β”‚  β”‚  Magnetometer / Spectrometer   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Features

Subsystem Description Technology
OBC Firmware Real-time task management, watchdog, safe mode STM32F4 + FreeRTOS (C)
ADCS B-dot detumbling, sun/nadir/target pointing Quaternion math, PID control
EPS MPPT solar charging, battery management Perturb & Observe algorithm
Communication UHF 9600 bps + S-band 256 kbps AX.25 v2.2 full (streaming decoder, bit-stuffing, CRC-16/X.25, Β§3.12 addresses) + CCSDS Space Packet + HMAC-SHA256
Flight Software Async mission control, imaging, orbit prediction Python 3.11+ asyncio
Ground Station 10-page dashboard with real-time telemetry Streamlit + Plotly
Simulation Orbit, power, thermal, link budget Python scientific stack
Configurator Web-based mission builder with validation Streamlit
Payloads 5 swappable payload modules Plugin architecture

Quick Start

1. Clone the repository

git clone https://github.com/root3315/unisat.git
cd unisat

2. Install dependencies

chmod +x scripts/setup.sh
./scripts/setup.sh

3. Run the ground station

cd ground-station
pip install -r requirements.txt
streamlit run app.py

4. Run simulation

cd simulation
pip install -r requirements.txt
python mission_analyzer.py

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ руководство: docs/guides/USAGE_GUIDE.md β€” ΠΎΡ‚ Π²Ρ‹Π±ΠΎΡ€Π° Ρ‚ΠΈΠΏΠ° миссии (CanSat / CubeSat / HAB / Rocket / Drone) Π΄ΠΎ ΠΏΠΎΠ΄Π°Ρ‡ΠΈ Π½Π° конкурс.

Π§Ρ‚ΠΎ Π΅Ρ‰Ρ‘ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ: docs/project/GAPS_AND_ROADMAP.md β€” чСстный статус, ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ список ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡.

5. End-to-end AX.25 SITL demo (one command)

# Requires Docker Desktop running. No local gcc/cmake/pytest needed.
./scripts/verify.sh

That script builds the unisat-ci Docker image once (~30 s), then runs the full green pipeline inside it: firmware host build β†’ ctest β†’ pytest β†’ end-to-end SITL beacon demo. Expected final line: βœ“ UniSat green. Ready to submit.

For more granular control:

  • make all β€” build + tests
  • make ci β€” same, inside Docker
  • make demo β€” just the SITL beacon path
  • make test-c / make test-py β€” split suites
  • make help β€” list all targets

Project Status

TRL-5 hardening: all 6 phases on feat/trl5-hardening closed.

Check Status
Firmware host build (all subsystems) βœ… clean (unisat_core)
Firmware target build (STM32F446RE .elf/.bin/.hex) βœ… verified: 31.6 KB flash (6%) / 36.3 KB RAM (28%) under 90% budget
C unit tests (ctest) βœ… 28 / 28 passing (100+ sub-tests)
Python tests (pytest, full suite) βœ… 420 passing β€” 262 flight-software + 82 ground-station + 57 simulation + 19 configurator
Python coverage (MUST gate) βœ… 85.15 % (make coverage-py, β‰₯ 80 % enforced)
Streamlit page import smoke βœ… 12/13 passing (1 skipped β€” streamlit not installed)
Universal platform (v1.3.1) βœ… 14 form factors: CanSat min/std/adv + CubeSat 1U/1.5U/2U/3U/6U/12U + rocket/HAB/drone/rover/custom
SBOM (SPDX) βœ… make sbom generates docs/sbom/sbom-summary.md
FreeRTOS autodetect in CMake βœ… make setup-freertos + make setup-all
AX.25 golden vectors cross-validation βœ… 28/28 byte-identical C ↔ Python
SHA-256 FIPS 180-4 oracle βœ… "abc" + "" canonical digests
HMAC-SHA256 RFC 4231 vectors βœ… Β§4.2 + Β§4.3 on both C and Python
End-to-end SITL demo βœ… C encoder β†’ TCP β†’ Python decoder
E2E mission scenario (startup β†’ nominal β†’ safe) βœ… flight-software/tests/test_mission_e2e.py
Long-soak harness (48 h gated via UNISAT_SOAK_SECONDS) βœ… test_long_soak.py
Driver reality audit βœ… all 9 drivers verified real (incl. BoardTemp)
Threat T1 (command injection) βœ… HMAC dispatcher
Threat T2 (replay) βœ… 32-bit counter + 64-bit sliding window
Persistent key store (A/B + CRC + rotation) βœ… 10/10 tests
Boot-time key_store β†’ dispatcher wiring in main.c βœ… 4/4 integration tests
Python counter-aware HMAC frame builder (CounterSender) βœ… 22/22 pytest
FDIR fault advisor + watchdog integration βœ… 9/9 tests, 12 fault IDs
FDIR mode supervisor (SAFE/DEGRADED/REBOOT wiring) βœ… 9/9 tests
Persistent fault log (.noinit, survives warm reboot) βœ… 6/6 tests
Tboard (TMP117) facade in beacon bytes 14–15 βœ… 6/6 tests
cppcheck static-analysis gate βœ… clean (make cppcheck)
Line coverage (C) βœ… 85.3 % / functions 84.0 % (make coverage)
ASAN + UBSAN under ctest βœ… 28/28 clean (make sanitizers)
STRICT mode (-Werror -Wshadow -Wconversion) βœ… 28/28 clean (cmake -DSTRICT=ON)
ADRs for architectural decisions βœ… 8 ADRs under docs/adr/
Full SRS + traceability CSV βœ… docs/requirements/SRS.md
HIL test plan + characterization templates βœ… docs/testing + docs/characterization
Requirement traceability (AX.25 subset) βœ… auto-generated (docs/verification/ax25_trace_matrix.md)

Deferred (not TRL-5 blockers) β€” see docs/project/GAPS_AND_ROADMAP.md: Streamlit↔AX.25 live bridge, CC1125 radio config doc, MISRA backlog cleanup (~1000 Rule 8.7/10.x style deviations).

6. Build firmware manually (optional)

If you don't want to use Docker:

cd firmware
cmake -B build -S .
cmake --build build
ctest --test-dir build --output-on-failure

Cross-compile for STM32F446 (requires arm-none-eabi-gcc):

cd firmware
cmake -B build-arm -S . -DCMAKE_TOOLCHAIN_FILE=arm.cmake
cmake --build build-arm
# Output: build-arm/unisat_firmware.{elf,bin,hex}

Supported Form Factors

UniSat supported form factors

UniSat's form-factor registry is the single source of truth for every supported class. Every envelope in the tables below is enforced at runtime; each row also ships a mission template, a hardware BOM, a compile-time firmware profile, and a dedicated ops guide.

Form factor Max mass Dimensions (mm) ADCS tiers Typical radios BOM Ops guide
CanSat minimal 350 g Ø66 Γ— 115 cyl. none ISM 433/868/915, LoRa cansat_minimal.csv cansat_minimal.md
CanSat standard 500 g Ø68 Γ— 80 cyl. none ISM, LoRa cansat_standard.csv cansat_standard.md
CanSat advanced 500 g Ø68 Γ— 115 cyl. passive-spin ISM, UHF amateur cansat_advanced.csv cansat_advanced.md
CubeSat 1U 2.0 kg 100 Γ— 100 Γ— 113.5 passive-magnetic VHF/UHF amateur cubesat_1u.csv cubesat_1u.md
CubeSat 1.5U 3.0 kg 100 Γ— 100 Γ— 170.25 magnetorquer UHF amateur cubesat_1_5u.csv cubesat_1_5u.md
CubeSat 2U 4.0 kg 100 Γ— 100 Γ— 227.0 magnetorquer + sensors UHF + optional S-band cubesat_2u.csv cubesat_2u.md
CubeSat 3U ← TRL-5 ref 6.0 kg 100 Γ— 100 Γ— 340.5 reaction wheels 3-axis UHF + S-band + X-band cubesat_3u.csv cubesat_3u.md
CubeSat 6U 12.0 kg 226.3 Γ— 100 Γ— 366 star tracker fine-pointing UHF + S + X + Ka cubesat_6u.csv cubesat_6u.md
CubeSat 12U 24.0 kg 226.3 Γ— 226.3 Γ— 366 star tracker + propulsion UHF + S + X + Ka + optical cubesat_12u.csv cubesat_12u.md
Rocket payload 10 kg Ø100 Γ— 300 cyl. none / passive-spin ISM, UHF, S-band β€” rocket_avionics.md
HAB payload 4 kg 150 Γ— 150 Γ— 150 none ISM, APRS, UHF amateur β€” hab_payload.md
Small drone (UAS) 5 kg 500 Γ— 500 Γ— 200 IMU attitude control ISM 2.4 GHz β€” drone.md

Mission templates live in mission_templates/ β€” copy the one you want into mission_config.json and the flight controller, firmware, and ground station all follow along. Profile-selection flowchart + trade-offs in docs/ops/README.md.

Picking a profile

# 1. Choose a template (CanSat, CubeSat 1U … 12U, rocket, HAB, drone).
cp mission_templates/cubesat_3u.json mission_config.json

# 2. Build the matching firmware image.
make target-cubesat-3u       # β†’ firmware/build-arm-cubesat-3u/

# 3. Launch the flight controller and ground station β€” they read
#    mission_config.json and configure themselves automatically.
cd flight-software && python3 flight_controller.py
cd ground-station && streamlit run app.py

Build every profile at once with make target-all-profiles (produces nine separate build-arm-<profile>/ trees).

Feature flags

mission_config.json accepts a top-level features block whose keys are defined in flight-software/core/feature_flags.py. The resolver combines explicit overrides with platform / form-factor / ADCS-tier / radio-band gates so the final enabled set is deterministic and logged. Examples:

"features": {
    "orbit_predictor": true,         // CubeSat-only β†’ disabled for CanSat
    "reaction_wheels": true,         // requires 2U+ and an RW tier
    "star_tracker":   false,         // explicit disable always wins
    "descent_controller": true,      // CanSat / rocket / HAB only
    "parachute_pyro": true,
    "s_band_radio":   true           // requires s_band radio configured
}

Competition Adaptation

Ready-to-submit adaptations for aerospace competitions. Detailed per-profile guides live in docs/ops/ (one file per form factor) + short form in USAGE_GUIDE.md Β§7.

Competition Template Highlights Ops guide Prep time
CanSat (beginner) cansat_minimal.json RP2040, ISM 433 MHz, ≀350 g cansat_minimal.md 1 evening
πŸ‡ΊπŸ‡Ώ UzCanSat 2026 (cmspace.uz) cansat_uzcansat.json 1 Hz telemetry, buzzer locator, camera 640Γ—480 @ 30 fps β€” preset full compliant with cmspace.uz rulebook UZCANSAT_COMPLIANCE.md 2–3 days
ESERO / national CanSat cansat_standard.json Parachute, IMU, Ø68 Γ— 80 mm, ≀500 g cansat_standard.md 2–3 days
NASA CanSat cansat_advanced.json Pyro deploy, camera, guided descent cansat_advanced.md 1 week
CubeSat Design cubesat_3u.json 3U LEO, CDR docs, HMAC auth cubesat_3u.md 1 week
CubeSat 6U/12U research cubesat_6u.json / cubesat_12u.json X/Ka-band, propulsion slot cubesat_6u.md 2–3 weeks
NASA Space Apps Any CubeSat + NDVI Earth observation cubesat_6u.md 48 h
IREC / SA Cup rocket rocket_competition.json Dual-deploy, HMAC telemetry rocket_avionics.md 2–3 days
HAB flight hab_standard.json GNSS + camera hab_payload.md 1 day
UAV survey drone_survey.json Mission planner drone.md 1–2 days

Also: COMPETITION_GUIDE.md (short form), docs/ops/README.md (profile-selection flowchart).


Project Structure

unisat/
β”œβ”€β”€ firmware/             # STM32F446 firmware (C11 + FreeRTOS)
β”‚   β”œβ”€β”€ stm32/Core/       #   OBC, COMM, GNSS, CCSDS, telemetry,
β”‚   β”‚                     #   command_dispatcher (HMAC-auth)
β”‚   β”œβ”€β”€ stm32/Drivers/    #   9 sensor drivers + AX25 + Crypto +
β”‚   β”‚                     #   VirtualUART (SITL TCP shim)
β”‚   β”œβ”€β”€ stm32/ADCS/       #   B-dot, quaternion, sun/target pointing
β”‚   β”œβ”€β”€ stm32/EPS/        #   MPPT, battery manager
β”‚   └── tests/            #   28 Unity test targets
β”œβ”€β”€ flight-software/      # Python async flight controller (RPi Zero 2 W)
β”‚   β”œβ”€β”€ core/             #   form_factors.py, feature_flags.py, mission_types.py
β”‚   └── tests/            #   262 pytest incl. e2e + soak + hypothesis
β”œβ”€β”€ ground-station/       # Streamlit UI + AX.25 CLI + HMAC tooling
β”‚   β”œβ”€β”€ utils/ax25.py     #   AX.25 v2.2 Python mirror
β”‚   β”œβ”€β”€ utils/hmac_auth.py#   HMAC-SHA256 mirror (RFC 4231)
β”‚   β”œβ”€β”€ utils/profile_gate.py #  hides orbit/image/ADCS pages by profile
β”‚   β”œβ”€β”€ cli/              #   ax25_listen / ax25_send TCP tools
β”‚   └── tests/            #   82 pytest incl. hypothesis + fuzz
β”œβ”€β”€ simulation/           # 10 simulators (orbit, power, thermal, link) β€” 57 tests
β”œβ”€β”€ configurator/         # Web-based mission configurator + BOM gen β€” 19 tests
β”œβ”€β”€ hardware/
β”‚   β”œβ”€β”€ bom/by_form_factor/  # 7 per-class BOMs with real masses
β”‚   └── kicad/              # 4 KiCad boards (OBC, EPS, Comm, Sensor)
β”œβ”€β”€ payloads/             # 5 swappable payload templates
β”œβ”€β”€ mission_templates/    # 8 ready-to-use presets (CanSat min/std/adv + CubeSat 1U-12U)
β”œβ”€β”€ tests/golden/         # Shared AX.25 test vectors (C + Python)
β”œβ”€β”€ docs/                 # 25+ md docs (USAGE_GUIDE, TECHNICAL_DOC,
β”‚                         # ADRs, threat model, tutorials, verification)
β”œβ”€β”€ docker/Dockerfile.ci  # Reusable CI image (cmake + pytest baked)
β”œβ”€β”€ scripts/verify.sh     # One-command reproducibility
β”œβ”€β”€ Makefile              # make all / test / demo / ci / help
β”œβ”€β”€ CHANGELOG.md          # Semantic-versioned history
└── README.md             # This file

Documentation

Full index: docs/README.md β€” every doc in the repo, grouped by purpose.

Start here

Per-profile operations guides (docs/ops/)

One file per form factor covering setup β†’ build β†’ bench test β†’ flight β†’ post-flight:

Design & architecture (docs/design/)

Quantitative budgets (docs/budgets/, 3U reference)

Per-profile envelopes (mass / volume / power) are in flight-software/core/form_factors.py; per-class BOMs are under hardware/bom/by_form_factor/.

Reference (docs/reference/)

Architecture decisions (docs/adr/ β€” 8 ADRs)

Hardware (docs/hardware/)

Verification, testing, reliability

Project state & regulatory (docs/project/)

Tutorials, operations, SBOM, diagrams

Contributing & security


Testing

One command:

./scripts/verify.sh   # Docker-based, no local toolchain needed

Via Makefile:

make all              # build + test (C + Python)
make test-c           # ctest only (28 targets, 100+ sub-tests)
make test-py          # pytest only (420 tests across all 4 Python packages)
make demo             # end-to-end SITL AX.25 beacon demo
make help             # list all targets

Quality gates:

# C firmware
make cppcheck         # static-analysis gate (zero issues)
make cppcheck-strict  # + MISRA-C:2012 advisory report
make coverage         # lcov html report (85.3 % lines)
make sanitizers       # ASAN + UBSAN under ctest

# Python
make coverage-py      # pytest + coverage (β‰₯ 50 % MUST gate, 80 % SHOULD)
make lint-py          # mypy type check on flight-software

# supply-chain
make sbom             # SPDX bill-of-materials under docs/sbom/

STM32 target (Phase 1):

make setup-all        # fetch STM32Cube HAL + FreeRTOS kernel (one-time)
make target           # cross-compile .elf / .bin / .hex
make size             # per-section flash / RAM usage
make flash            # st-flash to Nucleo-F446RE

Manual:

cd firmware && cmake -B build -S . && cmake --build build
ctest --test-dir build --output-on-failure
cd ../ground-station && python -m pytest tests/test_ax25.py -v

Contributing

See CONTRIBUTING.md for guidelines on how to contribute to UniSat.


License

This project is licensed under the Apache License, Version 2.0 β€” see LICENSE and NOTICE for the full terms and the third-party attribution summary.

License history: the project was initially published under MIT (2026-02-15 β€” 2026-04-18) and migrated to Apache-2.0 on 2026-04-18 for its patent-grant clause (Β§3) and the defensive-termination language (retaliation against a patent suit terminates the aggressor's patent licence). Copies obtained during the MIT window stay MIT-licensed; new releases from 2026-04-18 onward are Apache-2.0 only.


Acknowledgments

  • CCSDS (Consultative Committee for Space Data Systems) for protocol standards
  • FreeRTOS for the real-time operating system
  • SGP4 algorithm authors for orbit prediction
  • CubeSat Design Specification (CalPoly) for mechanical standards

About

πŸ›°οΈ Universal satellite software platform β€” CanSat, CubeSat 1U-12U, HAB, rocket, drone. One codebase β†’ 14 form factors. 471 tests green, TRL-5 hardened.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.