Kampagnen
Ein einzelnes Szenario beantwortet eine Frage zu einer Situation. Eine Mission ist eine Folge von Situationen, und eine Entwurfsstudie ist eine Familie davon. Die Szenarioart campaign setzt die bestehenden Arten zu einem Lauf zusammen, ohne eine davon neu zu implementieren: Jedes Mitglied ist eine gewöhnliche Szenariotabelle mit eigenem kind, wird über api::run_toml genau so abgewickelt, wie kshana <file>.toml es ausführen würde, und die Kampagne liest nur Zahlen aus den Ergebnisdokumenten zurück.
Eine Kampagne ist MODELLED. Ihre Kompositionsidentitäten sind getestet (siehe unten), aber das Verketten von Phasen ist eine Modellierungsentscheidung, und jede Phase ist nur so gut wie die Art, die sie ausgeführt hat.
Führen Sie eine aus wie jedes andere Szenario:
kshana scenarios/campaign-jam-spoof-holdover-integrity.toml
# writes .result.json, .chart.svg, .report.html and .report.json next to the file
Eine Kampagne kann jede Kombination von vier Abschnitten enthalten; eine ohne Abschnitte läuft, und ihre Zusammenfassung besagt, dass sie nichts zusammengesetzt hat.
[[phases]]: eine verkettete Mission auf einer Zeitleiste#
Jede Phase führt ein oder mehrere Szenarien über ein Fenster einer gemeinsamen Missionszeitleiste aus, zum Beispiel eine Uhr im holdover und ein Trägheitsnavigationssystem (INS) im Auslauf zur selben Zeit. Die Ausgaben jedes Laufs werden in benannte Kanäle gelesen, zur Startzeit der Phase platziert und per Zero-Order-Hold auf ein gemeinsames Raster ([timeline] step_s) umgetastet: Ein Rasterzeitpunkt übernimmt den letzten Abtastwert des Laufs der zugehörigen Phase zu oder vor diesem Zeitpunkt und ist null, wo kein Lauf dieser Phase den Kanal liefert.
| Kanal | Einheit | Was es ist | Voreingestellte Quelle |
|---|---|---|---|
time_error_ns |
ns | Zeitfehler der Uhr | clock: <side>.series[].error_ns; spoof: <side>.series[].offset_ns |
guard_ns |
ns | Zeitfehler-Wächter | das eigene threshold_ns des Laufs |
cn0_dbhz |
dB-Hz | mittleres effektives Träger-zu-Rauschdichte-Verhältnis (C/N0) über die sichtbaren Satelliten | jamming: Mittelwert von epochs[].sats[].cn0_effective_dbhz |
cn0_floor_dbhz |
dB-Hz | Untergrenze des Tracking-Verlusts | jamming: das tracking_threshold_dbhz des Szenarios, wenn es eines angibt |
tracking |
Anzahl | Satelliten, die noch verfolgt werden | jamming: epochs[].tracking |
protection_level_m |
m | vertikales Schutzniveau | integrity: epochs[].vpl_m |
alert_limit_m |
m | vertikale Alarmgrenze | integrity: al_v_m |
position_error_m |
m | Positionsfehler | gnss-ins: <side>.series[].error_m |
position_threshold_m |
m | Schwelle für den Positionsfehler | gnss-ins: threshold_m |
alarm |
1 | 1, solange irgendein Monitor der Phase alarmiert | siehe unten |
<side> ist classical, sofern der Lauf nicht side = "quantum" setzt. Jede andere Größe wird mit einem expliziten Eintrag [[phases.runs.series]] gelesen: ein Zeitpfad mit einem [], das die Zeilen benennt (epochs[].t), ein Wertpfad, der diese Zeilen teilt, oder ein Skalar, der an jede Zeile gesendet wird (das Präfix input: liest das Szenario des Laufs statt seines Ergebnisses), eine optionale Reduktion (mean, min, max, count) für mehrere Werte unter einer Zeile, ein Maßstab und eine Einheit für einen Kanal, den die Kampagne nicht kennt.
Alarme stammen aus drei Quellen, innerhalb einer Phase per logischem ODER verknüpft:
- voreingestellte Flags, die aus dem Lauf gelesen werden:
jammingalarmiert, solange weniger als vier Satelliten verfolgt werden (seine eigene Verfügbarkeitsdefinition);integrityalarmiert in Epochen, die es als nicht verfügbar markiert; - voreingestellte Regeln auf den Kanälen der Phase, ausgewertet nach
carry:clockalarmiert, solange der absolute Zeitfehlerguard_nsüberschreitet;gnss-ins, solange der Positionsfehlerposition_threshold_müberschreitet; explizite Regeln stehen in[[phases.runs.alarms]]; - alarmierende Ereignisse:
spooflöst eines beidetect_time_sseines uhrengestützten Monitors aus;spoof-detectlöst eines zu Beginn der Phase aus, wenn seine fusionierte Entscheidung alarmiert.
Der Zustand wird weitergereicht zwischen Phasen, auf drei ausdrückliche Arten:
carry = ["time_error_ns"]addiert den Wert des Kanals am Ende der vorigen Phase zu den Werten dieser Phase dafür. Die von einem Spoofer verstellte Uhrenphase ist der Punkt, von dem der holdover ausgeht. Das Addieren des Versatzes ist für die Uhrenphase exakt, die Frequenz integriert; bei einem Positionsfehler setzt es voraus, dass die beiden Fehler kollinear sind, der pessimistische Fall.[[phases.handoff]]schreibt vor dem Lauf eine Zahl aus der vorigen Phase (channel:<name>für den Endwert eines Kanals oder jeden Ergebnispfad eines früheren Laufs) in einen gepunkteten Schlüssel des Szenarios dieser Phase, mit optionalem Maßstab und Versatz.end_at = "<result path>"beendet die Phase zu einem Zeitpunkt, den ein Lauf berechnet hat, begrenzt durchduration_s. Die mitgelieferte Mission beendet ihre Spoofing-Phase beiclassical.detect_time_s.
skip_s verwirft vor dem Phasen-Nullpunkt die ersten Sekunden der eigenen Zeitleiste eines Laufs (einen Einschwingvorlauf).
Die mitgelieferte Mission#
scenarios/campaign-jam-spoof-holdover-integrity.toml führt 18 Mitgliedsszenarien über sechs Phasen auf einem 10-s-Raster aus:
| Phase | Läufe | Was die Zeitleiste zeigt |
|---|---|---|
| nominal, 600 s | clock, jamming (kein Jammer), integrity |
Zeitfehler 0 ns; C/N0 43,0 dB-Hz gegenüber einer Untergrenze von 25 dB-Hz; vertikales Schutzniveau 9,1 bis 21,6 m gegenüber einer Alarmgrenze von 50 m |
| jamming, 600 s | dasselbe, Jammer bei -30 dBW, 1 km | C/N0 fällt auf 27,7 dB-Hz, alle 8 Satelliten werden noch verfolgt |
Spoofing, bei 370 s durch end_at beendet |
spoof (Zeitrampe von 0,1 ns/s), spoof-detect, jamming |
der Zeitfehler steigt rampenförmig auf 36 ns; der Hochfrequenzdetektor alarmiert zu Phasenbeginn, der uhrengestützte Monitor bei 370 s |
| holdover, 1800 s | clock (verweigert, trägt 37,0 ns), gnss-ins (taktische Einheit im Auslauf), jamming bei 10 dBW |
jeder Satellit verloren (C/N0 etwa -12 dB-Hz); Zeitfehler 36,4 bis 62,7 ns gegenüber dem Wächter von 50 ns; Positionsfehler bis 24 km |
| integrity-alarm, 600 s | clock (trägt 59,6 ns), jamming und integrity mit einer Maske von 25 Grad |
5 Satelliten werden verfolgt; Schutzniveau 19 bis 135 m, fehlend zu 18 von 60 Rasterzeitpunkten; der übernommene Zeitfehler, 52,1 bis 61,7 ns, bleibt über dem Wächter von 50 ns, sodass der Alarm die ganze Phase über aktiv ist |
| recovery, 600 s | clock, jamming (kein Jammer), integrity |
Zeitfehler wieder bei 0 ns; Alarm ruhig |
Die Integritätsläufe verwenden die eigene Nutzerspur des Beispiels integrity (eine Kreisspur in 0,4 km Höhe), nicht den festen Standort des jamming-Empfängers, und die Maske von 25 Grad steht für den Teilhimmel eines Empfängers, der neu erfasst. Das sind Szenarioentscheidungen, die in der Datei festgehalten sind.
Eine vom L-Band-Spektrum getriebene Mission#
scenarios/campaign-spectrum-holdover-integrity.toml führt 8 Mitgliedsszenarien über drei Phasen auf einem 1-s-Raster aus, wobei das C/N0 von GPS L1 C/A und Galileo E1 aus der Art spectrum gelesen wird (siehe SPECTRUM.md) statt aus der Satellitentabelle der Art jamming. Die Jammer sind die aus scenarios/l-band-waterfall-jamming.toml.
| Phase | Läufe | Was die Zeitleiste zeigt |
|---|---|---|
Einsatz, bei 10 s durch end_at beendet |
clock, spectrum (Chirp ab 10 s), integrity |
L1 C/A 43,48 und E1 44,73 dB-Hz; die Phase endet beim eigenen ersten Verlust von L1 C/A im Spektrumlauf (timeline.bands[0].first_loss_t_s); Schutzniveau 21,6 m gegenüber 50 m |
| holdover, 600 s | clock (verweigert, trägt den Einsatzfehler, hier 0 ns), spectrum (Chirp an) |
L1 C/A 3,38 und E1 4,44 dB-Hz, beide unter der Untergrenze von 25 dB-Hz; Zeitfehler -0.07 bis 5,06 ns gegenüber dem Wächter von 50 ns; Alarm aktiv |
| galileo-fallback, 300 s | clock (neu synchronisiert), spectrum (CW-Ton auf dem L1-Träger), integrity auf einem Galileo-ähnlichen Walker 24/3/1 |
L1 C/A bleibt bei 17,98 dB-Hz, E1 wieder bei 44,73 dB-Hz; Schutzniveau 6,1 bis 17,7 m; Alarm ruhig |
Dass sich E1 unter dem CW-Ton erholt, beruht auf der Behandlung des kontinuierlichen Spektrums durch die Spektrumart: Der Ton sitzt in der Nullstelle des MBOC-Spektrums und koppelt nichts ein. Ein echter Ton würde über die Spektrallinien des Codes einkoppeln; das ist in der Datei und in SPECTRUM.md festgehalten.
[sweep]: ein Parameterraster über jede Art#
Ein bis drei gepunktete Szenarioschlüssel, jeweils über einen linearen oder logarithmischen Bereich, auf denselben Achsenwerten, die die Art sweep-nd verwendet. Jede Achse hat einen Namen und eine Einheit; jede Metrik hat einen Namen und einen Ergebnispfad, und ihre Einheit wird aus dem eigenen Einheitenblock der durchlaufenen Art gelesen, sofern die Kampagne keine deklariert. Mit runs > 1 ist jeder Knoten ein Monte-Carlo-Ensemble mit Startwerten (Realisierung k beim Startwert des Knotens plus k), das mit den unten genannten Statistiken berichtet wird. scenarios/campaign-sweep-jammer-power.toml durchläuft einen Jammer in 1 km Entfernung vom Empfänger von -50 bis +10 dBW: Das mittlere Verhältnis von Jammer zu Signal verschiebt sich genau um 1 dB je dB (12,2 bis 72,2 dB), und die Verfügbarkeit fällt zwischen -30 und -25 dBW von 1 auf 0.
Ein gepunkteter Schlüssel kann ein Array von Tabellen nach Position indizieren: system.2.sisre_m ist das sisre_m der dritten Tabelle [[system]], und case.0.system.0.shell.0.altitude_km reicht drei Ebenen tief.
[monte_carlo]: ein Ensemble mit Startwerten#
Realisierung k führt das Szenario mit seinem auf base_seed + k gesetzten Startwertschlüssel aus, der Konvention, die das Uhrenensemble bereits verwendet, sodass das Ensemble exakt reproduzierbar ist. Jede Metrik berichtet den Mittelwert, die Standardabweichung der Grundgesamtheit, das 5., 50. und 95. Perzentil nach dem Nearest-Rank-Verfahren, ein Perzentil-Bootstrap-95-%-Konfidenzintervall des Mittelwerts mit festem Startwert (2000 Neuziehungen) und standardmäßig jede Stichprobe in der Reihenfolge der Startwerte. Ergebnispfade dürfen Arrays indizieren: classical.series[-1].error_ns ist die letzte Stichprobe.
[compose]: mehrere Szenarien unter gemeinsamen Bedingungen#
Benannte gemeinsame Werte (eine Zahl oder ein Array von Zahlen, mit einer Einheit) werden in jedes Mitglied an die Schlüssel geschrieben, an die es sie bindet, sodass die Mitglieder über die gemeinsame Bedingung nicht uneins sein können. Jedes Mitglied läuft, und für jede Metrik nennt die zusammengefasste Übersicht den kleinsten, größten und mittleren Wert über die Mitglieder und benennt das beste und das schlechteste. scenarios/campaign-shared-jammer-sea-road.toml setzt einen Jammer mit 8 dBW zwischen ein Schiff im Finnischen Meerbusen (etwa 30 km entfernt) und ein Auto auf einer Küstenstraße bei Helsinki (etwa 50 km): Das Schiff verliert jeden Satelliten (mittleres Verhältnis von Jammer zu Signal 39,0 dB), während das Auto mindestens vier behält (34,6 dB).
[optimize]: der beste Wert einer Metrik#
Ein bis drei gepunktete Szenarioschlüssel, jeweils auf [lo, hi] auf einer lin- oder log-Skala begrenzt, werden nach dem besten Wert einer Metrik durchsucht (goal = "minimize", "maximize" oder "target", das den Abstand von target minimiert).
Es gibt zwei Verfahren:
method = "grid"führt jeden Knoten eines Rasters mitstepsje Schlüssel aus, auf den Achsenwerten des Sweeps.method = "nelder-mead"(der Standard) führt ein deterministisches Nelder-Mead-Simplex in je Schlüssel auf [0, 1] normierten Koordinaten aus. Probepunkte werden auf die Box projiziert. Der Abschnitt nimmtmax_evals, einen anfänglichenstepund die Abbruchtoleranzenftolundxtolentgegen.
Ein Lauf, dessen Metrik fehlt oder nicht endlich ist, wird als schlechtester bewertet und bleibt in der Spur erhalten. Mit runs > 1 ist die Metrik bei jeder Auswertung der Mittelwert über dieselben Startwerte. Das Ergebnis liefert best_coords, best_metric, best_score, evals, stop_reason und jede Auswertung in trace.
scenarios/campaign-optimize-link-budget.toml sucht Reichweite und Datenrate für eine Verbindungsreserve von 3 dB. Das Optimum ist lokal zur Box und zum Start. Es ist MODELLED, nie eine globale Aussage.
Das Protokoll und seine vorab festgelegten Zielwerte stehen in docs/design/evidence/cap32-optimize/. Der Test ist tests/campaign_optimize_reference.rs. Die Ergebnisse:
- eine 1-D-Zielwertlösung stimmt mit der geschlossenen Form auf 6e-15 überein;
- das Rasterverfahren stimmt bitgenau mit einer unabhängigen Brute-Force-Schleife überein;
- das Simplex schneidet mindestens so gut ab wie das Raster 41 × 41, mit etwa einem Zehntel seiner Läufe.
Der 1-D-Zielwert von Runde 1 ist als NOT MET festgehalten: Die vorab festgelegte Box schloss die Lösung aus.
Reproduzierbarkeit#
Jedes Kampagnenergebnis trägt scenario_hash, den SHA-256 (Secure Hash Algorithm 2, 256-Bit-Digest) der kanonischen JavaScript-Object-Notation-Form (JSON) des Kampagnendokuments (Schlüsselreihenfolge und Formatierung ändern ihn nicht), und einen Block reproducibility mit der Zahl der Mitgliedsläufe und run_digest, einem SHA-256 über den Digest jedes Mitgliedsergebnisses in Dispatch-Reihenfolge. Zwei Läufe mit demselben Digest haben byteidentische Mitgliedsergebnisse erzeugt. Jeder Phasenlauf hält außerdem seine Art fest, sein eigenes scenario_hash, wo die Art eines hat, und den SHA-256 seines Ergebnisdokuments. Jede Zahl im Dokument hat einen Einheiteneintrag.
Der Kern ist sequenziell und liest keine Dateien, sodass eine Kampagne im WebAssembly-Build unverändert läuft. Kampagnen dürfen keine Kampagnen enthalten.
Exporte#
--export bei einer Kampagne schreibt jedes Mitgliedsszenario mit Geometrie als eigenen Dateisatz, wobei die Bezeichnung des Mitglieds vor das Formatsuffix eingefügt wird: jeden Phasenlauf (<phase> oder <phase>-<k>, wenn die Phase mehrere Läufe hat), das Basisszenario des Sweeps (sweep), das Monte-Carlo-Szenario (monte-carlo) und jedes zusammengesetzte Mitglied (mit seiner eigenen Bezeichnung, mit den eingeschriebenen gebundenen gemeinsamen Werten). Ein Mitglied, das einem früheren gleicht, wird einmal geschrieben; Übergaben sowie zur Laufzeit angewandte Sweep- oder Startwerte stehen nicht in den exportierten Szenarien.
kshana scenarios/campaign-shared-jammer-sea-road.toml --export kml
# after the usual result, chart and report files:
# wrote scenarios/campaign-shared-jammer-sea-road.ship-strait.kml
# wrote scenarios/campaign-shared-jammer-sea-road.car-coast-road.kml
Ein Format, das keines der Mitglieder beschreiben kann, wird mit dieser Begründung zurückgewiesen. Die Tabelle je Szenario steht in INTEROP.md.
LEO-PNT-Kampagnen#
Fünfzehn mitgelieferte Kampagnen rahmen Fragen der Positionierung, Navigation und Zeitgebung (PNT) im niedrigen Erdorbit (LEO); LEO-PNT.md beschreibt, was jede zeigt. Was jede ausführt, wie es die Kommandozeile zusammenfasst:
| Szenario | Modus | Frage |
|---|---|---|
leo-focus-data-services.toml |
compose, 4 Mitglieder | Dienstdaten der Navigationsnachricht gegenüber der Rahmenlänge |
leo-focus-fused-pnt-sisre.toml |
Sweep von leo-pvt, 7 Knoten |
fusionierte MEO- und LEO-Positionierung gegenüber dem Signal-in-Space-Entfernungsfehler (SISRE) von LEO |
leo-focus-indoor-uhf.toml |
compose, 2 Mitglieder | LEO-PNT in Gebäuden nach Band und Gebäudeklasse |
leo-focus-iot-eirp.toml |
Sweep von leo-pass, 9 Knoten |
Energie je Fix im Internet der Dinge (IoT) gegenüber der LEO-UHF-Sendeleistung |
leo-focus-ntn-bandwidth.toml |
Sweep von ntn-positioning, 9 Knoten |
Positionierung über nichtterrestrische Netze (NTN) gegenüber der Bandbreite des Referenzsignals |
leo-focus-ppp-altitude.toml |
Sweep von leo-ppp, 3 Knoten |
Konvergenz der präzisen Punktpositionierung (PPP) gegenüber der Höhe einer LEO-Schicht mit 192 Satelliten |
leo-resilience-gnss-jammed-leo-carries.toml |
Kette, 3 Phasen über 2100 s | Globales Navigationssatellitensystem (GNSS) gestört, die LEO-Schicht trägt den Nutzer, Integrität bleibt gewahrt |
leo-resilience-multiband-diversity.toml |
Sweep von spectrum, 13 Knoten |
LEO-Banddiversität gegenüber einem L-Band-Sperrjammer |
leo-resilience-spoof-monitors.toml |
compose, 4 Mitglieder | die Spoofing-Monitore gegenüber vier Spoofern |
leo-vertical-5g-network-timing.toml |
Kette, 1 Phase über 86.400 s | Zeitgebung von 5G-Basisstationen: holdover und LEO-Zeit |
leo-vertical-asset-tracking-iot.toml |
Kette, 3 Phasen über 1440 s | Containerverfolgung mit LEO-UHF: Energie je Fix entlang einer Reise |
leo-vertical-autonomous-vehicle.toml |
Kette, 2 Phasen über 1500 s | ein autonomes Fahrzeug in einer Straßenschlucht mit einer LEO-Schicht |
leo-vertical-autonomous-vehicle-skyline.toml |
Kette, 2 Phasen über 1800 s | dieselbe Straßenschlucht als flache Abschaltgrenze von 35 Grad und als Horizontlinie city-street |
leo-vertical-critical-infrastructure-timing.toml |
Kette, 2 Phasen über 87.000 s | Zeitgebung kritischer Infrastruktur: holdover mit LEO-Zeit |
leo-vertical-polar-arctic.toml |
Kette, 3 Phasen über 10.800 s | polare und arktische Nutzer mit einer polaren LEO-Schicht |
leo-vertical-rail-maritime.toml |
Kette, 3 Phasen über 2520 s | Eisenbahn- und Seeverkehrsnutzer mit einer LEO-Schicht |
MEO ist der mittlere Erdorbit, UHF ultrahohe Frequenz und 5G die fünfte Generation der Mobilfunknetze.
Was geprüft wird#
tests/campaign_composition_reference.rs legt die Kompositionsidentitäten fest:
- Eine einphasige Kampagne reproduziert den eigenständigen Lauf bitgenau. Für
clock,integrityundjammingist das Ergebnisdokument des Mitglieds byteidentisch mitrun_tomlauf der Szenariodatei, sein Digest ist der, den die Kampagne berichtet, und mit dem Raster im eigenen Schritt des Laufs entspricht jeder ausgerichtete Wert dem Wert der eigenständigen Reihe (das jamming-C/N0 entspricht dem unabhängig aus dem eigenständigen Dokument berechneten Mittelwert). - Ein Sweep mit einem Knoten und eine Komposition mit einem Mitglied lesen genau die eigenständige Zahl.
- Ein Ensemble mit festem Startwert ist byte-stabil, und Realisierung
kist genau der eigenständige Lauf beiseed + k; der Kampagnen-Hash ignoriert die Schlüsselreihenfolge. - Ein analytischer Fall.
scenarios/campaign-monte-carlo-clock-holdover.tomlführt 200 Startwerte einer Chip-Scale-Atomuhr mit ausschließlich weißem Frequenzrauschen aus (q_wf = 9e-20 s^2/s, Microchip SA.45s sigma_y(1 s) = 3e-10), auf 590 s synchronisiert und bis 3600 s im Auslauf. Der Endzeitfehler ist gaußverteilt mit Mittelwert 0 und Standardabweichung sqrt(q_wf * 3010 s) = 16,459 ns (der Random Walk der Phase unter weißem Frequenzrauschen, National Institute of Standards and Technology (NIST) Technical Note 1337). Das berichtete Intervall, [-2.52, 1,59] ns, enthält den wahren Mittelwert 0; die Stichprobenstandardabweichung, 14,93 ns, ergibt eine Chi-Quadrat-Statistik von 164,5 bei 199 Freiheitsgraden, innerhalb des zweiseitigen 99-%-Intervalls [151,37, 254,14]. Bei 3000 Startwerten ergibt dasselbe Szenario 16,31 ns. - Die spektrumgetriebene Kette liest die eigenständigen Zahlen: Die Einsatzphase dauert genau so lange wie die Zeit bis zum ersten Verlust im Spektrumlauf, und jeder Wert von L1 C/A und E1 auf der Zeitleiste entspricht, auf 1e-9 dB, der Zeile des eigenständigen Wasserfallbeispiels für denselben Jammerzustand (nominal, Chirp allein, CW-Ton allein).
- Die Kette reicht den Zustand wie dokumentiert weiter: Die Spoofing-Phase dauert genau so lange wie die Erkennungszeit des Spoofing-Laufs, der holdover übernimmt genau den Versatz des Spoofing-Laufs bei der Erkennung, recovery übernimmt nichts, und der Alarm ist überall dort aktiv, wo das Schutzniveau fehlt oder die Alarmgrenze überschreitet.
Diese Prüfungen stellen sicher, dass das Zusammensetzen nichts ändert, was es nicht ändern darf. Sie validieren keine verkettete Mission gegen eine gemessene, weshalb die drei Kampagnenzeilen in VERIFICATION-MATRIX.md MODELLED sind.