Документация Engee
Notebook

Модуляция основной полосы частот

Открыть пример в Engee

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

  1. В виде скрипта;
  2. В виде модели.

Схема алгоритма имеет следующий вид:

passband.png

Построение системы при помощи скрипта

Первый шаг построения системы: подключаем все используемые системные элементы и библиотеки.

In [ ]:
using FFTW, Plots
import .EngeeComms
gr()
step = EngeeComms.step;

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

In [ ]:
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

Создадим функцию для выполнения логики работы системы.

In [ ]:
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
Out[0]:
step1 (generic function with 1 method)

Запуск системы и получение выходных данных.

In [ ]:
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.") # Построение графика
0.001493131594664543 BER;
60.0 Bit errors;
40184.0 Bits;

35.140576755325306 EVM_rms.

Построим спектр сигнала на выходе передатчика и спектр вносимых искажений.

In [ ]:
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)
Out[0]: