Lab033: add priority link scheduler

This commit is contained in:
LittleSam129
2026-08-03 12:21:49 +03:00
parent 3dbb7afa83
commit 21751f41dd
13 changed files with 1697 additions and 0 deletions

View File

@@ -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.
- Следующий этап посвящён отбрасыванию устаревших видеокадров.

View File

@@ -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
1 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
2 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
3 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
4 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
5 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
6 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
7 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
8 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
9 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
10 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
11 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
12 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
13 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
14 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
15 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
16 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
17 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
18 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
19 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
20 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
21 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
22 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
23 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
24 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
25 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
26 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
27 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
28 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
29 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
30 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
31 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
32 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
33 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
34 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
35 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
36 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
37 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,165 @@
Lab033. Общий пакет канала и приоритетное обслуживание
1. Git и конфигурация
- Git-корень: C:/Users/user/Desktop/projects/SDR_Rover.
- Ветка: main; HEAD: 3dbb7afa8332b49535d867f1eabca7bdd2b7cdde.
- Исходное видео: 20.766667 с, 63 составных кадров, 3 кадра/с.
- BASE 240x135 grayscale JPEG Q23; ROI 320x180 grayscale JPEG Q33.
- Lab028: payload 512 байт; Lab030: FEC 12+3; Lab031: D=1.
- Фактический внешний видеопоток до Lab033: 226.951 кбит/с; с общим заголовком: 240.240 кбит/с.
- Аварийная команда: 0.024655; обычные команды: 10.256; телеметрия: 7.692 кбит/с.
- Общая предложенная нагрузка: 258.214 кбит/с; суммарная служебная доля: 34.923%.
2. Формат общего заголовка
- struct: !4sBBBBHIQHII; размер: 32 байта; 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
300 | FIFO | 0.8607 | 238.634 | 1.707 | 233.680 | 304.579 | 18 | 0.231867 | 1.000000
300 | Строгий приоритет | 0.8607 | 17.466 | 1.707 | 20.107 | 322.072 | 15 | 0.231867 | 1.000000
300 | Приоритет + замена | 0.8607 | 17.466 | 1.707 | 20.107 | 322.072 | 15 | 0.231867 | 1.000000
260 | FIFO | 0.9931 | 333.059 | 1.969 | 331.782 | 420.025 | 32 | 0.399200 | 1.000000
260 | Строгий приоритет | 0.9931 | 18.754 | 1.969 | 22.448 | 445.846 | 23 | 0.399200 | 1.000000
260 | Приоритет + замена | 0.9931 | 18.754 | 1.969 | 22.448 | 445.846 | 23 | 0.399200 | 1.000000
230 | FIFO | 1.1227 | 2240.535 | 881.113 | 2225.607 | 2417.731 | 181 | 2.547420 | 1.000000
230 | Строгий приоритет | 1.1227 | 21.848 | 11.548 | 25.111 | 2505.995 | 127 | 2.547420 | 1.000000
230 | Приоритет + замена | 1.1227 | 21.848 | 11.548 | 25.111 | 2505.995 | 127 | 2.547420 | 1.000000
4. Подробные показатели
[300 кбит/с; FIFO]
- Передано 1703 пакетов, 670280 байт; средняя/максимальная очередь 10.478/22 пакетов и 4452.4/12221 байт.
- На конце видео: 18 пакетов, 8695.0 байт; полное освобождение 20.998534 с, дополнительно 0.231867 с.
- Команды: mean/P95/max 106.072/238.634/296.186 мс; превышений 100 мс 203; промежутков >100 мс 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@@ -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
1 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
2 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
3 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
4 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
5 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
6 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
7 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
8 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
9 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
10 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

195
protocol/link_packet.py Normal file
View File

@@ -0,0 +1,195 @@
"""Common Lab033 link packet shared by commands, telemetry, and video.
The fixed 32-byte header uses network byte order and no implicit padding::
!4sBBBBHIQHII
Offset Size Field
0 4 magic (b"SLP1")
4 1 version
5 1 traffic_class
6 1 direction
7 1 flags
8 2 stream_id
10 4 sequence_number
14 8 generation_time_us
22 2 deadline_ms
24 4 payload_length
28 4 packet_crc32
``packet_crc32`` is IEEE CRC32 over the complete header with that field set
to zero, followed by the complete payload.
"""
from __future__ import annotations
from dataclasses import dataclass, replace
from enum import IntEnum
import struct
import zlib
MAGIC = b"SLP1"
VERSION = 1
HEADER_FORMAT = "!4sBBBBHIQHII"
HEADER_SIZE = struct.calcsize(HEADER_FORMAT)
SUPPORTED_FLAGS_MASK = 0
class TrafficClass(IntEnum):
"""Traffic classes in descending scheduling priority."""
EMERGENCY = 1
CONTROL = 2
TELEMETRY = 3
VIDEO = 4
class Direction(IntEnum):
"""Logical direction of a packet on the shared modelled resource."""
GROUND_TO_ROVER = 1
ROVER_TO_GROUND = 2
class LinkPacketError(ValueError):
"""Base class for malformed Lab033 link packets."""
class LinkPacketCRCError(LinkPacketError):
"""The Lab033 packet header or payload failed CRC32 validation."""
@dataclass(frozen=True)
class LinkPacket:
"""Decoded common packet, including its CRC-validated payload."""
traffic_class: TrafficClass
direction: Direction
stream_id: int
sequence_number: int
generation_time_us: int
deadline_ms: int
payload: bytes
flags: int = 0
version: int = VERSION
packet_crc32: int = 0
def crc32(data: bytes) -> 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

View File

@@ -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),
)

File diff suppressed because it is too large Load Diff