水箱水位控制系统MATLAB实现,包括建模、控制器设计和仿真分析
水箱水位控制系统建模
系统微分方程
单容水箱系统可以用一阶惯性加纯滞后模型描述:
A·dh/dt = Q_in - Q_out
其中:
A:水箱截面积 (m²)h:水位高度 (m)Q_in:进水流量 (m³/s)Q_out:出水流量 (m³/s)
MATLAB实现代码
1. 水箱系统模型定义
matlab
function [h, Q_in, t] = water_tank_system(controller_type, h_ref, sim_time)
% 水箱水位控制系统仿真
% 输入参数:
% controller_type: 控制器类型 ('PID', 'Fuzzy', 'LQR')
% h_ref: 目标水位 (m)
% sim_time: 仿真时间 (s)
% 系统参数
A = 2.0; % 水箱截面积 (m²)
h0 = 0.5; % 初始水位 (m)
Q_out = 0.1; % 固定出水流量 (m³/s)
Q_max = 0.5; % 最大进水流量 (m³/s)
Q_min = 0; % 最小进水流量 (m³/s)
% 仿真参数
dt = 0.1; % 采样时间 (s)
t = 0:dt:sim_time;
N = length(t);
% 初始化变量
h = zeros(1, N);
h(1) = h0;
Q_in = zeros(1, N);
e = zeros(1, N);
e_int = 0; % 误差积分项
e_prev = 0; % 上一次误差
% 控制器参数
switch controller_type
case 'PID'
Kp = 1.5; Ki = 0.1; Kd = 0.5;
case 'Fuzzy'
% 模糊逻辑控制器参数
fis = create_fuzzy_controller();
case 'LQR'
% 状态空间模型
A_sys = -0.1; B_sys = 1/A; C_sys = 1; D_sys = 0;
Q_lqr = 10; R_lqr = 1;
K_lqr = lqr(A_sys, B_sys, Q_lqr, R_lqr);
end
% 主仿真循环
for k = 1:N-1
% 计算当前误差
e(k) = h_ref - h(k);
% 控制器计算
switch controller_type
case 'PID'
% PID控制器
e_int = e_int + e(k) * dt;
e_deriv = (e(k) - e_prev) / dt;
Q_in(k) = Kp * e(k) + Ki * e_int + Kd * e_deriv;
e_prev = e(k);
case 'Fuzzy'
% 模糊逻辑控制器
Q_in(k) = evalfis(fis, [e(k), e(k)-e_prev]);
e_prev = e(k);
case 'LQR'
% LQR控制器
Q_in(k) = -K_lqr * (h(k) - h_ref);
end
% 控制输入饱和限制
Q_in(k) = max(Q_min, min(Q_max, Q_in(k)));
% 系统动态更新 (欧拉法)
dh_dt = (Q_in(k) - Q_out) / A;
h(k+1) = h(k) + dh_dt * dt;
% 添加测量噪声
h(k+1) = h(k+1) + 0.01 * randn;
end
% 最后时刻的控制量
Q_in(N) = Q_in(N-1);
end
2. PID控制器设计
matlab
function [Kp, Ki, Kd] = pid_tuning_method(method, A, tau)
% PID控制器参数整定
% method: 整定方法 ('ZN', 'CC', 'IMC')
% A: 水箱截面积, tau: 时间常数
switch method
case 'ZN' % Ziegler-Nichols方法
Ku = 2.5; Pu = 2*pi*tau;
Kp = 0.6 * Ku;
Ki = 2 * Kp / Pu;
Kd = Kp * Pu / 8;
case 'CC' % Chien-Hrones-Reswick方法
Kp = 0.6 * A / tau;
Ki = Kp / (2.5 * tau);
Kd = 0.5 * Kp * tau;
case 'IMC' % 内模控制
lambda = 1.5 * tau; % 滤波器时间常数
Kp = A / lambda;
Ki = Kp / tau;
Kd = 0;
end
fprintf('PID参数: Kp=%.3f, Ki=%.3f, Kd=%.3f\n', Kp, Ki, Kd);
end
3. 模糊逻辑控制器
matlab
function fis = create_fuzzy_controller()
% 创建模糊逻辑控制器
fis = newfis('WaterLevelControl');
% 输入变量1: 误差e
fis = addvar(fis, 'input', 'error', [-1, 1]);
fis = addmf(fis, 'input', 1, 'NB', 'trapmf', [-1 -1 -0.6 -0.3]);
fis = addmf(fis, 'input', 1, 'NS', 'trimf', [-0.5 -0.2 0]);
fis = addmf(fis, 'input', 1, 'Z', 'trimf', [-0.1 0 0.1]);
fis = addmf(fis, 'input', 1, 'PS', 'trimf', [0 0.2 0.5]);
fis = addmf(fis, 'input', 1, 'PB', 'trapmf', [0.3 0.6 1 1]);
% 输入变量2: 误差变化率de
fis = addvar(fis, 'input', 'delta_error', [-0.5, 0.5]);
fis = addmf(fis, 'input', 2, 'N', 'trapmf', [-0.5 -0.5 -0.2 -0.05]);
fis = addmf(fis, 'input', 2, 'Z', 'trimf', [-0.1 0 0.1]);
fis = addmf(fis, 'input', 2, 'P', 'trapmf', [0.05 0.2 0.5 0.5]);
% 输出变量: 控制量Q_in
fis = addvar(fis, 'output', 'control', [-0.5, 0.5]);
fis = addmf(fis, 'output', 1, 'NB', 'trapmf', [-0.5 -0.5 -0.3 -0.1]);
fis = addmf(fis, 'output', 1, 'NS', 'trimf', [-0.2 -0.1 0]);
fis = addmf(fis, 'output', 1, 'Z', 'trimf', [-0.05 0 0.05]);
fis = addmf(fis, 'output', 1, 'PS', 'trimf', [0 0.1 0.2]);
fis = addmf(fis, 'output', 1, 'PB', 'trapmf', [0.1 0.3 0.5 0.5]);
% 模糊规则
ruleList = [
1 1 1 1 1; % 误差NB, 变化率N -> 控制NB
1 2 1 1 1;
1 3 2 1 1;
2 1 1 1 1;
2 2 3 1 1;
2 3 4 1 1;
3 1 2 1 1;
3 2 3 1 1;
3 3 4 1 1;
4 1 2 1 1;
4 2 4 1 1;
4 3 5 1 1;
5 1 4 1 1;
5 2 5 1 1;
5 3 5 1 1;
];
fis = addrule(fis, ruleList);
end
4. 完整的仿真比较系统
matlab
function water_tank_control_comparison()
% 水箱水位控制系统对比仿真
close all; clc;
% 仿真参数
h_ref = 1.0; % 目标水位 (m)
sim_time = 100; % 仿真时间 (s)
fprintf('=== 水箱水位控制系统仿真 ===\n');
fprintf('目标水位: %.1f m\n', h_ref);
fprintf('仿真时间: %d s\n\n', sim_time);
% 测试不同控制器
controllers = {'PID', 'Fuzzy', 'LQR'};
colors = {'r', 'b', 'g'};
line_styles = {'-', '--', ':'};
figure('Position', [100, 100, 1400, 900]);
% 存储性能指标
performance = struct();
for i = 1:length(controllers)
controller_type = controllers{i};
fprintf('仿真 %s 控制器...\n', controller_type);
% 运行仿真
[h, Q_in, t] = water_tank_system(controller_type, h_ref, sim_time);
% 计算性能指标
[ise, iae, itae, overshoot, settling_time] = ...
calculate_performance(h, h_ref, t);
performance.(controller_type) = struct(...
'ISE', ise, 'IAE', iae, 'ITAE', itae, ...
'Overshoot', overshoot, 'SettlingTime', settling_time);
% 绘制水位响应
subplot(2, 2, 1);
plot(t, h, [colors{i}, line_styles{i}], 'LineWidth', 2); hold on;
% 绘制控制输入
subplot(2, 2, 2);
plot(t, Q_in, [colors{i}, line_styles{i}], 'LineWidth', 2); hold on;
% 绘制误差
subplot(2, 2, 3);
error = h_ref - h;
plot(t, error, [colors{i}, line_styles{i}], 'LineWidth', 2); hold on;
end
% 完善图形1: 水位响应
subplot(2, 2, 1);
plot([t(1), t(end)], [h_ref, h_ref], 'k--', 'LineWidth', 1, ...
'DisplayName', '目标水位');
title('水位响应曲线');
xlabel('时间 (s)'); ylabel('水位高度 (m)');
legend([controllers, {'目标水位'}], 'Location', 'best');
grid on;
% 完善图形2: 控制输入
subplot(2, 2, 2);
title('控制输入 (进水流量)');
xlabel('时间 (s)'); ylabel('流量 (m³/s)');
legend(controllers, 'Location', 'best');
grid on;
% 完善图形3: 跟踪误差
subplot(2, 2, 3);
title('跟踪误差');
xlabel('时间 (s)'); ylabel('误差 (m)');
legend(controllers, 'Location', 'best');
grid on;
% 性能指标表格
subplot(2, 2, 4);
axis off;
% 创建性能比较表格
performance_data = zeros(length(controllers), 5);
for i = 1:length(controllers)
ctrl = controllers{i};
perf = performance.(ctrl);
performance_data(i, :) = [perf.ISE, perf.IAE, perf.ITAE, ...
perf.Overshoot, perf.SettlingTime];
end
% 显示性能表格
column_names = {'ISE', 'IAE', 'ITAE', '超调量(%)', '调节时间(s)'};
row_names = controllers;
uitable('Data', performance_data, ...
'ColumnName', column_names, ...
'RowName', row_names, ...
'Position', [300, 50, 450, 100]);
sgtitle('水箱水位控制系统 - 控制器性能比较', 'FontSize', 14, 'FontWeight', 'bold');
% 显示性能总结
fprintf('\n=== 性能指标总结 ===\n');
fprintf('控制器\t\tISE\t\tIAE\t\tITAE\t\t超调量(%%)\t调节时间(s)\n');
fprintf('-------------------------------------------------------------------\n');
for i = 1:length(controllers)
ctrl = controllers{i};
perf = performance.(ctrl);
fprintf('%s\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.1f\t\t%.1f\n', ...
ctrl, perf.ISE, perf.IAE, perf.ITAE, ...
perf.Overshoot, perf.SettlingTime);
end
end
function [ise, iae, itae, overshoot, settling_time] = calculate_performance(h, h_ref, t)
% 计算控制系统性能指标
error = h_ref - h;
dt = t(2) - t(1);
% ISE: 误差平方积分
ise = sum(error.^2) * dt;
% IAE: 绝对误差积分
iae = sum(abs(error)) * dt;
% ITAE: 时间乘绝对误差积分
itae = sum(t .* abs(error)) * dt;
% 超调量
max_overshoot = max(h) - h_ref;
overshoot = max(0, (max_overshoot / h_ref) * 100);
% 调节时间 (进入±5%误差带的时间)
error_band = 0.05 * h_ref;
settled_indices = find(abs(error) <= error_band);
if ~isempty(settled_indices)
% 找到持续保持在误差带内的时间点
for i = 1:length(settled_indices)
if all(abs(error(settled_indices(i):end)) <= error_band)
settling_time = t(settled_indices(i));
break;
end
end
else
settling_time = t(end);
end
end
5. 鲁棒性测试函数
matlab
function robustness_test()
% 鲁棒性测试:参数变化对控制器性能的影响
close all;
% 测试不同的系统参数
areas = [1.5, 2.0, 2.5]; % 不同水箱截面积
outflows = [0.08, 0.1, 0.12]; % 不同出水流速
controllers = {'PID', 'Fuzzy'};
figure('Position', [100, 100, 1200, 800]);
% 测试截面积变化的影响
subplot(2, 2, 1);
for i = 1:length(areas)
A = areas(i);
[h, ~, t] = water_tank_system('PID', 1.0, 50);
plot(t, h, 'LineWidth', 2); hold on;
end
title('PID控制器 - 不同水箱截面积');
xlabel('时间 (s)'); ylabel('水位 (m)');
legend(['A=' num2str(areas(1)) 'm²'], ['A=' num2str(areas(2)) 'm²'], ...
['A=' num2str(areas(3)) 'm²'], 'Location', 'best');
grid on;
subplot(2, 2, 2);
for i = 1:length(areas)
A = areas(i);
[h, ~, t] = water_tank_system('Fuzzy', 1.0, 50);
plot(t, h, 'LineWidth', 2); hold on;
end
title('模糊控制器 - 不同水箱截面积');
xlabel('时间 (s)'); ylabel('水位 (m)');
legend(['A=' num2str(areas(1)) 'm²'], ['A=' num2str(areas(2)) 'm²'], ...
['A=' num2str(areas(3)) 'm²'], 'Location', 'best');
grid on;
% 测试出水流速变化的影响
subplot(2, 2, 3);
for i = 1:length(outflows)
Q_out = outflows(i);
[h, ~, t] = water_tank_system('PID', 1.0, 50);
plot(t, h, 'LineWidth', 2); hold on;
end
title('PID控制器 - 不同出水流速');
xlabel('时间 (s)'); ylabel('水位 (m)');
legend(['Q_{out}=' num2str(outflows(1))], ['Q_{out}=' num2str(outflows(2))], ...
['Q_{out}=' num2str(outflows(3))], 'Location', 'best');
grid on;
subplot(2, 2, 4);
for i = 1:length(outflows)
Q_out = outflows(i);
[h, ~, t] = water_tank_system('Fuzzy', 1.0, 50);
plot(t, h, 'LineWidth', 2); hold on;
end
title('模糊控制器 - 不同出水流速');
xlabel('时间 (s)'); ylabel('水位 (m)');
legend(['Q_{out}=' num2str(outflows(1))], ['Q_{out}=' num2str(outflows(2))], ...
['Q_{out}=' num2str(outflows(3))], 'Location', 'best');
grid on;
sgtitle('控制系统鲁棒性测试', 'FontSize', 14, 'FontWeight', 'bold');
end
使用方法
- 运行主比较程序:
matlab
water_tank_control_comparison();
- 测试鲁棒性:
matlab
robustness_test();
- 单独测试特定控制器:
matlab
[h, Q_in, t] = water_tank_system('PID', 1.0, 100);
figure;
subplot(2,1,1); plot(t, h); title('水位响应');
subplot(2,1,2); plot(t, Q_in); title('控制输入');
参考代码 matlab实现水箱水位控制系统 www.3dddown.com/csa/79942.html
性能分析要点
| 控制器类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| PID | 简单可靠,参数整定明确 | 对非线性系统适应性差 | 线性系统,参数变化小的场合 |
| 模糊控制 | 适应非线性,鲁棒性强 | 设计复杂,缺乏系统方法 | 复杂非线性系统 |
| LQR | 最优控制,理论完整 | 需要精确模型 | 模型精确已知的线性系统 |