Engee 文档
Notebook

DSP基础:信号生成

让我们考虑生成周期、脉冲和噪声信号的基本技术,以测试数字信号处理(DSP)算法、通信系统、雷达和无线电工程系统的总体建模。 示例的主要主题:
*设置周期信号
*离散信号时间网格
*典型周期信号的生成(正弦、蜿蜒、锯)
*离散噪声产生
*脉冲序列
*频率调制信号

示例中使用的库:

In [ ]:
let
    intalled_packages = collect(x.name for (_, x) in Pkg.dependencies() if x.is_direct_dep)
    list_packages = ["DSP","ChirpSignal","Waveforms"]
    for pack in list_packages
        pack in intalled_packages || Pkg.add(pack)
    end
end
In [ ]:
using DSP, ChirpSignal, Waveforms

周期信号的产生

周期信号是重复序列。 让我们创建一段信号值,然后用函数重复五次 repeat. 我们使用阶梯线及时可视化它。:

In [ ]:
one_period = [1; 4; 6; 8; 7; 5; 0; 0; 0; 0];
five_period = repeat(one_period, 5);
plot(five_period, 
    linewidth = 2,
    marker = "circle", 
    markersize = 3, 
    linetype=:steppost,
    title = "Простой периодический сигнал")
Out[0]:

现在让我们尝试使用数学函数生成周期性信号。 例如,函数 sin 计算以弧度为单位的输入角度值的正弦值。 为了生成具有所需重复率的正弦曲线,值得使用时间向量-具有指定采样周期的均匀增加的时间样本序列。 让我们为采样频率为1000Hz的信号设置时间矢量:

In [ ]:
fs = 1000;              # частота дискретизации сигнала
dt = 1/fs;              # период дискретизации
stoptime = 0.5;         # время окончания сигнала
t = 0:dt:stoptime-dt    # вектор отсчётов времени
Out[0]:
0.0:0.001:0.499

现在我们将创建一个基频为10Hz的周期性正弦信号(正弦曲线的形状将每0.1秒重复一次)。 变量 sine_wave -这是500个样本的向量。 用函数可视化信号 plot:

In [ ]:
sine_wave = sin.(2*pi*t*10);
plot(t, sine_wave, title = "Синусоида частотой 10 Гц")
Out[0]:

通过一行代码,我们可以生成具有不同振幅、频率和初始相位的多个正弦曲线。 为此,我们将这些参数设置为向量。 产生的变量 three_sines 它已经是一个500x3矩阵。 我们可以把它传递给函数 plot 在同一轴上同时显示三个图形:

In [ ]:
three_sines = [1.4 0.6 1] .* sin.(2*pi*t.*[10 15 30] .+ [pi/4 0 pi/6]);
plot(t, three_sines, title = "Три синусоиды 10 Гц, 15 Гц и 30 Гц")
Out[0]:

如果我们有兴趣观察三个正弦总和的形状,那么我们可以使用函数将矩阵的列相加 sum:

In [ ]:
sum_sines = sum(three_sines, dims = 2);
plot(t, sum_sines, title = "Сумма трёх синусоид")
Out[0]:

用于信号生成的附加功能

我们经常需要矩形、锯齿和三角形周期信号,以及随机序列来模拟噪声。

图书馆 Waveforms.jl 它包含生成所列周期性信号的功能,但作为决定基频的"主"信号,使用均匀增加的锯齿信号,从0到2pi不等。 让我们从时间矢量创建它,并用除法运算循环。 mod 在2pi:

In [ ]:
base_signal = mod.(2*pi*t*10, 2*pi);
plot(t, base_signal, title = "Задающий сигнал для функций")
Out[0]:

无线电工程中的一个流行信号是一个蜿蜒的信号。 它也是一个矩形周期信号,钻孔为2(或填充因子为50%)。 我们可以用函数生成它 squarewave. 此函数还可以采用额外的输入参数,填充因子范围为0到1。 我们将生成第二个具有20%填充的矩形信号。:

In [ ]:
sqw = squarewave.(base_signal);
sqw02 = squarewave.(base_signal, 0.2);
plot(t, sqw)
plot!(t, sqw02, title = "Прямоугольный сигнал")
Out[0]:

从-1到+1变化的锯齿信号可以通过函数获得 sawtoothwave:

In [ ]:
st = sawtoothwave.(base_signal);
plot(t, st, title = "Пилообразный сигнал")
Out[0]:

还要考虑功能 trianglewave 以产生三角信号:

In [ ]:
trw = trianglewave.(base_signal);
plot(t, trw, title = "Треугольный сигнал")
Out[0]:

Engee中提供了生成具有不同分布的随机数的函数。 让我们使用该功能 rand 以产生均匀的噪声信号:

In [ ]:
noise = rand.(length(t));
noise = noise .- 0.5;
plot(t, noise, title = "Шум с равномерным распределением")
Out[0]:

现在让我们尝试结合噪声和锯齿信号,但我们将这样做的方式,噪声水平增加的信号电平。 使用主信号,我们将生成一个锯齿,从0到+1不等。 然后我们将噪声乘以产生的锯齿信号,并将增加的"saw"与增加的噪声相加。:

In [ ]:
clean_sawtooth = mod.(t*10,1);                          # "чистый" пилообразный сигнал
amp_noise = noise .* clean_sawtooth;                    # нарастающий шумовой сигнал
noisy_sawtooth = clean_sawtooth .+ (0.25 .* amp_noise); # их сумма
plot(t, noisy_sawtooth, title = "Усиление сигнал и шума")
Out[0]:

非周期信号和脉冲包的生成

作为非周期信号的一个例子,考虑共 sinc-一种冲动。 我们使用三角函数和以弧度为单位的角度值的输入向量得到它。 在该示例中,我们生成从-2pi到+2pi范围内的脉冲(以pi/16为增量)。

In [ ]:
rads = -2*pi:pi/16:2*pi;
rads = rads[1:end-1];
one_sinc = sinc.(rads);
plot(rads, one_sinc, title = "sinc-импульс")
Out[0]:

现在让我们创建一个bundle sinc-脉冲遵循一定的周期。 为此,在结束时向一个脉冲的矢量添加一些零,并将结果乘以函数 repeat. 我们还将为脉冲突发增加衰减。 该功能将帮助我们做到这一点。 LinRange:

In [ ]:
zero_padding = [one_sinc; zeros(2*length(one_sinc))];   # sinc-импульс с нулями
four_sinc = repeat(zero_padding, 4);                    # пачка импульсов без затухания
decay = LinRange(1, 0.4, length(four_sinc));            # сигнал затухания
pulse_train = four_sinc .* decay;                       # пачка импульсов с затуханием
plot(pulse_train, title = "Пачка sinc-импульсов с затуханием")
Out[0]:

频率调制信号

总之,我们将考虑典型的频率调制信号,如线性频率调制(LFM)和正交频率调制信号。 要创建这样的信号,我们将使用函数 chirp:

In [ ]:
LFM = chirp(10, fs, 0, 500; method = "linear");
sg1 = DSP.spectrogram(LFM, 511, 256; fs = fs);
heatmap(sg1.time, sg1.freq, pow2db.(sg1.power), 
        xlabel = "Время, сек", 
        ylabel = "Частота, Гц",
        title = "Спектрограмма ЛЧМ-сигнала")
Out[0]:

为了显示信号,我们将调用函数 DSP.spectrogram,它可视化信号频谱(取决于其功率和频率)随时间的变化。 我们可以观察到FM信号的线性频率增加,在选项的情况下可以观察到二次频率增加 method = "quadratic":

In [ ]:
QFM = chirp(10, fs, 0, 500; method = "quadratic");
sg2 = DSP.spectrogram(QFM, 511, 256; fs = fs);
heatmap(sg2.time, sg2.freq, pow2db.(sg2.power), 
        xlabel = "Время, сек", 
        ylabel = "Частота, Гц",
        title = "Спектрограмма КЧМ-сигнала")
Out[0]:

结论

我们回顾了生成周期性、非周期性和噪声信号的基本技术,这些技术帮助我们开发信号处理算法和模拟无线电工程系统。