Расчёт вероятности ошибки для AX.25

Введение

Обычно вероятность ошибки используется для сравнения различных типов модуляции между собой. Однако, на практике помимо демодулятора используются дополнительные блоки:

И каждый из этих блоков может как уменьшить вероятность декодирования фрейма, так и увеличить. Все алгоритмы контроля и коррекции ошибок предназначены для того, чтобы увеличить вероятность декодирования фрейма. А вот формирование самих фреймов может сильно повлиять на возможности получения данных.

Одним из самых распространённых протоколов канального уровня является HDLC. Также он используется в стеке AX.25, который в свою очередь используется в большинстве кубсатов для связи с наземными станциями. Увеличение количества принимаемых данных из космоса - одна из основных задач моего проекта r2cloud, поэтому мне интересно было померить насколько AX.25 хорош.

Описание стенда

Итак, для того, чтобы посчитать количество ошибочно принятых бит, я создал класс Ax25G3ruhBer. Он работает следующим образом:

  • для каждого Eb/No
  • сгенерировать паузу, равную sampleRate / 8. Во время паузы в демодулятор будет приходить только белый гауссовский шум.
  • сформировать фрейм, смодулировать его в GMSK сигнал
  • добавить к GMSK сигналу шум
  • сгенерировать шум и полезный сигнал для оставшихся 99 фреймов.
  • пропустить полученный сигнал через демодулятор
  • посчитать количество успешных бит из общего количество переданных бит.

Этот алгоритм значительно проще, чем алгоритм вычисления ошибки для FSK, так как количество переданных и полученных бит легко посчитать.

Результаты

Результаты представлены на графике ниже. Я так же добавил теоретический минимум FSK модуляции. Так как AX.25 зачастую используется поверх FSK модуляции и в нём нет блоков коррекции ошибок, то его теоретический минимум не может быть меньше минимума FSK.

Анализ

Многие графики обрываются. Это может значить несколько вещей:

  • Либо не было проведено достаточно симуляций, чтобы получить статистически значимых результатов
  • Либо ошибки в тесте. AX.25 не может быть лучше теоретического предела FSK модуляции

BER кривая FSK вычислялась по формуле. Её результат записывался во float, поэтому очень маленькие значения просто округлились до 0. Это объясняет, почему жёлтая кривая обрывается.

Опыты, в которых была проверка контрольной суммы, при низком уровне сигнала совсем не декодируются, а начиная с какого-то значения декодируются все. Это вполне объяснимо, так как ошибка даже в одном бите детектируется контрольной суммой и весь фрейм отбрасывается. При этом опыты, в которых проверка контрольной суммы отключена, показывают плавное уменьшение количества ошибок. Это вполне ожидаемо и как раз показывает, что демодулятор распознаёт фреймы, но они отбрасываются из-за ошибок контрольной суммы.

Ещё интересный и очевидный факт - количество декодируемых фреймов зависит от их длины. Для длины в 20 байт минимальный уровень сигнала должен быть 9дБ, а для 131 байт - 11дБ. 131 байт я взял не случайно, а вычислил на основе средней длины AX.25 фрейма всех поддерживаемых спутников в jradio.

Резкий переход между ни одним полученным фреймом и всеми полученными фреймами, мне показался достаточно странным. Я попробовал построить спектограмму сигнала для первых 10 фреймов:

Оказывается, шум на самом деле не настоящий. Вернее он настоящий, но из-за того, что блок генерации шума стартует всегда с одного и того же seed, получается, что шум повторяется через какие-то интервалы. Это как раз видно на спектограмме - повторяющиеся паттерны:

Результаты 2

Я решил провести ещё раз опыт на основе полученных результатов со следующими модификациями:

  • выбрать разный начальный seed псевдослучайного генератора
  • добавить 3 байта преамбулы - 0xAA для того, чтобы синхронизировать демодулятор и скрэмблер

Анализ 2

  • графики ожидаемо хуже теоретического минимума FSK модуляции.
  • При Eb/N0=13дБ фреймы лучше не декодируются.
  • размер фрейма перестал влиять на результаты.

Судя по результатам теста, демодулятор работает не так как ожидается. При полном отсутствии шума, все фреймы должны были декодироваться, ну или большая их часть. А в моём случае совсем наоборот.

Результаты 3

Одной из причин такого поведения может быть внутреннее состояние демодулятора. Внутри демодулятора есть множество циклов обратной связи. Эти циклы корректируют поведение блоков в зависимости от выходных данных. Внутри каждого цикла есть некое состояние, которое описывает обратную связь. Если на вход демодулятора подаётся шум, то такой цикл обратной связи будет находится в “свободном поиске” и внутреннее состояние может плавать от +Х до -Х. Если же, сигнал, то цикл будет стремится к некоему локальному минимуму и состояние будет стремится к какому-нибудь числу. В итоге он достигнет равновесия и будет корректировать выходные данные. Но время, которое нужно для того, чтобы цикл пришёл в нужное равновесие лежит в каком-то интервале. Собственно, передавая достаточно длинную преамбулу в начале каждого пакета, можно заставить демодулятор синхронизироваться с потоком данных и улучшить декодирование.

Я попробовал преамбулы нескольких длин: 3, 6 и 9 байт. Каждый байт такой преамбулы - это 0x7e. В итоге получилось следующее:

Анализ 3

На графике явно видно, что, чем длиннее преамбула, тем больше данных декодировано. Преамбула длиной 9 байт показывает наилучшие показатели.

По-прежнему демодулятор не может приблизится к теоретическому пределу FSK, хотя кривые в чём-то повторяют BER кривую теории.