От нуля до работающей миссии за 10 минут.
Этот документ — пошаговое руководство по всем сценариям использования платформы UniSat: выбор типа миссии (CanSat / CubeSat / HAB / Rocket / Drone), подготовка окружения, запуск, кастомизация, подача на конкурс.
git clone https://github.com/root3315/unisat.git
cd unisat
./scripts/verify.sh # 1) полная самопроверка в Docker
make demo # 2) end-to-end SITL-демо AX.25
cd configurator && streamlit run configurator_app.py # 3) визуальный конфигуратор
Если verify.sh печатает ✓ UniSat green. Ready to submit. —
платформа работает на твоей машине, и можно идти дальше.
| Ты | Что тебе подходит | Время до результата |
|---|---|---|
| Студент, первый CanSat | mission_templates/cansat_standard.json + flight-software симулятор |
1 вечер |
| CubeSat Design конкурс | mission_templates/cubesat_sso.json + configurator + CDR docs |
1 неделя |
| NASA Space Apps / хакатон | Любой темплейт + Streamlit UI + симуляция орбиты | 48 часов |
| Ракетный конкурс (Spaceport America etc.) | mission_templates/rocket_competition.json + dual-deploy |
2–3 дня |
| HAB / стратосферный шар | mission_templates/hab_standard.json + GNSS + камера |
1 день |
| Исследователь, готовит к реальному запуску | Всё выше + HIL тесты + CDR документация + flight heritage plan | Месяцы |
Если ты просто хочешь понять как устроен спутник — запусти
симуляцию (cd simulation && python mission_analyzer.py) и почитай
docs/reference/TECHNICAL_DOCUMENTATION.md.
arm-none-eabi-gcc) — для прошивки STM32hardware/ (BOM, KiCad схемы)gcc / cmake — всё собирается в Dockergit clone https://github.com/root3315/unisat.git
cd unisat
./scripts/verify.sh
Что происходит:
unisat-ci (30 сек, один раз).cmake → make → ctest (28/28) → pytest (420/420 по всем 4 пакетам).Ожидаемый финал: ✓ UniSat green. Ready to submit.
Открой configurator/ — визуальный помощник:
cd configurator
pip install -r requirements.txt
streamlit run configurator_app.py
В браузере откроется мастер. Выбираешь форм-фактор, настраиваешь
полезную нагрузку, получаешь mission_config.json.
Или напрямую возьми готовый темплейт:
cp mission_templates/cubesat_sso.json mission_config.json
cd ground-station
pip install -r requirements.txt
streamlit run app.py
Откроется веб-интерфейс с 10 страницами: Mission Dashboard, Telemetry Charts, Orbit 3D, Command Center (HMAC-authenticated), Image Gallery, Attitude Viz, Power Monitor, Pass Predictor, Data Export, Health Report.
Демо-данные загрузятся из ground-station/data/demo.db.
Когда: школьные/университетские CanSat чемпионаты. Форм-фактор: диаметр 64 мм, высота 68 мм (банка), 80 мм (капсула), масса ≤500 г. Запуск: ракета/дрон/шар на 500–1000 м, парашютный спуск.
Файлы:
mission_templates/cansat_standard.json # канонический конфиг
flight-software/run_cansat.py # entry point
payloads/cansat_descent/ # descent controller
simulation/analytical_solutions.py # аналитика спуска
Запуск симуляции:
cp mission_templates/cansat_standard.json mission_config.json
cd flight-software
python run_cansat.py --config ../mission_config.json --sim
Типичный тест-полёт в симуляции занимает ~5 минут реального времени, производит ~300 КБ телеметрии, 20 снимков.
Когда: NASA CSLI, университетские design challenges, реальные CubeSat миссии. Форм-фактор: 10×10×11.35 см × n юнитов. Орбита: LEO 400–700 км, SSO 97.6° или ISS-release 51.6°.
Файлы:
mission_templates/cubesat_sso.json # 3U на солнечно-синхронке
firmware/stm32/... # вся OBC-прошивка
ground-station/ # полная наземная станция
docs/design/mission_design.md # CDR-level документация
Тут работает всё: firmware, flight-software, ground-station, simulation, configurator. Это основной use-case.
Когда: стратосферные эксперименты (30–40 км), любительские исследования. Форм-фактор: латексный шар + pod ≤1 кг. Полёт: 2–4 часа, дрейф до 200 км.
mission_templates/hab_standard.json
payloads/earth_observation/ # камера для стратосферы
simulation/orbit_simulator.py # в HAB-режиме даёт
ballistic trajectory
Когда: Spaceport America Cup, FAR-Mars, университетские ракеты. Особенность: dual-deploy recovery, апогей-детекция, высотомер.
mission_templates/rocket_competition.json
payloads/radiation/ или custom # научная нагрузка
Когда: CanSat-like тесты на дроне, тренировочные полёты.
mission_templates/drone_survey.json
Использует тот же flight-software stack, но без парашюта и с GPS waypoint navigation.
Host-build (для host-тестов, без железа):
make build # cmake + cmake --build
make test-c # ctest 25/25 (post-TRL-5)
make test-py # pytest 56+ тестов
Note on pyserial / flight-software tests. A full green pytest run on
flight-software/tests/requirespip install -r flight-software/requirements.txt(pyserial is the one that trips this). Without it, theCommunicationManagertests auto-skip cleanly — they no longer abort collection. The rest of the suite (camera, module_registry, …) still runs end-to-end.
Или вручную:
cd firmware
cmake -B build -S .
cmake --build build
ctest --test-dir build --output-on-failure
Cross-build для реального STM32F446 (после TRL-5 hardening):
# Одной командой из корня проекта (нужен arm-none-eabi-gcc):
make setup-hal # первый раз — fetch STM32Cube HAL (~15 MB)
make target # cross-compile -> build-arm/unisat_firmware.{elf,bin,hex}
make size # per-section flash / RAM report
make flash # прошить через ST-Link (со 90% footprint-бюджетом)
Quality gates (запустить локально перед PR):
make cppcheck # static-analysis gate (zero warnings)
make coverage # lcov HTML report (≥ 80% lines target)
make sanitizers # ASAN + UBSAN под ctest
cmake -DSTRICT=ON ...; make # -Werror -Wshadow -Wconversion
Python-слой поверх RPi Zero 2 W (или любого Linux):
cd flight-software
pip install -r requirements.txt
python main.py --config ../mission_config.json
В режиме симуляции данные от датчиков берутся из simulation/.
Реальный приём данных через радио (если есть железо):
# Терминал 1: AX.25 listener на TCP
cd ground-station
python -m cli.ax25_listen --port 52100
# Терминал 2: подключить SDR к TCP-пайпу
# (rtl-sdr + gr-satellites + FSK demod → netcat 52100)
Или имитация приёма:
# Терминал 1: listener
python -m cli.ax25_listen --port 52100 --count 10
# Терминал 2: отправка одного frame'а
python -m cli.ax25_send --host 127.0.0.1 --port 52100 \
--dst-call CQ --src-call UN8SAT --src-ssid 1 \
--info-hex "48656c6c6f"
Streamlit UI:
streamlit run app.py # http://localhost:8501
Прогон всех симуляторов разом:
cd simulation
pip install -r requirements.txt
python mission_analyzer.py --config ../mission_config.json
Индивидуально:
python orbit_simulator.py # Keplerian + J2, 1 орбита за 2 сек
python power_simulator.py # энергобаланс с eclipse/sunlight
python thermal_simulator.py # 6-face thermal model
python link_budget_calculator.py
python igrf_model.py # магнитное поле Земли для ADCS
python ndvi_analyzer.py # NDVI для Earth observation payload
Ключ — 32 байта, задаётся один раз при boot’е.
На ground station:
from utils.ax25 import Address, encode_ui_frame
from utils.hmac_auth import hmac_sha256
KEY = bytes.fromhex("0011..." * 4) # 32 B pre-shared secret
command = b"\x03\xF0\x01" # CCSDS APID=CMD, cmd_id=REBOOT
tag = hmac_sha256(KEY, command)
frame = encode_ui_frame(Address("UN8SAT", 1), Address("MYCALL", 0),
0xF0, command + tag)
# отправить frame по TCP/радио
На satellite (firmware):
#include "command_dispatcher.h"
static uint8_t g_key[32] = { /* burned at manufacturing */ };
int main(void) {
CommandDispatcher_SetKey(g_key, sizeof(g_key));
CommandDispatcher_SetHandler(my_command_handler);
/* ... */
}
static void my_command_handler(const uint8_t *packet, uint16_t len) {
/* CCSDS-уже проверен dispatcher'ом, tag уже валидирован */
uint8_t cmd_id = packet[2];
switch (cmd_id) {
case 0x01: OBC_SoftwareReset(); break;
case 0x02: EPS_EmergencyShutdown(); break;
/* ... */
}
}
Без валидного HMAC-тэга command отклоняется, счётчик
rejected_bad_tag++, ответа нет — атакующий не отличает
отброшенный спуф от потерянной реальной команды.
mission_config.json управляет почти всем:
{
"mission_name": "MyFirstSat-1",
"form_factor": "3U",
"mass_kg": 3.8,
"orbit": { "altitude_km": 550, "inclination_deg": 97.6 },
"subsystems": {
"obc": { "enabled": true },
"eps": { "enabled": true, "solar_panels": 6 },
"adcs": { "enabled": true, "magnetorquers": 3 },
"comm": { "uhf_enabled": true, "sband_enabled": false },
"gnss": { "enabled": true },
"payload": { "enabled": true }
},
"payload_type": "earth_observation",
"callsign": { "dst": "CQ", "src": "UN8SAT", "src_ssid": 1 }
}
Configurator (streamlit run configurator/configurator_app.py) —
визуальный редактор с валидацией (проверяет mass/power/volume
budgets перед сохранением).
payloads/my_experiment/payloads/interface.py:class PayloadInterface:
def init(self, config): ...
def activate(self): ...
def deactivate(self): ...
def read_data(self) -> bytes: ...
def get_status(self) -> dict: ...
mission_config.json:"payload_type": "my_experiment",
"payload_config": { "sample_rate_hz": 10 }
importlib.См. firmware/stm32/Drivers/ как шаблон. Паттерн:
*_Handle_t с void *i2c_handle / spi_handle*_Platform_* weak-symbol hooks (переопределяются STM32 HAL)*_Init / *_Read* API с *_Status_t return codesSIMULATION_MODE ветка с константными ответамиЗатем подключи в sensors.c по образцу LIS3MDL/MPU9250.
В firmware/stm32/Core/Inc/ccsds.h:
#define APID_MY_EXPERIMENT 0x042
В telemetry.c добавь функцию Telemetry_PackMyExperiment,
вызови CCSDS_BuildPacket с новым APID. Ground station
автоматически распарсит — ccsds.py::parse_packet() смотрит
APID из заголовка.
cp mission_templates/cansat_standard.json mission_config.jsonconfigurator/bom_generator.py → PDF с BOM.python scripts/gen_mission_report.pymission_config.json./scripts/verify.sh run (доказательство работающего софта)docs/design/mission_design.mddocs/budgets/power_budget.mddocs/budgets/mass_budget.mddocs/budgets/link_budget.mddocs/budgets/thermal_analysis.mddocs/budgets/orbit_analysis.mddocs/reference/REQUIREMENTS_TRACEABILITY.md под свои
требования.docs/verification/ax25_trace_matrix.md — показывает
формальное прослеживание requirements → tests../scripts/verify.sh, запиши на видео финал
✓ UniSat green. Ready to submit.48-часовой хакатон — используй готовое:
git clone https://github.com/root3315/unisat.git
cd unisat
./scripts/verify.sh
cd configurator && streamlit run configurator_app.py
Доработай payloads/earth_observation/ или напиши свой
NDVI-анализатор в simulation/ndvi_analyzer.py. За 48 часов
вполне реально получить готовый submission с живой демкой.
Смотри simulation/analytical_solutions.py — там задачи по
орбитальной механике, power budget, ADCS, с аналитическими
решениями (не численными) — идеально для олимпиадных защит.
./scripts/verify.sh падает на Docker buildПроверь что Docker Desktop запущен (иконка кита в трее, зелёная).
Если компьютер только что проснулся, часы в контейнере могут
разойтись с Debian security репозиторием — Dockerfile.ci это
переживает (apt-get update || true).
No tests were found после cmakeТы в неправильной директории. ctest должен быть в
firmware/build, не в корне.
pip install --upgrade streamlit plotly
CMake кеширует. make clean && make all или
rm -rf firmware/build && ./scripts/verify.sh.
verify.sh работает на Windows Git Bash благодаря
MSYS_NO_PATHCONV=1 внутри. Если что-то не так — используй WSL2
или PowerShell + прямые docker run команды из README.
См. docs/guides/TROUBLESHOOTING.md.
unisat/
├── README.md ← стартовая точка, бейджи и обзор
├── CHANGELOG.md ← история версий
├── COMPETITION_GUIDE.md ← адаптация под конкурсы (быстрая)
├── CONTRIBUTING.md
├── LICENSE ← MIT
├── Makefile ← make all / test / demo / ci
├── docker/
│ └── Dockerfile.ci ← образ для воспроизводимых прогонов
│
├── firmware/ ← C firmware для STM32F446
│ ├── CMakeLists.txt
│ ├── tests/ ← 16 ctest targets
│ └── stm32/
│ ├── Core/ ← OBC, COMM, GNSS, telemetry, CCSDS
│ ├── Drivers/ ← 9 драйверов + AX25 + Crypto + VirtualUART
│ ├── ADCS/ ← B-dot, quaternion, sun/target pointing
│ └── EPS/ ← MPPT, battery manager
│
├── flight-software/ ← Python layer для RPi Zero 2 W
│ ├── main.py
│ ├── tests/ ← 14 unit-test файлов
│ └── modules/ ← camera, orbit predictor, health monitor
│
├── ground-station/ ← Streamlit + Plotly UI
│ ├── app.py ← главная точка входа
│ ├── pages/ ← 10 страниц dashboard'а
│ ├── utils/
│ │ ├── ax25.py ← AX.25 кодек (Python)
│ │ └── hmac_auth.py ← HMAC-SHA256 зеркало
│ ├── cli/
│ │ ├── ax25_listen.py ← TCP listener
│ │ └── ax25_send.py ← TCP sender
│ └── tests/ ← 82 pytest-теста (hypothesis + golden + profile-gate)
│
├── simulation/ ← 10 симуляторов
├── configurator/ ← web-конфигуратор миссии
├── payloads/ ← 5 шаблонов полезной нагрузки
├── mission_templates/ ← 5 готовых `mission_config.json`
├── hardware/ ← BOM, KiCad схемы, mechanical
├── notebooks/ ← Jupyter demo notebooks
├── tests/golden/ ← shared C/Python AX.25 vectors
│
├── docs/ ← 23 документа
│ ├── TECHNICAL_DOCUMENTATION.md ← полная тех. дока (1100+ строк)
│ ├── USAGE_GUIDE.md ← этот файл
│ ├── TROUBLESHOOTING.md
│ ├── API_REFERENCE.md
│ ├── architecture.md
│ ├── mission_design.md ← CDR-level design
│ ├── communication_protocol.md ← CCSDS + AX.25 wire format
│ ├── power_budget.md
│ ├── mass_budget.md
│ ├── link_budget.md
│ ├── thermal_analysis.md
│ ├── orbit_analysis.md
│ ├── testing_plan.md
│ ├── assembly_guide.md
│ ├── REQUIREMENTS_TRACEABILITY.md
│ ├── POSTER_TEMPLATE.md
│ ├── adr/ ← architectural decisions
│ │ ├── ADR-001-no-csp.md
│ │ └── ADR-002-style-adapter.md
│ ├── security/
│ │ └── ax25_threat_model.md
│ ├── tutorials/
│ │ └── ax25_walkthrough.md ← byte-by-byte beacon разбор
│ ├── verification/
│ │ ├── ax25_trace_matrix.md ← auto-gen req → test mapping
│ │ └── driver_audit.md ← все 8 драйверов verified real
│ └── superpowers/ ← design specs + plans
│
└── scripts/
├── verify.sh ← one-command reproducibility
├── demo.py ← SITL end-to-end
├── sitl_fw.c ← firmware side of SITL
├── gen_golden_vectors.py
└── gen_trace_matrix.py
docs/reference/TECHNICAL_DOCUMENTATION.md целиком — там все
детали архитектуры.notebooks/ — интерактивные демо в Jupyter.hardware/).Документ обновлён: Апрель 2026 · версия 1.1