Кампании
Один сценарий отвечает на один вопрос об одной ситуации. Миссия — это последовательность ситуаций, а исследование проекта — их семейство. Вид сценария campaign объединяет существующие виды в один прогон, не реализуя ни один из них заново: каждый участник — это обычная таблица сценария со своим kind, диспетчеризуемая через api::run_toml точно так же, как её запустил бы kshana <file>.toml, а кампания только считывает числа из документов результатов.
Кампания имеет уровень MODELLED. Её тождества композиции проверены (см. ниже), но цепочка фаз — это выбор моделирования, и каждая фаза настолько хороша, насколько хорош вид, который её выполнил.
Запустите её, как любой другой сценарий:
kshana scenarios/campaign-jam-spoof-holdover-integrity.toml
# writes .result.json, .chart.svg, .report.html and .report.json next to the file
Кампания может содержать любую комбинацию из четырёх разделов; кампания без них запускается, а её сводка сообщает, что ничего не скомпоновано.
[[phases]]: цепочка миссии на одной временной шкале#
Каждая фаза запускает один или несколько сценариев на окне общей временной шкалы миссии, например часы в режиме holdover и инерциальную навигационную систему (INS) в режиме выбега одновременно. Результаты каждого прогона считываются в именованные каналы, помещаются в момент начала фазы и передискретизируются на общую сетку ([timeline] step_s) удержанием нулевого порядка: узел сетки берёт последний отсчёт прогона соответствующей фазы в этот момент или раньше и равен null там, где ни один прогон этой фазы не предоставляет канал.
| Канал | Единица | Что это | Источник пресета |
|---|---|---|---|
time_error_ns |
нс | ошибка времени часов | clock: <side>.series[].error_ns; spoof: <side>.series[].offset_ns |
guard_ns |
нс | защитный интервал ошибки времени | собственный threshold_ns прогона |
cn0_dbhz |
dB-Hz | среднее эффективное отношение мощности несущей к спектральной плотности шума (C/N0) по видимым спутникам | jamming: среднее значение epochs[].sats[].cn0_effective_dbhz |
cn0_floor_dbhz |
dB-Hz | порог потери слежения | jamming: tracking_threshold_dbhz сценария, если он задан |
tracking |
число | спутники, всё ещё находящиеся на слежении | jamming: epochs[].tracking |
protection_level_m |
m | вертикальный уровень защиты | integrity: epochs[].vpl_m |
alert_limit_m |
m | вертикальный предел тревоги | integrity: al_v_m |
position_error_m |
m | ошибка положения | gnss-ins: <side>.series[].error_m |
position_threshold_m |
m | порог ошибки положения | gnss-ins: threshold_m |
alarm |
1 | 1 пока любой монитор фазы подаёт тревогу | см. ниже |
<side> равно classical, если прогон не задаёт side = "quantum". Любая другая величина читается с помощью явной записи [[phases.runs.series]]: путь времени с одним [], называющим строки (epochs[].t), путь значения, использующий те же строки, или скаляр, распространяемый на каждую строку (префикс input: читает сценарий прогона, а не его результат), необязательное свёртывание (mean, min, max, count) для нескольких значений в одной строке, масштаб и единица измерения для канала, который кампании неизвестен.
Тревоги поступают из трёх источников, объединяемых логическим ИЛИ внутри фазы:
- флаги пресетов, считываемые из прогона:
jammingподаёт тревогу, пока на слежении менее четырёх спутников (собственное определение доступности);integrityподаёт тревогу в эпохи, которые он отмечает как недоступные; - правила пресетов для каналов фазы, вычисляемые после
carry:clockподаёт тревогу, пока абсолютная ошибка времени превышаетguard_ns;gnss-ins— пока ошибка положения превышаетposition_threshold_m; явные правила помещаются в[[phases.runs.alarms]]; - события-тревоги:
spoofпорождает одно вdetect_time_sсвоего монитора с поддержкой часов;spoof-detectпорождает одно в начале фазы, когда его объединённое решение подаёт тревогу.
Состояние передаётся между фазами тремя явными способами:
carry = ["time_error_ns"]добавляет значение канала в конце предыдущей фазы к значениям этого канала в данной фазе. Фаза часов, которую сдвинул спуфер, — это точка, от которой начинается holdover. Добавление смещения точно для фазы часов, которая интегрирует частоту; для ошибки положения оно предполагает, что две ошибки коллинеарны, то есть пессимистичный случай.[[phases.handoff]]записывает число из предыдущей фазы (channel:<name>для конечного значения канала или любой путь результата предыдущего прогона) в ключ с точками сценария этой фазы перед её запуском, с необязательными масштабом и смещением.end_at = "<result path>"завершает фазу в момент, вычисленный прогоном, с ограничениемduration_s. Поставляемая миссия завершает свою фазу спуфинга наclassical.detect_time_s.
skip_s отбрасывает первые секунды собственной временной шкалы прогона (прогрев) до нулевого момента фазы.
Поставляемая миссия#
scenarios/campaign-jam-spoof-holdover-integrity.toml запускает 18 сценариев-участников в шести фазах на сетке 10 с:
| Фаза | Прогоны | Что показывает временная шкала |
|---|---|---|
| норма, 600 с | clock, jamming (без передатчика помех), integrity |
ошибка времени 0 нс; C/N0 43,0 дБ-Гц при пороге 25 дБ-Гц; вертикальный уровень защиты от 9,1 до 21,6 м при пределе тревоги 50 м |
| подавление, 600 с | то же, передатчик помех -30 дБВт, 1 км | C/N0 падает до 27,7 дБ-Гц, все 8 спутников остаются на слежении |
спуфинг, завершён на 370 с по end_at |
spoof (линейное смещение времени 0,1 нс/с), spoof-detect, jamming |
ошибка времени нарастает до 36 нс; радиочастотный детектор подаёт тревогу в начале фазы, монитор с поддержкой часов — на 370 с |
| holdover, 1800 с | clock (GNSS недоступен, несёт 37,0 нс), gnss-ins (тактический блок в режиме выбега), jamming при 10 дБВт |
потеряны все спутники (C/N0 около -12 дБ-Гц); ошибка времени от 36,4 до 62,7 нс при защитном интервале 50 нс; ошибка положения до 24 км |
| тревога целостности, 600 с | clock (несёт 59,6 нс), jamming и integrity с маской 25 град |
на слежении 5 спутников; уровень защиты от 19 до 135 м, отсутствует в 18 из 60 узлов сетки по времени; перенесённая ошибка времени, от 52,1 до 61,7 нс, остаётся выше защитного интервала 50 нс, поэтому тревога держится всю фазу |
| восстановление, 600 с | clock, jamming (без передатчика помех), integrity |
ошибка времени вернулась к 0 нс; тревога снята |
Прогоны целостности используют собственную трассу пользователя из примера integrity (круговая трасса на высоте 0,4 км), а не фиксированное место приёмника из прогона подавления, а маска 25 град заменяет частичное небо повторно захватывающего приёмника. Это выбор сценария, заявленный в файле.
Миссия, управляемая спектром L-диапазона#
scenarios/campaign-spectrum-holdover-integrity.toml запускает 8 сценариев-участников в трёх фазах на сетке 1 с, причём C/N0 для GPS L1 C/A и Galileo E1 считывается из вида spectrum (см. SPECTRUM.md), а не из таблицы по спутникам вида jamming. Передатчики помех — те же, что в scenarios/l-band-waterfall-jamming.toml.
| Фаза | Прогоны | Что показывает временная шкала |
|---|---|---|
начало, завершено на 10 с по end_at |
clock, spectrum (чирп с 10 с), integrity |
L1 C/A 43,48 и E1 44,73 дБ-Гц; фаза заканчивается на первой потере L1 C/A в собственном прогоне спектра (timeline.bands[0].first_loss_t_s); уровень защиты 21,6 м при 50 м |
| holdover, 600 с | clock (GNSS недоступен, несёт ошибку начала, здесь 0 нс), spectrum (чирп включён) |
L1 C/A 3,38 и E1 4,44 дБ-Гц, оба ниже порога 25 дБ-Гц; ошибка времени от -0.07 до 5,06 нс при защитном интервале 50 нс; тревога держится |
| резерв Galileo, 300 с | clock (повторно синхронизированы), spectrum (тон CW на несущей L1), integrity на Walker 24/3/1, подобном Galileo |
L1 C/A удерживается на 17,98 дБ-Гц, E1 вернулся к 44,73 дБ-Гц; уровень защиты от 6,1 до 17,7 м; тревога снята |
Восстановление E1 под тоном CW опирается на обработку непрерывного спектра в виде spectrum: тон находится в нуле спектра MBOC и ничего не связывает. Настоящий тон связывался бы через спектральные линии кода; это заявлено в файле и в SPECTRUM.md.
[sweep]: сетка параметров для любого вида#
От одного до трёх ключей сценария с точками, каждый в линейном или логарифмическом диапазоне, на тех же значениях оси, что использует вид sweep-nd. У каждой оси есть имя и единица измерения; у каждой метрики есть имя и путь результата, а её единица измерения читается из собственного блока единиц перебираемого вида, если кампания не объявляет свою. При runs > 1 каждый узел — это ансамбль Монте-Карло с начальными значениями (реализация k при начальном значении узла плюс k), отчёт по которому даётся со статистиками ниже. scenarios/campaign-sweep-jammer-power.toml перебирает передатчик помех на расстоянии 1 км от приёмника от -50 до +10 дБВт: среднее отношение помехи к сигналу меняется ровно на 1 дБ на дБ (от 12,2 до 72,2 дБ), а доступность падает с 1 до 0 между -30 и -25 дБВт.
Ключ с точками может индексировать массив таблиц по позиции: system.2.sisre_m — это sisre_m третьей таблицы [[system]], а case.0.system.0.shell.0.altitude_km уходит на три уровня вглубь.
[monte_carlo]: ансамбль с начальными значениями#
Реализация k запускает сценарий с ключом начального значения, равным base_seed + k, — по соглашению, которое уже использует ансамбль часов, — так что ансамбль воспроизводится точно. Каждая метрика сообщает среднее, стандартное отклонение по генеральной совокупности, 5-й, 50-й и 95-й процентили по ближайшему рангу, процентильный доверительный интервал бутстрепа 95% для среднего с фиксированным начальным значением (2000 передискретизаций) и по умолчанию каждый отсчёт в порядке начальных значений. Пути результатов могут индексировать массивы: classical.series[-1].error_ns — последний отсчёт.
[compose]: несколько сценариев при общих условиях#
Именованные общие значения (число или массив чисел с единицей измерения) записываются в каждого участника по ключам, к которым он их привязывает, так что участники не могут расходиться в общем условии. Выполняется каждый участник, а для каждой метрики объединённая сводка даёт наименьшее, наибольшее и среднее значения по участникам с указанием лучшего и худшего. scenarios/campaign-shared-jammer-sea-road.toml помещает один передатчик помех мощностью 8 дБВт между судном в Финском заливе (около 30 км) и автомобилем на прибрежной дороге Хельсинки (около 50 км): судно теряет каждый спутник (среднее отношение помехи к сигналу 39,0 дБ), а автомобиль сохраняет не менее четырёх (34,6 дБ).
[optimize]: наилучшее значение одной метрики#
От одного до трёх ключей сценария с точками, каждый в границах [lo, hi] на шкале lin или log, перебираются в поиске наилучшего значения одной метрики (goal = "minimize", "maximize" или "target", минимизирующее расстояние от target).
Существуют два метода:
method = "grid"запускает каждый узел сетки изstepsна ключ, на значениях оси перебора.method = "nelder-mead"(по умолчанию) запускает детерминированный симплекс Нелдера–Мида в координатах, нормированных на [0, 1] по каждому ключу. Пробные точки проецируются на параллелепипед. Раздел принимаетmax_evals, начальныйstepи допуски остановкиftolиxtol.
Прогон, у которого метрика отсутствует или не конечна, получает худшую оценку и сохраняется в трассе. При runs > 1 метрика — это среднее по тем же начальным значениям при каждой оценке. Результат содержит best_coords, best_metric, best_score, evals, stop_reason и каждую оценку в trace.
scenarios/campaign-optimize-link-budget.toml ищет дальность и скорость передачи данных для запаса линии 3 дБ. Оптимум локален для параллелепипеда и начальной точки. Он имеет уровень MODELLED и никогда не является глобальным утверждением.
Протокол и его заранее зарегистрированные пороги приведены в docs/design/evidence/cap32-optimize/. Тест — tests/campaign_optimize_reference.rs. Результаты:
- решение для цели 1-D совпадает с замкнутой формой до 6e-15;
- метод сетки совпадает побитово с независимым перебором в цикле;
- симплекс справляется не хуже сетки 41 × 41 примерно за одну десятую её прогонов.
Порог 1-D раунда 1 записан как NOT MET: заранее зарегистрированный параллелепипед исключал решение.
Воспроизводимость#
Каждый результат кампании содержит scenario_hash — SHA-256 (Secure Hash Algorithm 2, 256-битный дайджест) канонической формы JavaScript Object Notation (JSON) документа кампании (порядок ключей и форматирование его не меняют) — и блок reproducibility с числом прогонов участников и run_digest — SHA-256 по дайджесту каждого результата участника в порядке диспетчеризации. Два прогона с одним и тем же дайджестом дали побайтно идентичные результаты участников. Каждый прогон фазы также записывает свой вид, собственный scenario_hash, если он есть у этого вида, и SHA-256 своего документа результата. У каждого числа в документе есть запись единицы измерения.
Ядро последовательно и не читает файлов, поэтому кампания без изменений работает в сборке WebAssembly. Кампании не могут содержать кампании.
Экспорт#
--export для кампании записывает каждого участника-сценарий с геометрией в виде отдельного набора файлов, вставляя метку участника перед суффиксом формата: каждый прогон фазы (<phase> или <phase>-<k>, когда у фазы несколько прогонов), базовый сценарий перебора (sweep), сценарий Монте-Карло (monte-carlo) и каждого составного участника (со своей меткой и с записанными в него привязанными общими значениями). Участник, идентичный более раннему, записывается один раз; передачи между фазами и значения перебора или начальные значения, применённые во время выполнения, в экспортируемые сценарии не попадают.
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
Формат, который не может описать ни один из участников, отклоняется с указанием этой причины. Таблица по сценариям приведена в INTEROP.md.
Кампании LEO-PNT#
Пятнадцать поставляемых кампаний формулируют вопросы позиционирования, навигации и времени (PNT) на низкой околоземной орбите (LEO); LEO-PNT.md описывает, что показывает каждая из них. Что запускает каждая, в том виде, как это резюмирует командная строка:
| Сценарий | Режим | Вопрос |
|---|---|---|
leo-focus-data-services.toml |
композиция, 4 участника | служебные данные навигационного сообщения в зависимости от длины кадра |
leo-focus-fused-pnt-sisre.toml |
перебор leo-pvt, 7 узлов |
совместное позиционирование по MEO и LEO в зависимости от ошибки дальности сигнала в пространстве LEO (SISRE) |
leo-focus-indoor-uhf.toml |
композиция, 2 участника | LEO-PNT в помещениях по диапазону и классу зданий |
leo-focus-iot-eirp.toml |
перебор leo-pass, 9 узлов |
энергия Интернета вещей (IoT) на одно определение места в зависимости от мощности передачи LEO в диапазоне UHF |
leo-focus-ntn-bandwidth.toml |
перебор ntn-positioning, 9 узлов |
позиционирование в нетерриториальной сети (NTN) в зависимости от полосы опорного сигнала |
leo-focus-ppp-altitude.toml |
перебор leo-ppp, 3 узлов |
сходимость прецизионного абсолютного позиционирования (PPP) в зависимости от высоты слоя LEO из 192 спутников |
leo-resilience-gnss-jammed-leo-carries.toml |
цепочка, 3 фазы за 2100 с | глобальная навигационная спутниковая система (GNSS) подавлена, пользователя ведёт слой LEO, целостность сохраняется |
leo-resilience-multiband-diversity.toml |
перебор spectrum, 13 узлов |
разнообразие диапазонов LEO против заградительного передатчика помех в L-диапазоне |
leo-resilience-spoof-monitors.toml |
композиция, 4 участника | мониторы спуфинга против четырёх спуферов |
leo-vertical-5g-network-timing.toml |
цепочка, 1 фаза за 86 400 с | синхронизация времени базовой станции 5G: holdover и время LEO |
leo-vertical-asset-tracking-iot.toml |
цепочка, 3 фазы за 1440 с | отслеживание контейнеров по LEO UHF: энергия на одно определение места по ходу рейса |
leo-vertical-autonomous-vehicle.toml |
цепочка, 2 фазы за 1500 с | автономное транспортное средство в городском каньоне со слоем LEO |
leo-vertical-autonomous-vehicle-skyline.toml |
цепочка, 2 фазы за 1800 с | тот же городской каньон как плоская отсечка 35 град и как линия горизонта city-street |
leo-vertical-critical-infrastructure-timing.toml |
цепочка, 2 фазы за 87 000 с | синхронизация времени критической инфраструктуры: holdover со временем LEO |
leo-vertical-polar-arctic.toml |
цепочка, 3 фазы за 10 800 с | полярные и арктические пользователи с полярным слоем LEO |
leo-vertical-rail-maritime.toml |
цепочка, 3 фазы за 2520 с | железнодорожные и морские пользователи со слоем LEO |
MEO — средняя околоземная орбита, UHF — ультравысокие частоты, а 5G — пятое поколение мобильных сетей.
Что проверяется#
tests/campaign_composition_reference.rs закрепляет тождества композиции:
- Кампания из одной фазы побитово воспроизводит автономный прогон. Для
clock,integrityиjammingдокумент результата участника побайтно идентиченrun_tomlна файле сценария, его дайджест — тот, который сообщает кампания, а при сетке с собственным шагом прогона каждое выровненное значение равно значению автономного ряда (C/N0 подавления равно среднему, вычисленному независимо по автономному документу). - Перебор из одного узла и композиция из одного участника читают в точности автономное число.
- Ансамбль с фиксированным начальным значением побайтно стабилен, а реализация
k— это в точности автономный прогон приseed + k; хеш кампании не зависит от порядка ключей. - Аналитический случай.
scenarios/campaign-monte-carlo-clock-holdover.tomlзапускает 200 начальных значений для атомных часов чип-масштаба только с белым шумом частоты (q_wf = 9e-20 с^2/с, Microchip SA.45s sigma_y(1 с) = 3e-10), синхронизированных на 590 с и работающих в режиме выбега до 3600 с. Итоговая ошибка времени гауссова со средним 0 и стандартным отклонением sqrt(q_wf * 3010 с) = 16,459 нс (случайное блуждание фазы при белом шуме частоты, Technical Note 1337 Национального института стандартов и технологий (NIST)). Сообщённый интервал, [-2.52, 1,59] нс, содержит истинное среднее 0; выборочное стандартное отклонение, 14,93 нс, даёт статистику хи-квадрат 164,5 при 199 степенях свободы, внутри двустороннего интервала 99% [151,37, 254,14]. При 3000 начальных значениях тот же сценарий даёт 16,31 нс. - Цепочка под управлением спектра читает автономные числа: фаза начала длится ровно столько, сколько время первой потери в прогоне спектра, а каждое значение L1 C/A и E1 на временной шкале равно с точностью до 1e-9 дБ строке автономного примера водопада для того же состояния передатчика помех (норма, один чирп, один тон CW).
- Цепочка передаёт состояние, как описано: фаза спуфинга длится ровно столько, сколько время обнаружения в прогоне спуфинга, holdover несёт ровно смещение прогона спуфинга в момент обнаружения, восстановление ничего не несёт, а тревога держится везде, где уровень защиты отсутствует или превышает предел тревоги.
Эти проверки подтверждают, что композиция не меняет того, чего не должна менять. Они не валидируют цепочку миссии относительно измеренной, поэтому три строки кампаний в VERIFICATION-MATRIX.md имеют уровень MODELLED.