From 21751f41dd0af022fc1f935c67e795e3ae4257c5 Mon Sep 17 00:00:00 2001 From: LittleSam129 <1qwe432@gmail.com> Date: Mon, 3 Aug 2026 12:21:49 +0300 Subject: [PATCH] Lab033: add priority link scheduler --- PROJECT_LOG.md | 25 + .../processed/lab033/lab033_class_metrics.csv | 37 + .../processed/lab033/lab033_control_delay.png | Bin 0 -> 35387 bytes .../lab033/lab033_deadline_misses.png | Bin 0 -> 35459 bytes .../lab033/lab033_emergency_delay.png | Bin 0 -> 35266 bytes data/processed/lab033/lab033_queue_length.png | Bin 0 -> 36054 bytes data/processed/lab033/lab033_report.txt | 165 +++ .../lab033/lab033_scheduler_comparison.png | Bin 0 -> 83229 bytes data/processed/lab033/lab033_summary.csv | 10 + data/processed/lab033/lab033_video_delay.png | Bin 0 -> 36173 bytes protocol/link_packet.py | 195 +++ protocol/priority_scheduler.py | 222 ++++ tests/lab033_priority_channel_scheduler.py | 1043 +++++++++++++++++ 13 files changed, 1697 insertions(+) create mode 100644 data/processed/lab033/lab033_class_metrics.csv create mode 100644 data/processed/lab033/lab033_control_delay.png create mode 100644 data/processed/lab033/lab033_deadline_misses.png create mode 100644 data/processed/lab033/lab033_emergency_delay.png create mode 100644 data/processed/lab033/lab033_queue_length.png create mode 100644 data/processed/lab033/lab033_report.txt create mode 100644 data/processed/lab033/lab033_scheduler_comparison.png create mode 100644 data/processed/lab033/lab033_summary.csv create mode 100644 data/processed/lab033/lab033_video_delay.png create mode 100644 protocol/link_packet.py create mode 100644 protocol/priority_scheduler.py create mode 100644 tests/lab033_priority_channel_scheduler.py diff --git a/PROJECT_LOG.md b/PROJECT_LOG.md index d08cc36..a531046 100644 --- a/PROJECT_LOG.md +++ b/PROJECT_LOG.md @@ -163,3 +163,28 @@ git version 2.51.1.windows.1 - Режим 8+3 не принят из-за отсутствия устойчивого преимущества. - Подтверждено, что продолжительные помехи нельзя компенсировать только увеличением числа проверочных пакетов. - Следующий этап посвящён совместной передаче команд, телеметрии и видео с приоритетным обслуживанием. + +--- + +# Запись 008 + +## Дата + +3 августа 2026 года + +## Тема + +Завершение Lab033: общий пакет канала и приоритетное обслуживание. + +## Выполнено + +- Добавлен общий 32-байтный заголовок канала для команд, телеметрии и видео. +- Общая предложенная нагрузка составляет 258,214 кбит/с. +- Подтверждено, что FIFO не обеспечивает требуемую задержку команд. +- Выбран строгий приоритет с заменой устаревших состояний. +- Аварийная команда имеет наивысший приоритет. +- Скорость 260 кбит/с практически полностью загружена. +- При 230 кбит/с видеоданные накапливаются и устаревают. +- Итоговое восстановление всех кадров после освобождения очереди не означает работу видео в реальном времени. +- Расчёты и графики выполнены с Matplotlib 3.11.1. +- Следующий этап посвящён отбрасыванию устаревших видеокадров. diff --git a/data/processed/lab033/lab033_class_metrics.csv b/data/processed/lab033/lab033_class_metrics.csv new file mode 100644 index 0000000..d382f7a --- /dev/null +++ b/data/processed/lab033/lab033_class_metrics.csv @@ -0,0 +1,37 @@ +channel_kbps,scheduler,traffic_class,offered_load_kbps,created_packets,transmitted_packets,replaced_packets,remaining_at_source_end_packets,mean_start_delay_ms,p95_start_delay_ms,max_start_delay_ms,mean_total_delay_ms,p95_total_delay_ms,max_total_delay_ms,deadline_misses,deadline_miss_fraction,mean_blocking_delay_ms,max_blocking_delay_ms +300.0,fifo,emergency,0.02465489566613162,1,1,0,0,0.0,0.0,0.0,1.7066666666671892,1.7066666666671892,1.7066666666671892,0,0.0,0.0,0.0 +300.0,fifo,control,10.256436597110755,416,416,0,2,104.3649927884586,236.92691666666235,294.47966666665957,106.0716594551255,238.6335833333294,296.1863333333259,203,0.4879807692307692,5.879864583331442,16.212999999996036 +300.0,fifo,telemetry,7.692327447833066,208,208,0,1,98.47181249999751,231.12033333332866,294.26699999999425,101.03181249999754,233.68033333332914,296.8269999999933,0,0.0,5.797325320511048,16.212999999996036 +300.0,fifo,video,240.24038523274479,1078,1078,0,15,128.3044211502762,254.33199999999601,309.6799999999931,143.7311125541102,264.7599999999962,325.89333333332604,0,0.0,0.0026771799628383768,0.16033333332998723 +300.0,strict_priority,emergency,0.02465489566613162,1,1,0,0,0.0,0.0,0.0,1.7066666666671892,1.7066666666671892,1.7066666666671892,0,0.0,0.0,0.0 +300.0,strict_priority,control,10.256436597110755,416,416,0,0,7.733262019229404,15.759666666666755,16.106333333334,9.439928685896334,17.46633333333346,17.813000000000745,0,0.0,7.7291594551268386,16.106333333334 +300.0,strict_priority,telemetry,7.692327447833066,208,208,0,0,9.864120192306657,17.546883333334474,17.813000000000745,12.424120192306697,20.10688333333437,20.37300000000064,0,0.0,8.149248397434599,16.106333333334 +300.0,strict_priority,video,240.24038523274479,1078,1078,0,15,135.37173098330103,269.12799999999464,323.36000000000143,150.79842238713505,279.70533333332844,333.4933333333332,0,0.0,0.0026771799628976987,0.16033333333353994 +300.0,latest_state,emergency,0.02465489566613162,1,1,0,0,0.0,0.0,0.0,1.7066666666671892,1.7066666666671892,1.7066666666671892,0,0.0,0.0,0.0 +300.0,latest_state,control,10.256436597110755,416,416,0,0,7.733262019229404,15.759666666666755,16.106333333334,9.439928685896334,17.46633333333346,17.813000000000745,0,0.0,7.7291594551268386,16.106333333334 +300.0,latest_state,telemetry,7.692327447833066,208,208,0,0,9.864120192306657,17.546883333334474,17.813000000000745,12.424120192306697,20.10688333333437,20.37300000000064,0,0.0,8.149248397434599,16.106333333334 +300.0,latest_state,video,240.24038523274479,1078,1078,0,15,135.37173098330103,269.12799999999464,323.36000000000143,150.79842238713505,279.70533333332844,333.4933333333332,0,0.0,0.0026771799628976987,0.16033333333353994 +260.0,fifo,emergency,0.02465489566613162,1,1,0,0,0.0,0.0,0.0,1.969230769230279,1.969230769230279,1.969230769230279,0,0.0,0.0,0.0 +260.0,fifo,control,10.256436597110755,416,416,0,7,167.10386353552764,331.0900769231244,458.97469230786925,169.07309430475814,333.0593076923547,460.9439230770995,298,0.7163461538461539,7.857339866886274,18.615384615390695 +260.0,fifo,telemetry,7.692327447833066,208,208,0,4,160.36350517753885,328.8285384616073,460.9439230770995,163.31735133138503,331.7823846154539,463.8977692309467,0,0.0,7.732144230791379,18.615384615390695 +260.0,fifo,video,240.24038523274479,1078,1078,0,21,175.94024482662746,343.1754384616482,473.6000000001752,193.74027336951343,357.6154384615683,492.3076923078682,0,0.0,3.3139568289080654,18.257076923131166 +260.0,strict_priority,emergency,0.02465489566613162,1,1,0,0,0.0,0.0,0.0,1.969230769230279,1.969230769230279,1.969230769230279,0,0.0,0.0,0.0 +260.0,strict_priority,control,10.256436597110755,416,416,0,0,8.313035133156095,16.784365384612144,18.69776923077815,10.282265902386632,18.753596153843198,20.66700000000843,0,0.0,8.308301405345444,18.69776923077815 +260.0,strict_priority,telemetry,7.692327447833066,208,208,0,0,10.909659023688215,19.493946153856623,20.66700000000843,13.863505177534366,22.44779230770204,23.620846153853847,0,0.0,8.930960798836377,18.69776923077815 +260.0,strict_priority,video,240.24038523274479,1078,1078,0,23,187.65972534610552,365.73226153856297,480.49230769247583,205.4597538889915,380.5630769230985,499.20000000016887,0,0.0,3.9965313971947523,18.25707692318801 +260.0,latest_state,emergency,0.02465489566613162,1,1,0,0,0.0,0.0,0.0,1.969230769230279,1.969230769230279,1.969230769230279,0,0.0,0.0,0.0 +260.0,latest_state,control,10.256436597110755,416,416,0,0,8.313035133156095,16.784365384612144,18.69776923077815,10.282265902386632,18.753596153843198,20.66700000000843,0,0.0,8.308301405345444,18.69776923077815 +260.0,latest_state,telemetry,7.692327447833066,208,208,0,0,10.909659023688215,19.493946153856623,20.66700000000843,13.863505177534366,22.44779230770204,23.620846153853847,0,0.0,8.930960798836377,18.69776923077815 +260.0,latest_state,video,240.24038523274479,1078,1078,0,23,187.65972534610552,365.73226153856297,480.49230769247583,205.4597538889915,380.5630769230985,499.20000000016887,0,0.0,3.9965313971947523,18.25707692318801 +230.0,fifo,emergency,0.02465489566613162,1,1,0,0,878.8869565216775,878.8869565216775,878.8869565216775,881.1130434781998,881.1130434781998,881.1130434781998,1,1.0,0.4173913042819777,0.4173913042819777 +230.0,fifo,control,10.256436597110755,416,416,0,42,1172.0617892976043,2238.3086956520533,2606.2956521737738,1174.2878762541263,2240.5347826085754,2608.5217391302963,414,0.9951923076923077,9.870735785906158,21.13043478255605 +230.0,fifo,telemetry,7.692327447833066,208,208,0,21,1161.6391304347285,2222.267826086846,2608.5217391302963,1164.978260869511,2225.6069565216276,2611.860869565078,177,0.8509615384615384,9.380434782561796,21.043478260802218 +230.0,fifo,video,240.24038523274479,1078,1078,0,118,1186.612664354224,2267.033969565095,2618.4808260868167,1206.7344357505297,2288.1817956520513,2639.628652173773,0,0.0,8.20556586266141,21.136565217338088 +230.0,strict_priority,emergency,0.02465489566613162,1,1,0,0,9.32173913036749,9.32173913036749,9.32173913036749,11.547826086889756,11.547826086889756,11.547826086889756,0,0.0,9.32173913036749,9.32173913036749 +230.0,strict_priority,control,10.256436597110755,416,416,0,1,10.02424749162144,19.62173913038057,21.113043478251825,12.250334448143445,21.84782608690261,23.33913043477409,0,0.0,10.018896321052877,21.113043478251825 +230.0,strict_priority,telemetry,7.692327447833066,208,208,0,0,12.175083612023139,21.772173913030322,23.33913043477409,15.51421404680579,25.111304347813142,26.678260869555714,0,0.0,9.938294314364006,21.113043478251825 +230.0,strict_priority,video,240.24038523274479,1078,1078,0,126,1273.2989271597767,2364.9321739130005,2626.272130434721,1293.4206985560818,2379.542608695629,2647.4199565216772,0,0.0,9.628813422585635,19.802565217331036 +230.0,latest_state,emergency,0.02465489566613162,1,1,0,0,9.32173913036749,9.32173913036749,9.32173913036749,11.547826086889756,11.547826086889756,11.547826086889756,0,0.0,9.32173913036749,9.32173913036749 +230.0,latest_state,control,10.256436597110755,416,416,0,1,10.02424749162144,19.62173913038057,21.113043478251825,12.250334448143445,21.84782608690261,23.33913043477409,0,0.0,10.018896321052877,21.113043478251825 +230.0,latest_state,telemetry,7.692327447833066,208,208,0,0,12.175083612023139,21.772173913030322,23.33913043477409,15.51421404680579,25.111304347813142,26.678260869555714,0,0.0,9.938294314364006,21.113043478251825 +230.0,latest_state,video,240.24038523274479,1078,1078,0,126,1273.2989271597767,2364.9321739130005,2626.272130434721,1293.4206985560818,2379.542608695629,2647.4199565216772,0,0.0,9.628813422585635,19.802565217331036 diff --git a/data/processed/lab033/lab033_control_delay.png b/data/processed/lab033/lab033_control_delay.png new file mode 100644 index 0000000000000000000000000000000000000000..9443611f7cf6629369f73079711933588123735f GIT binary patch literal 35387 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 ODI8Qi5HI(K>wf_Fzmwho literal 0 HcmV?d00001 diff --git a/data/processed/lab033/lab033_deadline_misses.png b/data/processed/lab033/lab033_deadline_misses.png new file mode 100644 index 0000000000000000000000000000000000000000..e58e19ae679b9b046c01962efe298b78dbc9f625 GIT binary patch literal 35459 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 MjQru)gJ-Y(4>AZx!2kdN literal 0 HcmV?d00001 diff --git a/data/processed/lab033/lab033_emergency_delay.png b/data/processed/lab033/lab033_emergency_delay.png new file mode 100644 index 0000000000000000000000000000000000000000..4b0f48783003db85340c32bee6c12e1e27fa5518 GIT binary patch literal 35266 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 literal 0 HcmV?d00001 diff --git a/data/processed/lab033/lab033_queue_length.png b/data/processed/lab033/lab033_queue_length.png new file mode 100644 index 0000000000000000000000000000000000000000..5956749ef021acd5c38c28f29b5b3d43a98ee04a GIT binary patch literal 36054 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 мс 63; max gap 344.480 мс; заменено 0. +- Аварийная команда: start/total 0.000/1.707 мс; deadline 50 мс соблюдён; блокировал none, 0 байт, seq=-1, ожидание 0.000 мс. +- Телеметрия: mean/P95/max 101.032/233.680/296.827 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.984127, после drain 1.000000, итог 1.000000; delay mean/P95/max 261.559/304.579/311.146 мс. +- Возраст изображения mean/P95/max 423.846/580.000/643.333 мс; доля >1 с 0.000000; поздних кадров 0, max серия 0. +[300 кбит/с; Строгий приоритет] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 8.050/22 пакетов и 4452.4/12221 байт. +- На конце видео: 15 пакетов, 8695.0 байт; полное освобождение 20.998534 с, дополнительно 0.231867 с. +- Команды: mean/P95/max 9.440/17.466/17.813 мс; превышений 100 мс 0; промежутков >100 мс 0; max gap 65.760 мс; заменено 0. +- Аварийная команда: start/total 0.000/1.707 мс; deadline 50 мс соблюдён; блокировал none, 0 байт, seq=-1, ожидание 0.000 мс. +- Телеметрия: mean/P95/max 12.424/20.107/20.373 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.984127, после drain 1.000000, итог 1.000000; delay mean/P95/max 276.337/322.072/330.773 мс. +- Возраст изображения mean/P95/max 437.649/593.333/660.000 мс; доля >1 с 0.000000; поздних кадров 0, max серия 0. +[300 кбит/с; Приоритет + замена] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 8.050/22 пакетов и 4452.4/12221 байт. +- На конце видео: 15 пакетов, 8695.0 байт; полное освобождение 20.998534 с, дополнительно 0.231867 с. +- Команды: mean/P95/max 9.440/17.466/17.813 мс; превышений 100 мс 0; промежутков >100 мс 0; max gap 65.760 мс; заменено 0. +- Аварийная команда: start/total 0.000/1.707 мс; deadline 50 мс соблюдён; блокировал none, 0 байт, seq=-1, ожидание 0.000 мс. +- Телеметрия: mean/P95/max 12.424/20.107/20.373 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.984127, после drain 1.000000, итог 1.000000; delay mean/P95/max 276.337/322.072/330.773 мс. +- Возраст изображения mean/P95/max 437.649/593.333/660.000 мс; доля >1 с 0.000000; поздних кадров 0, max серия 0. +[260 кбит/с; FIFO] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 14.800/37 пакетов и 6010.5/16512 байт. +- На конце видео: 32 пакетов, 12974.0 байт; полное освобождение 21.165867 с, дополнительно 0.399200 с. +- Команды: mean/P95/max 169.073/333.059/460.944 мс; превышений 100 мс 298; промежутков >100 мс 63; max gap 384.348 мс; заменено 0. +- Аварийная команда: start/total 0.000/1.969 мс; deadline 50 мс соблюдён; блокировал none, 0 байт, seq=-1, ожидание 0.000 мс. +- Телеметрия: mean/P95/max 163.317/331.782/463.898 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.984127, после drain 1.000000, итог 1.000000; delay mean/P95/max 329.072/420.025/436.185 мс. +- Возраст изображения mean/P95/max 489.627/666.667/766.667 мс; доля >1 с 0.000000; поздних кадров 0, max серия 0. +[260 кбит/с; Строгий приоритет] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 10.783/28 пакетов и 6010.2/16384 байт. +- На конце видео: 23 пакетов, 12974.0 байт; полное освобождение 21.165867 с, дополнительно 0.399200 с. +- Команды: mean/P95/max 10.282/18.754/20.667 мс; превышений 100 мс 0; промежутков >100 мс 0; max gap 63.477 мс; заменено 0. +- Аварийная команда: start/total 0.000/1.969 мс; deadline 50 мс соблюдён; блокировал none, 0 байт, seq=-1, ожидание 0.000 мс. +- Телеметрия: mean/P95/max 13.864/22.448/23.621 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.968254, после drain 1.000000, итог 1.000000; delay mean/P95/max 351.218/445.846/459.559 мс. +- Возраст изображения mean/P95/max 511.188/693.333/783.333 мс; доля >1 с 0.000000; поздних кадров 0, max серия 0. +[260 кбит/с; Приоритет + замена] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 10.783/28 пакетов и 6010.2/16384 байт. +- На конце видео: 23 пакетов, 12974.0 байт; полное освобождение 21.165867 с, дополнительно 0.399200 с. +- Команды: mean/P95/max 10.282/18.754/20.667 мс; превышений 100 мс 0; промежутков >100 мс 0; max gap 63.477 мс; заменено 0. +- Аварийная команда: start/total 0.000/1.969 мс; deadline 50 мс соблюдён; блокировал none, 0 байт, seq=-1, ожидание 0.000 мс. +- Телеметрия: mean/P95/max 13.864/22.448/23.621 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.968254, после drain 1.000000, итог 1.000000; delay mean/P95/max 351.218/445.846/459.559 мс. +- Возраст изображения mean/P95/max 511.188/693.333/783.333 мс; доля >1 с 0.000000; поздних кадров 0, max серия 0. +[230 кбит/с; FIFO] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 86.915/184 пакетов и 34309.1/76497 байт. +- На конце видео: 181 пакетов, 73238.3 байт; полное освобождение 23.314087 с, дополнительно 2.547420 с. +- Команды: mean/P95/max 1174.288/2240.535/2608.522 мс; превышений 100 мс 414; промежутков >100 мс 63; max gap 427.304 мс; заменено 0. +- Аварийная команда: start/total 878.887/881.113 мс; deadline 50 мс НАРУШЕН; блокировал video, 608 байт, seq=461, ожидание 0.417 мс. +- Телеметрия: mean/P95/max 1164.978/2225.607/2611.861 мс; превышений 500 мс 177 (0.850962); заменено 0. +- Видео: опубликовано к концу источника 0.888889, после drain 1.000000, итог 1.000000; delay mean/P95/max 1347.217/2417.731/2576.186 мс. +- Возраст изображения mean/P95/max 1506.487/2588.167/2906.667 мс; доля >1 с 0.771870; поздних кадров 42, max серия 42. +[230 кбит/с; Строгий приоритет] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 59.750/132 пакетов и 34307.1/75969 байт. +- На конце видео: 127 пакетов, 73238.3 байт; полное освобождение 23.314087 с, дополнительно 2.547420 с. +- Команды: mean/P95/max 12.250/21.848/23.339 мс; превышений 100 мс 0; промежутков >100 мс 0; max gap 69.009 мс; заменено 0. +- Аварийная команда: start/total 9.322/11.548 мс; deadline 50 мс соблюдён; блокировал video, 608 байт, seq=458, ожидание 9.322 мс. +- Телеметрия: mean/P95/max 15.514/25.111/26.678 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.888889, после drain 1.000000, итог 1.000000; delay mean/P95/max 1445.995/2505.995/2583.977 мс. +- Возраст изображения mean/P95/max 1594.537/2678.167/2916.667 мс; доля >1 с 0.804460; поздних кадров 47, max серия 47. +[230 кбит/с; Приоритет + замена] +- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 59.750/132 пакетов и 34307.1/75969 байт. +- На конце видео: 127 пакетов, 73238.3 байт; полное освобождение 23.314087 с, дополнительно 2.547420 с. +- Команды: mean/P95/max 12.250/21.848/23.339 мс; превышений 100 мс 0; промежутков >100 мс 0; max gap 69.009 мс; заменено 0. +- Аварийная команда: start/total 9.322/11.548 мс; deadline 50 мс соблюдён; блокировал video, 608 байт, seq=458, ожидание 9.322 мс. +- Телеметрия: mean/P95/max 15.514/25.111/26.678 мс; превышений 500 мс 0 (0.000000); заменено 0. +- Видео: опубликовано к концу источника 0.888889, после drain 1.000000, итог 1.000000; delay mean/P95/max 1445.995/2505.995/2583.977 мс. +- Возраст изображения mean/P95/max 1594.537/2678.167/2916.667 мс; доля >1 с 0.804460; поздних кадров 47, max серия 47. + +5. Интерпретация планировщиков +- FIFO задерживает команды, потому что все ранее поступившие внешние видеопакеты остаются перед ними независимо от срочности. +- Строгий приоритет после каждого окончания пакета выбирает управление раньше телеметрии и видео, поэтому сокращает очередь команд. +- Уже начатая передача не прерывается: модель сериализует целый пакет как атомарную единицу и не задаёт фрагментацию общего пакета или возобновление передачи. +- Поэтому нижняя граница задержки срочной команды включает остаток времени самого длинного пакета, уже занявшего ресурс. +- Замена старого состояния новым не тратит канал на запоздалую команду, которая к моменту приёма уже не отражает актуальное управление. +- Строгий приоритет перераспределяет порядок, но не уменьшает объём видео; при нагрузке выше пропускной способности видеопакеты продолжают накапливаться. +- Длинная очередь видео увеличивает возраст изображения даже без потерь: полные, но старые кадры публикуются позже времени формирования. +- Восстановление 100% кадров после drain подтверждает целостность, но не пригодность задержек канала для управления в реальном времени. + +6. Допущения модели +- Один общий абстрактный ресурс и одна расчётная скорость для обоих направлений; переключение направления не задерживает передачу. +- Не выбран физический полудуплекс/дуплекс, TDD/FDD, модуляция, ретранслятор или физическое разделение восходящего и нисходящего каналов. +- Ошибки и помехи отсутствуют; полностью переданный пакет доставляется без повреждений; видеопакеты не отбрасываются по возрасту. +- После конца исходного видео новые данные не создаются, а очередь полностью освобождается. +- При совпадении времени FIFO использует traffic_class, stream_id и sequence_number как устойчивое правило разрешения совпадений. +- Средняя очередь рассчитана по времени на основном интервале и включает пакет, находящийся в передатчике; остаток байтов активного пакета учитывается пропорционально недопереданному времени. + +7. Функциональные проверки +- PASS 01_header_roundtrip: PASS +- PASS 02_header_crc_detection: PASS +- PASS 03_payload_crc_detection: PASS +- PASS 04_video_wrapper_byte_exact: PASS +- PASS 05_lab030_crc: PASS +- PASS 06_lab028_crc: PASS +- PASS 07_fifo_global_order: PASS +- PASS 08_strict_priority: PASS +- PASS 09_non_preemptive: PASS +- PASS 10_intra_class_sequence: PASS +- PASS 11_latest_state_scope: PASS +- PASS 12_active_state_not_removed: PASS +- PASS 13_emergency_never_replaced: PASS +- PASS 14_300kbps_all_video: PASS +- PASS 15_overload_visible: PASS +- PASS 16_exact_transmission_duration: PASS +- PASS 17_total_bits_accounting: PASS +- PASS 18_reproducible_schedule: PASS +- PASS 19_no_video_control_isolated: PASS +- PASS 20_latest_state_reaches_receiver: PASS + +8. Созданные файлы и итоговый Git status +- protocol/link_packet.py +- protocol/priority_scheduler.py +- tests/lab033_priority_channel_scheduler.py +- data/processed/lab033/lab033_summary.csv +- data/processed/lab033/lab033_class_metrics.csv +- data/processed/lab033/lab033_report.txt +- data/processed/lab033/lab033_control_delay.png +- data/processed/lab033/lab033_emergency_delay.png +- data/processed/lab033/lab033_video_delay.png +- data/processed/lab033/lab033_queue_length.png +- data/processed/lab033/lab033_deadline_misses.png +- data/processed/lab033/lab033_scheduler_comparison.png +- Lab028-Lab032 и их сохранённые результаты не изменены. +- Lab033 не добавлена в индекс и не закоммичена. + +## main...origin/main +?? data/processed/lab033/ +?? protocol/link_packet.py +?? protocol/priority_scheduler.py +?? tests/lab033_priority_channel_scheduler.py diff --git a/data/processed/lab033/lab033_scheduler_comparison.png b/data/processed/lab033/lab033_scheduler_comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..aa1fda5702548214eb7827f7c9acd27dd206f146 GIT binary patch literal 83229 zcmeFZcTiMa_ch4#7%_mNq99osBnyaS5F~YzBuiGJl5=RHf+CU|nw&FD5|Er!l1)@H zk|gI$gU~e0x#;_Tzi+B${+O!yW2%NKOK7_9J?GqW_Fj9fwF!KxBzyG|q8=H&Xq!IVhxg_E6?t&`O&BRUsT2gg^o zHoTnN+??F(bT6Hp>>P!-xUB#C4o+JKb1sLUXMTgL5ZlRVI}#DyCWHR{W1iBhO7ssA z5nM__-7Rr-{DPaB#@)|bmAqM|8~S_Mbn=hSo|Vexkv^w#O~sDRTjBck3zsgw`Ec<= zF1xAn^(gvMlW!9q#XN{KC#Fe9CApXKm&f-j4o;Gpd%EE3iW7;Ek0bY!_p3&%9wmT# z|NXKfUYEJ>pC5>b=+?sN&i?mDy^F+>|NY_f+yAfpO7-(nUykYT&8gm0i8CzEKBhin zC&xx}B&ZiWQ$gaEVF~=U*(qS5iHLkzPM70{1oXp_hKWh$6&jIe4TsBY#H6G?zZ#T9 zaZ#QpgniXaxrm2Bq|m#F=pLC}`xpF=l_ROJ7(g`qp1zz!RiIs#eYD%B>~QqkzS?mi zRIk=W@sZ8g{d$jma#~ti?GmH6o`*|0yZon@co3CSq6}Rv(~yAQAA*aUE`Cqj{vk`- zQe_A`x6+@N!DU;w^-g4e%<;T5v=51h>_~Ypf+71d3LtlLJqfs>!^52(aUVm62NjoY zv3`r^v&=-GS-VFEiw(JKY-|q6C@ERxV>r?CT?z6Nb?!LIcQ8a$xHsVti(46*@f!2H zK-#{L;=>t2$%mS530ld_)WLt038CDc3ZPxq4z>?G9{a&HF)^W9W%uIMP*GBWLH%J` z8>VWeFI(|$eNTdI1H}SCGhf53D?ZEo#e7eSp?D>74O4G5QmXF0zS!0#8}iyXMOo~C zvBk(I_IE2|gS;mJ6UC;rp4R5GKkk~h?agDPr#fAhdG_47r5=ZJi-Fyh?kJYXC{_)G zfyWx3pyzM9c%SGB>(TkTlh%;C_MtH|$7SX{Vw+o$qs8_kHO~3#%+5YN$)d2LTME53 z%FqL4yz+OIVg>BerKF_;Yim8~;F-e?bM3HtB<{nG7~dHcG;7FubKnggv(7tl!mdRH z`n8%LZn3#c+Rt^wG;UOU{P*$axrHJ2KbMAdu!=_cVcs8LXx3}O1lS25XPi|XA2Qy*fy{4-y^jVY2uLL=<1opMj zN@ehnTny9KhD(eOd7PKk35T^#OGcO;RUMqARjtcf?+OMyDYgATgg~1TV~tS?w9A&x z{hiUXatri?*!H)3NEcOyJb#(TkA07DLxyBzWa*KLkxYsxum#)m)N*D=%u@!4vBRty zn9L!*qy0%A9O;4uc`r7S*|a^11$llrj@O*#aHjU~hknol9#(2hYgl15;uab3Rou}=ba;oXe|~*tdp1&e*~Gmqlp6Olf7xqe*$X-e znaqrT&cSe_Pb05HEE(ASndXo9Y{s6&{OU*&uH+oy_c``7XAy71E$*$3WcV-^Yvf1Y zWPkQFMs0V0KW2TrwnO~nC?oP2>qrLT7Lz~gKe-4JrDPH9$^p`Cd-Nj(5{>vi6&kzl zL_r?AUynsIIyyS!Kip(V@3>BK_mRS+IM|p;-{dY^yo-w;$ZSo0hO{;0}Z-+zVcR^-fd?3&Bgbj#V6>o;#^4t@6k!3|fC z`XfVD9-%r%M2*e5P;UleXx`JbHw_Jr3rcWn5Hw>(D{VV2bJfw|mIvguO4?$Yl@M

_Y*p+)Q* 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

uAAOih>rvud@ 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 My85}Sb4q9e05{q!A^-pY literal 0 HcmV?d00001 diff --git a/data/processed/lab033/lab033_summary.csv b/data/processed/lab033/lab033_summary.csv new file mode 100644 index 0000000..1e7ec91 --- /dev/null +++ b/data/processed/lab033/lab033_summary.csv @@ -0,0 +1,10 @@ +channel_kbps,scheduler,offered_load_kbps,emergency_load_kbps,control_load_kbps,telemetry_load_kbps,video_load_kbps,service_share_percent,offered_to_capacity_ratio,transmitted_packets,transmitted_bytes,source_duration_seconds,drain_end_seconds,additional_drain_seconds,queue_at_source_end_packets,queue_at_source_end_bytes,mean_queue_packets,max_queue_packets,mean_queue_bytes,max_queue_bytes,control_mean_age_ms,control_p95_age_ms,control_max_age_ms,control_gaps_over_100ms,control_max_receive_gap_ms,control_replaced,emergency_start_delay_ms,emergency_total_delay_ms,emergency_deadline_met,emergency_blocker_class,emergency_blocker_size_bytes,emergency_blocker_sequence,emergency_blocking_delay_ms,telemetry_mean_age_ms,telemetry_p95_age_ms,telemetry_max_age_ms,telemetry_misses_500ms,telemetry_miss_fraction,telemetry_replaced,video_published_at_source_end_fraction,video_published_after_drain_fraction,video_final_recovery_fraction,video_mean_publication_delay_ms,video_p95_publication_delay_ms,video_max_publication_delay_ms,video_mean_display_age_ms,video_p95_display_age_ms,video_max_display_age_ms,video_age_over_1s_fraction,video_late_frame_count,video_max_late_run +300.0,fifo,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,0.8607126805778491,1703,670280,20.766666666666666,20.99853366666666,0.23186699999999405,18,8695.012499999913,10.477643691813581,22,4452.409985633955,12221,106.0716594551255,238.6335833333294,296.1863333333259,63,344.4796666666594,0,0.0,1.7066666666671892,True,none,0,-1,0.0,101.03181249999754,233.68033333332914,296.8269999999933,0,0.0,0,0.9841269841269841,1.0,1.0,261.5593703703662,304.57866666666183,311.1463333333262,423.8457877201335,580.0,643.3333333333333,0.0,0,0 +300.0,strict_priority,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,0.8607126805778491,1703,670280,20.766666666666666,20.99853366666666,0.23186699999999405,15,8695.012499999915,8.05016637239154,22,4452.387224542477,12221,9.439928685896334,17.46633333333346,17.813000000000745,0,65.7596666666671,0,0.0,1.7066666666671892,True,none,0,-1,0.0,12.424120192306697,20.10688333333437,20.37300000000064,0,0.0,0,0.9841269841269841,1.0,1.0,276.3369365079338,322.0720000000001,330.77299999999,437.6487386958594,593.3333333333334,660.0000000000001,0.0,0,0 +300.0,latest_state,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,0.8607126805778491,1703,670280,20.766666666666666,20.99853366666666,0.23186699999999405,15,8695.012499999915,8.05016637239154,22,4452.387224542477,12221,9.439928685896334,17.46633333333346,17.813000000000745,0,65.7596666666671,0,0.0,1.7066666666671892,True,none,0,-1,0.0,12.424120192306697,20.10688333333437,20.37300000000064,0,0.0,0,0.9841269841269841,1.0,1.0,276.3369365079338,322.0720000000001,330.77299999999,437.6487386958594,593.3333333333334,660.0000000000001,0.0,0,0 +260.0,fifo,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,0.9931300160513643,1703,670280,20.766666666666666,21.165867000000176,0.39920033333351057,32,12974.010833338622,14.800483013954153,37,6010.5496338357525,16512,169.07309430475814,333.0593076923547,460.9439230770995,63,384.34838461538055,0,0.0,1.969230769230279,True,none,0,-1,0.0,163.31735133138503,331.7823846154539,463.8977692309467,0,0.0,0,0.9841269841269841,1.0,1.0,329.07164590967284,420.0249487180816,436.18494871812175,489.62700661000974,666.6666666666679,766.6666666666692,0.0,0,0 +260.0,strict_priority,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,0.9931300160513643,1703,670280,20.766666666666666,21.16586700000017,0.39920033333350347,23,12974.010833338338,10.783079034450305,28,6010.224630522928,16384,10.282265902386632,18.753596153843198,20.66700000000843,0,63.476923076922546,0,0.0,1.969230769230279,True,none,0,-1,0.0,13.863505177534366,22.44779230770204,23.620846153853847,0,0.0,0,0.9682539682539683,1.0,1.0,351.2176776557015,445.84648717956554,459.55930769245157,511.18822788794483,693.3333333333316,783.3333333333314,0.0,0,0 +260.0,latest_state,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,0.9931300160513643,1703,670280,20.766666666666666,21.16586700000017,0.39920033333350347,23,12974.010833338338,10.783079034450305,28,6010.224630522928,16384,10.282265902386632,18.753596153843198,20.66700000000843,0,63.476923076922546,0,0.0,1.969230769230279,True,none,0,-1,0.0,13.863505177534366,22.44779230770204,23.620846153853847,0,0.0,0,0.9682539682539683,1.0,1.0,351.2176776557015,445.84648717956554,459.55930769245157,511.18822788794483,693.3333333333316,783.3333333333314,0.0,0,0 +230.0,fifo,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,1.1226687137971945,1703,670280,20.766666666666666,23.3140869565216,2.5474202898549336,181,73238.33333333043,86.91502882266383,184,34309.08168164904,76497,1174.2878762541263,2240.5347826085754,2608.5217391302963,63,427.3043478260803,0,878.8869565216775,881.1130434781998,False,video,608,461,0.4173913042819777,1164.978260869511,2225.6069565216276,2611.860869565078,177,0.8509615384615384,0,0.8888888888888888,1.0,1.0,1347.216563146941,2417.731014492629,2576.1855072462367,1506.486563750715,2588.1666666666674,2906.6666666666697,0.7718696397941681,42,42 +230.0,strict_priority,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,1.1226687137971945,1703,670280,20.766666666666666,23.314086956521678,2.547420289855012,127,73238.33333333276,59.749842696627866,132,34307.118394888734,75969,12.250334448143445,21.84782608690261,23.33913043477409,0,69.00869565217427,0,9.32173913036749,11.547826086889756,True,video,608,458,9.32173913036749,15.51421404680579,25.111304347813142,26.678260869555714,0,0.0,0,0.8888888888888888,1.0,1.0,1445.9947550034299,2505.9953623187953,2583.976811594141,1594.536878216124,2678.1666666666674,2916.666666666668,0.8044596912521441,47,47 +230.0,latest_state,258.21380417335473,0.02465489566613162,10.256436597110755,7.692327447833066,240.24038523274479,34.922718863758426,1.1226687137971945,1703,670280,20.766666666666666,23.314086956521678,2.547420289855012,127,73238.33333333276,59.749842696627866,132,34307.118394888734,75969,12.250334448143445,21.84782608690261,23.33913043477409,0,69.00869565217427,0,9.32173913036749,11.547826086889756,True,video,608,458,9.32173913036749,15.51421404680579,25.111304347813142,26.678260869555714,0,0.0,0,0.8888888888888888,1.0,1.0,1445.9947550034299,2505.9953623187953,2583.976811594141,1594.536878216124,2678.1666666666674,2916.666666666668,0.8044596912521441,47,47 diff --git a/data/processed/lab033/lab033_video_delay.png b/data/processed/lab033/lab033_video_delay.png new file mode 100644 index 0000000000000000000000000000000000000000..80182cd69959f890fdd0cd20ed237e864465f31e GIT binary patch literal 36173 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 int: + """Return unsigned IEEE CRC32.""" + + return zlib.crc32(data) & 0xFFFFFFFF + + +def _validated(packet: LinkPacket) -> LinkPacket: + if not isinstance(packet, LinkPacket): + raise TypeError("packet must be LinkPacket") + try: + traffic_class = TrafficClass(packet.traffic_class) + direction = Direction(packet.direction) + except ValueError as error: + raise LinkPacketError("unsupported enumeration value") from error + if packet.version != VERSION: + raise LinkPacketError("unsupported link packet version") + if packet.flags & ~SUPPORTED_FLAGS_MASK: + raise LinkPacketError("unsupported link packet flags") + if not 0 <= packet.stream_id <= 0xFFFF: + raise LinkPacketError("stream_id is outside uint16") + if not 0 <= packet.sequence_number <= 0xFFFFFFFF: + raise LinkPacketError("sequence_number is outside uint32") + if not 0 <= packet.generation_time_us <= 0xFFFFFFFFFFFFFFFF: + raise LinkPacketError("generation_time_us is outside uint64") + if not 0 <= packet.deadline_ms <= 0xFFFF: + raise LinkPacketError("deadline_ms is outside uint16") + if not isinstance(packet.payload, (bytes, bytearray)): + raise TypeError("payload must be bytes or bytearray") + payload = bytes(packet.payload) + if len(payload) > 0xFFFFFFFF: + raise LinkPacketError("payload is outside uint32 length") + return replace( + packet, + traffic_class=traffic_class, + direction=direction, + payload=payload, + ) + + +def _pack_header(packet: LinkPacket, crc_value: int) -> bytes: + return struct.pack( + HEADER_FORMAT, + MAGIC, + packet.version, + int(packet.traffic_class), + int(packet.direction), + packet.flags, + packet.stream_id, + packet.sequence_number, + packet.generation_time_us, + packet.deadline_ms, + len(packet.payload), + crc_value, + ) + + +def encode_link_packet(packet: LinkPacket) -> bytes: + """Serialize a common packet and calculate its CRC32.""" + + packet = _validated(packet) + header_without_crc = _pack_header(packet, 0) + packet_crc32 = crc32(header_without_crc + packet.payload) + return _pack_header(packet, packet_crc32) + packet.payload + + +def decode_link_packet(wire_packet: bytes) -> LinkPacket: + """Deserialize a common packet and validate its format and CRC32.""" + + if not isinstance(wire_packet, (bytes, bytearray)): + raise TypeError("wire_packet must be bytes or bytearray") + wire_packet = bytes(wire_packet) + if len(wire_packet) < HEADER_SIZE: + raise LinkPacketError("link packet is shorter than its header") + ( + magic, + version, + traffic_class, + direction, + flags, + stream_id, + sequence_number, + generation_time_us, + deadline_ms, + payload_length, + received_crc32, + ) = struct.unpack(HEADER_FORMAT, wire_packet[:HEADER_SIZE]) + if magic != MAGIC: + raise LinkPacketError("invalid link packet magic") + if len(wire_packet) != HEADER_SIZE + payload_length: + raise LinkPacketError("payload_length does not match packet length") + try: + packet = LinkPacket( + traffic_class=TrafficClass(traffic_class), + direction=Direction(direction), + stream_id=stream_id, + sequence_number=sequence_number, + generation_time_us=generation_time_us, + deadline_ms=deadline_ms, + payload=wire_packet[HEADER_SIZE:], + flags=flags, + version=version, + packet_crc32=received_crc32, + ) + except ValueError as error: + raise LinkPacketError("unsupported enumeration value") from error + packet = _validated(packet) + calculated_crc32 = crc32(_pack_header(packet, 0) + packet.payload) + if calculated_crc32 != received_crc32: + raise LinkPacketCRCError( + "link packet CRC mismatch: " + f"received 0x{received_crc32:08X}, " + f"calculated 0x{calculated_crc32:08X}" + ) + return packet + + +assert HEADER_SIZE == 32 diff --git a/protocol/priority_scheduler.py b/protocol/priority_scheduler.py new file mode 100644 index 0000000..8b6777e --- /dev/null +++ b/protocol/priority_scheduler.py @@ -0,0 +1,222 @@ +"""Deterministic non-preemptive queue schedulers for Lab033.""" + +from __future__ import annotations + +from dataclasses import dataclass +from enum import Enum +from typing import Iterable + +from protocol.link_packet import ( + HEADER_SIZE, + LinkPacket, + TrafficClass, + encode_link_packet, +) + + +TIME_EPSILON_SECONDS = 1e-12 + + +class SchedulerMode(str, Enum): + FIFO = "fifo" + STRICT_PRIORITY = "strict_priority" + LATEST_STATE = "latest_state" + + +@dataclass(frozen=True) +class QueuedPacket: + """A packet plus a stable global arrival-order tie breaker.""" + + packet: LinkPacket + arrival_order: int + + @property + def generation_time_seconds(self) -> float: + return self.packet.generation_time_us / 1_000_000.0 + + @property + def wire_size_bytes(self) -> int: + return HEADER_SIZE + len(self.packet.payload) + + +@dataclass(frozen=True) +class Replacement: + removed: QueuedPacket + replacement: QueuedPacket + + +@dataclass(frozen=True) +class ScheduledPacket: + queued: QueuedPacket + start_seconds: float + end_seconds: float + blocked_by: QueuedPacket | None + blocking_delay_seconds: float + wire_packet: bytes + + +@dataclass(frozen=True) +class QueueSample: + time_seconds: float + packets: int + bytes: int + + +@dataclass(frozen=True) +class ScheduleResult: + mode: SchedulerMode + channel_bitrate_bps: float + transmitted: tuple[ScheduledPacket, ...] + replacements: tuple[Replacement, ...] + queue_samples: tuple[QueueSample, ...] + + +def transmission_duration_seconds( + packet_size_bytes: int, + channel_bitrate_bps: float, +) -> float: + """Return exact serialization duration for a complete packet.""" + + if packet_size_bytes < 0: + raise ValueError("packet size must not be negative") + if channel_bitrate_bps <= 0.0: + raise ValueError("channel bitrate must be positive") + return packet_size_bytes * 8.0 / channel_bitrate_bps + + +def _selection_key(item: QueuedPacket, mode: SchedulerMode) -> tuple[int, int]: + if mode is SchedulerMode.FIFO: + return (0, item.arrival_order) + return (int(item.packet.traffic_class), item.arrival_order) + + +def _enqueue( + ready: list[QueuedPacket], + item: QueuedPacket, + mode: SchedulerMode, + replacements: list[Replacement], +) -> None: + if ( + mode is SchedulerMode.LATEST_STATE + and item.packet.traffic_class + in (TrafficClass.CONTROL, TrafficClass.TELEMETRY) + ): + retained = [] + for old in ready: + if ( + old.packet.traffic_class == item.packet.traffic_class + and old.packet.stream_id == item.packet.stream_id + ): + replacements.append(Replacement(old, item)) + else: + retained.append(old) + ready[:] = retained + ready.append(item) + + +def schedule_packets( + packets: Iterable[QueuedPacket], + mode: SchedulerMode, + channel_bitrate_bps: float, +) -> ScheduleResult: + """Serialize all packets through one non-preemptive shared resource. + + The caller supplies a unique ``arrival_order``. Packets are admitted by + ``(generation_time, arrival_order)``. FIFO selects the smallest arrival + order; priority modes select the smallest ``TrafficClass`` and preserve + arrival order within a class. Latest-state replacement only touches items + still waiting in ``ready`` and therefore can never remove an active packet. + """ + + try: + mode = SchedulerMode(mode) + except ValueError as error: + raise ValueError("unsupported scheduler mode") from error + if channel_bitrate_bps <= 0.0: + raise ValueError("channel bitrate must be positive") + arrivals = sorted( + tuple(packets), + key=lambda item: ( + item.generation_time_seconds, + item.arrival_order, + ), + ) + if len({item.arrival_order for item in arrivals}) != len(arrivals): + raise ValueError("arrival_order values must be unique") + + ready: list[QueuedPacket] = [] + transmitted: list[ScheduledPacket] = [] + replacements: list[Replacement] = [] + samples: list[QueueSample] = [] + blocker_by_order: dict[int, tuple[QueuedPacket, float]] = {} + cursor = 0.0 + arrival_index = 0 + + def sample(time_seconds: float) -> None: + samples.append( + QueueSample( + time_seconds=time_seconds, + packets=len(ready), + bytes=sum(item.wire_size_bytes for item in ready), + ) + ) + + while arrival_index < len(arrivals) or ready: + if not ready: + cursor = max(cursor, arrivals[arrival_index].generation_time_seconds) + while ( + arrival_index < len(arrivals) + and arrivals[arrival_index].generation_time_seconds + <= cursor + TIME_EPSILON_SECONDS + ): + _enqueue(ready, arrivals[arrival_index], mode, replacements) + arrival_index += 1 + sample(cursor) + selected_index = min( + range(len(ready)), + key=lambda index: _selection_key(ready[index], mode), + ) + selected = ready.pop(selected_index) + start = max(cursor, selected.generation_time_seconds) + wire_packet = encode_link_packet(selected.packet) + end = start + transmission_duration_seconds( + len(wire_packet), channel_bitrate_bps + ) + + while ( + arrival_index < len(arrivals) + and arrivals[arrival_index].generation_time_seconds + <= end + TIME_EPSILON_SECONDS + ): + arriving = arrivals[arrival_index] + if arriving.generation_time_seconds > start + TIME_EPSILON_SECONDS: + blocker_by_order[arriving.arrival_order] = ( + selected, + max(0.0, end - arriving.generation_time_seconds), + ) + _enqueue(ready, arriving, mode, replacements) + arrival_index += 1 + + blocker, blocking_delay = blocker_by_order.get( + selected.arrival_order, (None, 0.0) + ) + transmitted.append( + ScheduledPacket( + queued=selected, + start_seconds=start, + end_seconds=end, + blocked_by=blocker, + blocking_delay_seconds=blocking_delay, + wire_packet=wire_packet, + ) + ) + cursor = end + sample(cursor) + + return ScheduleResult( + mode=mode, + channel_bitrate_bps=channel_bitrate_bps, + transmitted=tuple(transmitted), + replacements=tuple(replacements), + queue_samples=tuple(samples), + ) diff --git a/tests/lab033_priority_channel_scheduler.py b/tests/lab033_priority_channel_scheduler.py new file mode 100644 index 0000000..f7b5cb5 --- /dev/null +++ b/tests/lab033_priority_channel_scheduler.py @@ -0,0 +1,1043 @@ +"""Lab033: one shared link queue for control, telemetry, and FEC video. + +The experiment deliberately models one abstract, error-free, non-preemptive +serialization resource. Both logical directions consume the same configured +bitrate; direction-switch time and a physical duplexing scheme are outside the +scope of this laboratory. +""" + +from __future__ import annotations + +import csv +from dataclasses import asdict, dataclass +from pathlib import Path +import struct +import subprocess +from typing import Iterable + +import cv2 +import matplotlib +import numpy as np + +matplotlib.use("Agg") +import matplotlib.pyplot as plt + +from protocol.link_packet import ( + Direction, + HEADER_FORMAT, + HEADER_SIZE, + LinkPacket, + LinkPacketCRCError, + TrafficClass, + decode_link_packet, + encode_link_packet, +) +from protocol.packet_erasure_fec import ( + decode_fec_block, + decode_outer_symbol, +) +from protocol.priority_scheduler import ( + QueuedPacket, + ScheduleResult, + SchedulerMode, + schedule_packets, + transmission_duration_seconds, +) +from protocol.video_packet import ( + CompositeReassembler, + decode_packet as decode_inner_packet, +) +from tests.lab028_video_packetization import ( + COMPOSITE_FPS, + SOURCE_VIDEO_PATH, + EncodedComposite, + VideoMetadata, + load_video_profile, +) +from tests.lab029_packet_channel_simulation import prepare_profiles +from tests.lab030_packet_erasure_fec import ( + FECBlockPlan, + SourcePacket, + TransmissionUnit, + prepare_source_packets, +) +from tests.lab032_fec_parameter_sweep import ( + SweepMode, + build_parameter_units, +) + + +OUTPUT_DIRECTORY = Path("data/processed/lab033") +SUMMARY_CSV_PATH = OUTPUT_DIRECTORY / "lab033_summary.csv" +CLASS_CSV_PATH = OUTPUT_DIRECTORY / "lab033_class_metrics.csv" +REPORT_PATH = OUTPUT_DIRECTORY / "lab033_report.txt" +CONTROL_PLOT_PATH = OUTPUT_DIRECTORY / "lab033_control_delay.png" +EMERGENCY_PLOT_PATH = OUTPUT_DIRECTORY / "lab033_emergency_delay.png" +VIDEO_PLOT_PATH = OUTPUT_DIRECTORY / "lab033_video_delay.png" +QUEUE_PLOT_PATH = OUTPUT_DIRECTORY / "lab033_queue_length.png" +DEADLINE_PLOT_PATH = OUTPUT_DIRECTORY / "lab033_deadline_misses.png" +COMPARISON_PLOT_PATH = OUTPUT_DIRECTORY / "lab033_scheduler_comparison.png" +PLOT_PATHS = ( + CONTROL_PLOT_PATH, + EMERGENCY_PLOT_PATH, + VIDEO_PLOT_PATH, + QUEUE_PLOT_PATH, + DEADLINE_PLOT_PATH, + COMPARISON_PLOT_PATH, +) + +VIDEO_MODE = SweepMode("12+3", 12, 3, "12+3") +VIDEO_PAYLOAD_SIZE = 512 +CHANNEL_RATES_KBPS = (300.0, 260.0, 230.0) +SCHEDULER_MODES = ( + SchedulerMode.FIFO, + SchedulerMode.STRICT_PRIORITY, + SchedulerMode.LATEST_STATE, +) +CLASS_NAMES = { + TrafficClass.EMERGENCY: "аварийная команда", + TrafficClass.CONTROL: "обычные команды", + TrafficClass.TELEMETRY: "телеметрия", + TrafficClass.VIDEO: "видео", +} +MODE_NAMES = { + SchedulerMode.FIFO: "FIFO", + SchedulerMode.STRICT_PRIORITY: "Строгий приоритет", + SchedulerMode.LATEST_STATE: "Приоритет + замена", +} +STREAM_EMERGENCY = 1 +STREAM_CONTROL = 2 +STREAM_TELEMETRY = 3 +STREAM_VIDEO = 4 +CONTROL_PERIOD_US = 50_000 +TELEMETRY_PERIOD_US = 100_000 +EMERGENCY_TIME_US = 10_000_000 +TIME_EPSILON_SECONDS = 1e-9 + + +@dataclass(frozen=True) +class Workload: + metadata: VideoMetadata + composites: tuple[EncodedComposite, ...] + packets: tuple[QueuedPacket, ...] + video_units: tuple[TransmissionUnit, ...] + video_blocks: tuple[FECBlockPlan, ...] + total_jpeg_bytes: int + + +@dataclass(frozen=True) +class ClassMetrics: + channel_kbps: float + scheduler: str + traffic_class: str + offered_load_kbps: float + created_packets: int + transmitted_packets: int + replaced_packets: int + remaining_at_source_end_packets: int + mean_start_delay_ms: float + p95_start_delay_ms: float + max_start_delay_ms: float + mean_total_delay_ms: float + p95_total_delay_ms: float + max_total_delay_ms: float + deadline_misses: int + deadline_miss_fraction: float + mean_blocking_delay_ms: float + max_blocking_delay_ms: float + + +@dataclass(frozen=True) +class SimulationSummary: + channel_kbps: float + scheduler: str + offered_load_kbps: float + emergency_load_kbps: float + control_load_kbps: float + telemetry_load_kbps: float + video_load_kbps: float + service_share_percent: float + offered_to_capacity_ratio: float + transmitted_packets: int + transmitted_bytes: int + source_duration_seconds: float + drain_end_seconds: float + additional_drain_seconds: float + queue_at_source_end_packets: int + queue_at_source_end_bytes: float + mean_queue_packets: float + max_queue_packets: int + mean_queue_bytes: float + max_queue_bytes: int + control_mean_age_ms: float + control_p95_age_ms: float + control_max_age_ms: float + control_gaps_over_100ms: int + control_max_receive_gap_ms: float + control_replaced: int + emergency_start_delay_ms: float + emergency_total_delay_ms: float + emergency_deadline_met: bool + emergency_blocker_class: str + emergency_blocker_size_bytes: int + emergency_blocker_sequence: int + emergency_blocking_delay_ms: float + telemetry_mean_age_ms: float + telemetry_p95_age_ms: float + telemetry_max_age_ms: float + telemetry_misses_500ms: int + telemetry_miss_fraction: float + telemetry_replaced: int + video_published_at_source_end_fraction: float + video_published_after_drain_fraction: float + video_final_recovery_fraction: float + video_mean_publication_delay_ms: float + video_p95_publication_delay_ms: float + video_max_publication_delay_ms: float + video_mean_display_age_ms: float + video_p95_display_age_ms: float + video_max_display_age_ms: float + video_age_over_1s_fraction: float + video_late_frame_count: int + video_max_late_run: int + + +@dataclass(frozen=True) +class ScenarioResult: + summary: SimulationSummary + classes: tuple[ClassMetrics, ...] + schedule: ScheduleResult + publication_times: dict[int, float] + + +@dataclass(frozen=True) +class FunctionalTestResult: + name: str + passed: bool + detail: str + + +def percentile(values: Iterable[float], q: float) -> float: + values = tuple(values) + return float(np.percentile(values, q)) if values else 0.0 + + +def deterministic_payload(prefix: bytes, sequence: int, size: int) -> bytes: + """Build an exact-size reproducible educational payload.""" + + head = prefix[:8].ljust(8, b"\0") + struct.pack("!I", sequence) + tail = bytes((sequence * 37 + index * 17) & 0xFF for index in range(size)) + return (head + tail)[:size] + + +def _packet( + traffic_class: TrafficClass, + direction: Direction, + stream_id: int, + sequence: int, + generation_time_us: int, + deadline_ms: int, + payload: bytes, +) -> LinkPacket: + return LinkPacket( + traffic_class=traffic_class, + direction=direction, + stream_id=stream_id, + sequence_number=sequence, + generation_time_us=generation_time_us, + deadline_ms=deadline_ms, + payload=payload, + ) + + +def build_workload() -> Workload: + metadata, composites = load_video_profile(SOURCE_VIDEO_PATH) + profile = prepare_profiles(composites)[VIDEO_PAYLOAD_SIZE] + source_packets: tuple[SourcePacket, ...] = prepare_source_packets(profile) + video_units, video_blocks = build_parameter_units(source_packets, VIDEO_MODE) + candidates: list[LinkPacket] = [] + + duration_us = int(round(metadata.duration_seconds * 1_000_000.0)) + for sequence, generation_us in enumerate(range(0, duration_us, CONTROL_PERIOD_US)): + candidates.append( + _packet( + TrafficClass.CONTROL, + Direction.GROUND_TO_ROVER, + STREAM_CONTROL, + sequence, + generation_us, + 100, + deterministic_payload(b"CONTROL", sequence, 32), + ) + ) + for sequence, generation_us in enumerate(range(0, duration_us, TELEMETRY_PERIOD_US)): + candidates.append( + _packet( + TrafficClass.TELEMETRY, + Direction.ROVER_TO_GROUND, + STREAM_TELEMETRY, + sequence, + generation_us, + 500, + deterministic_payload(b"TELEM", sequence, 64), + ) + ) + if EMERGENCY_TIME_US < duration_us: + candidates.append( + _packet( + TrafficClass.EMERGENCY, + Direction.GROUND_TO_ROVER, + STREAM_EMERGENCY, + 0, + EMERGENCY_TIME_US, + 50, + deterministic_payload(b"E-STOP", 0, 32), + ) + ) + for unit in video_units: + candidates.append( + _packet( + TrafficClass.VIDEO, + Direction.ROVER_TO_GROUND, + STREAM_VIDEO, + unit.sequence_index, + int(round(unit.generation_time_seconds * 1_000_000.0)), + 0, + unit.wire_packet, + ) + ) + + # FIFO coincidence rule: class priority, stream_id, then sequence number. + candidates.sort( + key=lambda packet: ( + packet.generation_time_us, + int(packet.traffic_class), + packet.stream_id, + packet.sequence_number, + ) + ) + packets = tuple( + QueuedPacket(packet=packet, arrival_order=index) + for index, packet in enumerate(candidates) + ) + return Workload( + metadata=metadata, + composites=tuple(composites), + packets=packets, + video_units=video_units, + video_blocks=video_blocks, + total_jpeg_bytes=sum( + len(frame.base_jpeg) + len(frame.roi_jpeg) for frame in composites + ), + ) + + +def _class_items(workload: Workload, traffic_class: TrafficClass) -> tuple[QueuedPacket, ...]: + return tuple( + item for item in workload.packets + if item.packet.traffic_class is traffic_class + ) + + +def _wire_bytes(item: QueuedPacket) -> int: + return HEADER_SIZE + len(item.packet.payload) + + +def queue_metrics( + schedule: ScheduleResult, + source_end: float, +) -> tuple[float, int, float, int, int, float]: + """Time-weighted in-system queue metrics over the source interval.""" + + intervals: list[tuple[float, float, int]] = [] + for sent in schedule.transmitted: + intervals.append( + ( + sent.queued.generation_time_seconds, + sent.end_seconds, + _wire_bytes(sent.queued), + ) + ) + for replacement in schedule.replacements: + intervals.append( + ( + replacement.removed.generation_time_seconds, + replacement.replacement.generation_time_seconds, + _wire_bytes(replacement.removed), + ) + ) + packet_area = 0.0 + byte_area = 0.0 + events: dict[float, list[int]] = {} + for start, end, size in intervals: + clipped_start = max(0.0, start) + clipped_end = min(source_end, end) + if clipped_end <= clipped_start + TIME_EPSILON_SECONDS: + continue + packet_area += clipped_end - clipped_start + byte_area += (clipped_end - clipped_start) * size + delta = events.setdefault(clipped_start, [0, 0]) + delta[0] += 1 + delta[1] += size + delta = events.setdefault(clipped_end, [0, 0]) + delta[0] -= 1 + delta[1] -= size + packets_now = bytes_now = max_packets = max_bytes = 0 + for time_seconds in sorted(events): + packets_now += events[time_seconds][0] + bytes_now += events[time_seconds][1] + max_packets = max(max_packets, packets_now) + max_bytes = max(max_bytes, bytes_now) + + remaining = [ + sent for sent in schedule.transmitted + if sent.queued.generation_time_seconds <= source_end + TIME_EPSILON_SECONDS + and sent.end_seconds > source_end + TIME_EPSILON_SECONDS + ] + remaining_bytes = 0.0 + for sent in remaining: + if sent.start_seconds >= source_end: + remaining_bytes += _wire_bytes(sent.queued) + else: + remaining_bytes += ( + sent.end_seconds - source_end + ) * schedule.channel_bitrate_bps / 8.0 + return ( + packet_area / source_end, + max_packets, + byte_area / source_end, + max_bytes, + len(remaining), + remaining_bytes, + ) + + +def receive_video( + schedule: ScheduleResult, + frame_count: int, +) -> tuple[dict[int, float], int]: + """Unwrap both CRC layers and publish only complete BASE+ROI frames.""" + + receiver = CompositeReassembler() + publication_times: dict[int, float] = {} + block_symbols: dict[int, list[bytes]] = {} + decoded_blocks: set[int] = set() + for sent in schedule.transmitted: + link = decode_link_packet(sent.wire_packet) + if link.traffic_class is not TrafficClass.VIDEO: + continue + outer = decode_outer_symbol(link.payload) + symbols = block_symbols.setdefault(outer.block_id, []) + symbols.append(link.payload) + if not outer.is_parity: + completed = receiver.ingest(outer.data) + if completed is not None: + publication_times[completed.composite_frame_id] = sent.end_seconds + if outer.block_id not in decoded_blocks and len(symbols) >= outer.source_count: + decoded = decode_fec_block(tuple(symbols)) + for inner in decoded.source_packets: + decode_inner_packet(inner) + decoded_blocks.add(outer.block_id) + if len(publication_times) != frame_count: + raise AssertionError( + f"video receiver published {len(publication_times)} of {frame_count} frames" + ) + return publication_times, len(decoded_blocks) + + +def display_age_metrics( + publication_times: dict[int, float], + drain_end: float, +) -> tuple[float, float, float, float]: + events = sorted((time, frame_id) for frame_id, time in publication_times.items()) + sample_times = np.arange(0.0, drain_end + 0.005, 0.01) + ages = [] + event_index = 0 + last_frame_id: int | None = None + for sample_time in sample_times: + while event_index < len(events) and events[event_index][0] <= sample_time: + last_frame_id = events[event_index][1] + event_index += 1 + generation = 0.0 if last_frame_id is None else last_frame_id / COMPOSITE_FPS + ages.append(max(0.0, sample_time - generation)) + return ( + float(np.mean(ages)), + percentile(ages, 95), + max(ages, default=0.0), + sum(age > 1.0 for age in ages) / len(ages) if ages else 0.0, + ) + + +def max_true_run(flags: Iterable[bool]) -> int: + longest = current = 0 + for flag in flags: + current = current + 1 if flag else 0 + longest = max(longest, current) + return longest + + +def class_metrics( + workload: Workload, + schedule: ScheduleResult, + channel_kbps: float, + source_end: float, +) -> tuple[ClassMetrics, ...]: + rows = [] + for traffic_class in TrafficClass: + created = _class_items(workload, traffic_class) + sent = tuple( + record for record in schedule.transmitted + if record.queued.packet.traffic_class is traffic_class + ) + replaced = tuple( + item for item in schedule.replacements + if item.removed.packet.traffic_class is traffic_class + ) + start_delays = [ + record.start_seconds - record.queued.generation_time_seconds + for record in sent + ] + total_delays = [ + record.end_seconds - record.queued.generation_time_seconds + for record in sent + ] + blocking = [record.blocking_delay_seconds for record in sent] + deadline_misses = sum( + delay > record.queued.packet.deadline_ms / 1000.0 + TIME_EPSILON_SECONDS + for delay, record in zip(total_delays, sent) + if record.queued.packet.deadline_ms > 0 + ) + deadline_population = sum( + record.queued.packet.deadline_ms > 0 for record in sent + ) + rows.append( + ClassMetrics( + channel_kbps=channel_kbps, + scheduler=schedule.mode.value, + traffic_class=traffic_class.name.lower(), + offered_load_kbps=sum(_wire_bytes(item) for item in created) * 8.0 / source_end / 1000.0, + created_packets=len(created), + transmitted_packets=len(sent), + replaced_packets=len(replaced), + remaining_at_source_end_packets=sum( + record.end_seconds > source_end + TIME_EPSILON_SECONDS for record in sent + ), + mean_start_delay_ms=float(np.mean(start_delays)) * 1000.0 if start_delays else 0.0, + p95_start_delay_ms=percentile(start_delays, 95) * 1000.0, + max_start_delay_ms=max(start_delays, default=0.0) * 1000.0, + mean_total_delay_ms=float(np.mean(total_delays)) * 1000.0 if total_delays else 0.0, + p95_total_delay_ms=percentile(total_delays, 95) * 1000.0, + max_total_delay_ms=max(total_delays, default=0.0) * 1000.0, + deadline_misses=deadline_misses, + deadline_miss_fraction=deadline_misses / deadline_population if deadline_population else 0.0, + mean_blocking_delay_ms=float(np.mean(blocking)) * 1000.0 if blocking else 0.0, + max_blocking_delay_ms=max(blocking, default=0.0) * 1000.0, + ) + ) + return tuple(rows) + + +def simulate(workload: Workload, channel_kbps: float, mode: SchedulerMode) -> ScenarioResult: + bitrate = channel_kbps * 1000.0 + source_end = workload.metadata.duration_seconds + schedule = schedule_packets(workload.packets, mode, bitrate) + publication_times, decoded_blocks = receive_video( + schedule, len(workload.composites) + ) + if decoded_blocks != len(workload.video_blocks): + raise AssertionError("not every FEC block passed Lab030/Lab028 decoding") + classes = class_metrics(workload, schedule, channel_kbps, source_end) + by_class = { + TrafficClass[row.traffic_class.upper()]: row for row in classes + } + sent_by_class = { + traffic_class: tuple( + record for record in schedule.transmitted + if record.queued.packet.traffic_class is traffic_class + ) + for traffic_class in TrafficClass + } + load_by_class = { + traffic_class: sum(_wire_bytes(item) for item in _class_items(workload, traffic_class)) + * 8.0 / source_end / 1000.0 + for traffic_class in TrafficClass + } + offered_load = sum(load_by_class.values()) + useful_bytes = workload.total_jpeg_bytes + sum( + len(item.packet.payload) + for item in workload.packets + if item.packet.traffic_class is not TrafficClass.VIDEO + ) + proposed_wire_bytes = sum(_wire_bytes(item) for item in workload.packets) + service_share = 100.0 * (proposed_wire_bytes - useful_bytes) / proposed_wire_bytes + drain_end = max(record.end_seconds for record in schedule.transmitted) + mean_qp, max_qp, mean_qb, max_qb, queue_end_packets, queue_end_bytes = queue_metrics( + schedule, source_end + ) + + control = sent_by_class[TrafficClass.CONTROL] + control_ages = [record.end_seconds - record.queued.generation_time_seconds for record in control] + control_receive_times = [record.end_seconds for record in control] + control_gaps = [right - left for left, right in zip(control_receive_times, control_receive_times[1:])] + telemetry = sent_by_class[TrafficClass.TELEMETRY] + telemetry_ages = [record.end_seconds - record.queued.generation_time_seconds for record in telemetry] + emergency = sent_by_class[TrafficClass.EMERGENCY] + if len(emergency) != 1: + raise AssertionError("exactly one emergency command must be transmitted") + emergency_record = emergency[0] + blocker = emergency_record.blocked_by + + publication_delays = [ + publication_times[index] - index / COMPOSITE_FPS + for index in range(len(workload.composites)) + ] + late_flags = [delay > 1.0 for delay in publication_delays] + mean_age, p95_age, max_age, age_over_one = display_age_metrics( + publication_times, drain_end + ) + summary = SimulationSummary( + channel_kbps=channel_kbps, + scheduler=mode.value, + offered_load_kbps=offered_load, + emergency_load_kbps=load_by_class[TrafficClass.EMERGENCY], + control_load_kbps=load_by_class[TrafficClass.CONTROL], + telemetry_load_kbps=load_by_class[TrafficClass.TELEMETRY], + video_load_kbps=load_by_class[TrafficClass.VIDEO], + service_share_percent=service_share, + offered_to_capacity_ratio=offered_load / channel_kbps, + transmitted_packets=len(schedule.transmitted), + transmitted_bytes=sum(len(record.wire_packet) for record in schedule.transmitted), + source_duration_seconds=source_end, + drain_end_seconds=drain_end, + additional_drain_seconds=max(0.0, drain_end - source_end), + queue_at_source_end_packets=queue_end_packets, + queue_at_source_end_bytes=queue_end_bytes, + mean_queue_packets=mean_qp, + max_queue_packets=max_qp, + mean_queue_bytes=mean_qb, + max_queue_bytes=max_qb, + control_mean_age_ms=float(np.mean(control_ages)) * 1000.0, + control_p95_age_ms=percentile(control_ages, 95) * 1000.0, + control_max_age_ms=max(control_ages) * 1000.0, + control_gaps_over_100ms=sum(gap > 0.1 + TIME_EPSILON_SECONDS for gap in control_gaps), + control_max_receive_gap_ms=max(control_gaps, default=0.0) * 1000.0, + control_replaced=by_class[TrafficClass.CONTROL].replaced_packets, + emergency_start_delay_ms=(emergency_record.start_seconds - emergency_record.queued.generation_time_seconds) * 1000.0, + emergency_total_delay_ms=(emergency_record.end_seconds - emergency_record.queued.generation_time_seconds) * 1000.0, + emergency_deadline_met=(emergency_record.end_seconds - emergency_record.queued.generation_time_seconds) <= 0.05 + TIME_EPSILON_SECONDS, + emergency_blocker_class=blocker.packet.traffic_class.name.lower() if blocker else "none", + emergency_blocker_size_bytes=_wire_bytes(blocker) if blocker else 0, + emergency_blocker_sequence=blocker.packet.sequence_number if blocker else -1, + emergency_blocking_delay_ms=emergency_record.blocking_delay_seconds * 1000.0, + telemetry_mean_age_ms=float(np.mean(telemetry_ages)) * 1000.0, + telemetry_p95_age_ms=percentile(telemetry_ages, 95) * 1000.0, + telemetry_max_age_ms=max(telemetry_ages) * 1000.0, + telemetry_misses_500ms=sum(age > 0.5 + TIME_EPSILON_SECONDS for age in telemetry_ages), + telemetry_miss_fraction=sum(age > 0.5 + TIME_EPSILON_SECONDS for age in telemetry_ages) / len(telemetry_ages), + telemetry_replaced=by_class[TrafficClass.TELEMETRY].replaced_packets, + video_published_at_source_end_fraction=sum(time <= source_end + TIME_EPSILON_SECONDS for time in publication_times.values()) / len(workload.composites), + video_published_after_drain_fraction=sum(time <= drain_end + TIME_EPSILON_SECONDS for time in publication_times.values()) / len(workload.composites), + video_final_recovery_fraction=len(publication_times) / len(workload.composites), + video_mean_publication_delay_ms=float(np.mean(publication_delays)) * 1000.0, + video_p95_publication_delay_ms=percentile(publication_delays, 95) * 1000.0, + video_max_publication_delay_ms=max(publication_delays) * 1000.0, + video_mean_display_age_ms=mean_age * 1000.0, + video_p95_display_age_ms=p95_age * 1000.0, + video_max_display_age_ms=max_age * 1000.0, + video_age_over_1s_fraction=age_over_one, + video_late_frame_count=sum(late_flags), + video_max_late_run=max_true_run(late_flags), + ) + return ScenarioResult(summary, classes, schedule, publication_times) + + +def run_experiment(workload: Workload) -> tuple[ScenarioResult, ...]: + return tuple( + simulate(workload, rate, mode) + for rate in CHANNEL_RATES_KBPS + for mode in SCHEDULER_MODES + ) + + +def _synthetic_item( + traffic_class: TrafficClass, + sequence: int, + generation_us: int, + arrival_order: int, + payload_size: int = 32, + stream_id: int | None = None, +) -> QueuedPacket: + direction = ( + Direction.GROUND_TO_ROVER + if traffic_class in (TrafficClass.EMERGENCY, TrafficClass.CONTROL) + else Direction.ROVER_TO_GROUND + ) + return QueuedPacket( + _packet( + traffic_class, + direction, + int(traffic_class) if stream_id is None else stream_id, + sequence, + generation_us, + 100, + deterministic_payload(b"TEST", sequence, payload_size), + ), + arrival_order, + ) + + +def run_functional_tests( + workload: Workload, + results: tuple[ScenarioResult, ...], +) -> tuple[FunctionalTestResult, ...]: + checks: list[tuple[str, callable]] = [] + + def add(name: str): + def decorator(function): + checks.append((name, function)) + return function + return decorator + + sample = next(item for item in workload.packets if item.packet.traffic_class is TrafficClass.VIDEO) + + @add("01_header_roundtrip") + def _(): + decoded = decode_link_packet(encode_link_packet(sample.packet)) + assert decoded == LinkPacket(**{**asdict(sample.packet), "packet_crc32": decoded.packet_crc32}) + + @add("02_header_crc_detection") + def _(): + wire = bytearray(encode_link_packet(sample.packet)); wire[11] ^= 1 + try: decode_link_packet(wire) + except LinkPacketCRCError: return + raise AssertionError("header corruption was accepted") + + @add("03_payload_crc_detection") + def _(): + wire = bytearray(encode_link_packet(sample.packet)); wire[-1] ^= 1 + try: decode_link_packet(wire) + except LinkPacketCRCError: return + raise AssertionError("payload corruption was accepted") + + @add("04_video_wrapper_byte_exact") + def _(): + assert decode_link_packet(encode_link_packet(sample.packet)).payload == sample.packet.payload + + @add("05_lab030_crc") + def _(): + decode_outer_symbol(decode_link_packet(encode_link_packet(sample.packet)).payload) + + @add("06_lab028_crc") + def _(): + systematic = next(unit for unit in workload.video_units if not unit.is_parity) + decode_inner_packet(decode_outer_symbol(systematic.wire_packet).data) + + @add("07_fifo_global_order") + def _(): + items = (_synthetic_item(TrafficClass.VIDEO, 0, 0, 0, 1000), _synthetic_item(TrafficClass.EMERGENCY, 0, 1, 1)) + order = schedule_packets(items, SchedulerMode.FIFO, 100_000).transmitted + assert [item.queued.arrival_order for item in order] == [0, 1] + + @add("08_strict_priority") + def _(): + items = tuple(_synthetic_item(cls, 0, 0, index) for index, cls in enumerate((TrafficClass.VIDEO, TrafficClass.TELEMETRY, TrafficClass.CONTROL, TrafficClass.EMERGENCY))) + order = schedule_packets(items, SchedulerMode.STRICT_PRIORITY, 100_000).transmitted + assert [item.queued.packet.traffic_class for item in order] == list(TrafficClass) + + @add("09_non_preemptive") + def _(): + items = (_synthetic_item(TrafficClass.VIDEO, 0, 0, 0, 1000), _synthetic_item(TrafficClass.EMERGENCY, 0, 1, 1)) + order = schedule_packets(items, SchedulerMode.STRICT_PRIORITY, 100_000).transmitted + assert order[0].queued.packet.traffic_class is TrafficClass.VIDEO + assert order[1].start_seconds >= order[0].end_seconds - TIME_EPSILON_SECONDS + + @add("10_intra_class_sequence") + def _(): + items = tuple(_synthetic_item(TrafficClass.CONTROL, index, 0, index) for index in range(4)) + order = schedule_packets(items, SchedulerMode.STRICT_PRIORITY, 100_000).transmitted + assert [item.queued.packet.sequence_number for item in order] == list(range(4)) + + @add("11_latest_state_scope") + def _(): + items = ( + _synthetic_item(TrafficClass.VIDEO, 0, 0, 0, 1000), + _synthetic_item(TrafficClass.CONTROL, 0, 1, 1, stream_id=20), + _synthetic_item(TrafficClass.CONTROL, 1, 2, 2, stream_id=20), + _synthetic_item(TrafficClass.CONTROL, 2, 3, 3, stream_id=21), + _synthetic_item(TrafficClass.TELEMETRY, 0, 4, 4, stream_id=30), + _synthetic_item(TrafficClass.TELEMETRY, 1, 5, 5, stream_id=30), + ) + result = schedule_packets(items, SchedulerMode.LATEST_STATE, 100_000) + removed = {(x.removed.packet.traffic_class, x.removed.packet.stream_id, x.removed.packet.sequence_number) for x in result.replacements} + assert removed == {(TrafficClass.CONTROL, 20, 0), (TrafficClass.TELEMETRY, 30, 0)} + + @add("12_active_state_not_removed") + def _(): + items = (_synthetic_item(TrafficClass.CONTROL, 0, 0, 0, 1000), _synthetic_item(TrafficClass.CONTROL, 1, 1, 1)) + result = schedule_packets(items, SchedulerMode.LATEST_STATE, 100_000) + assert len(result.transmitted) == 2 and not result.replacements + + @add("13_emergency_never_replaced") + def _(): + items = (_synthetic_item(TrafficClass.VIDEO, 0, 0, 0, 1000), _synthetic_item(TrafficClass.EMERGENCY, 0, 1, 1), _synthetic_item(TrafficClass.EMERGENCY, 1, 2, 2)) + result = schedule_packets(items, SchedulerMode.LATEST_STATE, 100_000) + assert sum(x.queued.packet.traffic_class is TrafficClass.EMERGENCY for x in result.transmitted) == 2 + + @add("14_300kbps_all_video") + def _(): + assert all(r.summary.video_final_recovery_fraction == 1.0 for r in results if r.summary.channel_kbps == 300.0) + + @add("15_overload_visible") + def _(): + low = [r.summary for r in results if r.summary.channel_kbps == 230.0] + assert any(r.queue_at_source_end_packets > 0 and r.additional_drain_seconds > 0 for r in low) + + @add("16_exact_transmission_duration") + def _(): + assert abs(transmission_duration_seconds(123, 230_000) - 984 / 230_000) < 1e-15 + + @add("17_total_bits_accounting") + def _(): + for result in results: + assert result.summary.transmitted_bytes * 8 == sum(len(x.wire_packet) * 8 for x in result.schedule.transmitted) + + @add("18_reproducible_schedule") + def _(): + original = results[0].schedule + repeated = schedule_packets(workload.packets, original.mode, original.channel_bitrate_bps) + assert [(x.queued.arrival_order, x.start_seconds, x.end_seconds) for x in original.transmitted] == [(x.queued.arrival_order, x.start_seconds, x.end_seconds) for x in repeated.transmitted] + + @add("19_no_video_control_isolated") + def _(): + items = tuple(_synthetic_item(TrafficClass.CONTROL, index, index * CONTROL_PERIOD_US, index) for index in range(20)) + result = schedule_packets(items, SchedulerMode.STRICT_PRIORITY, 300_000) + assert max(x.end_seconds - x.queued.generation_time_seconds for x in result.transmitted) < 0.1 + + @add("20_latest_state_reaches_receiver") + def _(): + latest = next(r for r in results if r.summary.channel_kbps == 230.0 and r.summary.scheduler == SchedulerMode.LATEST_STATE.value) + for cls in (TrafficClass.CONTROL, TrafficClass.TELEMETRY): + created_last = max(item.packet.sequence_number for item in _class_items(workload, cls)) + sent_last = max(item.queued.packet.sequence_number for item in latest.schedule.transmitted if item.queued.packet.traffic_class is cls) + assert sent_last == created_last + + output = [] + for name, function in checks: + try: + function() + output.append(FunctionalTestResult(name, True, "PASS")) + except Exception as error: + output.append(FunctionalTestResult(name, False, f"{type(error).__name__}: {error}")) + if not all(item.passed for item in output): + failed = ", ".join(item.name for item in output if not item.passed) + raise AssertionError(f"functional checks failed: {failed}") + return tuple(output) + + +def save_csv(results: tuple[ScenarioResult, ...]) -> None: + OUTPUT_DIRECTORY.mkdir(parents=True, exist_ok=True) + with SUMMARY_CSV_PATH.open("w", newline="", encoding="utf-8") as file: + writer = csv.DictWriter(file, fieldnames=list(SimulationSummary.__dataclass_fields__)) + writer.writeheader() + writer.writerows(asdict(result.summary) for result in results) + with CLASS_CSV_PATH.open("w", newline="", encoding="utf-8") as file: + writer = csv.DictWriter(file, fieldnames=list(ClassMetrics.__dataclass_fields__)) + writer.writeheader() + writer.writerows(asdict(row) for result in results for row in result.classes) + + +def _grouped_plot( + results: tuple[ScenarioResult, ...], + values, + ylabel: str, + title: str, + path: Path, +) -> None: + x = np.arange(len(CHANNEL_RATES_KBPS)); width = 0.24 + fig, axis = plt.subplots(figsize=(10, 5.5)) + for index, mode in enumerate(SCHEDULER_MODES): + subset = [r for r in results if r.summary.scheduler == mode.value] + axis.bar(x + (index - 1) * width, [values(r.summary) for r in subset], width, label=MODE_NAMES[mode]) + axis.set_xticks(x, [f"{rate:.0f}" for rate in CHANNEL_RATES_KBPS]) + axis.set_xlabel("Скорость общего канала, кбит/с") + axis.set_ylabel(ylabel); axis.set_title(title); axis.grid(axis="y", alpha=0.3); axis.legend() + fig.tight_layout(); fig.savefig(path, dpi=150); plt.close(fig) + + +def save_plots(results: tuple[ScenarioResult, ...]) -> None: + _grouped_plot(results, lambda x: x.control_p95_age_ms, "P95 полной задержки, мс", "Задержка обычных команд", CONTROL_PLOT_PATH) + _grouped_plot(results, lambda x: x.emergency_total_delay_ms, "Полная задержка, мс", "Задержка аварийной команды", EMERGENCY_PLOT_PATH) + _grouped_plot(results, lambda x: x.video_p95_publication_delay_ms, "P95 задержки, мс", "Задержка публикации видео", VIDEO_PLOT_PATH) + _grouped_plot(results, lambda x: x.max_queue_packets, "Максимум, пакетов", "Длина общей очереди", QUEUE_PLOT_PATH) + _grouped_plot(results, lambda x: sum(row.deadline_misses for row in next(r.classes for r in results if r.summary is x)), "Число превышений", "Превышения допустимых сроков", DEADLINE_PLOT_PATH) + + fig, axes = plt.subplots(1, 2, figsize=(12, 5)) + for mode in SCHEDULER_MODES: + subset = [r.summary for r in results if r.summary.scheduler == mode.value] + axes[0].plot(CHANNEL_RATES_KBPS, [r.control_p95_age_ms for r in subset], marker="o", label=MODE_NAMES[mode]) + axes[1].plot(CHANNEL_RATES_KBPS, [r.additional_drain_seconds for r in subset], marker="o", label=MODE_NAMES[mode]) + axes[0].set_ylabel("P95 команд, мс"); axes[1].set_ylabel("Освобождение после видео, с") + for axis in axes: + axis.set_xlabel("Скорость, кбит/с"); axis.grid(alpha=0.3); axis.invert_xaxis() + axes[0].legend(); fig.suptitle("Сравнение планировщиков"); fig.tight_layout(); fig.savefig(COMPARISON_PLOT_PATH, dpi=150); plt.close(fig) + + +def write_report( + workload: Workload, + results: tuple[ScenarioResult, ...], + tests: tuple[FunctionalTestResult, ...], +) -> None: + first = results[0].summary + git_root = subprocess.run( + ("git", "rev-parse", "--show-toplevel"), + check=True, + capture_output=True, + text=True, + encoding="utf-8", + ).stdout.strip() + git_branch = subprocess.run( + ("git", "branch", "--show-current"), + check=True, + capture_output=True, + text=True, + encoding="utf-8", + ).stdout.strip() + git_head = subprocess.run( + ("git", "rev-parse", "HEAD"), + check=True, + capture_output=True, + text=True, + encoding="utf-8", + ).stdout.strip() + git_status = subprocess.run( + ("git", "status", "--short", "--branch"), + check=True, + capture_output=True, + text=True, + encoding="utf-8", + ).stdout.rstrip() + external_video_kbps = ( + sum(len(unit.wire_packet) for unit in workload.video_units) + * 8.0 + / workload.metadata.duration_seconds + / 1000.0 + ) + lines = [ + "Lab033. Общий пакет канала и приоритетное обслуживание", + "", + "1. Git и конфигурация", + f"- Git-корень: {git_root}.", + f"- Ветка: {git_branch}; HEAD: {git_head}.", + f"- Исходное видео: {workload.metadata.duration_seconds:.6f} с, {len(workload.composites)} составных кадров, {COMPOSITE_FPS:.0f} кадра/с.", + "- BASE 240x135 grayscale JPEG Q23; ROI 320x180 grayscale JPEG Q33.", + "- Lab028: payload 512 байт; Lab030: FEC 12+3; Lab031: D=1.", + f"- Фактический внешний видеопоток до Lab033: {external_video_kbps:.3f} кбит/с; с общим заголовком: {first.video_load_kbps:.3f} кбит/с.", + f"- Аварийная команда: {first.emergency_load_kbps:.6f}; обычные команды: {first.control_load_kbps:.3f}; телеметрия: {first.telemetry_load_kbps:.3f} кбит/с.", + f"- Общая предложенная нагрузка: {first.offered_load_kbps:.3f} кбит/с; суммарная служебная доля: {first.service_share_percent:.3f}%.", + "", + "2. Формат общего заголовка", + f"- struct: {HEADER_FORMAT}; размер: {HEADER_SIZE} байта; network byte order, неявного padding нет.", + "- Смещения: magic[4]@0, version:u8@4, traffic_class:u8@5, direction:u8@6, flags:u8@7, stream_id:u16@8, sequence_number:u32@10, generation_time_us:u64@14, deadline_ms:u16@22, payload_length:u32@24, packet_crc32:u32@28.", + "- traffic_class: 1=EMERGENCY, 2=CONTROL, 3=TELEMETRY, 4=VIDEO; direction: 1=GROUND_TO_ROVER, 2=ROVER_TO_GROUND; flags в версии 1 равен нулю.", + "- CRC32 защищает заголовок с нулевым packet_crc32 и всю полезную нагрузку.", + "", + "3. Девять сочетаний скорости и планировщика", + "speed | scheduler | offered/capacity | control P95 ms | emergency ms | telemetry P95 ms | video P95 ms | queue@end packets | drain extra s | final video", + ] + for result in results: + row = result.summary + lines.append( + f"{row.channel_kbps:.0f} | {MODE_NAMES[SchedulerMode(row.scheduler)]} | {row.offered_to_capacity_ratio:.4f} | {row.control_p95_age_ms:.3f} | {row.emergency_total_delay_ms:.3f} | {row.telemetry_p95_age_ms:.3f} | {row.video_p95_publication_delay_ms:.3f} | {row.queue_at_source_end_packets} | {row.additional_drain_seconds:.6f} | {row.video_final_recovery_fraction:.6f}" + ) + lines.extend([ + "", + "4. Подробные показатели", + ]) + for result in results: + row = result.summary + class_rows = {item.traffic_class: item for item in result.classes} + lines.extend([ + f"[{row.channel_kbps:.0f} кбит/с; {MODE_NAMES[SchedulerMode(row.scheduler)]}]", + f"- Передано {row.transmitted_packets} пакетов, {row.transmitted_bytes} байт; средняя/максимальная очередь {row.mean_queue_packets:.3f}/{row.max_queue_packets} пакетов и {row.mean_queue_bytes:.1f}/{row.max_queue_bytes} байт.", + f"- На конце видео: {row.queue_at_source_end_packets} пакетов, {row.queue_at_source_end_bytes:.1f} байт; полное освобождение {row.drain_end_seconds:.6f} с, дополнительно {row.additional_drain_seconds:.6f} с.", + f"- Команды: mean/P95/max {row.control_mean_age_ms:.3f}/{row.control_p95_age_ms:.3f}/{row.control_max_age_ms:.3f} мс; превышений 100 мс {class_rows['control'].deadline_misses}; промежутков >100 мс {row.control_gaps_over_100ms}; max gap {row.control_max_receive_gap_ms:.3f} мс; заменено {row.control_replaced}.", + f"- Аварийная команда: start/total {row.emergency_start_delay_ms:.3f}/{row.emergency_total_delay_ms:.3f} мс; deadline 50 мс {'соблюдён' if row.emergency_deadline_met else 'НАРУШЕН'}; блокировал {row.emergency_blocker_class}, {row.emergency_blocker_size_bytes} байт, seq={row.emergency_blocker_sequence}, ожидание {row.emergency_blocking_delay_ms:.3f} мс.", + f"- Телеметрия: mean/P95/max {row.telemetry_mean_age_ms:.3f}/{row.telemetry_p95_age_ms:.3f}/{row.telemetry_max_age_ms:.3f} мс; превышений 500 мс {row.telemetry_misses_500ms} ({row.telemetry_miss_fraction:.6f}); заменено {row.telemetry_replaced}.", + f"- Видео: опубликовано к концу источника {row.video_published_at_source_end_fraction:.6f}, после drain {row.video_published_after_drain_fraction:.6f}, итог {row.video_final_recovery_fraction:.6f}; delay mean/P95/max {row.video_mean_publication_delay_ms:.3f}/{row.video_p95_publication_delay_ms:.3f}/{row.video_max_publication_delay_ms:.3f} мс.", + f"- Возраст изображения mean/P95/max {row.video_mean_display_age_ms:.3f}/{row.video_p95_display_age_ms:.3f}/{row.video_max_display_age_ms:.3f} мс; доля >1 с {row.video_age_over_1s_fraction:.6f}; поздних кадров {row.video_late_frame_count}, max серия {row.video_max_late_run}.", + ]) + lines.extend([ + "", + "5. Интерпретация планировщиков", + "- FIFO задерживает команды, потому что все ранее поступившие внешние видеопакеты остаются перед ними независимо от срочности.", + "- Строгий приоритет после каждого окончания пакета выбирает управление раньше телеметрии и видео, поэтому сокращает очередь команд.", + "- Уже начатая передача не прерывается: модель сериализует целый пакет как атомарную единицу и не задаёт фрагментацию общего пакета или возобновление передачи.", + "- Поэтому нижняя граница задержки срочной команды включает остаток времени самого длинного пакета, уже занявшего ресурс.", + "- Замена старого состояния новым не тратит канал на запоздалую команду, которая к моменту приёма уже не отражает актуальное управление.", + "- Строгий приоритет перераспределяет порядок, но не уменьшает объём видео; при нагрузке выше пропускной способности видеопакеты продолжают накапливаться.", + "- Длинная очередь видео увеличивает возраст изображения даже без потерь: полные, но старые кадры публикуются позже времени формирования.", + "- Восстановление 100% кадров после drain подтверждает целостность, но не пригодность задержек канала для управления в реальном времени.", + "", + "6. Допущения модели", + "- Один общий абстрактный ресурс и одна расчётная скорость для обоих направлений; переключение направления не задерживает передачу.", + "- Не выбран физический полудуплекс/дуплекс, TDD/FDD, модуляция, ретранслятор или физическое разделение восходящего и нисходящего каналов.", + "- Ошибки и помехи отсутствуют; полностью переданный пакет доставляется без повреждений; видеопакеты не отбрасываются по возрасту.", + "- После конца исходного видео новые данные не создаются, а очередь полностью освобождается.", + "- При совпадении времени FIFO использует traffic_class, stream_id и sequence_number как устойчивое правило разрешения совпадений.", + "- Средняя очередь рассчитана по времени на основном интервале и включает пакет, находящийся в передатчике; остаток байтов активного пакета учитывается пропорционально недопереданному времени.", + "", + "7. Функциональные проверки", + ]) + lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests) + lines.extend([ + "", + "8. Созданные файлы и итоговый Git status", + "- protocol/link_packet.py", + "- protocol/priority_scheduler.py", + "- tests/lab033_priority_channel_scheduler.py", + "- data/processed/lab033/lab033_summary.csv", + "- data/processed/lab033/lab033_class_metrics.csv", + "- data/processed/lab033/lab033_report.txt", + ]) + lines.extend(f"- data/processed/lab033/{path.name}" for path in PLOT_PATHS) + lines.extend([ + "- Lab028-Lab032 и их сохранённые результаты не изменены.", + "- Lab033 не добавлена в индекс и не закоммичена.", + "", + git_status, + ]) + REPORT_PATH.write_text("\n".join(lines) + "\n", encoding="utf-8") + + +def validate_outputs() -> None: + for path, expected_rows in ((SUMMARY_CSV_PATH, 9), (CLASS_CSV_PATH, 36)): + with path.open("r", newline="", encoding="utf-8") as file: + rows = list(csv.DictReader(file)) + if len(rows) != expected_rows or not rows or any(set(rows[0]) != set(row) for row in rows): + raise AssertionError(f"invalid CSV output: {path}") + text = REPORT_PATH.read_text(encoding="utf-8") + if "Lab033" not in text or "Функциональные проверки" not in text: + raise AssertionError("report validation failed") + for path in PLOT_PATHS: + image = cv2.imread(str(path), cv2.IMREAD_UNCHANGED) + if image is None or image.size == 0: + raise AssertionError(f"OpenCV could not read {path}") + + +def main() -> None: + workload = build_workload() + results = run_experiment(workload) + tests = run_functional_tests(workload, results) + save_csv(results) + save_plots(results) + write_report(workload, results, tests) + validate_outputs() + print( + f"Lab033 complete: {len(results)} scenarios, " + f"{len(tests)} functional checks, " + f"{len(workload.composites)} video frames" + ) + + +if __name__ == "__main__": + main()