Модуляция основной полосы частот¶
Этот пример показывает простой способ выполнения модуляции основной полосы частот путем умножения модулированного комплексного сигнала на сложную синусоидальную волну для выполнения преобразования частоты с повышением. Предпочтительнее моделировать систему в сложной основной полосе частот. Однако существуют некоторые обстоятельства, при которых необходимо моделировать систему в реальной полосе пропускания. Примером этого является случай, когда сигнал соседней полосы частот обрабатывается с нелинейностью и вызывает помехи в желаемой полосе частот. Этот пример также иллюстрирует эффект такого вмешательства и представлен в двух вариантах:
- В виде скрипта;
- В виде модели.
Схема алгоритма имеет следующий вид:
Построение системы при помощи скрипта¶
Первый шаг построения системы: подключаем все используемые системные элементы и библиотеки.
using FFTW, Plots
import .EngeeComms
gr()
step = EngeeComms.step;
Создадим структуру, в которой содержатся все переменные, связанные с параметрами подключенных блоков.
mutable struct passband_modulator
# Transmitter
obj_random_integer
obj_QPSK_modulator
obj_raised_cosine_transmit
# Upconverter
obj_sine_upc
obj_prod_upc
obj_re_upc
# Channel
obj_sum
obj_AWGN
#interference
obj_sine_inter
obj_re_inter
obj_const_inter
obj_math_inter
obj_gain_inter
# Receiver
# downconverter
obj_sine_wave_dc
obj_conj_dc
obj_prod_dc
obj_raised_cosine_receive
obj_QPSK_demodulator
# Metrics
obj_int_to_bit
obj_BER
obj_delay
obj_EVM
function passband_modulator()
new(EngeeComms.random_integer(4, 37, 1e-6, 100, "Int"), EngeeComms.QPSK(pi/4), EngeeComms.rcostrans(0.2, 8, 8, 1.0),
EngeeComms.sine_wave(1.0, 2500000.0, 0.0, "Discrete", "Complex", "Trigonometric fcn", 1e-6/8, 800, "Restart at time zero"), EngeeComms.product(2, "Element-wise"), EngeeComms.complex_to_real_imag("Real"),
EngeeComms.Sum("+"), EngeeComms.AWGN(67, "mode", 8.0, 2, 1/(2*8), 1e-6, 1e-4), EngeeComms.sine_wave(1.0 ,8.833333333333334e+05, 0.0, "Discrete", "Complex", "Trigonometric fcn", 1e-6/8, 800, "Restart at time zero"), EngeeComms.complex_to_real_imag("Real"), 3, EngeeComms.math("pow"), EngeeComms.Gain(.25),
EngeeComms.sine_wave(1.0 ,2500000.0, 0.0, "Discrete", "Complex", "Trigonometric fcn", 1e-6/8, 800, "Restart at time zero"), EngeeComms.math("conj"), EngeeComms.product(2, "Element-wise"), EngeeComms.rcosreciev(0.2, 8, 8, 2.0, 8, 0), EngeeComms.deQPSK(pi/4),
EngeeComms.IntToBit(2, "Unsigned", "MSB first", "Boolean"), EngeeComms.error_rate(16, 0, "Entire frame", "Port", false, false), EngeeComms.delay(8,1), EngeeComms.EVM("Average reference signal power", "Input port", "Input length", 1))
end
end
Создадим функцию для выполнения логики работы системы.
function step1(obj::passband_modulator)
out_upconv1 =[];
out_downcov =[];
out_rec_filt =[];
out_interfer =[];
out_BER =zeros(3);
EngeeComms.setup(obj.obj_random_integer);
EngeeComms.setup(obj.obj_AWGN, [1]);
EVM_out = 0;
for i =1:201
# Передатчик
ri = step(obj.obj_random_integer);
QPSK_tr = step(obj.obj_QPSK_modulator, ri);
raised_cos_tr = step(obj.obj_raised_cosine_transmit, QPSK_tr)
test_rcos = raised_cos_tr;
# Повышающий преобразователь
sine_wave_upc = step(obj.obj_sine_upc);
prod_upc = step(obj.obj_prod_upc, sine_wave_upc,raised_cos_tr);
out_upconv = step(obj.obj_re_upc, prod_upc);
# Канал
# Интерференция с нелинейными искажениями
sine_wave_nonl = step(obj.obj_sine_inter);
re_nonl = step(obj.obj_re_inter, sine_wave_nonl);
inter_pow = step(obj.obj_math_inter, re_nonl, obj.obj_const_inter);
inter_gain = step(obj.obj_gain_inter, inter_pow);
AWGN_in = step(obj.obj_sum, out_upconv, inter_gain);
Channel_out = step(obj.obj_AWGN, AWGN_in);
# Приемник
# Понижающий преобразователь
sine_dc = step(obj.obj_sine_wave_dc);
conj_dc = step(obj.obj_conj_dc, sine_dc);
out_dc = step(obj.obj_prod_dc, conj_dc, Channel_out);
raised_cos_reciev = step(obj.obj_raised_cosine_receive, out_dc[:,1]);
out_reciever = step(obj.obj_QPSK_demodulator, raised_cos_reciev);
# Расчет побитовой ошибки (BER)
out_bits = step(obj.obj_int_to_bit, out_reciever);
rand_int_bits = step(obj.obj_int_to_bit, ri);
BER = step(obj.obj_BER, rand_int_bits, out_bits);
# Расчет EVM_rms
ref_sig = step(obj.obj_delay, QPSK_tr)
EVM_out = step(obj.obj_EVM, ref_sig, raised_cos_reciev)
# Выходы
out_BER = BER;
out_upconv1 = vcat(out_upconv1, out_upconv);
out_downcov = vcat(out_downcov, out_dc);
out_rec_filt = vcat(out_rec_filt, raised_cos_reciev);
out_interfer = vcat(out_interfer, inter_gain);
end
return out_BER, out_upconv1, out_downcov, out_rec_filt, out_interfer, EVM_out;
end
Запуск системы и получение выходных данных.
passband = passband_modulator() # Вызов структуры
BER,Upconverter,Downconverter,receive_filter,Interference, EVM_out = step1(passband); # Вызов функции
println(BER[1]," BER;") # Вывод данных в командной строке
println(BER[2], " Bit errors;")
println(BER[3], " Bits;")
println()
println(EVM_out, " EVM_rms.") # Построение графика
Построим спектр сигнала на выходе передатчика и спектр вносимых искажений.
b = Float64.(Upconverter);
spec_b = fftshift(fft(b))[80400:160800];
plot([0:4e6/80400:4e6...],(20log10.(abs.((spec_b)./[4e6/80400,4e6/80400:4e6/80400:4e6...]))), label ="Сигнал на выходе передатчика")
e = Float64.(Interference);
spec_e = fftshift(fft(e))[80400:160800];
plot!([0:4e6/80400:4e6...],20log10.(abs.((spec_e))), label ="Искажения")
ylabel!("Мощность дБВт")
xlabel!("Частота Гц")
plot!(legend=:outerbottom)
ylims!(-240, -60)
xlims!(0.2e6,4e6)