Engee documentation
Notebook

FIR filter generation using command control

In this demonstration, we will show you how to use command control to implement the same type of actions and share methods to simplify the process of model building.

Let's start with connecting the libraries we will need to implement the project.

In [ ]:
Pkg.add(["DSP"])
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`
In [ ]:
using Plots, DSP; # Подключение библиотек PLots и DSP

Now, using the DSP library, let's generate coefficients for our filter.

In [ ]:
st = 0.0001;
fc = [500 1200]'; # Частоты сигнала
fs = 6000; # Частота дискретизации сигнала
t = [0:1/fs:0.001;]; # Диапазон времени сигнала
x = cos.(2*pi*fc[1]*t) + cos.(2*pi*fc[2]*t); # Пример сигнала для фильтрации
responsetype = Lowpass(2000; fs); # Определение полосы пропускания
print("Размер окна фильтрации:")
N = parse(Int,readline())
designmethod = FIRWindow(hanning(N)); # Определение размеров окна
x_filt =filt(digitalfilter(responsetype, designmethod), x); # Фильтрация сигнала
c=digitalfilter(responsetype, designmethod); # FIR-фильтр
coef=length(c); # Количество коэффициентов фильтра
Размер окна фильтрации:stdin>  5
Out[0]:
5

Let's plot the power spectral density of the original signal and the signal after filtering.

In [ ]:
p1 = DSP.periodogram(x); 
plot(freq(p1), power(p1), xlabel="частота, Гц", ylabel="спектральная плотность мощности", label="исходный сигнал")
p2 = DSP.periodogram(x_filt);
plot!(freq(p2), power(p2), label="отфильтрованный сигнал")
Out[0]:

Now let's create a model in which we will generate the filter itself.

In [ ]:
print("Напишите название вашей модели:")
name_model = readline()
Path = (@__DIR__) * "/" * name_model * ".engee"
if isdir(Path)
	rm(Path;force = true, recursive = true)	
end
engee.create(name_model) # Создать модель
Напишите название вашей модели:stdin>  FIR
Out[0]:
Model(
	name: FIR
	id: f3a728f9-5ee6-4dfc-a629-25769ba42923
)

First of all, let's set input and output ports of the model.

In [ ]:
engee.add_block("/Basic/Ports & Subsystems/In1", name_model*"/"); # Создание входного порта для подсистемы
engee.add_block("/Basic/Ports & Subsystems/Out1", name_model*"/"); # Создание выходного порта для подсистемы

Now let's declare a loop to create the FIR-filter model.

In [ ]:
for n in 1:coef-1 
    name_gain="Gain-"*string(n); # Задаем имя блока для Gain 
    engee.add_block("/Basic/Math Operations/Gain", name_model*"/"*name_gain); # Добавим в модель Gain
    engee.set_param!(name_model*"/"*name_gain, "Gain" => c[n]); # Установим значения коэффициентов фильтра
    name_delay="Delay-"*string(n); # Задаем имя блока для Delay
    engee.add_block("/Basic/Discrete/Delay", name_model*"/"*name_delay); # Добавим в модель Delay
    engee.set_param!(name_model*"/"*name_delay, "DelayLength" => 1); # Установим длину задержки равной 1
    engee.set_param!(name_model*"/"*name_delay, "SampleTime" => st); # SampleTime для Delay
    name_add="Add-"*string(n); # Задаем имя блока для Add
    engee.add_block("/Basic/Math Operations/Add", name_model*"/"*name_add); # Добавим в модель Add
    if n==1
        engee.add_line(name_gain*"/1", name_add*"/1"); # Соединим Gain и Add 1 вход
    end
    if n>1
        name_delay_1="Delay-"*string(n-1); # Задаем имя блока для предыдущего Delay
        engee.add_line(name_delay_1*"/1", name_delay*"/1"); # Соединим Delay n-1 и Delay n
        engee.add_line(name_delay_1*"/1", name_gain*"/1"); # Соединим Delay n-1 и Gain n
        name_add_1="Add-"*string(n-1); # Задаем имя блока для предыдущего Add
        engee.add_line(name_add_1*"/1", name_add*"/1");  # Соединим Add n-1 и Add 1 вход
        engee.add_line(name_gain*"/1", name_add_1*"/2"); # Соединим Gain n-1 и Add 2 вход
    end
    if n==coef-1
        name_gain="Gain-"*string(n+1); # Задаем имя блока для Gain
        engee.add_block("/Basic/Math Operations/Gain", name_model*"/"*name_gain); # Добавим в модель Gain
        engee.set_param!(name_model*"/"*name_gain, "Gain" => c[n+1]); # Установим значения коэффициентов фильтра
        engee.add_line(name_delay*"/1", name_gain*"/1"); # Соединим Delay и Gain
        engee.add_line(name_gain*"/1", name_add*"/2"); # Соединим Gain и Add 2 вход
        engee.add_line(name_add*"/1", "Out1/1");  # Соединим Add и Out1
    end
end
engee.add_line("In1/1", "Gain-1/1"); # Соединим In1 и Gain-1
engee.add_line("In1/1", "Delay-1/1"); # Соединим In1 и Delay-1

Let's save the result to the model and change the modelling parameters.

In [ ]:
engee.save(Path)
model = engee.load(Path, force=true ) # Загрузить модель
engee.set_param!(model, "StopTime" => 5, "FixedStep" => 0.1) # меняем фиксированный размер шага и время окончания симуляции
param = engee.get_param(model) # Получение параметров текущей модели

Conclusion

In this example, we have shown an example of using command control for automatic generation of models.

Blocks used in example