用滑动窗口平滑信号
让我们考虑用滑动窗口平滑信号的4种方法,从低级到最高级。
不同的方式来平滑信号
在不同的应用中,工程师可能需要多种信号滤波方法,我们将分析四种方法(工作相同)并讨论它们的优缺点。
延迟链(显式FIR)
首先,实现滑动窗口的最低级方法是简单地存储一定数量的信号点,例如100,当它们到达时。 结果将是所有这些"延迟测量"的总和除以它们的数量(100)。
滤波器内部有10个相同的块,其输出求和并除以100。
每个这样的块内部有10个延迟块。 Unit Delay,在将他们之前收到的值传递给下一个块之前存储下一个值。
我们为什么要创建这样的块层次结构? 通过以这种方式排列延迟块,我们避免了创建一行100个延迟块的需要。
这种方法不是很灵活,因为我们仍然需要手动创建延迟块。 使用遮罩参数化这样的滤波器将是困难的。
使用现成的FIR滤波器单元
在图表上放置一个块要容易得多。 Discrete FIR filter
我们将为块指定系数的相同权重,以便每个测量对最终信号具有相同的贡献。
通过CIC滤波器平滑
可以使用如下所示的更简单和更优雅的设计创建具有相同权重的FIR滤波器。
在这里,使用100的延迟长度和几个简单的块,我们创建了BIH类型的级联集成梳状滤波器(具有无限脉冲响应)。 根本没有乘法运算,所以过滤器的工作速度非常快。
"移动平均线"区块
来自标准库的另一个块被称为 Moving Average 如果在其设置中指定了"滑动窗口"方法,它将实现与以前相同的操作。
块需要一个值的向量来进入它的输入,所以我们发送一个缓冲信号到输入端口(块 Buffer 长度 100 有重叠 99). 在输出时,它将返回一个打包成大小矩阵的单个值 1х1. 我们将使用块将其转换为标量 Demux.
启动模型
让我们运行2500计数的模型。 输入信号由以下子系统生成:
这是对常数求和的结果 1 具有幅度均匀分布噪声的矢量 0.01. 在模型的500个采样之后,向信号添加幅度步长。 1.
# Если модель еще не открыта, загрузим из файла
if "moving_average" ∉ getfield.(engee.get_all_models(), :name)
engee.load( "$(@__DIR__)/moving_average.engee");
end;
data = engee.run( "moving_average" )
让我们相互比较结果。 它们应该是相同的,但由于信号缓冲的实现方式,后一种方法会引入一个计数的延迟。
plot( data["Сглаженный явным FIR"].time, data["Сглаженный явным FIR"].value, label="Сглаженный явным FIR" )
plot!( data["Сглаженный блоком FIR"].time, data["Сглаженный блоком FIR"].value, label="Сглаженный блоком FIR" )
plot!( data["Сглаженный CIC фильтром"].time, data["Сглаженный CIC фильтром"].value, label="Сглаженный CIC фильтром" )
plot!( data["Сглаженный через блок MA"].time, data["Сглаженный через блок MA"].value, label="Сглаженный через блок MA" )
plot!( legend=:bottomright )
结论
如果您经常必须在工作中过滤信号,那么使用本示例中提供的模型将非常有用。
滤波器的选择取决于您是否需要设置权重(例如,实现指数滤波器),以及输入的信号(标量或矢量)以及是否需要将模型转换为代码。
