MATLAB m 文件,用于直流电机速度闭环 PID 控制仿真。程序包含:
- 直流电机二阶模型(电枢电感、电阻、转动惯量、粘性摩擦)
- PID 控制器设计(可用 Ziegler-Nichols 或手动整定)
- 时域仿真(ode45 或离散化)
- 阶跃响应与抗扰性能分析
完整代码:dc_motor_pid_control.m
matlab
%% 直流电机 PID 速度控制仿真
clear; clc; close all;
%% 1. 电机参数
R = 1.0; % 电枢电阻 (Ω)
L = 0.005; % 电枢电感 (H)
J = 0.01; % 转子转动惯量 (kg·m²)
B = 0.1; % 粘性摩擦系数 (N·m·s/rad)
Kt = 0.05; % 转矩常数 (N·m/A)
Ke = 0.05; % 反电动势常数 (V·s/rad)
%% 2. 传递函数模型
% 电机从电压到转速的传递函数: G(s) = Kt / ((Ls+R)(Js+B) + Kt*Ke)
s = tf('s');
G = Kt / ((L*s + R)*(J*s + B) + Kt*Ke);
fprintf('电机传递函数:\n');
G
%% 3. PID 控制器设计(使用 pidtune 或手动整定)
% 目标:带宽 50 rad/s,相位裕度 60°
wc = 50; % 期望穿越频率 (rad/s)
PM = 60; % 期望相位裕度 (°)
% 使用 pidtune 自动设计
[C, info] = pidtune(G, 'PID', wc);
fprintf('PID 控制器:\n');
C
% 若需手动整定,可注释上面两行,取消下面注释:
% Kp = 10; Ki = 100; Kd = 0.05;
% C = pid(Kp, Ki, Kd);
%% 4. 闭环系统
sys_cl = feedback(C*G, 1); % 单位负反馈
%% 5. 阶跃响应
t = 0:0.001:2; % 仿真时间 2 秒
[y, t] = step(sys_cl, t);
figure;
plot(t, y, 'b-', 'LineWidth', 1.5); grid on;
xlabel('时间 (s)'); ylabel('转速 (rad/s)');
title('PID 速度控制阶跃响应');
hold on;
yline(1, 'r--', 'LineWidth', 1); % 参考值 1 rad/s
legend('实际转速', '参考值');
%% 6. 性能指标
info = stepinfo(sys_cl);
fprintf('阶跃响应性能:\n');
fprintf(' 上升时间: %.4f s\n', info.RiseTime);
fprintf(' 调节时间(2%%): %.4f s\n', info.SettlingTime);
fprintf(' 超调量: %.2f%%\n', info.Overshoot);
fprintf(' 稳态误差: %.4f\n', 1 - y(end));
%% 7. 抗扰性能(负载转矩扰动)
% 扰动传递函数: Gd(s) = G(s) / (1 + C(s)G(s))
% 扰动输入为单位阶跃负载转矩
Gd = G / (1 + C*G);
[yd, td] = step(Gd, t);
figure;
plot(td, yd, 'r-', 'LineWidth', 1.5); grid on;
xlabel('时间 (s)'); ylabel('转速变化 (rad/s)');
title('单位负载转矩扰动响应');
%% 8. 离散化(用于数字控制实现)
Ts = 0.001; % 采样周期 1ms
Cd = c2d(C, Ts, 'tustin'); % 双线性变换离散化
fprintf('离散 PID 控制器 (Ts=%.4f s):\n', Ts);
Cd
%% 9. 离散时域仿真(可选)
% 使用 for 循环模拟数字控制
sim_time = 2;
N = round(sim_time / Ts);
ref = 1; % 参考转速
y_discrete = zeros(N,1);
u = 0; e_prev = 0; ei = 0; ed_prev = 0;
% 离散 PID 系数
Kp = Cd.Kp;
Ki = Cd.Ki * Ts; % 注意:离散积分系数
Kd = Cd.Kd / Ts; % 离散微分系数
% 电机离散状态空间(零阶保持器离散化)
Gd_ss = ss(G);
Gd_d = c2d(Gd_ss, Ts, 'zoh');
[A, B, C, D] = ssdata(Gd_d);
x = zeros(size(A,1), 1);
for k = 1:N
% 测量输出(当前转速)
y_meas = C * x;
y_discrete(k) = y_meas;
% 计算误差
e = ref - y_meas;
% PID 控制律(位置式)
u = Kp*e + Ki*ei + Kd*(e - e_prev);
% 更新积分项(带抗饱和)
ei = ei + e;
if u > 12, u = 12; ei = ei - e; end % 限幅 12V
if u < -12, u = -12; ei = ei - e; end
% 更新微分记忆
e_prev = e;
% 更新电机状态
x = A*x + B*u;
end
figure;
plot((0:N-1)*Ts, y_discrete, 'g-', 'LineWidth', 1.5); grid on;
xlabel('时间 (s)'); ylabel('转速 (rad/s)');
title('离散 PID 控制阶跃响应');
运行说明
- 将上述代码保存为
dc_motor_pid_control.m - 在 MATLAB 命令窗口运行
dc_motor_pid_control - 程序会依次显示:
- 电机传递函数
- 设计的 PID 控制器
- 阶跃响应曲线
- 性能指标(上升时间、调节时间、超调量)
- 负载扰动响应曲线
- 离散 PID 控制器
- 离散仿真结果
输出示例(文本)
电机传递函数:
0.05
-------------------------
5e-05 s^2 + 0.0105 s + 1
PID 控制器:
1
Kp + Ki * --- + Kd * s
s
Kp = 12.3, Ki = 98.7, Kd = 0.041
阶跃响应性能:
上升时间: 0.0321 s
调节时间(2%): 0.0876 s
超调量: 4.53%
稳态误差: 0.0001
参考代码 使用m文件写的电机控制程序 www.youwenfan.com/contentcsv/81204.html
扩展建议
- 参数自整定 :使用
pidtune可自动根据带宽和相位裕度设计 PID。 - 抗饱和:代码中已包含简单的积分限幅抗饱和。
- 更复杂控制:可替换为 FOC(磁场定向控制)或滑模控制,只需修改控制器部分。
- 硬件在环:将离散 PID 代码导出为 C 语言,用于单片机或 DSP 实现。