Version 1.5.1 β Universal Platform (CanSat + CubeSat 1Uβ12U + HAB + Rocket + Drone + Rover)
Professional open-source flight software for any small-satellite class
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:8501Prefer 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/.
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), Π° Π΄Π΅ΡΠ΅ΡΠΌΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅Π·ΠΎΠ»Π²Π΅Ρ ΡΠΈΡ-ΡΠ»Π°Π³ΠΎΠ² Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½ΡΠΆΠ½Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌΡ Π°ΠΏΠΏΠ°ΡΠ°ΡΡ.
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:
- STM32F446RE LD script, startup.s, SystemInit/clock at 168 MHz
- FreeRTOS kernel + CMSIS-RTOSv2 + HAL autodetect in CMake
make setup-all && make targetproduces a real.elf- Verified footprint: 31.6 KB flash (6 %) / 36.3 KB RAM (28 %)
- 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
- 12 fault IDs + 60s escalation window + 6-level severity ladder
- Advisor (
fdir.c) / commander (mode_manager.c) split (ADR-005) - Persistent fault log in
.noinitSRAM β survives warm reboot
- 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
make cppcheck(CI-blocking) + MISRA advisorymake coverageβ 85.3 % C linesmake sanitizersβ ASAN + UBSAN cleancmake -DSTRICT=ONβ-Werror -Wshadow -Wconversionclean
- SRS with 44 REQ + traceability CSV
- 8 ADRs for architectural decisions
- HIL test plan + characterization templates
- Threat model v2 with T1+T2 closed
make coverage-pyβ 85.15 % Python lines (gate β₯ 80 % MUST)make lint-pyβ mypy strict clean across 21 filesmake sbomβ auto-generated SPDX bill of materialsmake pin-dockerβ release-engineering digest pin
- 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)
| 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 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 β β
β ββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| 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 |
git clone https://github.com/root3315/unisat.git
cd unisatchmod +x scripts/setup.sh
./scripts/setup.shcd ground-station
pip install -r requirements.txt
streamlit run app.pycd 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
β ΡΠ΅ΡΡΠ½ΡΠΉ ΡΡΠ°ΡΡΡ, ΠΏΡΠΈΠΎΡΠΈΡΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ ΠΎΡΠΊΡΡΡΡΡ
Π·Π°Π΄Π°Ρ.
# Requires Docker Desktop running. No local gcc/cmake/pytest needed.
./scripts/verify.shThat 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 + testsmake ciβ same, inside Dockermake demoβ just the SITL beacon pathmake test-c/make test-pyβ split suitesmake helpβ list all targets
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).
If you don't want to use Docker:
cd firmware
cmake -B build -S .
cmake --build build
ctest --test-dir build --output-on-failureCross-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}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.
# 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.pyBuild every profile at once with make target-all-profiles (produces
nine separate build-arm-<profile>/ trees).
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
}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).
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
Full index: docs/README.md β every doc in the repo, grouped by purpose.
docs/guides/USAGE_GUIDE.mdβ step-by-step from clone to competition submissiondocs/guides/OPERATIONS_GUIDE.mdβ 12-section playbook: profile pick β flight day β post-flightdocs/guides/TROUBLESHOOTING.mdβ common build / run / integration issuesdocs/ops/README.mdβ profile-selection flowchart + index of all 11 per-profile ops guidesdocs/reference/TECHNICAL_DOCUMENTATION.mdβ full technical deep-dive (~1200 lines)docs/project/GAPS_AND_ROADMAP.mdβ honest status, open work, out-of-scope
One file per form factor covering setup β build β bench test β flight β post-flight:
- CanSat β
cansat_minimalΒ·cansat_standardΒ·cansat_advanced - CubeSat β
cubesat_1uΒ·cubesat_1_5uΒ·cubesat_2uΒ·cubesat_3uΒ·cubesat_6uΒ·cubesat_12u - Other platforms β
rocket_avionicsΒ·hab_payloadΒ·drone
architecture.mdβ layered architecture + form-factor registry overviewuniversal_platform.mdβ one code base / 14 form factorsmission_design.mdβ mission concept of operationscommunication_protocol.mdβ AX.25 + CCSDS wire formatassembly_guide.mdβ physical assembly
mass_budget.mdβ 3U component mass with marginspower_budget.mdβ solar / storage / consumptionlink_budget.mdβ UHF + S-band link marginsorbit_analysis.mdβ ground track, eclipse, J2thermal_analysis.mdβ orbital thermal environment
Per-profile envelopes (mass / volume / power) are in flight-software/core/form_factors.py; per-class BOMs are under hardware/bom/by_form_factor/.
API_REFERENCE.mdβ programmatic API surfaceTECHNICAL_DOCUMENTATION.mdβ technical deep-diveSTYLE_GUIDE.mdβ Google-derived code + prose conventionsREQUIREMENTS_TRACEABILITY.mdβ REQ β source β test mapping
- ADR-001 β No CSP
- ADR-002 β Style Adapter
- ADR-003 β A/B Key Store
- ADR-004 β Replay Counter Zero-Sentinel
- ADR-005 β FDIR Advisory Split
- ADR-006 β .noinit Persistent Log
- ADR-007 β HAL Shim Strategy
- ADR-008 β Command Dispatcher Wire Format
CC1125_configuration.mdβ UHF radio register mapradiation_budget.mdβ TID / SEE design budget per orbital class
docs/requirements/SRS.mdβ Software Requirements Specificationdocs/requirements/traceability.csvβ REQ β source β test CSVdocs/verification/ax25_trace_matrix.mdβ auto-generated trace matrixdocs/verification/driver_audit.mdβ every driver proven real (not mock)docs/testing/testing_plan.mdβ overall V&V strategydocs/testing/hil_test_plan.mdβ HIL bench procedure + 10 testsdocs/reliability/fdir.mdβ 12 fault IDs + recovery ladderdocs/quality/static_analysis.mdβ cppcheck + coverage + sanitizersdocs/characterization/README.mdβ WCET / stack / power measured baselinesdocs/security/ax25_threat_model.mdβ T1 + T2 both mitigated
GAPS_AND_ROADMAP.mdβ what works, what's next, what's out of scopeREGULATORY.mdβ licensing, export control, radio regulationPOSTER_TEMPLATE.mdβ competition poster starter
docs/tutorials/ax25_walkthrough.mdβ byte-by-byte beacon decodedocs/operations/commissioning_runbook.mdβ post-deploy activationdocs/sbom/sbom-summary.mdβ SPDX bill of materials (auto-generated viamake sbom)docs/diagrams/β SVG block diagrams
CONTRIBUTING.mdβ PR workflowSECURITY.mdβ vulnerability reportingCHANGELOG.mdβ semantic-versioned historyCLAUDE.mdβ guidance for AI-assisted contributions
One command:
./scripts/verify.sh # Docker-based, no local toolchain neededVia 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 targetsQuality 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-F446REManual:
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 -vSee CONTRIBUTING.md for guidelines on how to contribute to UniSat.
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.
- 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