САМОСТОЯТЕЛЬНАЯ
РАБОТА
«Радиосеть.
Доставка сообщений»
Статья 3.
Выполнила: студентка
группы 9110 Воробьева К.А.
Краткое описание задания:
Основная задача темы состоит в разработке модели
функционирования сети в состоянии предоставления услуги передачи текстовых
файлов от точки доступа к терминалам сети (рис.1). Точка доступа АР по
радиоинтерфейсу одновременно передает сообщения, включающие фрагменты текстовых
файлов, терминалам сети. Предполагается, что текстовый файл 1 передается Т1, 2
файл - Т2. В процессе приема сообщений терминалы осуществляют обнаружение и
исправление ошибок, измеряют качество радиосоединения.
Рис.1. Общая структура.
Постановка задачи:
1) Разработка и экспериментальное исследование модели.
Необходимо будет продемонстрировать процесс передачи двух текстовых файлов от
точки доступа двум терминалам. Каждому терминалу свой файл.
Анализ поставленной
задачи.
Для решения данной задачи сначала необходимо вспомнить
структуру передаваемого пакета (рис.2.) и изобразить алгоритм передачи и приема
текстовых файлов (рис.3.)
Рис.2. Структура
передаваемого пакета.
Рис.3. Алгоритм
передачи и приема текстовых файлов.
Исходя из этого, можно составить программу, описывающий данный
алгоритм.
Она состоит из нескольких частей:
1) initSettings.m – установка основных параметров системы,
таких как позиционность модуляции, размер кодового слова и длина кодируемого
сообщения, задается полином для службы проверки целостности принятого сообщения
и т.д.;
2) transmit.m – реализация передатчика, в котором идет
формирование сообщения L2
и L1 уровня, то есть происходит реализация службы CRC-8, кодирования, с помощью кода
БЧХ(255,223) и модуляции 8-PSK;
3) Receive_msg.m – реализация приемника. Здесь происходит обратный процесс, т.е. демодуляция, декодирование. С помощью службы CRC-8 идет проверка целостности принятого сообщения и извлекается информационная часть со всеми служебными полями;
4) test_unit.m –
главный файл, в котором осуществляется тестирование модели. В нем реализован
весь алгоритм передачи и приема. Здесь происходит чтение из файлов, запись в
переменную, вычисление числа пакетов, необходимых для передачи, формирование
сообщения L3 уровня.
Далее сообщение отправляется на передатчик, после чего уходит в канал, который
представлен в виде блока awgn, где накладывается шум заданной интенсивности. Пройдя
через него, сигнал поступает на приемник, где из него извлекается необходимая
информация и происходит ее обработка. Далее содержимое всех пакетов
записывается в текстовую переменную, и из них собирается целостное сообщение.
После вычисляется количество ошибочных символов, и алгоритм повторяется для
передачи содержимого второго файла второму терминалу.
Тексты программ:
1) initSettings.m
function set = initSettings()
%%
Инициализация основных параметров модели
%
Выбор файла для передачи из двух для
каждого терминала
set.FileName1 = 'SendText1.txt';
set.FileName2 = 'SendText2.txt';
%
Идентификаторы сообщений
set.BCCH
= 0;
set.RACH
= 1;
set.AGCH = 2;
set.SCH = 3;
set.TCH = 4;
%
параметры модели
%
позиционность модуляции - 8-PSK
set.mPos
= 8;
%
Параметры помехоустойчивого кодека
%
Для примера используется линейный блоковый код БЧХ(255,223):
%
Длина кодового слова n = 2^m-1 = 255 при m = 8
%
Размер кодируемого блока k = n-m = 223
set.m = 8;
set.n = 2^set.m-1; % Codeword length = 255
%
информационное поле физ. уровня - полная длина передаваемого L2-сообщения
set.k = 223; % 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;% сообщение состоит из 215 битов:
"set.k - CRC"
% переменная,
равная длине передаваемого сообщения 3 уровня,
set.length_msg_Lev3
= 208;% расчетная длина L3-сообщениz
2) transmit.m
function msgIQ =
transmit(Add, msgL3)
%
msgL3 - сообщение в бинарной форме
%
установка параметров модели
st=initSettings();
%
================== Канальный уровень
================================
% Формат
сообщения (223 бита):
% поле
"Add" - 7 бит
% поле
"Data" (L3-сообщение) - 208 битов
% поле CRC
- 8 битов
%
======================================================================
%% Подготовка к передаче сообщения
% сборка
части L2-сообщения
msg_L20 = [Add 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))]);
trx = msg_L2;
%
================== Физический уровень ================================
%% Помехоустойчивое кодирование
code_word = encode(trx,st.n,st.k,'bch/binary');
% codeword имеет размер 255 битов
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 [Add, length_data, TypeMSG, msgL3, NUMBER, errs]
= Receive_msg(rxIQ)
%
установка параметров модели
st =
initSettings();
TypeMSG = [];
Add = [];
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);
% % Преобразование в текстовый формат
%адрес
Add =
my_bi2de(received_mes_L2(1:7)','left_msb');
% % тип сообщения
TypeMSG =
my_bi2de(received_mes_L2(8:10)','left_msb');
% % Извлечение принимаемого сообщения (в
двоичном виде)
length_data = my_bi2de(received_mes_L2(11:17)','left_msb' );
%disp(received_mes_L2(2:9)');
if length_data < 13
msgL3 = received_mes_L2(18:16*length_data + 17)';
else
length_data = 12;
msgL3 = received_mes_L2(10:16*length_data + 17)';
end
%номер пакета
NUMBER
= received_mes_L2(210:215)';
4) test_unit.m
close all; %закрытие
всех диаграмм
clear; %очистка рабочей области
clc; % очистка командного окна
%
тестовый модуль обмена двоичными сообщениями
%%
установка параметров системы
st =
initSettings();
%организация
цикла для последовательной передачи сообщений сначала первому
%терминалу,
потом второму.
for j = 1:2
tx_msg = [];
%
Открытие для чтения и получение идентификатора текстового файла
%сначала
открывается файл для первого терминала, потом для второго
if j ==1
fid = fopen(st.FileName1, 'r');
disp(['Передача сообщения терминалу 1']);
else
disp(['Передача
сообщения терминалу 2']);
fid = fopen(st.FileName2, 'r');
end
%Проверка
на доступность указанного файла
if (fid < 0)
disp('Файл с
передаваемым сообщением не найден. Завершение работы.');
return
end;
tx_msg =
fscanf(fid, '%c'); %Копирование текста из файла в текстовую переменную tx_msg
fclose
(fid); %Закрытие файла
%%
подготовка сообщения "TCH" и формирование соответствующих ему
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(' ');
%
Тип передаваемого сообщения (BCCH, RACH, AGCH, SCH, TCH)
TypeMSG = 'TCH';
if strcmp(TypeMSG, 'BCCH')
TYPE = my_de2bi(st.BCCH,'left_msb',3);
elseif strcmp(TypeMSG, 'RACH')
TYPE = my_de2bi(st.RACH,'left_msb',3);
elseif strcmp(TypeMSG, 'AGCH')
TYPE = my_de2bi(st.AGCH,'left_msb',3);
elseif strcmp(TypeMSG, 'SCH')
TYPE = my_de2bi(st.SCH,'left_msb',3);
elseif strcmp(TypeMSG, 'TCH')
TYPE = my_de2bi(st.TCH,'left_msb',3);
end;
%переводит
тип сообщения в двоичный трехразрядный код
Add = j; %адрес вызываемого абонента
Addr =
my_de2bi(Add, 'left_msb',7);
%начало
передачи пакетов
for i = 1:M
Number =
my_de2bi(i, 'left_msb',6); %номер пакета, представленный 6-ти разрядным
%двоичным
числом
%
формат L3-сообщения:
% 3
бита - тип сообщения (BCCH, RACH, AGCH, SCH, TCH)
% 7
бит – длина сообщения
%
следующие 192 бита - информационная часть или служебное сообщение;
%
если сообщение меньше 192 бит, то оно дополняется нулями
%
последние 6 бит - номер передаваемого пакета (номер служебного сообщения
000000)
%передача
по 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
DATA = [bin_msg_i zeros(1, 192 -
length(bin_msg_i))];
Length = my_de2bi(length(bin_msg_i)/16, 'left_msb',7); %длина текста в двоичной форме
msg_L3 =
[TYPE Length DATA Number];
%
формирование блока IQ-символов
%
этот блок можно будет загружать в цифровой передатчик для последующей
%
передачи сообщения по радиоканалу
trxIQ =
transmit(Addr, msg_L3);
%%
Наложение шума на блок символов
noise_sgn = awgn(trxIQ,15,'measured');
%
отображение результата в виде сигнально-кодового созвездия
figure(j);
plot(noise_sgn,'.'); grid
hold all;
%приемная
часть. Извлечение из сообщения необходимой информации
[Addrr, Length_msgg, type, msg, numb, err] =
Receive_msg(noise_sgn);
disp(['Адрес: ' , num2str(Addrr)]);
%disp(['Длина
(символов): ' num2str(Length_msgg)]);
if type == 0
disp(['Тип сообщения: BCCH']);
elseif type == 1
disp(['Тип
сообщения: RACH']);
elseif type == 2
disp(['Тип
сообщения: AGCH']);
elseif type == 3
disp(['Тип сообщения: SCH']);
elseif type == 4
disp(['Тип сообщения: TCH']);
end
disp(['Номер пакета: ' num2str(my_bi2de(numb, 'left_msb'))]);
if my_bi2de(err) == 1
disp(['Имеются ошибки']);
else
disp(['Ошибки отсутствуют']);
end
txt_msg = bintostr(msg)';
disp(['Текстовое сообщение: ' txt_msg']);
disp(' ');
disp(['$$$$$$$$$']);
disp(' ');
%переменная,
в которую сохраняются сообщения из принятых пакетов
MSG_TEXT(1+12*(i-1):12*(i-1)+Length_msgg) =
txt_msg;
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(['Длина поля TYPE: ', num2str(length(TYPE))]);
disp(['Длина поля Length: ', num2str(length(Length))]);
disp(['Длина поля DATA: ', num2str(length(DATA))]);
disp(['Длина поля Number: ', num2str(length(Number))]);
disp(['Длина сообщения L3-уровня: ',
num2str(length(msg_L3))]);
disp([' ']);
disp(['Структура сообщения L2-уровня:']);
disp(['Длина поля Add: ', num2str(length(Add))]);
И в программе 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))]);
Тогда получим следующий результат:
Рис.4. Длины полей
передаваемого пакета.
Если сравнить с рис.2, то видно, что структура полностью
совпадает.
Теперь запустим систему и посмотрим на ее работу.
При этом первому терминалу передавался текстовый файл SendText1.txt
, а второму SendText2.txt :
а)
б)
Рис.5. Содержимое используемых текстовых
файлов.
Тогда результат работы программы будет выглядеть следующим образом:
а)
б)
Рис.6. Передача сообщения терминалу 1. а) заголовок и
первый пакет, б) восстановленное сообщение.
а)
б)
Рис.7. Передача сообщения терминалу 2. а) заголовок и
первый пакет, б) восстановленное сообщение.
Также
приведем сигнально-кодовые созвездия при передаче двух сообщений и при ОСШ = 20
дБ.
а)
б)
Рис.8. Сигнально-кодовые созвездия при передаче
первого сообщения (а), и при передаче второго сообщении (б) при ОСШ = 20 дБ.
Из данных
рисунков видно, что они несколько различаются. Это вызвано случайным характером
шума и тем, что в первом сообщении содержалось больше символов, а следовательно
и больше точек на СКС.
При
уменьшении ОСШ шум увеличивается на столько, что символы могут попасть в
область принятия решений соседних символов, и тогда возникают ошибки.
ОСШ = 12
дБ
а)
б)
Рис.9. Сигнально-кодовые созвездия при передаче
первого сообщения (а), и при передаче второго сообщении (б) при ОСШ = 12 дБ.
Принятые
сообщения:
а)
б)
Рис.10. Принятые сообщения.
Видно,
что в сообщения для первого терминала возникли ошибки, а в сообщении для
второго нет. Это вызвано случайным характером шума, и тем, что он не слишком
мощный. При еще большем уменьшении ОСШ ошибки появятся в обоих сообщениях.
Выводы:
В данной
работе было необходимо программно реализовать поставленную задачу, исходя из
сценария и структуры передаваемого пакета. Поставленная задача выполнена
полностью.