Выбор радиоканала по мощности сигнала
Выбор радиоканала по мощности сигнала
В этом примере рассмотрим, как в Engee разделить принятый широкополосный сигнал на несколько частотных полос. Модель формирует смесь трёх сигналов с шумом. С помощью объекта Channelizer библиотеки EngeeDSP оценим мощность в каждой полосе и выберем полосу с наименьшей энергией.
Приёмнику нужно понять, какие участки спектра заняты другими передатчиками. Для первичной оценки можно сравнить средние мощности в нескольких полосах. Такая оценка полезна при настройке многоканального приёмника и исследовании помеховой обстановки.
Разделение выполняет полифазный банк фильтров: общий вход проходит через набор фильтров, каждый из которых выделяет свою полосу. В Engee эту процедуру выполняет системный объект EngeeDSP.Channelizer.
Схема модели Engee:

Для выходного сигнала мощность в полосе оценим по формуле
Сравнивать полосы будем после начального переходного процесса. Для вещественного входа положительные и отрицательные частоты связаны комплексным сопряжением. Поэтому номера выходов банка нельзя напрямую воспринимать как номера восьми независимых положительных радиоканалов.
В модели ChannelSelection.engee три блока Sine Wave формируют компоненты 80, 210 и 340 Гц. Блок WidebandMix складывает их, RadioChannel добавляет белый гауссовский шум. Сигнал demo01_rx сохраняется блоком To Workspace.
Частота дискретизации равна 1000 Гц. Источники находятся внутри модели: скрипту достаточно запустить её и обработать полученный сигнал.
Подключим библиотеки и зададим путь к модели относительно папки скрипта. Вспомогательная функция загрузит и откроет модель, применит параметры и закроет её после запуска. Данные To Workspace читаются из общей рабочей области Engee, поэтому программный запуск этого примера выполняем с isolate = false.
using Statistics, DataFrames, Plots
gr()
name = "ChannelSelection"
path = joinpath(@__DIR__, name * ".engee")
@assert isfile(path) "Не найден файл модели: $path"
function load_and_run(path, name; settings=Pair{String,String}[])
try engee.close(name; force=true) catch end
model = engee.load(path; force=true)
engee.open(name)
for (block, keyvalue) in settings
engee.set_param!("$name/$block", keyvalue)
end
try
engee.run(model)
finally
engee.close(name; force=true)
end
end
wa(name) = Core.eval(Main, :(collect($(Symbol(name)))))
Теперь запустим модель, разделим принятый сигнал на восемь полос и рассчитаем их среднюю мощность. Первые две строки результата исключим из оценки, чтобы уменьшить влияние заполнения фильтра.
using EngeeDSP
load_and_run(path,name)
df = wa("demo01_rx")
t = Float64.(df.time); rx = Float64.(df.value)
bands = EngeeDSP.Channelizer(8)(rx)
@assert size(bands,2) == 8
power = vec(mean(abs2.(bands[3:end,:]),dims=1))
free_band = argmin(power)
Построим временной график принятого сигнала и диаграмму мощностей. Номер полосы с наименьшей мощностью также выведем в текстовом результате.
p1 = plot(t,rx,xlabel="Время, с",ylabel="Амплитуда",title="Сигнал после AWGN",legend=false)
p2 = bar(1:8,power,xlabel="Номер субполосы",ylabel="Средняя мощность",title="Занятость спектра",legend=false)
display(plot(p1,p2,layout=(2,1),size=(850,650)))
println("Минимальная мощность в полосе ",free_band,"; измерений: ",length(rx))
string("OK; полоса минимальной мощности=",free_band)
На первом графике виден составной сигнал с шумом. На втором сравниваются мощности выходов канального фильтра. Минимальный столбец показывает наименее энергетически нагруженную полосу в этом опыте.
Низкая мощность сама по себе не доказывает, что радиоканал свободен. Для такого решения нужен порог обнаружения, время наблюдения и проверка условий приёма. При смене частот источников распределение мощностей изменится.
Вывод
В данном примере мы рассмотрели совместную работу модели и скрипта Engee: модель сформировала сигнал, а объект Channelizer разделил его на полосы. Полученную оценку мощности можно использовать как основу исследования занятости спектра.
