Engee 文档
Notebook

MIC32代码生成(模糊控制器测试)

本演示展示了Engee模型的开发,用于在整个输入信号范围内测试模糊控制器,并将输出输出到MIK32V2微控制器的DAC。

导言

该示例的目的是测试具有两个输入和一个输出的模糊控制器的操作。 模糊控制器模型由Engee基础库的单独块组装而成,便于熟悉控制器的功能特性。 本演示中使用的目标设备是MIK32NUKE v0调试板。3基于微控制器*[K1948VK018MIK32Amur](https://mikron.ru/products/mikrokontrollery/mk32-amur /)。 代码通过PlatformIO扩展从VS Code*编译并上传到微控制器。

模型描述

模型的一般视图如下图所示。

mik32_fuzzy_model.png

它由用于设置两个输入、测试信号的块、具有两个输入和一个输出的模糊控制器的子系统、用于缩放输出信号的子系统和hal库MIC32的外围块组成。

调节器的输入和输出

来自[重复序列阶梯]块的重复可变离散信号被施加到控制器的输入(https://engee.com/helpcenter/stable/ru/base-lib-sources/repeating-sequence-stair.html ):

In [ ]:
# 输入信号:
x1_data = Vector(range(-2,2,105))
x2_data = Vector(range(-2,2,21))

# 取样步骤:
Ts = 0.01

using Plots
gr()
plot([x1_data,x2_data]; label=["x1_data" "x2_data"],
     st=:step, title = "输入信号", aspect_ratio=10)
Out[0]:
No description has been provided for this image

输入信号的这种设置允许您在一个和第二个信号的整个值范围内检查控制器输出信号的计算结果。

子系统操作 scaling 它包括改变值的范围和控制器的输出信号的数据类型: :

mik32_output_model.png

信号限制在0到4095之间,因为MIC32Dac具有12位比特率,数据格式为整数、无符号、2字节。

模糊控制器的结构

模糊控制器根据Mamdani算法构建,由相同的模糊化和聚合块,激活块(min函数),累积块(max函数)和去模糊化块(单点集的重心法,COGS)组成。

mik32_fuzzy_controller_model_2.png

输入信号的语言项数为3,输出信号为3。

模糊化和聚集

输入变量有三个语言术语,它们接受"低"范围内的非零真值: ,"平均": ,"高": . 在聚合阶段,对输入信号应用相对于零对称的三角隶属函数(AF)。 在子系统中 fuzzyfication OP以块[1-D查找表](https://engee.com/helpcenter/stable/ru/base-lib-tables/1d-lookup-table.html )。 下面给出了输入变量项的AF计算。

In [ ]:
# X1的OP
μ_S_x1 = -x1_data;
μ_M_x1 = 1.0.-abs.(x1_data);
μ_L_x1 = copy(x1_data);

μ_x1 = [μ_S_x1, μ_M_x1, μ_L_x1];

# X2的OP
μ_S_x2 = -x2_data;
μ_M_x2 = 1.0.-abs.(x2_data);
μ_L_x2 = copy(x2_data);

μ_x2 = [μ_S_x2, μ_M_x2, μ_L_x2];

термы = ["低" "平均" "高"];

输入饱和函数:

In [ ]:
函数饱和度(μ)
    for i in 1:length(μ) 
        if μ[i] > 1
            μ[i] = 1.0
        end
        if μ[i] < 0
            μ[i] = 0.0
        end
    end 
end;

对术语应用饱和度,构造成员函数:

In [ ]:
for i in 1:3
    饱和度(μ_x1[i])
end

for i in 1:3
    饱和度(μ_x2[i])
end

график1 = plot(x1_data, μ_x1; title = "X1的OP", label = термы, xlabel = "x1")
график2 = plot(x2_data, μ_x2; title = "X2的OP", label = :none, xlabel = "x2")
图(图1,图2;
     ylabel = "隶属度,μ", legend = :right, aspect_ratio=3)
Out[0]:
No description has been provided for this image

激活

在子系统中的激活阶段 activation 定义了所有术语组合的结论。 激活由最小函数执行:

积累

在子系统中 accumulation 以下规则库被再现:

  1. 如果( "低" "低" "平均"))然后 "低"
  2. 如果( "低" "高")
    ( "平均" "低" "平均"))
    ( "高" "低")然后 "平均"
  3. 如果( "平均" "高")
    ( "高" "平均" "高")) "高"

为了清楚起见,让我们以表格的形式呈现它。:

In [ ]:
колонки = ["低", "平均", "高"];
=复制(列);
baza_edited=[
                "低" "平均" "平均";
                "低" "平均" "高";
                "平均" "高" "高"
               ];
(n,m)=大小(base_edit)

heatmap(base_edit,fc=cgrad([:blue;:red;:green]),leg=false,xticks=(1:3,列),yticks=(1:3,行))
title!("规则库")
xlabel!("条款x1")
ylabel!("条款x2")
注释!([(j,i,base_added[i,j])对于i in1:n对于j in1:m])
vline!(0.5:(n+0.5), c=:black)
hline!(0.5:(m+0.5), c=:black)
Out[0]:

输出项的真实程度是根据表达式从结论中确定的最大函数:

脱雾化;脱雾化

在子系统中 defuzzyfication 实现了单点集(COGS)的重心法。 输出项的隶属函数的中点: . 计算是在不将隶属度降低到总和的情况下实现的( )和一个演员( ). 对于建模和测试,我们进一步使用第一种方法。

mik32_defuzzy_model.png

模拟结果

下载并执行示例模型:

In [ ]:
# @markdown**软件建模管理:**
# @markdown要求您只输入模型名称
имя_модели = "mik32_fuzzy_reg" # @param {type:"string"}
如果模型名称在[m.name 为m在engee。get_all_models()]
    模型=engee。open(型号名称);
else
    модель = engee.load( "$(@__DIR__)/"*имя_модели*".engee" );
end
数据=engee。运行(模型);

绘制输出变量

In [ ]:
plot(данные["dac_val"].time, данные["dac_val"].value;
     label="y", title="的输出信号", xlims=(0,1.1))
Out[0]:

该信号包含在加载到控制器中的程序中,并将被传输到数模转换器。

模型中的控制器外设使用[C函数]块实现(https://engee.com/helpcenter/stable/ru/base-lib-user-defined-function/c-function.html ),因为它在MIC32的早期DAC示例中实现:[锯齿信号](https://engee.com/community/ru/catalogs/projects/mik32-generator-piloobraznykh-signalov ),Engee标志

代码生成和项目汇编

In [ ]:
# @markdown**代码生成:**
# @markdown将在脚本文件夹中创建代码生成结果的文件夹:
папка = "code" # @param {type:"string"}

# 子系统的@markdown代码生成:
включить = false # @param {type:"boolean"}
如果(启用)
    подсистема = "" # @param {type:"string"}
    engee.generate_code( "$(@__DIR__)/"*имя_модели*".engee", "$(@__DIR__)/"*папка;
                     subsystem_name=子系统)
else
    engee.generate_code( "$(@__DIR__)/"*имя_модели*".engee", "$(@__DIR__)/"*папка)
end
[ Info: Generated code and artifacts: /user/start/examples/codegen/mik32_fuzzy/code

带有模型的项目在IDE中组装VS Code+PlatformIO,组装过程类似于示例中的过程*[MIC32:锯齿信号发生器](https://engee.com/community/ru/catalogs/projects/mik32-generator-piloobraznykh-signalov )*。
唯一的例外是编译的程序不是加载到控制器的RAM中,而是通过SPIFI接口加载到闪存中。 配置文件附加到示例中的配置PlatformIO。 platformio.ini. 让我们继续在微控制器上执行代码。

在MIK32上执行代码

在成功组装和编译项目后,我们将一个示波器连接到P1.12微控制器通道并显示示波器。

mik32_fuzzy_results.gif

从波形可以看出,在DAC通道中再现了被测模糊控制器模拟输出信号的形状。

结论

在这个例子中,我们检查了Engee模型中模糊控制器的结构,模拟了其测试,并在从模型生成代码后在MIC32Amur微控制器上测试了控制器。 控制器上的仿真和测试结果完全相同,并与指定的算法相对应。