Наверное каждый, кто хоть немного интересовался радиосвязью и радиолюбительством, слышал о цифровом протоколе связи FT8. Этот вид связи появился в 2017, и с тех пор его популярность только растет.
Источник фото: www.qsl.net/w1dyj/FT8%20for%20web.pdf
Для тех кому интересно, как это работает и зачем это нужно, продолжение под катом.
История
Для тех, кто далек от любительской радиосвязи, краткая историческая справка.
Первые самодельные, а позже и покупные, любительские радиостанции появились примерно 100 лет назад. Единственный сигнал, который они могли принимать и передавать, был простой тон, а передача шла с помощью кода Морзе. Разумеется, предварительно нужно было научиться принимать CW на слух, сей скилл кстати был востребован довольно долго не только у любителей, но и у профи, профессия радиста на флоте была отменена вроде бы только в 60х. Разумеется, была определенная романтика в приеме слабых сигналов на фоне шумов эфира, именно так простой деревенский радиолюбитель из Костромской области сумел в 1928г принять сигнал SOS от терпящей бедствие команды дирижабля Умберто Нобиле.
Следующим шагом была голосовая связь — передача голоса с помощью микрофона в однополосной модуляции сделала радиосвязь более удобной. Такой способ используется и до сих пор.
Наконец, где-то с 90х, у радиолюбителей стали набирать популярность цифровые виды связи. В этом случае сигнал (обычно RTTY или PSK) формирует компьютер, оператор общается с корреспондентом с помощью своего рода текстового чата.
Надо сказать, что технически подобные протоколы очень просты, и набираемые пользователем с клавиатуры символы практически без какой-либо сложной обработки посылались в эфир. И как ни странно, в этом были свои плюсы — оператор должен был сам найти нужную частоту, оценить на слух качество сигнала, увидеть на экране декодируемые символы, набрать ответ, и пр.
Но возможности цифровой обработки росли, и наконец, появился герой нашего обзора — стандарт связи FT8. Название FT8 переводится как Franke and Taylor, 8-FSK modulation. Профессор Steven Franke и астрофизик и нобелевский лауреат Joseph Taylor, создали действительно интересный и эффективный протокол для передачи данных.
Особенности FT8:
— Длина сообщения 15с, сообщения передаются в фиксированные тайм-слоты, что облегчает декодирование.
— Длина сообщения 77 бит + 12-бит CRC.
— Коррекция ошибок FEC LDPC(174,87).
— Частотная модуляция 8-FSK, расстояние между тонами 6.25Гц.
— Ширина полосы 50Гц. При такой узкой полосе может одновременно работать и декодироваться множество станций.
— Порог декодирования -20дБ.
— Опциональная возможность автоматической работы, автоматической отправки ответов и пр.
В общем, авторами сделана хорошая работа по созданию практически полностью автоматизированного протокола связи, способного с одной стороны, передать информацию более эффективно, с другой, убить «дух любительского радио» на корню. Нет больше романтики шумов и замираний эфира, приема слабого сигнала корреспондента с другой стороны океана, есть просто экран ПК, а все остальное делают алгоритмы и математика.
Скриншот программы WSJT-X, поддерживающей FT8 выглядит примерно так:
Источник: 3fs.net.au/ft8-digital-amateur-radio
Лично мне не очень понятно удовольствие от практически полностью автоматической радиосвязи, но раз FT8 пользуется популярностью, значит это кому-то нужно. Посмотрим подробнее, как это работает.
Битовое кодирование
Рассмотрим практический пример — передачу фразы «CQ RA1ABC KO50». Здесь CQ это общепринятый код вызова (подробнее здесь), RA1ABC это радиолюбительский позывной, KO50 это так называемый grid-локатор, определяющий регион откуда вещает радиолюбитель.
На первом шаге общепринятые аббревиатуры заменяются короткими кодами, например CQ получает код 2h. Радиолюбительские позывные имеют строго определенный формат из букв и цифр, что также позволяет записать их в более компактной форме.
const char A0[] = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?";
const char A1[] = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char A2[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char A3[] = "0123456789";
// Check for standard callsign
int i0, i1, i2, i3, i4, i5;
if ((i0 = char_index(A1, c6[0])) >= 0 && (i1 = char_index(A2, c6[1])) >= 0 &&
(i2 = char_index(A3, c6[2])) >= 0 && (i3 = char_index(A4, c6[3])) >= 0 &&
(i4 = char_index(A4, c6[4])) >= 0 && (i5 = char_index(A4, c6[5])) >= 0) {
// This is a standard callsign
int32_t n28 = i0;
n28 = n28 * 36 + i1;
n28 = n28 * 10 + i2;
n28 = n28 * 27 + i3;
n28 = n28 * 27 + i4;
n28 = n28 * 27 + i5;
printf("Pack28: n28=%d (%04xh)n", n28, n28);
return NTOKENS + MAX22 + n28;
}
Здесь важна сама идея замены символов индексами, что эффективно при небольшом размере словаря. В итоге позывной «RA1ABC» будет записан как 0BF1C2C1h — мы потратили 4 байта вместо 6.
Аналогично, grid-локатор «KO50» записывается в виде 2х-байтового числа 4BFAh. Все это нужно потому, что максимальная длина сообщения составляет 77бит, особо не разгуляешься. Разумеется, может передаваться произвольный текст и даже телеметрия, но с учетом этих ограничений. Длина сообщения в 77бит была выбрана как компромисс между временем передачи (примерно 13 секунд, что не так и быстро), и информационной емкостью — сообщение можно было бы сделать длиннее, но оно тогда передавалось бы дольше.
В итоге, все наше сообщение «CQ RA1ABC KO50» будет сконвертировано в блок данных 00 00 00 26 28 9F D4 92 FE 88. К нему также добавляется 14-битный CRC.
Следующим шагом 91-битное сообщение преобразуется в так называемый LDPC (Low-density parity-check) код длиной 174 бит — в него добавляется избыточность, используемая для коррекции ошибок при приеме. На этом шаге сообщение преобразуется в вид 00 00 00 26 28 9F D4 92 FE 8A CA 0C F3 D1 34 33 88 D0 C2 9C 3D CC.
Частотное кодирование
Здесь все уже довольно просто. На этом шаге мы преобразуем сообщение в последовательность тонов разной частоты. Как известно, у нас возможны 8 тонов (вид модуляции FSK-8), после преобразования мы получаем последовательность вида 3140652000000001153532746111274536563140652015757605451570523040614076423140652 где каждая цифра это номер тона от 0 до 7.
Разнос частот между тонами 6.25Гц, длительность одного тона 0.16с, имея показанную выше последовательность, можно легко сгенерировать WAV-файл или управлять непосредственно синтезатором частоты в случае автономного маяка.
Спектр сгенерированного сигнала нашего сообщения выглядит так:
Конечно, лучше один раз услышать, чем смотреть на спектр, увы, Хабр не позволяет приаттачить wav-файл, а нормального видео в youtube с демонстрацией звука FT8 найти не удалось. Современным радиолюбителям слушать эфир уже не обязательно, за них это делает компьютер. Пример процесса радиосвязи можно посмотреть здесь:
Заключение
Как можно видеть, математически FT8 достаточно интересный протокол. Оригиналы исходников WSJT-X написаны на Фортране, и с ними я до конца так и не разобрался. Отдельно версию энкодера на С++ можно посмотреть на github.com/kgoba/ft8_lib, из неё были взяты приведенные выше фрагменты кода. Желающие также могут просто скачать версию WSJT-X, она бесплатна, попробовать её можно без передатчика, достаточно звуковой карты. Можно даже настроиться на частоты FT8 с помощью http://websdr.ewi.utwente.nl:8901 и перенаправить звук через virtual audio cable, так что посмотреть программу в работе можно и без трансивера и без р/л позывного.
Что касается популярности FT8 в радиолюбительских кругах… Ну лично мне это не совсем понятно, по-моему никакой романтики в таких видах связи уже нет, это ближе к промышленному протоколу, чем к хобби и творчеству. Но у большинства видимо другое мнение, что показывает график, приведенный в начале статьи. Миллионы радиолюбителей ведь не могут ошибаться? Ну а сам FT8 разумеется, технически интересен, и тут пожалуй, процесс изучения протокола куда интереснее чем его использование. Хотя, попробовать программу хотя бы один раз безусловно тоже интересно.
Всем удачных экспериментов.
Автор: DmitrySpb79