3. 隶属度函数选择与参数设置

任务目标

为模糊PID控制器中的输入变量(误差e、误差变化率ec)和输出变量(ΔKp、ΔKi、ΔKd)设计隶属度函数,选择三角形或高斯型,并设置各变量的模糊论域与隶属度函数参数。

变量定义与论域设置

输入变量e和ec的模糊论域均设为[-3, 3],输出变量ΔKp、ΔKi、ΔKd的论域分别设为[-0.3, 0.3]、[-0.06, 0.06]、[-3, 3]。每个变量定义7个语言值:NB(负大)、NM(负中)、NS(负小)、ZO(零)、PS(正小)、PM(正中)、PB(正大)。

隶属度函数实现

以下Python代码定义三角形与高斯型隶属度函数的计算逻辑,并完成全部变量的参数设置。三角形函数使用三个顶点参数(a, b, c),高斯型函数使用中心c和宽度σ。

```python import numpy as np class FuzzySet: """隶属度函数集合,支持三角形与高斯型""" def __init__(self, name, mf_type, params): self.name = name self.mf_type = mf_type # 'tri' 或 'gauss' self.params = params # tri: (a,b,c); gauss: (c, sigma) def membership(self, x): if self.mf_type == 'tri': a, b, c = self.params if x <= a or x >= c: return 0.0 elif x == b: return 1.0 elif a < x < b: return (x - a) / (b - a) else: return (c - x) / (c - b) elif self.mf_type == 'gauss': c, sigma = self.params return np.exp(-0.5 * ((x - c) / sigma) ** 2) else: raise ValueError(f"不支持的隶属度函数类型: {self.mf_type}") def create_variable_mfs(var_name, universe, mf_type='tri'): """为变量创建7个语言值的隶属度函数""" n = len(universe) step = (universe[-1] - universe[0]) / 6 # 7个语言值均分论域 labels = ['NB', 'NM', 'NS', 'ZO', 'PS', 'PM', 'PB'] mfs = {} for i, label in enumerate(labels): center = universe[0] + i * step if mf_type == 'tri': # 三角形参数:左顶点、中心、右顶点 a = center - step b = center c = center + step # 边界处扩展顶点,保证覆盖完整论域 if i == 0: a = -np.inf elif i == 6: c = np.inf mfs[label] = FuzzySet(f"{var_name}_{label}", 'tri', (a, b, c)) elif mf_type == 'gauss': # 高斯参数:中心、标准差(取step/2使相邻函数有合理重叠) sigma = step / 2 mfs[label] = FuzzySet(f"{var_name}_{label}", 'gauss', (center, sigma)) return mfs # ========== 参数设置 ========== # 输入变量论域 e_universe = [-3, 3] ec_universe = [-3, 3] # 输出变量论域 dkp_universe = [-0.3, 0.3] dki_universe = [-0.06, 0.06] dkd_universe = [-3, 3] # 选择隶属度函数类型:e和ec用高斯型,输出用三角形 e_mfs = create_variable_mfs('e', e_universe, mf_type='gauss') ec_mfs = create_variable_mfs('ec', ec_universe, mf_type='gauss') dkp_mfs = create_variable_mfs('dkp', dkp_universe, mf_type='tri') dki_mfs = create_variable_mfs('dki', dki_universe, mf_type='tri') dkd_mfs = create_variable_mfs('dkd', dkd_universe, mf_type='tri') # ========== 验证:打印关键参数 ========== print("=== e变量(高斯型)参数 ===") for label in ['NB', 'ZO', 'PB']: fs = e_mfs[label] print(f"{label}: 中心={fs.params[0]:.2f}, σ={fs.params[1]:.2f}") print("\n=== dkp变量(三角形)参数 ===") for label in ['NB', 'ZO', 'PB']: fs = dkp_mfs[label] print(f"{label}: a={fs.params[0]:.2f}, b={fs.params[1]:.2f}, c={fs.params[2]:.2f}") # ========== 验证:隶属度计算示例 ========== test_points = [-3, -1, 0, 1, 3] print("\n=== 隶属度计算验证 ===") for x in test_points: e_nb = e_mfs['NB'].membership(x) e_zo = e_mfs['ZO'].membership(x) e_pb = e_mfs['PB'].membership(x) print(f"x={x:+.1f}: NB={e_nb:.3f}, ZO={e_zo:.3f}, PB={e_pb:.3f}") # 验证三角形函数在边界处的覆盖 print("\n=== 三角形边界覆盖验证 ===") for x in [-0.3, 0, 0.3]: dkp_nb = dkp_mfs['NB'].membership(x) dkp_pb = dkp_mfs['PB'].membership(x) print(f"x={x:+.2f}: NB={dkp_nb:.3f}, PB={dkp_pb:.3f}") ```

% 输入变量E(误差)隶属度函数 - 三角形
E_range = [-3 3];
E_mf = [-3 -2 -1; -2 -1 0; -1 0 1; 0 1 2; 1 2 3]; % 5个三角形: NB, NS, ZO, PS, PB
% 对应trimf参数: [a b c] 每行一个MF

% 输入变量EC(误差变化率)隶属度函数 - 高斯型
EC_range = [-1.5 1.5];
EC_sigma = 0.3;
EC_centers = [-1.5 -0.75 0 0.75 1.5]; % 5个高斯中心: NB, NS, ZO, PS, PB
% 对应gaussmf参数: [sigma center]

% 输出变量Kp, Ki, Kd隶属度函数 - 三角形
Kp_range = [0 3];
Kp_mf = [0 0 0.75; 0 0.75 1.5; 0.75 1.5 2.25; 1.5 2.25 3; 2.25 3 3]; % 5个: S, MS, M, MB, B

Ki_range = [0 1];
Ki_mf = [0 0 0.25; 0 0.25 0.5; 0.25 0.5 0.75; 0.5 0.75 1; 0.75 1 1];

Kd_range = [0 1];
Kd_mf = [0 0 0.25; 0 0.25 0.5; 0.25 0.5 0.75; 0.5 0.75 1; 0.75 1 1];

% 显示验证(可选)
figure;
subplot(2,2,1); hold on;
for i=1:5
    x = linspace(E_range(1), E_range(2), 100);
    y = trimf(x, E_mf(i,:));
    plot(x,y);
end
title('E - 三角形MF');
subplot(2,2,2); hold on;
for i=1:5
    x = linspace(EC_range(1), EC_range(2), 100);
    y = gaussmf(x, [EC_sigma EC_centers(i)]);
    plot(x,y);
end
title('EC - 高斯MF');
subplot(2,2,3); hold on;
for i=1:5
    x = linspace(Kp_range(1), Kp_range(2), 100);
    y = trimf(x, Kp_mf(i,:));
    plot(x,y);
end
title('Kp - 三角形MF');
subplot(2,2,4); hold on;
for i=1:5
    x = linspace(Ki_range(1), Ki_range(2), 100);
    y = trimf(x, Ki_mf(i,:));
    plot(x,y);
end
title('Ki - 三角形MF');

运行与验证

运行方式:直接执行上述Python脚本(需安装NumPy)。

验证方法:

  • 观察打印的高斯型参数:e变量论域[-3,3]被7个中心等距分割,间距为1.0,σ=0.5,相邻隶属度函数在中心点处重叠约60%(高斯函数在距离中心1σ处值为0.607),保证平滑过渡。
  • 观察三角形参数:dkp变量论域[-0.3,0.3]被均分为6段,步长0.1,NB的a为负无穷、PB的c为正无穷,确保边界处隶属度不为0。
  • 隶属度计算验证:在x=-3处,NB隶属度应为1.0(高斯中心在-3);x=0处ZO隶属度应为1.0;x=3处PB隶属度应为1.0。三角形边界验证中,x=-0.3处NB隶属度为1.0,x=0.3处PB隶属度为1.0。

通过条件:所有打印值与上述预期一致,且无报错。

设计说明

输入变量采用高斯型隶属度函数,因其导数连续,对误差变化更敏感,适合PID参数在线调整场景;输出变量采用三角形隶属度函数,计算简单且易于解模糊,适合实时控制。论域范围根据PID增量式调整的典型幅度设定,实际应用时可依据被控对象特性等比缩放。