水箱水位控制系统MATLAB实现

水箱水位控制系统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

使用方法

  1. 运行主比较程序
matlab 复制代码
water_tank_control_comparison();
  1. 测试鲁棒性
matlab 复制代码
robustness_test();
  1. 单独测试特定控制器
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 最优控制,理论完整 需要精确模型 模型精确已知的线性系统
相关推荐
通往曙光的路上2 小时前
授权vvvvvv
java·开发语言·windows
Data_agent2 小时前
京东商品视频API,Python请求示例
java·开发语言·爬虫·python
a努力。2 小时前
HSBC Java面试被问:CAS如何解决ABA问题
java·开发语言·面试
lang201509282 小时前
深入解析Java资源加载机制
java·开发语言·python
LCG米3 小时前
嵌入式Python工业环境监测实战:MicroPython读取多传感器数据
开发语言·人工智能·python
武汉唯众智创4 小时前
职业院校C语言程序设计(AIGC版)课程教学解决方案
c语言·开发语言·aigc·程序设计·c语言程序设计·c语言程序设计实训室
qq_401700414 小时前
C语言void*
c语言·开发语言
sg_knight4 小时前
Python 面向对象基础复习
开发语言·python·ai编程·面向对象·模型
毕设源码-朱学姐5 小时前
【开题答辩全过程】以 基于Java的人体骨骼健康知识普及系统为例,包含答辩的问题和答案
java·开发语言