Engee 文档
Notebook

用模糊PID控制器识别控制系统对象

在此示例中,一次解决两个任务。 首先,我们根据实验数据识别控制对象。 其次,我们正在实现PID控制器的模糊输出系统。

In [ ]:
EngeePkg.purge()
In [ ]:
Pkg.add(["ControlSystemIdentification", "FuzzyLogic"])
using ControlSystemIdentification, FuzzyLogic

让我提醒你,识别工作流程看起来像这样:

  1. 收集实验数据

  2. 选择模型结构

  3. 模型的识别

  4. 模型的验证

理对象的标识

从管理设施收集实验数据

在工厂中提出了控制设施的实验安装的模拟。engee模型。 控制对象是一个具有一个输入和一个输出的离散系统。 噪声和轻微的延迟也被添加到模型中。

对象的识别将通过过渡过程进行,为此我们将在系统入口处提供一个步骤。

Plant--1753359832841.png

让我们记录识别数据。:

In [ ]:
mode = 1; # 记录识别数据
if "Plant" in [m.name for m in engee.get_all_models()]
    m = engee.open( "Plant" ) # 加载模型
else
    m = engee.load( "Plant.engee" )
end
results = engee.run(m, verbose=true)
Building...
Progress 0%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    run_id => 1,
    "out" => WorkspaceArray{Float64}("Plant/out")
,
    "in" => WorkspaceArray{Float64}("Plant/in")

)
In [ ]:
dataout = collect(results["out"]);
datain = collect(results["in"]);
# 系统从时间矢量的采样率
Ts = dataout.time[2] - dataout.time[1]
ident_data = iddata(dataout.value, datain.value, Ts)
plot(ident_data)
Out[0]:

让我们记录模型验证的数据。:

In [ ]:
mode = 0; # 写入数据进行验证
if "Plant" in [m.name for m in engee.get_all_models()]
    m = engee.open( "Plant" ) # 加载模型
else
    m = engee.load( "Plant.engee" )
end
results = engee.run(m, verbose=true)
Building...
Progress 0%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    run_id => 2,
    "out" => WorkspaceArray{Float64}("Plant/out")
,
    "in" => WorkspaceArray{Float64}("Plant/in")

)
In [ ]:
dataout = collect(results["out"]);
datain = collect(results["in"]);
# 系统从时间矢量的采样率
Ts = dataout.time[2] - dataout.time[1]
val_data = iddata(dataout.value, datain.value, Ts)
plot(val_data)
Out[0]:

模型结构选择与识别

我们将在状态空间中识别线性静止系统。 让我们选择系统等于3的顺序。

为了识别,我们将选择pem(预测-误差方法)预测误差方法。 这是一种简单而有效的算法,用于以状态空间的形式识别具有离散时间的线性静止系统。 该方法还允许您获取系统的初始状态。

In [ ]:
nx = 3
sys_obj = subspaceid(ident_data, nx; r = 20);
sys, x0 = newpem(
    ident_data, nx;
    sys0   = sys_obj.sys,   # 亚太平洋模型
    focus  = :simulation
);
Warning: x_tol is deprecated. Use x_abstol or x_reltol instead. The provided value (0) will be used as x_abstol.
@ Optim /usr/local/ijulia-demos/packages/Optim/gmigl/src/types.jl:110
Iter     Function value   Gradient norm 
     0     6.209732e-03     1.261412e+00
 * time: 0.0360410213470459
    50     2.080925e-04     4.100484e-03
 * time: 1.891798973083496
   100     2.061785e-04     4.294817e-04
 * time: 1.9036390781402588
   150     2.059015e-04     4.564776e-04
 * time: 1.9153389930725098
   200     2.058087e-04     2.349875e-04
 * time: 1.9857029914855957

模型的验证

让我们在用于识别的相同数据上检查识别。

In [ ]:
simplot(ident_data, sys)
Out[0]:

我们将在一个特殊的验证数据集上检查它。

In [ ]:
simplot(val_data, sys)
Out[0]:

该方法显示出良好的鉴定结果。

模糊PID控制器控制系统

让我们回到使用模糊控制器对控制系统进行建模。 我们从实验数据中获得了控制对象的模型。

Fuzzycontroller--1753369066574.png

识别结果将在离散状态空间块中用于对控制对象进行建模。

Fuzzycontroller--1753369100219.png

它仍然是将控制器添加到控制系统电路中。 此示例使用以下模糊逻辑控制器结构:

Fuzzycontroller--1753362744936.png

在模糊输出系统的输入端接收归一化误差值 和派生的错误 . 使用缩放因子对输入值进行归一化。 使它们在[-1,1]范围内。

模糊输出系统输出范围为[-1,1]的结果,该结果按系数缩放 .

In [ ]:
CE = 10;
CD = 4.9829;
C0 = 2.5179;
C1 = 1.8103;

模糊推理系统表示为查找表的块。 形成该表的响应表面的过程如下所示:

In [ ]:
fis = @sugfis function FCtrl(E, delE)::U
    E := begin
        domain = -10.0:10.0
        N = GaussianMF(-10.0, 7.0)
        P = GaussianMF(10.0, 7.0)
    end

    delE := begin
        domain = -10.0:10.0
        N = GaussianMF(-10.0, 7.0)
        P = GaussianMF(10.0, 7.0)
    end    

    U := begin
        domain = -20.0:20.0
        Min = -20.0
        Zero = 0.0
        Max  = 20.0
    end

   # 工作规则
   E == N  && delE == N  -->  U == Min
   E == N  && delE == P  -->  U == Zero
   E == P  && delE == N  -->  U == Zero
   E == P  && delE == P  -->  U == Max

end;
In [ ]:
plot(fis, :E, ylabel="附件功能", w = 2)
Out[0]:
In [ ]:
plot(fis, :delE, ylabel="附件功能", w = 2)
Out[0]:

让我们创建一个响应表面,以便将其放置在查找表块中。

In [ ]:
errBrkpts = -10.0:0.5:10.0 
rateBrkpts = -10.0:0.5:10.0
LookUpTableData = zeros(length(errBrkpts), length(rateBrkpts))
i = 0;
for e in errBrkpts
    i = i+1
    j = 0;
    for de in rateBrkpts
        j = j+1
        LookUpTableData[i, j] = fis([e, de])[:U]
    end
end
surface(errBrkpts, rateBrkpts, LookUpTableData, xlabel="ΔE", ylabel="E", zlabel="U", title="响应面", camera=(30, 30))
Out[0]:

让我们运行控制系统模型并检查调节器的运行情况。

In [ ]:
if "Fuzzycontroller" in [m.name for m in engee.get_all_models()]
    m = engee.open( "Fuzzycontroller" ) # 加载模型
else
    m = engee.load( "Fuzzycontroller.engee" )
end
fuzzyresults = engee.run(m, verbose=true)
Building...
Progress 0%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    run_id => 3,
    "out" => WorkspaceArray{Float64}("Fuzzycontroller/out")
,
    "in" => WorkspaceArray{Float64}("Fuzzycontroller/in")

)
In [ ]:
fuzzydataout = collect(fuzzyresults["out"]);
fuzzydatain = collect(fuzzyresults["in"]);

在图表中,我们看到控制系统对逐步影响的响应。

In [ ]:
plot(fuzzydataout.time, fuzzydataout.value, titel = "模糊PID控制器控制系统", label="出口;出口")
plot!(fuzzydatain.time, fuzzydatain.value, label="入口处")
Out[0]:

结论

结果,我们得到了一个具有模糊PID控制器的工作控制系统。 事先并不知道对照对象的模型,而是根据实验数据通过鉴定获得的。