САМОСТОЯТЕЛЬНАЯ РАБОТА

«Радиомодем : процедура ARQ »

Статья 3.

Выполнили: студенты группы 9110 Городничев А.В, Воронин А.Е

Краткое описание задания:


Постановка задачи:

1) Разработка и экспериментальное исследование модели. Необходимо будет продемонстрировать процесс передачи текстового сообщения в произвольном направлении с реализованным механизмом автоматического повтора ранее переданных сообщений.

Анализ поставленной задачи.

Для решения данной задачи сначала необходимо вспомнить структуру передаваемого пакета (рис.2.) и изобразить алгоритм передачи и приема текстовых файлов (рис.3.)


Рис.2. Структура передаваемого пакета.



Рис.3. Алгоритм передачи и приема текстовых файлов.

Исходя из этого, можно составить программу, описывающий данный алгоритм.

Она состоит из нескольких частей:

1) initSettings.m – установка основных параметров системы, таких как позиционность модуляции, размер кодового слова и длина кодируемого сообщения, задается полином для службы проверки целостности принятого сообщения и т.д.;

2) transmit.m – реализация передатчика, в котором идет формирование сообщения L2  и L1 уровня, то есть происходит реализация службы CRC-8, кодирования, с помощью кода БЧХ(255,207) и модуляции 8-PSK;

3) Receive_msg.m – реализация приемника. Здесь происходит обратный процесс, т.е. демодуляция, декодирование. С помощью службы CRC-8 идет проверка целостности принятого сообщения и извлекается информационная  часть со всеми служебными полями;

4)  test_unit.m – главный файл, в котором осуществляется тестирование модели. В нем реализован весь алгоритм передачи и приема. Здесь происходит чтение из файлов, запись в переменную, вычисление числа пакетов, необходимых для передачи, формирование сообщения L3 уровня. Далее сообщение отправляется на передатчик, после чего уходит в канал, который представлен в виде блока awgn, где накладывается шум заданной интенсивности. Пройдя через него, сигнал поступает на приемник, где из него извлекается необходимая информация и происходит ее обработка. В приемнике осуществляется проверка на ошибки каждого отдельного пакета. Если ошибок нет, то на передатчик отправляется сообщение ACK, которое служит сигналом для передатчика об успешной передачи пакета и необходимости передачи следующего пакета.  Если ошибки есть, то на передатчик отправляется сообщение NACK, которое служит сигналом для передатчика об ошибочной передачи пакета и необходимости повторной передачи ошибочного пакета.    Далее содержимое всех пакетов записывается в текстовую переменную, и из них собирается целостное сообщение.

Тексты программ:

1) initSettings.m

 

function set = initSettings()

%% Инициализация основных параметров модели

 

% Выбор файла для передачи 

set.FileName = 'SendText.txt';

 

% параметры модели

% позиционность модуляции - 8-PSK

set.mPos = 8;

 

% Параметры помехоустойчивого кодека

% Для примера используется линейный блоковый код БЧХ(255,223):

% Длина кодового слова n = 2^m-1 = 255 при m = 8

% Размер кодируемого блока k = n-m = 207

set.m = 8;

set.n = 2^set.m-1; % Codeword length = 255

% информационное поле физ. уровня - полная длина передаваемого L2-сообщения

set.k = 207; % Message length = 223

 

% Параметры CRC

%CRC-8-CCIT, используется в ISDN Header Error Control and Cell Delineation ITU-T и т.п.

 set.poly=[1 0 0 0 0 0 1 1 1];

[set.x set.y]=size(set.poly); %размерность полинома

 

% переменная, равная длине информационной части L2-сообщения

set.length_msg_Lev2 = set.k - set.y + 1;% сообщение состоит из 199 битов: "set.k - CRC"

 

% переменная, равная длине передаваемого сообщения 3 уровня,

set.length_msg_Lev3 = 199;% расчетная длина L3-сообщения


2) transmit.m

 

function  msgIQ = transmit(msgL3)

 

% msgL3 - сообщение в бинарной форме

 

% установка параметров модели

st=initSettings();

 

   % ================== Канальный  уровень ================================

   % Формат сообщения (207 бита):

   % поле "Data" (L3-сообщение) - 199 битов

   % поле CRC - 8 битов

   % ======================================================================

   %% Подготовка к передаче сообщения    

         

   % сборка части L2-сообщения

   msg_L20 = [msgL3];

     

   % получение CRC кода

   m = [msg_L20 zeros(1,st.y-1)]; %вставка нулей в поле CRC

   [q r] = deconv(m,st.poly); % поиск частного и остатка от деления

   %информационной части на порождающий полином CRC кода

   r = mod(abs(r),2);

   CRC = r(st.length_msg_Lev2 + 1:end);%расчет CRC

   % сборка сообщения

   msg_L2 = [msg_L20 CRC];

   %disp(['Длина поля Сообщение_L2: ', num2str(length(msg_L2))]);

  

   %disp(['Длина поля Cообщение L3-уровня: ', num2str(length(msgL3))]);

   %disp(['Длина поля CRC-8: ', num2str(length(CRC))]);

   %disp(['Длина сообщения L2-уровня: ', num2str(length(msg_L2))]);

   trx = msg_L2;

  

   %disp([' ']);

  % disp(['Структура сообщения L1-уровня:']);

   % ================== Физический уровень ================================

   %% Помехоустойчивое кодирование

   code_word = encode(trx,st.n,st.k,'bch/binary');

   %disp(['Длина поля Cообщение L2-уровня: ', num2str(length(msg_L2))]);

   %disp(['Длина поля FEC: ', num2str(st.n-st.k)]);

   % codeword имеет размер 255 битов

  % disp(['Длина сообщения L1-уровня: ', num2str(length(code_word))]);     

   L1 = [code_word]';

   %disp(['Длина поля Сообщение_L1: ', num2str(length(L1))]);

 

 

   %% Модуляция

   h = modem.pskmod(st.mPos);

   % h - модем 8-PSK с позиционностью mPos

   % Требуется настроить остальные его параметры:

   % Параметры модуляции

   h.inputtype = 'bit';

   h.SymbolOrder = 'gray';

   h.PhaseOffset = 0;

 

   % собственно модуляция

   IQ_signal = modulate(h, L1);  

msgIQ = IQ_signal;


3) Receive_msg.m

 

function  [length_data, msgL3, errs] = Receive_msg(rxIQ)

 

% установка параметров модели

st = initSettings();

 

msgL3 = '';

errs = 0;

 

%% Параметры демодуляции

h = modem.pskdemod(st.mPos);

h.SymbolOrder = 'gray';

h.PhaseOffset = 0;

h.OutputType = 'bit';

  

% собственно демодуляция

s = demodulate(h,rxIQ);

 

%% Помехоустойчивое декодирование

received_mes_L1 = decode(s(1:st.n),st.n,st.k,'bch/binary');

 

% ================== Канальный  уровень ================================

%% декодирование L2-сообщения

 

% Подготовка к проверке CRC

[q r]=deconv(received_mes_L1,st.poly);

%проверка остатка

   r=mod(abs(r),2);

   if r == zeros(1,length(received_mes_L1))'

        detect=0;% ошибок нет

   else

        errs = errs + 1;

        detect=1;% обнаружены ошибки

   end;

 

% Собственно принятое сообщение

received_mes_L2 = received_mes_L1(1:st.length_msg_Lev2);

 

%    % Преобразование в текстовый формат

    length_data = my_bi2de(received_mes_L2(1:7)','left_msb' );

 

    % Извлечение принимаемого сообщения (в двоичном виде)

    if length_data < 13

      msgL3 = received_mes_L2(8:16*length_data + 7)';

    else

      length_data = 12;

      msgL3 = received_mes_L2(8:16*length_data + 7)';

    end

4)  test_unit.m

 

close all; %закрытие всех диаграмм

clear; %очистка рабочей области

clc; % очистка командного окна

 

% тестовый модуль обмена двоичными сообщениями

 

%% установка параметров системы

st = initSettings();

 

tx_msg = [];

% Открытие для чтения и получение идентификатора текстового файла

 

fid = fopen(st.FileName, 'r');

%Проверка на доступность указанного файла

if (fid < 0)

    disp('Файл с передаваемым сообщением не найден. Завершение работы.');

    return

end

tx_msg = fscanf(fid, '%c'); %Копирование текста из файла в текстовую переменную tx_msg

fclose (fid); %Закрытие файла

 

%% подготовка сообщения и формирование соответствующих ему IQ-символов

bin_msg = strtobin(tx_msg)'; %перевод текста в двоичный код (16 бит на символ)

length_tx_msg = length(tx_msg); %длина текста в символах

disp(['Количество символов текста: ', num2str(length_tx_msg)]);

disp(['Количество бит: ', num2str(length_tx_msg*16)]);

%Определение необходимого количества пакетов для передачи

if mod(length_tx_msg*16,192) == 0

   M = floor((length_tx_msg*16)/192);

else   

M = floor(((length_tx_msg*16)/192)+1);

end

disp(['Количество пакетов: ', num2str(M)]);

disp('  ');

disp(['$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);

disp('  ');

 

%начало передачи пакетов

i = 1;

for n = 1:100 % число возможных повторных передач

 

% формат L3-сообщения:

% 7 бит – длина сообщения

% следующие 192 бита - информационная часть или служебное сообщение;

% если сообщение меньше 192 бит, то оно дополняется нулями

 

%передача по 192 бита информации, если в последнем пакете меньше 192 бит,

%то передается число бит равное длине последнего пакета

if length_tx_msg*16 > 192*i

bin_msg_i = bin_msg((1+192*(i-1)):192*i);

else

    bin_msg_i = bin_msg((1+192*(i-1)):length_tx_msg*16);

end

%disp(['Длина поля иформации: ', num2str(length(bin_msg_i))]);

DATA = [bin_msg_i zeros(1, 192 - length(bin_msg_i))];

%disp(['Длина поля DATA: ', num2str(length(DATA))]);

Length = my_de2bi(length(bin_msg_i)/16, 'left_msb',7); %длина текста в двоичной форме

msg_L3  = [Length DATA];

%disp(['Длина поля Сообщение_L3: ', num2str(length(msg_L3))]);

 

% формирование блока IQ-символов

% этот блок можно будет загружать в цифровой передатчик для последующей

% передачи сообщения по радиоканалу

trxIQ = transmit(msg_L3);

 

 

%% Наложение шума на блок символов

% Здесь менять мощность шума!!!!!

noise_sgn = awgn(trxIQ,10,'measured');

 

% отображение результата в виде сигнально-кодового созвездия

 figure(1);

 plot(noise_sgn,'.');

 hold all;

 

%приемная часть. Извлечение из сообщения необходимой информации

[Length_msgg, msg, err] = Receive_msg(noise_sgn);

 

 

%Идет проверка на ошибки

if my_bi2de(err) == 1

    %если ошибки есть, то приемный терминал формирует пакет с NAKом

    %и отправляет его передатчику.

    disp(['Имеются ошибки. Повтор передачи пакета']);

    nak_msg = ['NAK']';

    bin_nak = strtobin(nak_msg)'; 

    Length_nak = my_de2bi(length(bin_nak)/16, 'left_msb',7);

    DATA_nak = [Length_nak bin_nak zeros(1,144)];

    nak_L3  = [DATA_nak];

    IQ = transmit(nak_L3);

    noise_ch = awgn(IQ,20,'measured');   

else

    %если ошибок нет, то отправляется ACK 

    disp(['Ошибки отсутствуют']);

    ack_msg = ['ACK']';

    bin_ack = strtobin(ack_msg)';

    Length_ack = my_de2bi(length(bin_ack)/16, 'left_msb',7);

    DATA_ack = [Length_ack bin_ack zeros(1,144)];

    ack_L3  = [DATA_ack];

    IQ = transmit(ack_L3);

    noise_ch = awgn(IQ,20,'measured');   

end

%Здесь передающий терминал принимает сообщение приемного терминала

[Length_msgg_arq, msg_arq, err_arq] = Receive_msg(noise_ch);

txt_arq = bintostr(msg_arq)';

disp(['Текстовое сообщение_arq: ' txt_arq']);

 

ARQ = (my_bi2de(msg_arq,'left_msb'))';

%если он получает NAK, то переменная не изменяется и повторяется передача

%того же пакета

if ARQ == 335011709003

    i = i+0;

    %магическое чилсо. Так выглядит слово NAK после перевода в двоичнный,

    %а потом в десятичный вид

else

% если все хорошо и пришел ACK, то приемник обрабатывает пришедшее сообщение...   

disp(['Длина (символов): ' num2str(Length_msgg)]);

txt_msg = bintostr(msg)';

disp(['Текстовое сообщение: ' txt_msg']);

 

disp('  ');

disp(['$$$$$$$$$']);

disp('  ');

 

%переменная, в которую сохраняются сообщения из принятых пакетов

MSG_TEXT(1+12*(i-1):12*(i-1)+Length_msgg) = txt_msg;

%... и передатчик начинает передавать следующий пакет

i = i+1;

 

end

% как только число принятых пакетов превысило число переданных,

%то цикл прерывается

if i> M

    break

end

end

%вывод всего сообщения на экран

disp(['Принятое сообщение: ' MSG_TEXT]);

 

%Подсчет количества ошибок в сообщении

error = 0;

for j = 1:length_tx_msg

         a = (my_bi2de((strtobin(tx_msg(j))'),'left_msb'))';

         b = (my_bi2de((strtobin(MSG_TEXT(j))'),'left_msb'))';

    if a-b == 0

        error = error + 0;

    else

        error = error + 1;

    end

end

MSG_TEXT = [];

disp(['Колличество ошибок: ', num2str(error)]);

disp('  ');

disp('  ');

disp(['$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);

disp(['$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);

disp('  ');

disp('  ');

 

end 

 

 

 

 

 

 

 

 

Для тестирования программы сначала выведем длины всех полей, чтобы убедится в соответствии предложенной структуре пакета. Для этого необходимо дописать в программе test_unit.m строки:

disp(['Структура сообщения L3-уровня:']);

disp(['Длина поля Length: ', num2str(length(Length))]);

disp(['Длина поля DATA: ', num2str(length(DATA))]);

disp(['Длина сообщения L3-уровня: ', num2str(length(msg_L3))]);

disp([' ']);

 

 

И в программе transmit.m:

disp(['Длина поля Cообщение L3-уровня: ', num2str(length(msgL3))]);

disp(['Длина поля CRC-8: ', num2str(length(CRC))]);

disp(['Длина сообщения L2-уровня: ', num2str(length(msg_L2))]);

disp([' ']);

disp(['Структура сообщения L1-уровня:']);

disp(['Длина поля Cообщение L2-уровня: ', num2str(length(msg_L2))]);

disp(['Длина поля FEC: ', num2str(st.n-st.k)]);

disp(['Длина сообщения L1-уровня: ', num2str(length(code_word))]);

 

Тогда получим следующий результат:

 

Структура сообщения L3-уровня:

Длина поля Length: 7

Длина поля DATA: 192

Длина сообщения L3-уровня: 199

 

Структура сообщения L3-уровня:

Длина  поля Сообщение L3-уровня: 199

Длина поля CRC-8:

Длина cообщения L2-уровня: 207

 

Структура сообщения L1-уровня:

Длина  поля Сообщение L2-уровня: 207

Длина поля FEC: 48

Длина cообщения L1-уровня: 255

 

 

Рис.4. Длины полей передаваемого пакета.

Если сравнить с рис.2, то видно, что структура полностью совпадает.

Теперь запустим систему и посмотрим на ее работу.

При этом  передавался текстовый файл SendText.txt .

 

Рис.5. Содержимое используемого текстового файла.

 

 Тогда результат работы программы будет выглядеть следующим образом:



а)



б)

Рис.6. Передача сообщения терминалу 1. а) заголовок и первый пакет, б) восстановленное сообщение.

 

 

 

Также приведем сигнально-кодовые созвездия при передаче сообщения и при ОСШ = 20 дБ.




 

 

Рис.7. Сигнально-кодовые созвездия при передаче сообщения  при ОСШ = 20 дБ.

 

При уменьшении ОСШ шум увеличивается на столько, что символы могут попасть в область принятия решений соседних символов, и тогда возникают ошибки. И тогда вступает в действие механизм ARQ.

 

ОСШ = 10 дБ


 

Рис.8. Сигнально-кодовые созвездия при передаче сообщения  при ОСШ = 10 дБ.

 

Выводы:

В ходе выполнения работы были решены задачи, поставленные в задании –спроектирована система передачи сообщения, использующая модуляцию 8-PSK, с помехоустойчивым кодом, исправляющим не менее 6 ошибок. В проделанной самостоятельной работе был разработан сценарий передачи данных от терминала 1 к терминалу 2 и наоборот, и часть его реализована программно.

 

Используемая литература :

1 http://omoled.ru/publications/view/360

2http://omoled.ru/publications/view/380

3 http://limonwifi.com/signal8.html

4 http://omoled.ru/publications/view/335

5 Скляр Б. Цифровая связь. Теоретические основы и практическое применение. М.: Вильямс, 2003г.