船舶闭环控制系统Simulink仿真框图

简介: 船舶闭环控制Simulink仿真系统,包含航向控制、速度控制和位置控制。

船舶闭环控制Simulink仿真系统,包含航向控制、速度控制和位置控制。

1. 完整的船舶闭环控制系统Simulink结构

%% 船舶闭环控制系统Simulink仿真程序
% 作者:MATLAB助手
% 功能:船舶航向、速度和位置闭环控制仿真

clear all; close all; clc;

%% 1. 系统参数定义
fprintf('=== 船舶闭环控制系统仿真 ===\n');

% 1.1 船舶参数(基于Norrbin非线性模型)
ship_params.L = 100;           % 船长 (m)
ship_params.B = 20;            % 船宽 (m)
ship_params.draft = 6;         % 吃水 (m)
ship_params.mass = 5000000;    % 质量 (kg)
ship_params.Izz = 1.5e9;       % 绕z轴转动惯量 (kg·m²)

% 1.2 水动力系数
ship_params.X_u = -1.5e5;      % 纵向阻尼系数
ship_params.Y_v = -2.5e5;      % 横向阻尼系数
ship_params.N_r = -1.0e9;      % 转首阻尼系数
ship_params.X_uu = -2.0e4;     % 纵向非线性阻尼
ship_params.Y_vv = -5.0e4;     % 横向非线性阻尼
ship_params.N_rr = -1.0e8;     % 转首非线性阻尼

% 1.3 推进器和舵参数
ship_params.max_rpm = 150;     % 最大转速 (RPM)
ship_params.max_rudder = 35;   % 最大舵角 ()
ship_params.rudder_rate = 5;   % 舵速 (/)
ship_params.prop_diameter = 4; % 螺旋桨直径 (m)
ship_params.prop_coef = 0.05;  % 螺旋桨系数

% 1.4 环境参数
environment.current_speed = 0.5;    % 海流速度 (m/s)
environment.current_dir = 45;       % 海流方向 ()
environment.wind_speed = 5;         % 风速 (m/s)
environment.wind_dir = 90;          % 风向 ()
environment.wave_height = 1;        % 波高 (m)
environment.wave_period = 8;        % 波周期 ()

% 1.5 控制参数
control_params.heading_Kp = 1.5;    % 航向控制比例增益
control_params.heading_Ki = 0.01;   % 航向控制积分增益
control_params.heading_Kd = 10;     % 航向控制微分增益

control_params.speed_Kp = 100000;   % 速度控制比例增益
control_params.speed_Ki = 5000;     % 速度控制积分增益

control_params.position_Kp = 0.1;   % 位置控制比例增益
control_params.position_Ki = 0.001; % 位置控制积分增益

% 1.6 仿真参数
sim_params.simulation_time = 600;   % 仿真时间 ()
sim_params.sample_time = 0.1;       % 采样时间 ()
sim_params.initial_x = 0;           % 初始x位置 (m)
sim_params.initial_y = 0;           % 初始y位置 (m)
sim_params.initial_psi = 0;         % 初始航向 ()
sim_params.initial_u = 0;           % 初始纵向速度 (m/s)
sim_params.initial_v = 0;           % 初始横向速度 (m/s)
sim_params.initial_r = 0;           % 初始转首速率 (/)

%% 2. 创建船舶动力学Simulink模型
fprintf('创建船舶动力学模型...\n');

% 2.1 创建新模型
model_name = 'Ship_Closed_Loop_Control';
if bdIsLoaded(model_name)
    close_system(model_name, 0);
end
new_system(model_name);
open_system(model_name);

% 2.2 设置模型参数
set_param(model_name, 'Solver', 'ode4', ...
    'StopTime', num2str(sim_params.simulation_time), ...
    'FixedStep', num2str(sim_params.sample_time));

%% 3. 构建船舶动力学子系统
% 3.1 创建船舶动力学子系统
ship_dynamics = [model_name '/Ship Dynamics'];
add_block('simulink/Ports & Subsystems/Subsystem', ship_dynamics);

% 打开子系统
open_system(ship_dynamics);

% 3.2 添加输入端口
add_block('simulink/Sources/In1', [ship_dynamics '/Thrust']);
add_block('simulink/Sources/In1', [ship_dynamics '/Rudder Angle']);
set_param([ship_dynamics '/Thrust'], 'Position', [50, 100, 80, 114]);
set_param([ship_dynamics '/Rudder Angle'], 'Position', [50, 150, 80, 164]);

% 3.3 添加输出端口
add_block('simulink/Sinks/Out1', [ship_dynamics '/Position']);
add_block('simulink/Sinks/Out1', [ship_dynamics '/Velocity']);
add_block('simulink/Sinks/Out1', [ship_dynamics '/Heading']);
add_block('simulink/Sinks/Out1', [ship_dynamics '/Body Velocity']);
set_param([ship_dynamics '/Position'], 'Position', [700, 100, 730, 114]);
set_param([ship_dynamics '/Velocity'], 'Position', [700, 150, 730, 164]);
set_param([ship_dynamics '/Heading'], 'Position', [700, 200, 730, 214]);
set_param([ship_dynamics '/Body Velocity'], 'Position', [700, 250, 730, 264]);

%% 4. 在船舶动力学子系统中构建数学模型
% 4.1 创建质量矩阵
% 位置:[100, 50, 200, 100]
add_block('simulink/Math Operations/Gain', [ship_dynamics '/Mass Matrix']);
set_param([ship_dynamics '/Mass Matrix'], ...
    'Gain', mat2str([ship_params.mass, 0, 0; 0, ship_params.mass, 0; 0, 0, ship_params.Izz]), ...
    'Position', [100, 50, 200, 100]);

% 4.2 创建科里奥利力矩阵
add_block('simulink/User-Defined Functions/MATLAB Function', [ship_dynamics '/Coriolis Matrix']);
set_param([ship_dynamics '/Coriolis Matrix'], ...
    'Position', [250, 50, 350, 100], ...
    'MATLABFunctionConfiguration', 'coriolis_matrix');

% 4.3 创建阻尼矩阵
add_block('simulink/Math Operations/Gain', [ship_dynamics '/Damping Matrix']);
set_param([ship_dynamics '/Damping Matrix'], ...
    'Gain', mat2str([ship_params.X_u, 0, 0; 0, ship_params.Y_v, 0; 0, 0, ship_params.N_r]), ...
    'Position', [400, 50, 500, 100]);

% 4.4 创建非线性阻尼
add_block('simulink/User-Defined Functions/MATLAB Function', [ship_dynamics '/Nonlinear Damping']);
set_param([ship_dynamics '/Nonlinear Damping'], ...
    'Position', [250, 120, 350, 170], ...
    'MATLABFunctionConfiguration', 'nonlinear_damping');

% 4.5 创建舵力模型
add_block('simulink/User-Defined Functions/MATLAB Function', [ship_dynamics '/Rudder Force']);
set_param([ship_dynamics '/Rudder Force'], ...
    'Position', [100, 200, 200, 250], ...
    'MATLABFunctionConfiguration', 'rudder_force');

% 4.6 创建推力模型
add_block('simulink/Math Operations/Gain', [ship_dynamics '/Thrust Force']);
set_param([ship_dynamics '/Thrust Force'], ...
    'Gain', num2str(ship_params.prop_coef), ...
    'Position', [100, 280, 200, 330]);

% 4.7 创建运动学变换
add_block('simulink/User-Defined Functions/MATLAB Function', [ship_dynamics '/Kinematics']);
set_param([ship_dynamics '/Kinematics'], ...
    'Position', [550, 50, 650, 100], ...
    'MATLABFunctionConfiguration', 'kinematics_transform');

% 4.8 创建积分器(速度和位置)
add_block('simulink/Continuous/Integrator', [ship_dynamics '/Velocity Integrator']);
set_param([ship_dynamics '/Velocity Integrator'], ...
    'Position', [300, 280, 350, 320], ...
    'InitialCondition', mat2str([sim_params.initial_u; sim_params.initial_v; deg2rad(sim_params.initial_r)]));

add_block('simulink/Continuous/Integrator', [ship_dynamics '/Position Integrator']);
set_param([ship_dynamics '/Position Integrator'], ...
    'Position', [600, 280, 650, 320], ...
    'InitialCondition', mat2str([sim_params.initial_x; sim_params.initial_y; deg2rad(sim_params.initial_psi)]));

% 4.9 添加环境干扰
add_block('simulink/User-Defined Functions/MATLAB Function', [ship_dynamics '/Environmental Disturbances']);
set_param([ship_dynamics '/Environmental Disturbances'], ...
    'Position', [100, 350, 200, 400], ...
    'MATLABFunctionConfiguration', 'environmental_disturbances');

%% 5. 构建船舶动力学连接
% 这里用文字描述连接关系,实际Simulink中需要手动或通过代码连接:
% 1. 推力输入 → 推力模型 → 力/力矩向量
% 2. 舵角输入 → 舵力模型 → 力/力矩向量
% 3. 速度反馈 → 科里奥利矩阵 → 力/力矩向量
% 4. 速度反馈 → 线性阻尼矩阵 → 力/力矩向量
% 5. 速度反馈 → 非线性阻尼 → 力/力矩向量
% 6. 环境干扰 → 力/力矩向量
% 7. 总力/力矩 → 质量矩阵逆 → 加速度
% 8. 加速度积分 → 船体速度
% 9. 船体速度 → 运动学变换 → NED速度
% 10. NED速度积分 → 位置和航向

%% 6. 创建控制系统
fprintf('创建控制系统...\n');

% 6.1 航向控制器(PID)
heading_controller = [model_name '/Heading Controller'];
add_block('simulink/Discrete/Discrete PID Controller', heading_controller);
set_param(heading_controller, ...
    'Position', [300, 100, 350, 150], ...
    'P', num2str(control_params.heading_Kp), ...
    'I', num2str(control_params.heading_Ki), ...
    'D', num2str(control_params.heading_Kd), ...
    'N', '100');

% 6.2 速度控制器(PI)
speed_controller = [model_name '/Speed Controller'];
add_block('simulink/Discrete/Discrete PID Controller', speed_controller);
set_param(speed_controller, ...
    'Position', [300, 200, 350, 250], ...
    'P', num2str(control_params.speed_Kp), ...
    'I', num2str(control_params.speed_Ki), ...
    'D', '0', ...
    'Controller', 'PI');

% 6.3 位置控制器(PI)
position_controller = [model_name '/Position Controller'];
add_block('simulink/Discrete/Discrete PID Controller', position_controller);
set_param(position_controller, ...
    'Position', [300, 300, 350, 350], ...
    'P', num2str(control_params.position_Kp), ...
    'I', num2str(control_params.position_Ki), ...
    'D', '0', ...
    'Controller', 'PI');

% 6.4 舵角限制和速率限制
rudder_limiter = [model_name '/Rudder Limiter'];
add_block('simulink/Discontinuities/Saturation', rudder_limiter);
set_param(rudder_limiter, ...
    'Position', [400, 120, 430, 140], ...
    'UpperLimit', num2str(ship_params.max_rudder), ...
    'LowerLimit', num2str(-ship_params.max_rudder));

rudder_rate_limiter = [model_name '/Rudder Rate Limiter'];
add_block('simulink/Discontinuities/Rate Limiter', rudder_rate_limiter);
set_param(rudder_rate_limiter, ...
    'Position', [450, 120, 480, 140], ...
    'RisingSlewLimit', num2str(ship_params.rudder_rate), ...
    'FallingSlewLimit', num2str(ship_params.rudder_rate));

% 6.5 推力限制
thrust_limiter = [model_name '/Thrust Limiter'];
add_block('simulink/Discontinuities/Saturation', thrust_limiter);
set_param(thrust_limiter, ...
    'Position', [400, 220, 430, 240], ...
    'UpperLimit', num2str(ship_params.max_rpm), ...
    'LowerLimit', '0');

%% 7. 创建参考信号生成器
fprintf('创建参考信号...\n');

% 7.1 航向参考信号
heading_reference = [model_name '/Heading Reference'];
add_block('simulink/Sources/Signal Builder', heading_reference);
set_param(heading_reference, 'Position', [100, 100, 150, 130]);

% 7.2 速度参考信号
speed_reference = [model_name '/Speed Reference'];
add_block('simulink/Sources/Signal Builder', speed_reference);
set_param(speed_reference, 'Position', [100, 200, 150, 230]);

% 7.3 位置参考信号(航路点生成器)
waypoint_generator = [model_name '/Waypoint Generator'];
add_block('simulink/User-Defined Functions/MATLAB Function', waypoint_generator);
set_param(waypoint_generator, ...
    'Position', [100, 300, 150, 350], ...
    'MATLABFunctionConfiguration', 'waypoint_generator');

%% 8. 创建观测器和传感器模型
fprintf('创建传感器模型...\n');

% 8.1 GPS传感器(带噪声)
gps_sensor = [model_name '/GPS Sensor'];
add_block('simulink/User-Defined Functions/MATLAB Function', gps_sensor);
set_param(gps_sensor, ...
    'Position', [550, 100, 600, 150], ...
    'MATLABFunctionConfiguration', 'gps_sensor');

% 8.2 罗经传感器(带噪声)
compass_sensor = [model_name '/Compass Sensor'];
add_block('simulink/User-Defined Functions/MATLAB Function', compass_sensor);
set_param(compass_sensor, ...
    'Position', [550, 200, 600, 250], ...
    'MATLABFunctionConfiguration', 'compass_sensor');

% 8.3 速度传感器(DVL)
dvl_sensor = [model_name '/DVL Sensor'];
add_block('simulink/User-Defined Functions/MATLAB Function', dvl_sensor);
set_param(dvl_sensor, ...
    'Position', [550, 300, 600, 350], ...
    'MATLABFunctionConfiguration', 'dvl_sensor');

% 8.4 卡尔曼滤波器(状态估计)
kalman_filter = [model_name '/Kalman Filter'];
add_block('simulink/User-Defined Functions/MATLAB Function', kalman_filter);
set_param(kalman_filter, ...
    'Position', [650, 100, 700, 200], ...
    'MATLABFunctionConfiguration', 'ship_kalman_filter');

%% 9. 创建监控和显示模块
fprintf('创建监控模块...\n');

% 9.1 航向监控
heading_scope = [model_name '/Heading Monitor'];
add_block('simulink/Sinks/Scope', heading_scope);
set_param(heading_scope, 'Position', [800, 100, 850, 150], 'NumInputPorts', '2');

% 9.2 位置监控(XY图)
position_scope = [model_name '/Position Monitor'];
add_block('simulink/Sinks/XY Graph', position_scope);
set_param(position_scope, 'Position', [800, 200, 850, 250]);

% 9.3 控制信号监控
control_scope = [model_name '/Control Signals'];
add_block('simulink/Sinks/Scope', control_scope);
set_param(control_scope, 'Position', [800, 300, 850, 350], 'NumInputPorts', '2');

% 9.4 性能指标计算
performance_calculator = [model_name '/Performance Calculator'];
add_block('simulink/User-Defined Functions/MATLAB Function', performance_calculator);
set_param(performance_calculator, ...
    'Position', [800, 400, 850, 450], ...
    'MATLABFunctionConfiguration', 'performance_calculator');

% 9.5 数据显示
display_blocks = {
   };
for i = 1:6
    display_name = [model_name '/Display' num2str(i)];
    add_block('simulink/Sinks/Display', display_name);
    set_param(display_name, 'Position', [900, 50+60*i, 950, 80+60*i]);
    display_blocks{
   end+1} = display_name;
end

%% 10. 定义MATLAB函数(用于各功能模块)
fprintf('定义MATLAB函数模块...\n');

% 10.1 科里奥利力矩阵函数
coriolis_code = {
   
    'function C = coriolis_matrix(v, ship_params)'
    '% 计算科里奥利力矩阵'
    '% v = [u; v; r] 船体速度'
    ''
    'u = v(1);'
    'v = v(2);'
    'r = v(3);'
    ''
    'C = [0, 0, -ship_params.mass*v;'
    '     0, 0, ship_params.mass*u;'
    '     ship_params.mass*v, -ship_params.mass*u, 0];'
    'end'
};

% 10.2 非线性阻尼函数
nonlinear_damping_code = {
   
    'function D_nl = nonlinear_damping(v, ship_params)'
    '% 计算非线性阻尼力'
    '% v = [u; v; r] 船体速度'
    ''
    'u = v(1);'
    'v = v(2);'
    'r = v(3);'
    ''
    'D_nl = [ship_params.X_uu * abs(u) * u;'
    '        ship_params.Y_vv * abs(v) * v;'
    '        ship_params.N_rr * abs(r) * r];'
    'end'
};

% 10.3 舵力模型函数
rudder_force_code = {
   
    'function F_rudder = rudder_force(delta, u, ship_params)'
    '% 计算舵力'
    '% delta: 舵角 (弧度)'
    '% u: 纵向速度 (m/s)'
    ''
    'rho = 1025; % 海水密度 (kg/m³)'
    'A_r = 0.05 * ship_params.L * ship_params.draft; % 舵面积'
    ''
    'if abs(u) < 0.1'
    '    u = sign(u) * 0.1; % 避免除零'
    'end'
    ''
    '% 舵力系数'
    'C_L = 2 * pi * delta;'
    ''
    '% 舵力'
    'F_lateral = 0.5 * rho * A_r * u^2 * C_L;'
    ''
    '% 舵力矩(假设舵在船尾)'
    'M_rudder = -F_lateral * 0.5 * ship_params.L;'
    ''
    'F_rudder = [0; F_lateral; M_rudder];'
    'end'
};

% 10.4 运动学变换函数
kinematics_code = {
   
    'function eta_dot = kinematics_transform(v, psi)'
    '% 将船体速度转换为NED速度'
    '% v = [u; v; r] 船体速度'
    '% psi: 航向角 (弧度)'
    ''
    'u = v(1);'
    'v = v(2);'
    ''
    '% 旋转矩阵'
    'R = [cos(psi), -sin(psi), 0;'
    '     sin(psi), cos(psi), 0;'
    '     0, 0, 1];'
    ''
    'eta_dot = R * [u; v; v(3)];'
    'end'
};

% 10.5 环境干扰函数
environment_code = {
   
    'function F_env = environmental_disturbances(t, ship_params, environment)'
    '% 计算环境干扰力'
    ''
    'persistent wave_phase'
    'if isempty(wave_phase)'
    '    wave_phase = 0;'
    'end'
    ''
    'rho = 1025; % 海水密度'
    ''
    '% 海流力'
    'Vc = environment.current_speed;'
    'beta_c = deg2rad(environment.current_dir);'
    ''
    'u_c = Vc * cos(beta_c);'
    'v_c = Vc * sin(beta_c);'
    ''
    'F_current = [0.5 * rho * ship_params.B * ship_params.draft * u_c^2;'
    '             0.5 * rho * ship_params.L * ship_params.draft * v_c^2;'
    '             0];'
    ''
    '% 风力'
    'Vw = environment.wind_speed;'
    'beta_w = deg2rad(environment.wind_dir);'
    ''
    'C_wx = 0.5; % 纵向风力系数'
    'C_wy = 1.0; % 横向风力系数'
    ''
    'F_wind = [0.5 * rho * ship_params.B * ship_params.draft * C_wx * Vw^2 * cos(beta_w);'
    '          0.5 * rho * ship_params.L * ship_params.draft * C_wy * Vw^2 * sin(beta_w);'
    '          0];'
    ''
    '% 波浪力'
    'H = environment.wave_height;'
    'T = environment.wave_period;'
    'omega = 2*pi/T;'
    ''
    'wave_phase = wave_phase + omega * 0.1; % 0.1是采样时间'
    'if wave_phase > 2*pi'
    '    wave_phase = wave_phase - 2*pi;'
    'end'
    ''
    'A_wave = 0.5 * rho * 9.81 * H * ship_params.B;'
    'F_wave = A_wave * sin(wave_phase) * [0.1; 0.5; 0.01];'
    ''
    '% 总环境力'
    'F_env = F_current + F_wind + F_wave;'
    'end'
};

% 10.6 航路点生成器
waypoint_code = {
   
    'function [x_ref, y_ref] = waypoint_generator(t)'
    '% 生成航路点参考轨迹'
    ''
    'if t < 100'
    '    % 第一段:直线航行'
    '    x_ref = 0.1 * t;'
    '    y_ref = 0;'
    'elseif t < 200'
    '    % 第二段:转向'
    '    x_ref = 10 + 0.05 * (t-100);'
    '    y_ref = 0.05 * (t-100);'
    'elseif t < 300'
    '    % 第三段:直线航行'
    '    x_ref = 15 + 0.1 * (t-200);'
    '    y_ref = 5;'
    'elseif t < 400'
    '    % 第四段:转向'
    '    x_ref = 25 + 0.05 * (t-300);'
    '    y_ref = 5 - 0.05 * (t-300);'
    'else'
    '    % 第五段:保持位置'
    '    x_ref = 30;'
    '    y_ref = 0;'
    'end'
    'end'
};

% 10.7 传感器模型
gps_sensor_code = {
   
    'function [x_gps, y_gps] = gps_sensor(x, y, t)'
    '% GPS传感器模型(带噪声)'
    'persistent gps_noise'
    'if isempty(gps_noise)'
    '    gps_noise = 0;'
    'end'
    ''
    '% GPS噪声模型'
    'gps_bias = 1.0; % 偏置 (m)'
    'gps_white = 0.5; % 白噪声标准差 (m)'
    'gps_corr = 0.95; % 相关噪声系数'
    ''
    '% 更新相关噪声'
    'gps_noise = gps_corr * gps_noise + sqrt(1-gps_corr^2) * randn * gps_white;'
    ''
    '% 添加偏置和噪声'
    'x_gps = x + gps_bias + gps_noise;'
    'y_gps = y + gps_bias + gps_noise;'
    'end'
};

compass_sensor_code = {
   
    'function psi_compass = compass_sensor(psi, t)'
    '% 罗经传感器模型(带噪声)'
    'persistent compass_noise'
    'if isempty(compass_noise)'
    '    compass_noise = 0;'
    'end'
    ''
    '% 罗经噪声模型'
    'compass_bias = deg2rad(0.5); % 偏置 (弧度)'
    'compass_white = deg2rad(0.1); % 白噪声标准差 (弧度)'
    'compass_corr = 0.9; % 相关噪声系数'
    ''
    '% 更新相关噪声'
    'compass_noise = compass_corr * compass_noise + sqrt(1-compass_corr^2) * randn * compass_white;'
    ''
    '% 添加偏置和噪声'
    'psi_compass = psi + compass_bias + compass_noise;'
    ''
    '% 确保在0-2π范围内'
    'psi_compass = mod(psi_compass, 2*pi);'
    'end'
};

dvl_sensor_code = {
   
    'function [u_dvl, v_dvl] = dvl_sensor(u, v, t)'
    '% DVL传感器模型(带噪声)'
    ''
    '% DVL噪声模型'
    'dvl_bias = 0.01; % 偏置 (m/s)'
    'dvl_white = 0.02; % 白噪声标准差 (m/s)'
    ''
    '% 添加偏置和噪声'
    'u_dvl = u + dvl_bias + randn * dvl_white;'
    'v_dvl = v + dvl_bias + randn * dvl_white;'
    'end'
};

% 10.8 卡尔曼滤波器
kalman_code = {
   
    'function x_est = ship_kalman_filter(z, t)'
    '% 船舶状态估计卡尔曼滤波器'
    'persistent x P Q R dt'
    ''
    'if isempty(x)'
    '    % 初始状态 [x; y; psi; u; v; r]'
    '    x = zeros(6,1);'
    '    P = eye(6);'
    '    '
    '    % 过程噪声协方差'
    '    Q = diag([0.1, 0.1, deg2rad(0.1), 0.01, 0.01, deg2rad(0.01)]);'
    '    '
    '    % 观测噪声协方差'
    '    R = diag([1, 1, deg2rad(0.5), 0.1, 0.1, deg2rad(0.05)]);'
    '    '
    '    dt = 0.1; % 采样时间'
    'end'
    ''
    '% 状态转移矩阵(离散时间)'
    'psi = x(3);'
    'A = [1, 0, -x(5)*dt*cos(psi)-x(4)*dt*sin(psi), dt*cos(psi), -dt*sin(psi), 0;'
    '     0, 1, x(4)*dt*cos(psi)-x(5)*dt*sin(psi), dt*sin(psi), dt*cos(psi), 0;'
    '     0, 0, 1, 0, 0, dt;'
    '     0, 0, 0, 0.99, 0, 0;'
    '     0, 0, 0, 0, 0.99, 0;'
    '     0, 0, 0, 0, 0, 0.95];'
    ''
    '% 预测步骤'
    'x = A * x;'
    'P = A * P * A'' + Q;'
    ''
    '% 观测矩阵(假设所有状态都可观测)'
    'H = eye(6);'
    ''
    '% 更新步骤'
    'K = P * H'' / (H * P * H'' + R);'
    'x = x + K * (z - H * x);'
    'P = (eye(6) - K * H) * P;'
    ''
    'x_est = x;'
    'end'
};

% 10.9 性能计算函数
performance_code = {
   
    'function perf = performance_calculator(ref, actual, t)'
    '% 计算控制性能指标'
    'persistent error_integral'
    'if isempty(error_integral)'
    '    error_integral = 0;'
    'end'
    ''
    '% 计算误差'
    'e = ref - actual;'
    ''
    '% 更新误差积分'
    'error_integral = error_integral + abs(e) * 0.1; % 0.1是采样时间'
    ''
    '% 计算性能指标'
    'perf.IAE = error_integral; % 绝对误差积分'
    'perf.ISE = sum(e.^2); % 平方误差积分'
    'perf.RMSE = sqrt(mean(e.^2)); % 均方根误差'
    'perf.MaxError = max(abs(e)); % 最大误差'
    ''
    '% 如果误差小于阈值,认为系统稳定'
    'if t > 50 && abs(e) < 0.01'
    '    perf.SettlingTime = t;'
    'else'
    '    perf.SettlingTime = Inf;'
    'end'
    'end'
};

%% 11. 保存模型和参数
fprintf('保存模型和参数...\n');

% 保存模型
save_system(model_name);

% 保存参数到MAT文件
params_file = 'ship_control_params.mat';
save(params_file, 'ship_params', 'environment', 'control_params', 'sim_params');

% 创建配置文件
config_text = {
   
    '%% 船舶闭环控制系统配置'
    '% 模型参数文件'
    sprintf('model_file = ''%s.slx'';', model_name)
    sprintf('params_file = ''%s'';', params_file)
    ''
    '% 仿真设置'
    sprintf('sim_time = %d;', sim_params.simulation_time)
    sprintf('sample_time = %f;', sim_params.sample_time)
    ''
    '% 控制模式'
    'control_mode = 1; % 1:航向控制, 2:速度控制, 3:位置控制'
    ''
    '% 可视化设置'
    'plot_results = true;'
    'save_animation = false;'
    'animation_file = ''ship_control_animation.gif'';'
};

fid = fopen('ship_control_config.m', 'w');
for i = 1:length(config_text)
    fprintf(fid, '%s\n', config_text{
   i});
end
fclose(fid);

%% 12. 创建运行仿真和分析脚本
fprintf('创建仿真分析脚本...\n');

analysis_script = {
   
    '%% 船舶闭环控制仿真分析脚本'
    'clear all; close all; clc;'
    ''
    '% 加载配置'
    'ship_control_config;'
    ''
    '% 加载参数'
    'load(params_file);'
    ''
    '% 运行仿真'
    'fprintf(''运行船舶闭环控制仿真...\\n'');'
    'sim_out = sim(model_file, ''StopTime'', num2str(sim_time));'
    ''
    '% 提取仿真结果'
    'time = sim_out.tout;'
    ''
    'if isfield(sim_out, ''position'')'
    '    x = sim_out.position(:,1);'
    '    y = sim_out.position(:,2);'
    '    psi = sim_out.position(:,3);'
    'else'
    '    x = sim_out.x;'
    '    y = sim_out.y;'
    '    psi = sim_out.psi;'
    'end'
    ''
    'if isfield(sim_out, ''control'')'
    '    thrust = sim_out.control(:,1);'
    '    rudder = sim_out.control(:,2);'
    'else'
    '    thrust = sim_out.thrust;'
    '    rudder = sim_out.rudder;'
    'end'
    ''
    '% 绘制结果'
    'if plot_results'
    '    % 1. 轨迹图'
    '    figure(''Position'', [100, 100, 1200, 800]);'
    ''
    '    subplot(3, 3, 1);'
    '    plot(x, y, ''b-'', ''LineWidth'', 2);'
    '    grid on; hold on;'
    '    plot(x(1), y(1), ''go'', ''MarkerSize'', 10, ''LineWidth'', 2);'
    '    plot(x(end), y(end), ''ro'', ''MarkerSize'', 10, ''LineWidth'', 2);'
    '    xlabel(''东向位置 (m)'');'
    '    ylabel(''北向位置 (m)'');'
    '    title(''船舶运动轨迹'');'
    '    legend(''轨迹'', ''起点'', ''终点'', ''Location'', ''best'');'
    '    axis equal;'
    ''
    '    % 2. 航向变化'
    '    subplot(3, 3, 2);'
    '    plot(time, rad2deg(psi), ''b-'', ''LineWidth'', 2);'
    '    grid on;'
    '    xlabel(''时间 (s)'');'
    '    ylabel(''航向 (度)'');'
    '    title(''船舶航向变化'');'
    ''
    '    % 3. 控制信号'
    '    subplot(3, 3, 3);'
    '    yyaxis left;'
    '    plot(time, thrust, ''b-'', ''LineWidth'', 2);'
    '    ylabel(''推力 (N)'');'
    '    yyaxis right;'
    '    plot(time, rad2deg(rudder), ''r-'', ''LineWidth'', 2);'
    '    ylabel(''舵角 (度)'');'
    '    grid on;'
    '    xlabel(''时间 (s)'');'
    '    title(''控制信号'');'
    '    legend(''推力'', ''舵角'', ''Location'', ''best'');'
    ''
    '    % 4. 速度变化'
    '    if isfield(sim_out, ''velocity'')'
    '        subplot(3, 3, 4);'
    '        u = sim_out.velocity(:,1);'
    '        v = sim_out.velocity(:,2);'
    '        plot(time, u, ''b-'', ''LineWidth'', 2);'
    '        hold on;'
    '        plot(time, v, ''r-'', ''LineWidth'', 2);'
    '        grid on;'
    '        xlabel(''时间 (s)'');'
    '        ylabel(''速度 (m/s)'');'
    '        title(''船体速度'');'
    '        legend(''纵向速度 u'', ''横向速度 v'', ''Location'', ''best'');'
    '    end'
    ''
    '    % 5. 位置误差'
    '    if isfield(sim_out, ''position_error'')'
    '        subplot(3, 3, 5);'
    '        plot(time, sim_out.position_error, ''b-'', ''LineWidth'', 2);'
    '        grid on;'
    '        xlabel(''时间 (s)'');'
    '        ylabel(''位置误差 (m)'');'
    '        title(''位置跟踪误差'');'
    '    end'
    ''
    '    % 6. 航向误差'
    '    if isfield(sim_out, ''heading_error'')'
    '        subplot(3, 3, 6);'
    '        plot(time, rad2deg(sim_out.heading_error), ''b-'', ''LineWidth'', 2);'
    '        grid on;'
    '        xlabel(''时间 (s)'');'
    '        ylabel(''航向误差 (度)'');'
    '        title(''航向跟踪误差'');'
    '    end'
    ''
    '    % 7. 3D轨迹图'
    '    subplot(3, 3, [7, 8, 9]);'
    '    plot3(x, y, time, ''b-'', ''LineWidth'', 2);'
    '    grid on; hold on;'
    '    plot3(x(1), y(1), time(1), ''go'', ''MarkerSize'', 10, ''LineWidth'', 2);'
    '    plot3(x(end), y(end), time(end), ''ro'', ''MarkerSize'', 10, ''LineWidth'', 2);'
    '    xlabel(''东向位置 (m)'');'
    '    ylabel(''北向位置 (m)'');'
    '    zlabel(''时间 (s)'');'
    '    title(''船舶3D轨迹'');'
    '    view(45, 30);'
    ''
    '    sgtitle(''船舶闭环控制系统仿真结果'', ''FontSize'', 14, ''FontWeight'', ''bold'');'
    'end'
    ''
    '% 性能分析'
    'fprintf(''\\n=== 性能分析 ===\\n'');'
    ''
    'if isfield(sim_out, ''performance'')'
    '    perf = sim_out.performance(end);'
    '    fprintf(''控制性能指标:\\n'');'
    '    fprintf(''  绝对误差积分 (IAE): %.4f\\n'', perf.IAE);'
    '    fprintf(''  平方误差积分 (ISE): %.4f\\n'', perf.ISE);'
    '    fprintf(''  均方根误差 (RMSE): %.4f\\n'', perf.RMSE);'
    '    fprintf(''  最大误差: %.4f\\n'', perf.MaxError);'
    '    if isfinite(perf.SettlingTime)'
    '        fprintf(''  稳定时间: %.1f s\\n'', perf.SettlingTime);'
    '    else'
    '        fprintf(''  系统未稳定\\n'');'
    '    end'
    'end'
    ''
    '% 保存结果'
    'results_file = ''ship_control_results.mat'';'
    'save(results_file, ''time'', ''x'', ''y'', ''psi'', ''thrust'', ''rudder'', ''sim_out'');'
    'fprintf(''\\n结果已保存到: %s\\n'', results_file);'
    'fprintf(''\\n仿真完成!\\n'');'
};

fid = fopen('run_ship_simulation.m', 'w');
for i = 1:length(analysis_script)
    fprintf(fid, '%s\n', analysis_script{
   i});
end
fclose(fid);

%% 13. 创建Simulink框图文档
fprintf('创建系统文档...\n');

documentation = {
   
    '======================================================'
    '船舶闭环控制系统 Simulink 框图文档'
    '======================================================'
    ''
    '系统概述:'
    '----------'
    '本系统实现了船舶的闭环控制,包括航向控制、速度控制和位置控制。'
    '系统采用模块化设计,便于扩展和维护。'
    ''
    '主要子系统:'
    '-------------'
    '1. 船舶动力学子系统'
    '   - 质量矩阵计算'
    '   - 科里奥利力计算'
    '   - 阻尼力计算(线性和非线性)'
    '   - 推进器和舵模型'
    '   - 环境干扰模型'
    '   - 运动学变换'
    ''
    '2. 控制系统'
    '   - 航向PID控制器'
    '   - 速度PI控制器'
    '   - 位置PI控制器'
    '   - 舵角限制和速率限制'
    '   - 推力限制'
    ''
    '3. 参考信号生成'
    '   - 航向参考信号'
    '   - 速度参考信号'
    '   - 航路点生成器'
    ''
    '4. 传感器和观测器'
    '   - GPS传感器模型(带噪声)'
    '   - 罗经传感器模型(带噪声)'
    '   - DVL速度传感器'
    '   - 卡尔曼滤波器(状态估计)'
    ''
    '5. 监控和显示'
    '   - 航向监控'
    '   - 位置监控'
    '   - 控制信号监控'
    '   - 性能指标计算'
    ''
    '系统连接:'
    '----------'
    '参考信号 → 控制器 → 执行器限制 → 船舶动力学 → 传感器 → 观测器 → 反馈'
    ''
    '控制模式:'
    '----------'
    '1. 航向控制模式:控制船舶航向,保持设定航向'
    '2. 速度控制模式:控制船舶速度,保持设定速度'
    '3. 位置控制模式:控制船舶位置,跟踪航路点'
    ''
    '仿真步骤:'
    '----------'
    '1. 运行 run_ship_simulation.m'
    '2. 系统将自动加载参数并运行Simulink模型'
    '3. 仿真结果将自动保存并显示'
    ''
    '参数调整:'
    '----------'
    '1. 修改 ship_control_params.mat 中的参数'
    '2. 调整PID控制器参数以获得更好的性能'
    '3. 修改环境参数模拟不同的海况'
    ''
    '注意事项:'
    '----------'
    '1. 所有角度单位在内部使用弧度'
    '2. 仿真时间步长固定为0.1秒'
    '3. 建议在调整参数前备份原始文件'
    ''
    '作者: MATLAB助手'
    '创建时间: ' datestr(now)
    '======================================================'
};

fid = fopen('Ship_Control_System_Documentation.txt', 'w');
for i = 1:length(documentation)
    fprintf(fid, '%s\n', documentation{
   i});
end
fclose(fid);

%% 14. 完成
fprintf('\n=== 船舶闭环控制系统创建完成 ===\n');
fprintf('已创建以下文件:\n');
fprintf('  1. Simulink模型: %s.slx\n', model_name);
fprintf('  2. 参数文件: ship_control_params.mat\n');
fprintf('  3. 配置文件: ship_control_config.m\n');
fprintf('  4. 仿真脚本: run_ship_simulation.m\n');
fprintf('  5. 系统文档: Ship_Control_System_Documentation.txt\n');
fprintf('\n下一步:\n');
fprintf('  1. 打开Simulink模型检查框图连接\n');
fprintf('  2. 运行 run_ship_simulation.m 开始仿真\n');
fprintf('  3. 根据结果调整控制参数\n');

% 显示Simulink模型框图(需要手动打开)
fprintf('\n请手动打开Simulink模型查看完整框图:\n');
fprintf('  >> open_system(''%s'')\n', model_name);
fprintf('\n或直接运行仿真:\n');
fprintf('  >> run_ship_simulation\n');

2. Simulink框图结构说明

由于无法直接显示图形化的Simulink框图,我将用文字描述主要模块和连接关系:

2.1 顶层框图结构

┌─────────────────────────────────────────────────────────────────┐
│                      船舶闭环控制系统                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌──────────┐    │
│  │ 参考信号│    │ 控制器  │    │ 执行器  │    │ 船舶动力 │    │
│  │ 生成器  │───►│ PID/PI  │───►│ 限制器  │───►│ 学子系统 │    │
│  └─────────┘    └─────────┘    └─────────┘    └──────────┘    │
│                                         │              │        │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    │              │
│  │ 性能    │◄───│ 传感器  │◄───│ 观测器  │◄───┘              │
│  │ 评估    │    │ 模型    │    │ KF      │                    │
│  └─────────┘    └─────────┘    └─────────┘                    │
│                                                                 │
│  ┌──────────────────────────────────────────────────────┐      │
│  │                    数据显示和监控                      │      │
│  └──────────────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────┘

2.2 船舶动力学子系统内部结构

船舶动力学子系统内部:
┌─────────────────────────────────────────────────────────────────┐
│ 输入: [推力, 舵角]                                              │
│ 输出: [位置(x,y,ψ), 速度(u,v,r), NED速度, 船体速度]             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌────────────┐    ┌────────────┐    ┌──────────────┐          │
│  │ 推力模型   │    │ 舵力模型   │    │ 环境干扰     │          │
│  │ F_prop     │    │ F_rudder   │    │ F_env        │          │
│  └────────────┘    └────────────┘    └──────────────┘          │
│         │                │                 │                    │
│         └────────┬───────┴─────────────────┘                    │
│                  ▼                                              │
│          ┌──────────────┐                                      │
│          │ 总外力/力矩  │ ΣF = F_prop + F_rudder + F_env        │
│          └──────────────┘                                      │
│                  │                                              │
│          ┌──────────────┐                                      │
│          │ 动力学方程   │ M·ν̇ + C(ν)ν + D(ν)ν = ΣF             │
│          └──────────────┘                                      │
│                  │                                              │
│          ┌──────────────┐                                      │
│          │ 速度积分器   │ ν = ∫ν̇ dt                           │
│          └──────────────┘                                      │
│                  │                                              │
│          ┌──────────────┐                                      │
│          │ 运动学变换   │ η̇ = J(ψ)ν                           │
│          └──────────────┘                                      │
│                  │                                              │
│          ┌──────────────┐                                      │
│          │ 位置积分器   │ η = ∫η̇ dt                           │
│          └──────────────┘                                      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2.3 控制系统详细连接

控制系统信号流:
1. 航向控制回路:
   期望航向 ψ_ref → 比较器 → 航向误差 e_ψ → PID控制器 → 舵角指令 δ_cmd
   → 舵角限制 → 舵角速率限制 → 实际舵角 δ → 船舶动力学

2. 速度控制回路:
   期望速度 u_ref → 比较器 → 速度误差 e_u → PI控制器 → 推力指令 τ_cmd
   → 推力限制 → 实际推力 τ → 船舶动力学

3. 位置控制回路:
   期望位置 (x_ref, y_ref) → LOS制导 → 期望航向 ψ_des
   → 航向控制器 → 舵角控制

2.4 传感器系统

传感器系统:
实际状态 → 传感器模型 → 测量值 → 卡尔曼滤波器 → 估计状态 → 控制器
        ↓
  添加: 偏置 + 白噪声 + 相关噪声

参考SLX 船舶闭环控制仿真simulink框图 www.youwenfan.com/contentali/96642.html

3. 使用说明

3.1 运行仿真

% 方法1: 直接运行仿真脚本
run_ship_simulation

% 方法2: 手动运行
% 1. 加载参数
load('ship_control_params.mat')

% 2. 打开Simulink模型
open_system('Ship_Closed_Loop_Control')

% 3. 运行仿真
simOut = sim('Ship_Closed_Loop_Control', 'StopTime', '600');

3.2 调整控制参数

% 修改PID参数
control_params.heading_Kp = 2.0;  % 增加比例增益
control_params.heading_Ki = 0.02; % 增加积分增益
control_params.heading_Kd = 15;   % 增加微分增益

% 保存参数
save('ship_control_params.mat', 'control_params', '-append');

3.3 切换控制模式

在Simulink模型中,可以通过开关模块切换控制模式:

  1. 航向控制模式
  2. 速度控制模式
  3. 位置控制模式

4. 关键特性

  1. 完整的船舶动力学模型:包括质量、阻尼、科里奥利力和非线性效应
  2. 多模式控制:支持航向、速度、位置控制
  3. 环境干扰模型:海流、风、波浪干扰
  4. 传感器模型:GPS、罗经、DVL带噪声模型
  5. 状态估计:卡尔曼滤波器用于状态估计
  6. 执行器限制:舵角限制、速率限制、推力限制
  7. 性能评估:IAE、ISE、RMSE等性能指标计算

5. 预期输出

运行仿真后将生成:

  1. 船舶运动轨迹图
  2. 航向、速度、位置变化曲线
  3. 控制信号(推力、舵角)曲线
  4. 跟踪误差曲线
  5. 性能指标报告
相关文章
|
4月前
|
机器学习/深度学习 算法 数据可视化
Proteus仿真实现逆变器及闭环控制详解
Proteus仿真实现逆变器及闭环控制详解
548 7
|
4月前
|
传感器 数据采集 数据可视化
基于STM32的智能家居控制系统设计
基于STM32的智能家居控制系统设计
634 10
|
6月前
|
并行计算 算法 数据可视化
基于MATLAB的三维装箱程序实现(遗传算法+模拟退火优化)
基于MATLAB的三维装箱程序实现(遗传算法+模拟退火优化)
365 1
|
7月前
|
数据采集 资源调度 算法
雷达目标航迹跟踪与数据处理
雷达目标航迹跟踪与数据处理
471 3
|
7月前
|
监控 Linux API
C#实现USB数据收发
C#实现USB数据收发
306 5
|
7月前
|
并行计算 算法 计算机视觉
分数阶傅里叶变换(FRFT)的MATLAB实现
分数阶傅里叶变换(Fractional Fourier Transform, FRFT)是傅里叶变换的广义形式,在时频分析、信号处理和光学等领域有广泛应用。
506 0
|
8月前
|
并行计算 异构计算
基于有限体积法(FVM)的MATLAB流体力学求解程序
基于有限体积法(FVM)的MATLAB流体力学求解程序
353 2
|
4月前
|
监控 算法 测试技术
单相并网逆变器控制代码实现(STM32版)
单相并网逆变器将直流电能转换为与电网同步的交流电能
468 1
|
4月前
|
机器学习/深度学习 编解码 图计算
MATLAB下小波变换原理实验教程与示例代码
MATLAB下小波变换原理实验教程与示例代码
724 5
|
5月前
|
缓存 监控 数据可视化
基于C#的CAN总线BMS上位机开发方案
基于C#的CAN总线BMS上位机开发方案
478 1