Maskinöversättning, inte granskad av en modersmålstalare. Engelska är referensen.

Utdata och exporterRedigera på GitHubKälla: docs/ANIMATION.md

Animeringsexport

--animate omvandlar en körnings tidsserie till något som rör sig: en animerad SVG-fil (Scalable Vector Graphics), en enda fristående HTML-spelare (HyperText Markup Language) eller en numrerad sekvens av SVG-bildrutor för en videokodare. En kampanj spelas upp som sina faser (jamming, spoofing, holdover, integritetslarm) med larmen markerade; en spektrumkörning spelar upp sitt vattenfall rad för rad; en passage i låg omloppsbana (LEO) spelar upp sin länk per band och, med en spoofer, övervakningsstatistiken epok för epok.

kshana scenarios/campaign-jam-spoof-holdover-integrity.toml --animate all
kshana scenarios/l-band-waterfall-jamming.toml --animate html
kshana scenarios/clock-holdover.toml --animate frames --animate-fps 24 --animate-duration 10

Kod: src/animation.rs. Tester: tests/animation.rs.

Vad det är, och vad det inte är#

Exportören läser resultatdokumentet som körningen redan skrivit. Den kör inte om fysiken, den samplar inte om, jämnar inte ut och interpolerar inte mellan sampel (bortsett från det enda raka linjesegment som avslutar ett spår vid markören), och den lägger inte till något eget tal. En animering är därför exakt lika bra som körningen bakom den. Dess nivå är MODELLED, intern konsistens: den är en rendering, aldrig evidens, och den har ingen egen rad i verifieringsmatrisen.

Utdata#

Varje format skrivs bredvid scenariot, intill de vanliga result.json, chart.svg och report.html:

Format Skrivs som Vad det innehåller
svg <scenario>.animation.svg En SVG animerad med Cascading Style Sheets (CSS) keyframes och utan skript: spåren ritas in bakom en rörlig tidsmarkör, händelser visas vid sitt ögonblick, vattenfallets rader avtäcks i tidsordning. Den loopar, med 1,5 s uppehåll på den färdiga bilden.
html <scenario>.animation.html En fil med inbäddat skript och inbäddad stil och utan externa resurser: spela och pausa, en skjutreglage för tidsposition, hastighet (0,25x till 4x), varje panel på en synkroniserad markör, ett levande värde per spår, fasremsan och en händelselista som söker vid klick. Mellanslag spelar eller pausar, piltangenterna stegar, Home och End hoppar.
frames <scenario>.frames/ frame_0000.svg, frame_0001.svg, … och manifest.json.

--animate kan upprepas och tar en kommaseparerad lista (--animate svg,html) eller all. --animate-fps (1 till 60, standard 12) och --animate-duration (0,5 s till 600 s, standard 8 s) styr uppspelningen; bildrutesekvensen är begränsad till 7 200 bildrutor.

När --export körs i samma kommando listar HTML-spelaren de exportfiler som skrivits bredvid den (CZML, KML, GeoJSON, STK, SigMF) som relativa länkar till de syskonfilerna; en länk skrivs bara för ett rent filnamn, så ingen kan lämna mappen eller nå nätverket. Den avancerade rapporten (report.html) bäddar in den animerade teckningen närhelst resultatet har en tidsserie, oavsett om --animate kördes eller inte.

När --animate körs får result.json ett animation-block: formaten, bildrutor per sekund (fps), varaktighet, antal bildrutor, tidsspannet, panelrubrikerna, de JSON-sökvägar som varje spår lästes från (sources) och alla serier som hittades men inte ritades (omitted). Utan --animate är resultatet byteidentiskt med en vanlig körning.

Bildrutesekvensen#

Sekvensen har exakt round(duration × fps) bildrutor. Bildruta i visar tidslinjen fram till t_start + (t_end − t_start) × i / (n − 1), så den första bildrutan är starten och den sista är den färdiga bilden. manifest.json registrerar fps, duration_s, frame_count, frame_pattern (frame_%04d.svg), pixelstorleken, t_start, t_end, uppdragstiden för varje bildruta (frame_times), faserna, händelserna och källorna. En ny export till samma katalog tar först bort varje frame_NNNN.svg som redan finns där (och inget annat), så en kortare sekvens lämnar aldrig kvar bildrutor från en längre för kodaren att läsa.

Bildrutorna är SVG, inte Portable Network Graphics (PNG). En ffmpeg byggd med biblioteket librsvg läser dem direkt, med den takt som sekvensen skrevs med (24 i exemplet ovan; manifestets fps):

ffmpeg -framerate 24 -i clock-holdover.frames/frame_%04d.svg -pix_fmt yuv420p clock-holdover.mp4

En ffmpeg utan librsvg stoppar med "no decoder found for: svg". Rastrera bildrutorna först, till exempel med rsvg-convert, och koda PNG-filerna:

for f in clock-holdover.frames/frame_*.svg; do rsvg-convert "$f" -o "${f%.svg}.png"; done
ffmpeg -framerate 24 -i clock-holdover.frames/frame_%04d.png -pix_fmt yuv420p clock-holdover.mp4

Tillgänglighet och tema#

  • Färgschema. Spelaren följer prefers-color-scheme och ritas om när det ändras; den animerade SVG:n har en ljus variant av sin palett under samma mediefråga. Bildrutorna använder den mörka paletten från de statiska diagrammen, eftersom en video inte har något schema.
  • Reducerad rörelse. Under prefers-reduced-motion: reduce stänger den animerade SVG:n av varje animering och visar den färdiga bilden (dess basstilar är sluttillståndet, så ingenting är dolt), och spelaren öppnas pausad på den färdiga bilden i stället för att spela; användaren kan fortfarande dra i tidsreglaget eller trycka på Play.
  • SVG:n har en <title> och <desc>; spelarens kontroller är märkta knappar, ett intervallfält med ett uppläst tidsvärde och en väljare.

Vad som räknas som en tidsserie#

Resultatdokumenten skiljer sig åt från typ till typ, så exportören känner igen de former som motorn avger i stället för en lista över typer:

  1. En array av poster med ett tidsfält (t, t_s, t_hours, t_min, t_days, eller k på en epochs-array) som strikt ökar längs arrayen. Varje annat numeriskt fält blir ett spår; samma fält under två rötter (quantum.series[].error_ns och classical.series[].error_ns) delar en panel.
  2. Ett objekt med en strikt ökande tidsarray (t_s, t, times_s, …) bredvid arrayer av samma längd: numeriska syskonarrayer, en channels-karta med {unit, values}-poster (tidslinjen campaign), en array av poster som håller sådana arrayer (banden i spectrum, en konstellations satellitspår), och en tvådimensionell array vars rader motsvarar tidsaxeln med en frekvensaxel *_hz som syskon (vattenfallet spectrum).
  3. Bredvid den tidsarrayen blir phases (name, t0_s, t1_s) fasremsan och events (t_s, label, alarm) blir markörerna. Ett bands skalärer *_t_s (dess första förlust av låsning, dess lägsta förhållande mellan bärvåg och brusdensitet) markeras också.

Spår med en enhet delar panel när deras storlek ligger inom en faktor 100, så att en vakt på 50 ns inte plattar till ett fel på 2 ns. Högst 6 paneler med 6 spår ritas; resten listas under omitted. Spår över 2 400 sampel tunnas ut med ett jämnt steg som behåller det sista samplet, och ett vattenfall över 96 × 120 celler medelvärdesbildas nedåt (i effekt, för decibelceller, så att en smal jammer inte späds ut).

En typ vars resultat inte bär någon av dessa former (en länkbudget, en geometri för en enda epok, en sammanfattning av enbart statistik från Monte Carlo, eller telecom-holdovern, vars resultat publicerar postens hash men inte posten) avvisas med no time series to animate, och ingenting skrivs. Med kshana 0.40.0 kan 94 av de 193 körbara scenariofilerna (alla filer utom en studiesvit) animeras och 99 avvisas. cargo test --test animation -- --nocapture skriver ut sammanställningen.

Bland LEO-typerna animeras varje medföljande scenario av typen leo-pass, leo-pnt-chain och leo-ppp. leo-pvt animeras i sina lägen Doppler, gemensam positionering och tidssynkronisering (en tidssynkroniseringskörning behöver trace = true, vilket gör att varje rad rapporterar sitt tidsfel och sin predikterade sigma vid varje epok) och avvisas i sitt läge för polär täckning. leo-navmsg animeras för sin uppdatering mitt i passagen och avvisas för analyserna av kodning, anpassningsintervall och modelljämförelse. Resultaten leo-signal och ntn-positioning har ingen tidsaxel och avvisas.

Determinism#

Utdata är en ren funktion av resultatdokumentet och alternativen: ingen klocka, inget slumptal, ingen iteration över hashtabeller, ingen fil- eller nätverksåtkomst i biblioteket och ingen tidsstämpel någonstans, så samma scenario, frö och alternativ ger byteidentiska filer. Modulen byggs för WebAssembly oförändrad; endast kommandoradsgränssnittet skriver filer.

Användning som bibliotek#

use kshana::animation::{AnimationFormat, AnimationOptions};
let anim = kshana::api::animate_toml(src, AnimationFormat::Html, &AnimationOptions::default())?;
std::fs::write("run.html", &anim.files[0].content)?;

kshana::animation::animate_result animerar ett resultatdokument du redan har, och extract_timeline returnerar det som skulle ritas utan att rendera det.

Begränsningar#

  • Python-wheelen och WebAssembly-modulen exponerar inte exportören ännu; den kan nås från kommandoraden, Rust-biblioteket och verktyget animate_scenario i Model Context Protocol-servern (MCP) (som returnerar högst 120 bildrutor i ett svar).
  • Axlarna är linjära. En serie som sträcker sig över många dekader (en klockas felväxt från 0,1 ns till en mikrosekund) ser platt ut till sent i körningen.
  • Den animerade SVG:n förlitar sig på CSS-animering av en klipprektangel; aktuella motorer i Chromium, Firefox och Safari spelar upp den, medan en visare utan CSS-animering visar den färdiga bilden.
  • Svep-, Monte Carlo- och compose-kampanjer har ingen tidsaxel och avvisas; sammanfattningsstatistiken för ett svep eller ett ensemble är inte en tidsserie. En kedjad kampanj animeras.