Konstrui Kosmoŝipan Komputadan Simulilon kun Claude Code
Mi volis kompreni kiel funkcias kosmoŝipaj komputiloj. La realtempan planadون, la radiado-hardadon, la prokrasto-tolereman rettadon kiu konservas la Marsmarsejojn komunikantaj kun la Tero. Kun Artemis II ĉe la horizonto (la unua pilotata luna misio en pli ol 50 jaroj) ŝajnis la ĝusta momento por enplonĝi. Do mi konstruis simulilon. Ekde la komenco. Kun Claude Code kiel mia parprogramisto.
Neniu fizika aparataro. Ĉio funkcias en QEMU kaj Docker sur portkomputilo. Kodo sur GitHub.
flowchart LR
QEMU["QEMU (Cortex-M3)"] -->|UART socket| Bridge[uart_bridge.py]
Bridge -->|bpsendfile| SC[Spacecraft Node]
SC -->|LTP + 5s delay| GS[Ground Station]
subgraph Docker
SC
GS
end
flowchart TB
QEMU["QEMU (Cortex-M3)"] -->|UART socket| Bridge[uart_bridge.py]
Bridge -->|bpsendfile| SC["Spacecraft Node (Docker)"]
SC -->|LTP + 5s delay| GS["Ground Station (Docker)"]
Kial Ĉi Tiu Projekto
Mi volis lerni ion vere malfacilan. Ion kie la konceptoj estas nekonataj kaj la iloj estas senkompatemaj. C-kompililoj celantaj ARM. Ligilaj skriptoj. Memoro-mapita Enigo/Eligo. Interrompo-vektora tablo.
Claude Code ebligis tion. Ne ĉar ĝi verkis la tutan kodon, sed ĉar ĝi klarigis kion faras ligila skripto dum ni verkis unu, do la klarigo estis enradikigita en la reala problemo kiun mi solvis. Same por volatile, FreeRTOS prioritat-antaŭpreno kaj LTP-retransmisiaj kronoj.
La Vojmapo
Mi dividis la projekton en kvar fazojn, ĉiu konstruita sur la antaŭa:
| Fazo | Kio | Ĉefaj Konceptoj |
|---|---|---|
| Nuda Metalo | ARM-kruckompilado, UART-eligo, interrompo-prizorgantoj | Memoro-mapita E/E, SysTick-krono, ekfunkcio-asembleo |
| FreeRTOS | Taskoj, vicoj, gardokronoj, prioritat-inversiĝo | Determinisma planado, mutex-protokoloj, antaŭpreno |
| DTN | Du-nodа reto, degraĵitaj ligiloj, CFDP, kontakta-grafea vojigado | Bundle Protocol, stoki-kaj-plusendi, LTP-fidindeco |
| Integrado | Plena telemetria konvejero kun Mars-distancaj prokrastoj | UART-ponto, tc netem, sinkronigita ION OWLT |
Ĉiu fazo havas aŭtomatigitajn testojn. Ĉiu ŝtono estas PR kun CI-pasado.
Fazo 1: Nuda Metalo
La unua defio estis igi ion funkcii. ARM-kruckompilado celanta Cortex-M3 (MPS2-AN385) en QEMU. Neniu OS, neniu norma biblioteko, neniu printf.
Claude helpis min kompreni la ekfunkcian sekvencon: la vektora tabelo, la restartiĝa prizorganto, kopiado de .data el fulmo al RAM, nuligo de .bss. Aĵoj kiuj okazas antaŭ ol main() eĉ kuras.
La unua venko estis ununura signo aperanta sur UART-konzolo:
#define UART0_DR (*(volatile uint32_t *)0x40004000)
void uart_putc(char c) {
UART0_DR = c;
}
Du linioj de C. Neniuj bibliotekoj. Nur skribi bajton al memor-adreso kiu hazarde estas kabeita al seria pordo. Ĝi sentis kiel rekte paroli al la maŝino.
De tie: SysTick-krona interrompoj, interrompo-prizorgantoj, strukturita eligo. La SysTick-demo agordigas aparatan kronon por ekfunkcii ĉe 2 Hz kaj kalkulas 10 taktojn:
SysTick interrupt demo
======================
Ticking at 2 Hz for 5 seconds (10 ticks)...
tick 1
tick 2
tick 3
tick 4
tick 5
tick 6
tick 7
tick 8
tick 9
tick 10
Done — 5 seconds counted by interrupt.
Neniuj perditaj taktoj. Neniaj ekstraaj taktoj. La CPU dormas inter interrompoj kaj la aparataro vekas ĝin precize en la ĝusta momento. Determinisma ekzekutado el nuda metalo.
Fazo 2: FreeRTOS
Kun nuda metalo funkcianta, mi aldonis FreeRTOS, realtempan operaciumon kiu funkcias sur ĉio de medicinaj aparatoj ĝis satelitoj.
La ekzercoj estis konstruitaj progresive:
- Du taskoj ĉe malsamaj rapidecoj. Baza pluritasking.
- Vic-bazita komunikado. Sekure kunhavi datumojn inter taskoj.
- Gardokrona krono. Detekti kaj rekovri de blokitaj taskoj.
- Sensor-konvejero. Kvar sensiloj ĉe malsamaj rapidecoj manĝigantaj procezan ĉenon.
- Prioritat-inversiĝo. Eligi kaj solvi la klasikan RTOS-cimon.
Jen la sensor-konvejero ekfunkcianta. Rimarkigu la 10 Hz giroskopo dominas la fluon, kun la 1 Hz temperatur-legado premita ĉe takto 1001:
FreeRTOS Sensor Pipeline Demo
=============================
[GYRO] Sensor online (10 Hz, priority 4)
[PROC] Processor online (priority 3)
[TELEM] Telemetry online (priority 2)
[TEMP] Sensor online (1 Hz, priority 1)
[TELEM] #000 GYRO: 300 at tick 100
[TELEM] #001 GYRO: 300 at tick 200
...
[TELEM] #009 GYRO: 300 at tick 1000
[TELEM] #010 TEMP: 1991 at tick 1001
[TELEM] #011 GYRO: 300 at tick 1100
Tio estas prioritat-bazita antaŭpreno en ago. La giroskopo funkcias ĉe prioritato 4, la temperatur-sensilo ĉe prioritato 1. La temperatur-legado nur trairas kiam la giroskopo ne okupas la CPU.
La prioritat-inversiĝa ekzerco estis la plej instrua. Mi kreis tri taskojn kie malalt-prioritata tasko tenas mutex kiu bezonas alt-prioritata tasko, kaj mez-prioritata tasko malfektas ambaŭ. La solvo: prioritat-heredo, kie FreeRTOS provizore plialtigas la malalt-prioritatan taskon por ke ĝi povu liberigi la mutex pli rapide.
Tio estas la cimo kiu preskaŭ mortigis la Mars Pathfinder-mision en 1997. Mem konstrui ĝin igis la lernolibran klarigon klaki.
Fazo 3: Prokrasto-Tolerema Rettado
TCP/IP ne funkcias en spaco. Reen-kaj-antaŭen-tempoj al Marso intervalas de 6 ĝis 44 minutoj. Ligiloj falas dum horoj kiam planedoj okzultas la signalon. La hipotezo de TCP pri daŭra, malalta-prokrasta konekto tute disfaliĝas.
La respondo de NASA JPL estas DTN, aŭ Prokrasto-Tolerema Rettado. La Bundle Protocol stokas datumojn loke kaj plusendas ilin salpet-post-salto kiam ligiloj fariĝas disponeblaj. Ĝi estas dezajnita por ĝuste la kondiĉoj kiuj rompiĝas la Interreton.
Mi konstruis la NASA ION-implementadon en Docker kaj plenumis progresive pli malfacilajn testojn:
- Baza konekteco. Du nodoj interŝanĝante bundlojn.
- Degraĵitaj ligiloj.
tc netemaldonanta 500ms prokrasto, 25% paketo-perdo, kompletaj interrompoj. - CFDP-dosiertransigo. Fidinda dosiero-livero kun integrity-kontroloj.
- Kontakta-grafea vojigado. Bundloj vicigitaj dum ligilaj breĉoj, liveritaj kiam fenestoj malfermiĝas.
La interrompa ligila testo rakontas la tutan DTN-historion en kelkaj linioj da eligo:
Test: intermittent link (send during outage, deliver on recovery)...
qdisc: qdisc netem root refcnt 2 limit 1000 loss 100%
confirmed: bundle queued (link is down)
restoring link...
PASS: bundle held during outage
PASS: bundle delivered after link recovery
Tio estas stoki-kaj-plusendi en ago. La bundle estas sendita dum la ligilo estas tute morta, 100% paketo-perdo. Ĝi sidas en la vico de la loka nodo. La momento kiam ni forigas la netem-regulon kaj restartigas konektecon, LTP retransmitigas kaj la bundle alvenas ĉe la alia fino. TCP jam delonge rezignus.
Fazo 4: Integrado
La fina fazo konektas ĉion. FreeRTOS-firmvaro generas telemetron en QEMU. Python-ponta skripto legas la UART-eligon kaj injektas ĝin kiel DTN-bundlojn. La bundloj trairas prokrastitan reton por atingi terfunkcian stacion.
La firmvaro ekfunkcias kaj tuj komencas striumi:
# Spacecraft Telemetry Firmware v1.0
# ===================================
# GYRO sensor online (10 Hz, priority 4)
# Processor online (priority 3)
# Telemetry online (priority 2)
# TEMP sensor online (1 Hz, priority 1)
# BATT sensor online (0.5 Hz, priority 1)
# SUN sensor online (2 Hz, priority 1)
$TELEM,0000,GYRO,300,100
$TELEM,0001,GYRO,300,200
...
$TELEM,0005,SUN,801,501
...
$TELEM,0011,TEMP,1991,1001
$TELEM,0012,SUN,801,1001
Kvar sensiloj ĉe kvar malsamaj rapidecoj. Oni povas vidi la 10 Hz giroskopo produktanta la plej multajn legadojn, kun la 2 Hz sun-sensilo, 1 Hz temperaturo kaj 0,5 Hz baterio interplektitaj. La ponto grupas tiujn en DTN-bundlojn ĉiun 2 sekundojn.
La Mars-prokrasta testo pruvas ke la tuta konvejero funkcias sub realistaj kondiĉoj:
Running Mars-delay end-to-end tests...
PASS: tc netem delay 5s applied on spacecraft
PASS: bridge exited cleanly
PASS: bridge read telemetry lines
PASS: bridge sent >= 1 bundle (got 12)
PASS: ground station received files (got 8)
PASS: received telemetry lines (got 224)
PASS: telemetry CSV format valid (5 fields)
INFO: delay observable (8 delivered at bridge exit < 12 sent)
7 passed, 0 failed
12 bundloj senditaj, sed nur 8 liveritaj kiam la ponto finiĝis. La resto ankoraŭ estis en flugo tra la 5-sekunda prokrasto. Tio estas la prokrasto estanta reala, ne simulita en programaro.
La Mars-prokrasta simulado uzas du sinkronigitajn mekanismojn:
- tc netem aldonas 5 sekundojn da reala rettada latenteco al ambaŭ ujooj
- ION-intervalo-tabeloj agordas la saman 5-sekundan unu-direksan lumovojan tempon por ke LTP-retransmisiaj kronoj estu ĝustaj
Ambaŭ devas konkordi. Se la reala prokrasto estas 5 sekundoj sed ION opinias ke ĝi estas 1 sekundo, LTP agreseme retransmitigas kaj inundas la ligilon. Ĝuste agordi tion instruis al mi pli pri protokola dezajno ol ajna lernolibra ĉapitro pri fidindeco.
Labori kun Claude Code
Ĉi tiu projekto estus kostinta al mi monatojn sen Claude. Ne ĉar la kodo estas kompleksa (plej multaj dosieroj havas malpli ol 300 liniojn) sed ĉar la lernkurvo por ĉiu fako estas kruta.
Kio bone funkciis:
- Trans-faka scio. La projekto etendiĝas sur C, Python, ARM-asembleo, Docker, ION DTN, FreeRTOS, QEMU, tc netem kaj LTP. Neniu sola persono konas ĉiujn ĉi bone. Claude povis kontext-ŝanĝi inter ili.
- Test-drivitaj ŝtonoj. Ĉiu fazo havas aŭtomatigitajn testojn. Claude helpis skribi asertojn kiuj kontrolas realan konduton, ne nur “ĝi kompiliĝas.”
- PR-bazita laborfluo. Ĉiu ŝtono estas aparta branĉo kaj PR kun CI. La worktree-subteno de Claude Code konservis tion pura. Izolitaj branĉoj, nenia hazarda trans-contaminator.
Kio postulas zorgecon:
- Enkonstruita C estas senkompata. Unu-for-unu eraroj en ligilaj skriptoj ne donas al vi stako-spuron. Ili donas al vi malmolan difekton aŭ silentan korupcion. La sugestoj de Claude bezonis zorgan kontrolon kontraŭ aparatara dokumentado.
- ION DTN-dokumentado estas malabunda. La trejn-datumoj de Claude ne inkluzivas profundajn ION-internaĵojn. Mi fidis pli sur la ION-fonta kodo kaj agord-ekzemploj ol sur la klarigoj de Claude pri ION-specifa konduto.
La Nombroj
| Metriko | Valoro |
|---|---|
| Totalaj testoj | 50+ asertoj en 7 test-aroj |
| Lingvoj | C, Python, Bash |
| Aparataro | Neniu (QEMU + Docker) |
| Linioj de C | ~1.200 (firmvaro + nuda metalo) |
| Linioj de Python | ~1.500 (testoj + ponto + DTN-skriptoj) |
| ION DTN-ago | ~350 linioj en 6 .rc-dosieroj |
Provu
Ĉio estas malfermitkoda kaj funkcias sur ajna Linux-maŝino kun QEMU kaj Docker:
sudo apt install gcc-arm-none-eabi qemu-system-arm build-essential
git clone https://github.com/granda/spacecraft-computing-sim
cd spacecraft-computing-sim
make -C bare-metal run # bare metal UART output
make -C freertos run # FreeRTOS sensor pipeline
make -C dtn test # two-node DTN network
make -C integration test-bridge # full telemetry pipeline
make -C integration test-mars-delay # Mars-distance delays
Neniu fizika aparataro. Neniaj nubaj servoj. Nur portkomputilo kaj scivolo pri kiel funkcias kosmoŝipaj komputiloj.