该演示介绍了Engee模型的开发过程,该模型用于测试一个模糊调节器,测试范围包括全部输入信号以及输出到MIK32V2微控制器 DAC 的信号。
本例的目的是测试具有两个输入和一个输出的模糊调节器的运行情况。模糊调节器模型由 Engee 基本库的各个模块构建而成,便于熟悉调节器的功能。本演示使用的目标设备是基于 K1948VK018 MIK32 Amur 微控制器的 MIK32 NUKE V0.3 调试板。代码的编译和加载是通过 VS Code 和 PlatformIO 扩展完成的。
它由两个输入分配块、测试信号、一个具有两个输入和一个输出的模糊控制器子系统、一个输出缩放子系统以及 HAL 库中的 MIC32 外设块组成。
这样设置输入信号,就可以在一个信号和另一个信号的整个数值范围内检查控制器输出计算的结果。
子系统scaling
的工作包括更改调节器输出信号的数值范围和数据类型:$dac\_val = 2048\cdot (y+1)$:
由于 MIC32 DAC 为 12 位,数据格式为整数、无符号、2 字节,因此信号范围限制在 0 至 4095 之间。
模糊控制器以 Mamdani 算法为基础,由相同的分阶段和聚合块、激活块(最小函数)、累积块(最大函数)、去模糊化块(单点集重心法,COGS)组成。
输入变量有三个语言项,其真值范围均为非零 - "LOW"(低):$x_S \in(-\infty;\ 0)$中":$x_M \in(-1;\ 1)$高":$x_L \in(0;\ \infty)$ 。在汇总阶段,与零对称的三角形成员函数(FP)被应用于输入信号。在fuzzyfication
子系统中,FP 由 1-D 查找表 块复制。输入变量项的 TPs 计算如下。
在激活步骤中,子系统activation
中定义了所有术语组合的子结论。激活由最小函数完成:
$$\mu_{SS} = \min(\mu_{1S},\mu_{2S}),\
\mu_{SM} = \min(\mu_{1S},\mu_{2M}),\
\mu_{SL} = \min(\mu_{1S},\mu_{2L})$$
$$\mu_{MS} = \min(\mu_{1M},\mu_{2S}),\
\mu_{MM} = \min(\mu_{1M},\mu_{2M}),\
\mu_{ML} = \min(\mu_{1M},\mu_{2L})$$
$$\mu_{LS} = \min(\mu_{1L},\mu_{2S}),\
\mu_{LM} = \min(\mu_{1L},\mu_{2M}),\
\mu_{LL} = \min(\mu_{1L},\mu_{2L})$$
accumulation
子系统中复制了以下规则库:
1.if ($x_{1}=$ "low" and ( "low" or "medium"))and ($x_{2}=$ "low" or$x_{2}=$ "medium"))则***$y =$ "低"。
2.if** ($x_{1}=$ "低" and$x_{2}=$ "高") or
($x_{1}=$ "中等"。and ($x_{2}=$ "low" or$x_{2}=$ "medium") ))或
($x_{1}=$ "高" ** 和$x_{2}=$ "低") **到$y =$ "中"。
3. 如果** ($x_{1}=$ "中" ** 和$x_{2}=$ "高") **or
($x_{1}=$ "高"and ($x_{2}=$ "medium" or$x_{2}=$ "high"))TO$y =$ "高"
根据表达式,输出项的真度定义在子结论的最大函数中:
$$\mu_{y_S} = \max(\mu_{SS},\ \mu_{SM}),$$
$$\mu_{y_M} = \max(\mu_{SL},\ \mu_{MS},\ \mu_{MM},\ \mu_{LS}),$$
$$\mu_{y_L} = \max(\mu_{ML},\ \mu_{LM},\ \mu_{LL})$$
子系统defuzzyfication
采用单点集重心法 (COGS)。输出项成员函数的中点为:$y_S= -1;\ y_M= 0;\ y_L= 1$ 。计算在没有 ($y$ ) 和有 ($y_1$ ) 的情况下进行。我们使用第一种方法进行建模和测试。
将程序中的信号加载到控制器中,并将其发送到数模转换器。
[ Info: Generated code and artifacts: /user/start/examples/codegen/mik32_fuzzy/code
包含模型的项目在集成开发环境 VS Code+PlatformIO 中构建,构建过程与示例 MIC32: 锯齿波信号发生器中的过程类似。
唯一不同的是,编译后的程序不是加载到控制器的 RAM 中,而是通过 SPIFI 接口加载到闪存中。在示例中配置 PlatformIO 时,配置文件platformio.ini
附后。下面我们继续在微控制器上执行代码。
成功组装和编译项目后,将示波器连接到微控制器的 P1.12 频道并显示示波器图。
从振荡图中可以看出,DAC 通道再现了被测模糊控制器的模拟输出信号的形状。
在本示例中,我们考虑了 Engee 模型中模糊控制器的结构,模拟了其测试,并在根据模型生成代码后在 MIC32 Amur 微控制器上测试了控制器。控制器的建模和测试结果与指定算法完全一致。
{"id": "883db1bc-effa-410d-8a28-d8c4c0db9f9b", "data": [{"showlegend": false, "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y1", "colorscale": [[0, "rgba(0, 0, 255, 1.000)"], [0.5, "rgba(255, 0, 0, 1.000)"], [1, "rgba(0, 128, 0, 1.000)"]], "yaxis": "y", "zmin": 0.5, "z": [[0.5, 1.5, 1.5], [0.5, 1.5, 2.5], [1.5, 2.5, 2.5]], "zmax": 2.5, "y": [0.5, 1.5, 2.5, 3.5], "type": "heatmap", "showscale": false, "x": [0.5, 1.5, 2.5, 3.5], "zaxis": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 4, "currentCount": 4}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y2", "zmin": 0.5, "yaxis": "y", "legendgroup": "y2", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [-299.5, 303.5], "type": "scatter", "x": [0.5, 0.5], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": false, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y2", "zmin": 0.5, "yaxis": "y", "legendgroup": "y2", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [-299.5, 303.5], "type": "scatter", "x": [1.5, 1.5], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": false, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y2", "zmin": 0.5, "yaxis": "y", "legendgroup": "y2", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [-299.5, 303.5], "type": "scatter", "x": [2.5, 2.5], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": false, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y2", "zmin": 0.5, "yaxis": "y", "legendgroup": "y2", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [-299.5, 303.5], "type": "scatter", "x": [3.5, 3.5], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y3", "zmin": 0.5, "yaxis": "y", "legendgroup": "y3", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.5, 0.5], "type": "scatter", "x": [-533.1246518237803, 537.1246518237803], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": false, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y3", "zmin": 0.5, "yaxis": "y", "legendgroup": "y3", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [1.5, 1.5], "type": "scatter", "x": [-533.1246518237803, 537.1246518237803], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": false, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y3", "zmin": 0.5, "yaxis": "y", "legendgroup": "y3", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [2.5, 2.5], "type": "scatter", "x": [-533.1246518237803, 537.1246518237803], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}, {"showlegend": false, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9943757030371203}, "name": "y3", "zmin": 0.5, "yaxis": "y", "legendgroup": "y3", "zmax": 2.5, "line": {"color": "rgba(0, 0, 0, 1)", "shape": "linear", "dash": "solid", "width": 1}, "y": [3.5, 3.5], "type": "scatter", "x": [-533.1246518237803, 537.1246518237803], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 2, "currentCount": 2}}}], "config": {"showlegend": false, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [1, 2, 3], "range": [-0.6623117006158221, 4.662311700615822], "domain": [0.11633858267716533, 0.9943757030371203], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["низкое", "среднее", "высокое"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "Термы x1", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [{"yanchor": "top", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "paper", "showarrow": false, "text": "База правил", "xref": "paper", "x": 0.5553571428571429}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "низкое", "xref": "x", "x": 1}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "среднее", "xref": "x", "x": 2}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "среднее", "xref": "x", "x": 3}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 2, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "низкое", "xref": "x", "x": 1}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 2, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "среднее", "xref": "x", "x": 2}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 2, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "высокое", "xref": "x", "x": 3}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 3, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "среднее", "xref": "x", "x": 1}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 3, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "высокое", "xref": "x", "x": 2}, {"yanchor": "middle", "xanchor": "center", "rotation": 0, "y": 3, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "y", "showarrow": false, "text": "высокое", "xref": "x", "x": 3}], "height": 400, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [1, 2, 3], "range": [0.5, 3.5], "domain": [0.07581474190726165, 0.9415463692038496], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["низкое", "среднее", "высокое"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "Термы x2", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "width": 679}}
{"id": "86b2128e-7898-40df-926d-edeb4b4a316e", "data": [{"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.48958333333333337, "title": {"text": ""}, "len": 0.9039260717410325, "x": 0.5254622736082012}, "name": "y", "yaxis": "y", "legendgroup": "y", "line": {"color": "rgba(0, 154, 250, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 409, 409, 819, 819, 1228, 1228, 1638, 1638, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 409, 409, 819, 819, 1228, 1228, 1638, 1638, 2048, 2048, 2457, 2457, 2599, 2599, 2678, 2678, 2756, 2756, 2835, 2835, 2914, 2914, 2993, 2993, 3072, 3072, 3150, 3150, 3229, 3229, 787, 787, 708, 708, 630, 630, 551, 551, 472, 472, 393, 393, 409, 409, 819, 819, 1228, 1228, 1638, 1638, 2048, 2048, 2457, 2457, 2867, 2867, 3276, 3276, 3686, 3686, 3702, 3702, 3623, 3623, 3544, 3544, 3465, 3465, 3387, 3387, 3308, 3308, 866, 866, 945, 945, 1024, 1024, 1102, 1102, 1181, 1181, 1260, 1260, 1748, 1748, 2237, 2237, 2725, 2725, 3213, 3213, 3702, 3702, 3686, 3686, 3276, 3276, 3276, 3276, 3686, 3686, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2457, 2457, 2867, 2867, 3276, 3276, 3686, 3686, 4095, 4095, 3686, 3686, 3276, 3276, 3276, 3276, 3686, 3686, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "type": "scatter", "x": [0, 0.01, 0.01, 0.02, 0.02, 0.03, 0.03, 0.04, 0.04, 0.05, 0.05, 0.06, 0.06, 0.07, 0.07, 0.08, 0.08, 0.09, 0.09, 0.1, 0.1, 0.11, 0.11, 0.12, 0.12, 0.13, 0.13, 0.14, 0.14, 0.15, 0.15, 0.16, 0.16, 0.17, 0.17, 0.18, 0.18, 0.19, 0.19, 0.2, 0.2, 0.21, 0.21, 0.22, 0.22, 0.23, 0.23, 0.24, 0.24, 0.25, 0.25, 0.26, 0.26, 0.27, 0.27, 0.28, 0.28, 0.29, 0.29, 0.3, 0.3, 0.31, 0.31, 0.32, 0.32, 0.33, 0.33, 0.34, 0.34, 0.35, 0.35, 0.36, 0.36, 0.37, 0.37, 0.38, 0.38, 0.39, 0.39, 0.4, 0.4, 0.41, 0.41, 0.42, 0.42, 0.43, 0.43, 0.44, 0.44, 0.45, 0.45, 0.46, 0.46, 0.47, 0.47, 0.48, 0.48, 0.49, 0.49, 0.5, 0.5, 0.51, 0.51, 0.52, 0.52, 0.53, 0.53, 0.54, 0.54, 0.55, 0.55, 0.56, 0.56, 0.57, 0.57, 0.58, 0.58, 0.59, 0.59, 0.6, 0.6, 0.61, 0.61, 0.62, 0.62, 0.63, 0.63, 0.64, 0.64, 0.65, 0.65, 0.66, 0.66, 0.67, 0.67, 0.68, 0.68, 0.69, 0.69, 0.7, 0.7, 0.71, 0.71, 0.72, 0.72, 0.73, 0.73, 0.74, 0.74, 0.75, 0.75, 0.76, 0.76, 0.77, 0.77, 0.78, 0.78, 0.79, 0.79, 0.8, 0.8, 0.81, 0.81, 0.82, 0.82, 0.83, 0.83, 0.84, 0.84, 0.85, 0.85, 0.86, 0.86, 0.87, 0.87, 0.88, 0.88, 0.89, 0.89, 0.9, 0.9, 0.91, 0.91, 0.92, 0.92, 0.93, 0.93, 0.94, 0.94, 0.95, 0.95, 0.96, 0.96, 0.97, 0.97, 0.98, 0.98, 0.99, 0.99, 1, 1, 1.01, 1.01, 1.02, 1.02, 1.03, 1.03, 1.04, 1.04, 1.05, 1.05, 1.06, 1.06, 1.07, 1.07, 1.08, 1.08, 1.09, 1.09, 1.1, 1.1], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 221, "currentCount": 221}}}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 0.25, 0.5, 0.75, 1], "range": [0, 1.1], "domain": [0.5253313771854498, 0.5254622736082012], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0.00", "0.25", "0.50", "0.75", "1.00"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [{"yanchor": "top", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "paper", "showarrow": false, "text": "Выходной сигнал", "xref": "paper", "x": 0.5253968253968254}], "height": 400, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 1000, 2000, 3000, 4000], "range": [-122.84999999999991, 4217.85], "domain": [0.03762029746281716, 0.9415463692038496], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0", "1000", "2000", "3000", "4000"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "auto", "xanchor": "auto", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 1}, "width": 679}}