直流电机,传递函数,模糊控制pid算法,matlab代码

在自动控制领域,直流电机因其良好的调速性能而被广泛应用。而要精准地控制直流电机,传递函数以及模糊控制PID算法就成了关键技术,Matlab则为我们实现这些控制算法提供了强大的平台。

直流电机传递函数

直流电机的传递函数描述了输入量(通常是电枢电压)与输出量(电机转速或转角)之间的动态关系。以直流电机的转速控制为例,在忽略一些次要因素后,其传递函数可以表示为典型的二阶系统形式:

\[ G(s)=\frac{\omega(s)}{U(s)}=\frac{K}{Js^2 + Bs + KbKa} \]

其中,\( \omega(s) \) 是电机转速的拉普拉斯变换,\( U(s) \) 是电枢电压的拉普拉斯变换,\( K \) 是电机的增益系数,\( J \) 是电机转子的转动惯量,\( B \) 是电机的粘滞摩擦系数,\( Kb \) 是反电动势系数,\( Ka \) 是电机的转矩系数。

模糊控制PID算法

传统的PID控制在面对复杂、非线性系统时,控制效果可能不尽人意。而模糊控制PID算法结合了模糊控制的灵活性和PID控制的精确性。它通过模糊推理系统,根据输入的误差 \( e \) 和误差变化率 \( ec \) 来实时调整PID控制器的三个参数 \( Kp \)、\( Ki \)、\( K_d \)。

模糊化

首先,我们需要将输入的精确量(误差 \( e \) 和误差变化率 \( ec \))转化为模糊量。比如,我们可以将误差 \( e \) 划分为负大(NB)、负中(NM)、负小(NS)、零(ZO)、正小(PS)、正中(PM)、正大(PB)等模糊子集。

模糊规则制定

根据经验和控制要求,制定一系列模糊规则。例如:

  • 如果 \( e \) 是正大(PB)且 \( ec \) 是正大(PB),那么 \( Kp \) 取较大值,\( Ki \) 取较小值,\( K_d \) 取较小值。
  • 如果 \( e \) 是零(ZO)且 \( ec \) 是零(ZO),那么 \( Kp \) 取适中值,\( Ki \) 取适中值,\( K_d \) 取适中值。

模糊推理与解模糊

利用模糊规则进行推理,得到模糊输出。最后通过解模糊方法(如重心法)将模糊输出转化为精确的 \( Kp \)、\( Ki \)、\( K_d \) 参数值,用于PID控制器。

Matlab代码实现

下面是一个简单的Matlab代码示例,用于实现基于模糊控制PID的直流电机转速控制。

% 定义直流电机传递函数参数
J = 0.01; % 转动惯量
B = 0.1; % 粘滞摩擦系数
Kb = 0.1; % 反电动势系数
Ka = 0.1; % 转矩系数
K = 1; % 增益系数
num = [K];
den = [J B Kb*Ka];
sys = tf(num, den);

% 模糊控制器设计
fis = newfis('fuzzy_PID');

% 定义误差e的模糊变量
fis = addvar(fis, 'input', 'e', [-1 1]);
fis = addmf(fis, 'input', 1, 'NB', 'zmf', [-1 -0.5]);
fis = addmf(fis, 'input', 1, 'NM', 'trimf', [-1 -0.5 0]);
fis = addmf(fis, 'input', 1, 'NS', 'trimf', [-0.5 0 0.5]);
fis = addmf(fis, 'input', 1, 'ZO', 'trimf', [-0.2 0 0.2]);
fis = addmf(fis, 'input', 1, 'PS', 'trimf', [0 0.5 1]);
fis = addmf(fis, 'input', 1, 'PM', 'trimf', [0.5 1 1.5]);
fis = addmf(fis, 'input', 1, 'PB', 'smf', [0.5 1]);

% 定义误差变化率ec的模糊变量
fis = addvar(fis, 'input', 'ec', [-1 1]);
fis = addmf(fis, 'input', 2, 'NB', 'zmf', [-1 -0.5]);
fis = addmf(fis, 'input', 2, 'NM', 'trimf', [-1 -0.5 0]);
fis = addmf(fis, 'input', 2, 'NS', 'trimf', [-0.5 0 0.5]);
fis = addmf(fis, 'input', 2, 'ZO', 'trimf', [-0.2 0 0.2]);
fis = addmf(fis, 'input', 2, 'PS', 'trimf', [0 0.5 1]);
fis = addmf(fis, 'input', 2, 'PM', 'trimf', [0.5 1 1.5]);
fis = addmf(fis, 'input', 2, 'PB', 'smf', [0.5 1]);

% 定义Kp的模糊变量
fis = addvar(fis, 'output', 'Kp', [0 2]);
fis = addmf(fis, 'output', 1, 'NB', 'zmf', [0 0.5]);
fis = addmf(fis, 'output', 1, 'NM', 'trimf', [0 0.5 1]);
fis = addmf(fis, 'output', 1, 'NS', 'trimf', [0.5 1 1.5]);
fis = addmf(fis, 'output', 1, 'ZO', 'trimf', [0.8 1.2 1.6]);
fis = addmf(fis, 'output', 1, 'PS', 'trimf', [1 1.5 2]);
fis = addmf(fis, 'output', 1, 'PM', 'trimf', [1.5 2 2.5]);
fis = addmf(fis, 'output', 1, 'PB','smf', [1.5 2]);

% 定义Ki的模糊变量
fis = addvar(fis, 'output', 'Ki', [0 0.5]);
fis = addmf(fis, 'output', 2, 'NB', 'zmf', [0 0.1]);
fis = addmf(fis, 'output', 2, 'NM', 'trimf', [0 0.1 0.2]);
fis = addmf(fis, 'output', 2, 'NS', 'trimf', [0.1 0.2 0.3]);
fis = addmf(fis, 'output', 2, 'ZO', 'trimf', [0.2 0.3 0.4]);
fis = addmf(fis, 'output', 2, 'PS', 'trimf', [0.3 0.4 0.5]);
fis = addmf(fis, 'output', 2, 'PM', 'trimf', [0.4 0.5 0.6]);
fis = addmf(fis, 'output', 2, 'PB','smf', [0.4 0.5]);

% 定义Kd的模糊变量
fis = addvar(fis, 'output', 'Kd', [0 0.2]);
fis = addmf(fis, 'output', 3, 'NB', 'zmf', [0 0.05]);
fis = addmf(fis, 'output', 3, 'NM', 'trimf', [0 0.05 0.1]);
fis = addmf(fis, 'output', 3, 'NS', 'trimf', [0.05 0.1 0.15]);
fis = addmf(fis, 'output', 3, 'ZO', 'trimf', [0.1 0.15 0.2]);
fis = addmf(fis, 'output', 3, 'PS', 'trimf', [0.15 0.2 0.25]);
fis = addmf(fis, 'output', 3, 'PM', 'trimf', [0.2 0.25 0.3]);
fis = addmf(fis, 'output', 3, 'PB','smf', [0.2 0.25]);

% 模糊规则
rulelist = [1 1 1 1 1;
            1 2 2 1 1;
            1 3 3 1 1;
            2 1 2 1 1;
            2 2 3 1 1;
            2 3 4 1 1;
            3 1 3 1 1;
            3 2 4 1 1;
            3 3 5 1 1;
            4 1 4 1 1;
            4 2 5 1 1;
            4 3 6 1 1;
            5 1 5 1 1;
            5 2 6 1 1;
            5 3 7 1 1;
            6 1 6 1 1;
            6 2 7 1 1;
            6 3 7 1 1;
            7 1 7 1 1;
            7 2 7 1 1;
            7 3 7 1 1];
fis = addrule(fis, rulelist);

% 仿真
t = 0:0.01:10;
r = ones(size(t)); % 设定转速参考值
[y, t] = lsim(sys, r, t);
e = r - y;
ec = diff(e)/0.01;
ec = [ec(1) ec];
Kp = zeros(size(t));
Ki = zeros(size(t));
Kd = zeros(size(t));
u = zeros(size(t));
for i = 1:length(t)
    in = [e(i) ec(i)];
    out = evalfis(in, fis);
    Kp(i) = out(1);
    Ki(i) = out(2);
    Kd(i) = out(3);
    if i == 1
        u(i) = Kp(i)*e(i);
    else
        u(i) = Kp(i)*e(i) + Ki(i)*sum(e(1:i))*0.01 + Kd(i)*(e(i)-e(i-1))/0.01;
    end
end

% 绘图
figure;
subplot(3,1,1);
plot(t, r, 'b', t, y, 'r');
legend('参考转速', '实际转速');
xlabel('时间 (s)');
ylabel('转速');
title('转速响应曲线');

subplot(3,1,2);
plot(t, Kp);
xlabel('时间 (s)');
ylabel('Kp');
title('比例系数Kp变化曲线');

subplot(3,1,3);
plot(t, Ki);
hold on;
plot(t, Kd, 'r');
legend('Ki', 'Kd');
xlabel('时间 (s)');
ylabel('参数值');
title('积分系数Ki和微分系数Kd变化曲线');

代码分析

  1. 传递函数定义部分:通过 tf 函数定义了直流电机的传递函数 sys,这里根据前面提到的传递函数形式,设置了分子 num 和分母 den 的系数。
  2. 模糊控制器设计部分
    - 使用 newfis 创建一个新的模糊推理系统 fis
    - 利用 addvaraddmf 函数分别定义了输入变量(误差 e 和误差变化率 ec)以及输出变量(\( Kp \)、\( Ki \)、\( K_d \))的模糊子集和隶属度函数。
    - 通过 addrule 函数添加了模糊规则,这些规则决定了如何根据输入的模糊量调整PID参数。
  3. 仿真部分
    - 设定了仿真时间 t 和参考转速 r
    - 通过 lsim 函数得到直流电机在参考输入下的实际转速 y,进而计算误差 e 和误差变化率 ec
    - 在循环中,根据当前的误差和误差变化率,利用 evalfis 函数计算出实时的 \( Kp \)、\( Ki \)、\( K_d \) 参数,并根据PID控制算法计算控制量 u
  4. 绘图部分:使用 subplotplot 函数绘制了转速响应曲线、比例系数 \( Kp \) 变化曲线以及积分系数 \( Ki \) 和微分系数 \( K_d \) 的变化曲线,方便直观地观察控制效果和参数调整情况。

通过上述代码和分析,我们可以看到如何在Matlab环境下实现基于模糊控制PID算法的直流电机转速控制,这对于深入理解和应用直流电机控制技术有着重要的意义。希望本文能为各位在相关领域探索的小伙伴提供一些帮助和启发。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐