AnyMath 文档
Notebook

传感器复用

如何保证测量的可靠性?

许多领域都需要可靠的物理参数测量。 这样的任务不能用单个传感器来解决,即使是超可靠的传感器也是如此。 为了确保测量的可靠性,使用了传感器冗余方法-测量由多个传感器同时进行,并且它们的测量受到仲裁。 这个项目将展示一个仲裁算法的例子.

算法的描述

在最简单的情况下,我们可以将该值计算为所有传感器读数总和的平均值。:

但是,有必要考虑到我们对每个传感器的"信任"程度。 事实上,如果发生了传感器故障,那么我们必须考虑到其可靠性下降。 因此,每个传感器被分配一个权重。 ,这是考虑到在计算:

传感器仿真

让我们创建一个传感器模型作为噪声正弦:

image.png

该系统的一般模型将包含四个传感器,检测一个"外部"信号-一个缓慢振荡的正弦波。 对于传感器,我们改变了自己的加性噪声参数。 此外,其中一个传感器能够以大振幅的附加短时脉冲的形式模拟故障。

信号滤波

首先,您需要用数字低通滤波器(低通滤波器)抑制自己的噪声。 让我们使用信号可视化部分中的"频域信号"选项构建信号频谱图。:

spectrum.png

我们观察到一个"有用的"低频信号,以及一个噪声"底部",这对于加性白高斯噪声是预期的。 有必要抑制高于约2赫兹的频率。 让我们使用图形应用程序"数字滤波器编辑器",并在其中创建具有无限脉冲响应(IIR)和以下指定参数的数字滤波器原型。:

fda.png

我们已经看到,所得滤波器的幅频响应(frequency response)适合于从白噪声中净化正弦波的任务。 此外,数字滤波器编辑器应用程序允许您自动获得具有合成系数的滤波器结构。 这就是自动生成的IIR滤波器子系统的样子。:

image.png

其中一个传感器的初始信号和滤波操作的结果如下所示。:

newplot (20).png

以及输入和输出光谱的比较。:

spectrum_double.png

然而,滤波器不能应对具有高振幅异常值的波形的平滑。 正弦波的形状似乎强烈扭曲:

filter_fail.png

这意味着有必要依靠传感器测量而不会出现故障。

传感器读数的验证

有必要监控传感器,看看我们是否可以信任测量。 控制将根据两个标准进行:

  1. 测量是否在指定范围内?
  2. 信号变化有多快?

这些监测方法的组合使得跟踪大多数传感器故障成为可能。

让我们以Engee模型的形式来看看这个方法的实现。:

image.png

信号测量速率将通过估计移动平均线来监测。 如果这个指标超出了可接受的极限,那么这显然是一个测量误差。

排除排放

传感器从监测算法的观点来看可以是可维修的,但是给出不充分的值(例如,在事故之后)。 必须检测此类测量值并将其排除在计算之外。

作为一个例子,我们将用4个传感器测量温度,我们将得到以下测量值:

In [ ]:
t = [22.3 22.1 21.9 68.8]
Out[0]:
1×4 Matrix{Float64}:
 22.3  22.1  21.9  68.8

68.8是一个明显的异常值! 应排除在计算之外。 为此,请使用以下算法:计算测量值的平均值,并找到与平均值的偏差。 然后我们找到样本的标准偏差,并排除那些与平均值的偏差大于样本标准偏差的测量值。 下面给出该算法的实现。:

In [ ]:
import Pkg
Pkg.add("Statistics")
using Statistics

meandev = abs(t .- mean(t))
stddev = std(t)
valid_nums = meandev .< stddev
t_valid = t[valid_nums]
   Resolving package versions...
     Project No packages added to or removed from `~/.project/Project.toml`
    Manifest No packages added to or removed from `~/.project/Manifest.toml`
Out[0]:
3-element Vector{Float64}:
 22.3
 22.1
 21.9

该算法可以建模为:

image.png

在输出端,我们将有一个位掩码,其中0意味着传感器应该被排除在计算之外。

体重管理

前面,在算法的描述中,我们介绍了传感器权重的概念。 让我提醒你,重量是传感器信心的衡量标准。 假设在传感器故障及其后续恢复之后,我们开始对传感器的信任度降低。 这意味着我们必须减轻它的重量。 而且,可以在传感器中输入置信度阈值,并从计算中排除权重低于某个阈值的传感器。

组装最终模型

算法的最终模型如下所示:

image.png

这里:
*滤波器子系统负责对信号进行滤波,由数字滤波器编辑器应用程序生成。
*异常值Clusion子系统负责消除异常值
*传感器验证子系统负责验证传感器

算法本身使用Engee功能块实现。:

mutable struct Block <: AbstractCausalComponent
    sensor_weights::Vector{Float64}
    function Block()
        dims = INPUT_SIGNAL_ATTRIBUTES[1].dimensions;
        new(vec(ones(1,prod(dims))))
        #new(vec(ones(1,4)))
    end

end

function (c::Block)(t::Real, TrustedSensors, sensor_data, SensorValid)
   if t<=0
      return(0.0,c.sensor_weights)
   end
   
   total_weight = sum(c.sensor_weights[TrustedSensors])
   sum_weight = sum(sensor_data[TrustedSensors].*c.sensor_weights[TrustedSensors])
   ret = sum_weight/total_weight;

   if isnan(ret)
      warning("Nan detected with values: TW $total_weight, SW: $sum_weight")
      pause_simulation()
   end

   返回(ret,c.sensor_weights)
结束

功能更新!(c::Block,t::Real,TrustedSensors,sensor_data,SensorValid)
    如果!isempty(c.sensor_weights[.!SensorValid])
        c.sensor_weights[。!SensorValid]。-= 0.001
    结束
    c.sensor_weights[c.sensor_weights.< 0] .= 0
    返回c
结束
```</span>
{%endcut%}

请注意,该模型已经矢量化,可以处理任意数量的传感器。 传感器验证子系统也值得关注。 这是ForEach子系统类型的子系统,它允许您为矢量信号的每个元素执行子系统的内容。

此外,还引入了重量限制。

测试算法

让我们检查一下我们的算法是否有效。 让我们建立一个测试模型:
main_model.png

4传感器进行建模(传感器模型如上所述)。 还模拟了第四传感器的故障。 算法模型本身作为参考模型插入。

让我们来看看算法在没有失败的情况下的行为。:

In [ ]:
mdl = engee.load(joinpath(@__DIR__,"FusionTestbed.engee"));
engee.set_param!("FusionTestbed/Fault","PortValue"=>false);
simResult = engee.run(mdl);
In [ ]:
using Plots
gr()
sensors = collect(simResult["SigGlue.1"]);
fusion = collect(simResult["SensorAlgo.FusedSignal"]);
p1 = plot(sensors.time,stack(sensors.value,dims=1),title="Raw Data",label=["传感器1" "传感器2" "传感器3" "传感器4"]);
p2 = plot(fusion.time,fusion.value,title="Fusion",label="Fusion");
plot(p1, p2, layout=(2, 1), link=:x, legend=:outerright)
Out[0]:
No description has been provided for this image

现在让我们模拟第四个传感器的故障并查看结果。:

In [ ]:
engee.set_param!("FusionTestbed/Fault","PortValue"=>true)
simResult = engee.run(mdl)
sensors = collect(simResult["SigGlue.1"]);
fusion = collect(simResult["SensorAlgo.FusedSignal"]);
p1 = plot(sensors.time,stack(sensors.value,dims=1),title="Raw Data",label=["传感器1" "传感器2" "传感器3" "传感器4"]);
p2 = plot(fusion.time,fusion.value,title="Fusion",label="Fusion");
plot(p1, p2, layout=(2, 1), link=:x, legend=:outerright)
Out[0]:
No description has been provided for this image

可以看出,传感器故障并没有影响算法的运行。 因此,我们获得了使用多个传感器测量某个值的容错算法。

结论

该项目考虑了一个容错测量算法,并演示了一个方法正确的方法组织测量与多个传感器。 作为该项目的开发,应考虑更详细的传感器模型,例如,精度等级。