Matlab利用for循环遍历生成3个传递函数绘制对应的奈奎斯特曲线(Nyquist)以及伯德图(Bode) 7

题目:

错误代码:

clc;clear all; close all;

num1=[10];
temp1=[8];temp2=[1 1];
num2=conv(temp1,temp2);
temp3=[4];temp4=[1/3 1];
num3=conv(temp3,temp4);

num_list=[num1 num2 num3];

den_temp11=[1 0 0];den_temp12=[5 1];den_temp13=[1 5];
den_tempx=conv(den_temp11,den_temp12);
den1=conv(den_tempx,den_temp13);

den_temp21=[1 0 0];den_temp22=[1 15];den_temp23=[1 6 10];
den_tempy=conv(den_temp21,den_temp22);
den2=conv(den_tempy,den_temp23);

den_temp31=[1 0 ];den_temp32=[0.05 1];den_temp33=[0.1 1];
den_tempz=conv(den_temp31,den_temp32);
den3=conv(den_tempz,den_temp33);

den_list=[den1 den2 den3];

for i=1 : length(3)
num=num_list(i);
den=den_list(i);
figure
nyquist(num,den); grid
bode(num,den);grid
end

一、代码核心功能与函数用法分析

1. 整体功能

该代码意图基于 MATLAB Control System Toolbox,对 3 个不同的开环传递函数 进行 频域分析,具体是绘制每个系统的 奈奎斯特图(Nyquist Plot) 和 伯德图(Bode Plot),用于评估系统的稳定性(奈奎斯特判据)和频率响应特性(幅频、相频特性)。

2. 关键函数详解

函数用法与功能
clc; clear all; close all初始化工作环境:清空命令窗口、删除工作区所有变量、关闭所有图形窗口,避免干扰。
conv(a, b)多项式乘法函数:输入两个多项式的系数向量(按 s 降幂排列),输出乘积多项式的系数向量。示例:conv([8],[1,1]) 对应 \(8 \times (s+1) = 8s+8\),输出 [8,8]
tf(num, den)创建线性时不变(LTI)系统的传递函数对象:num 为分子系数向量,den 为分母系数向量,使后续频域分析更规范。
nyquist(G)绘制奈奎斯特图:展示开环系统 \(G(j\omega)\) 随频率 \(\omega\) 从 0 到 \(\infty\) 的复平面轨迹,用于判断闭环系统稳定性(奈奎斯特判据)。
bode(G)绘制伯德图:包含两个子图 —— 上半部分为幅频特性(幅值 dB,频率对数刻度),下半部分为相频特性(相位 °,频率对数刻度),用于分析系统动态性能和相对稳定性(增益裕度、相位裕度)。
grid on为图形添加网格,提高数据可读性。
title/sprintf为图形添加动态标题(sprintf 实现系统编号动态显示),便于区分不同系统的图。

二、代码存在的 4 个关键错误(按严重性排序)

错误 1:分子 / 分母存储方式错误(致命错误)

  • 原代码用 普通数组 [] 拼接不同长度的分子 / 分母向量:num_list=[num1 num2 num3]; den_list=[den1 den2 den3];
  • 问题:num1=[10](1 维)、num2=[8,8](2 维)、num3=[4/3,4](2 维)拼接后,num_list 变成单个长向量 [10,8,8,4/3,4],而非 3 个独立的分子向量。
  • 后果:for 循环取 num_list(i) 时,仅能取到单个元素(如 i=1 取 10i=2 取 8),导致 nyquist/bode 输入的分子 / 分母长度不匹配,直接报错。

错误 2:for 循环次数错误(致命错误)

  • 原代码:for i=1 : length(3)
  • 问题:length(3) 计算标量 3 的长度,结果为 1,循环仅执行 1 次,无法遍历 3 个系统。

错误 3:图形显示冲突(显示错误)

  • 原代码在 同一个 figure 窗口 连续调用 nyquist 和 bodefigure; nyquist(num,den); grid; bode(num,den); grid;
  • 问题:伯德图默认包含 2 个子图(幅频 + 相频),会覆盖奈奎斯特图,导致两个图重叠,无法正常观察。

错误 4:图形缺少标识(优化问题)

  • 原代码的图形无明确标题,无法区分是哪个系统的图,不利于结果对比分析。

三、错误修改方案与完整代码

修改核心思路

  1. 用 细胞数组 {} 存储 3 个系统的分子 / 分母(细胞数组支持存储不同长度的向量);
  2. 修正 for 循环为 i=1:length(num_list)(基于细胞数组长度,灵活遍历 3 个系统);
  3. 为每个系统的 奈奎斯特图和伯德图分别创建独立窗口,避免重叠;
  4. 添加动态标题,明确区分系统编号。

完整修改后代码

clc; clear all; close all;

% -------------------------- 步骤1:构建3个系统的分子多项式 --------------------------
% 系统1分子:10(常数项)
num1 = [10];
% 系统2分子:8*(s+1) = 8s + 8 → 系数向量[8,8]
temp1 = [8];       % 因式1:8
temp2 = [1 1];     % 因式2:s+1
num2 = conv(temp1, temp2);
% 系统3分子:4*( (1/3)s + 1 ) = (4/3)s + 4 → 系数向量[4/3, 4]
temp3 = [4];       % 因式1:4
temp4 = [1/3 1];   % 因式2:(1/3)s + 1
num3 = conv(temp3, temp4);

% 用细胞数组存储3个系统的分子(每个元素是独立的系数向量)
num_list = {num1, num2, num3};

% -------------------------- 步骤2:构建3个系统的分母多项式 --------------------------
% 系统1分母:s²*(5s+1)*(s+5) = 5s⁴ + 26s³ + 5s² → 系数向量[5,26,5,0,0]
den_temp11 = [1 0 0];  % 因式1:s²
den_temp12 = [5 1];    % 因式2:5s+1
den_temp13 = [1 5];    % 因式3:s+5
den_tempx = conv(den_temp11, den_temp12);
den1 = conv(den_tempx, den_temp13);

% 系统2分母:s²*(s+15)*(s²+6s+10) = s⁵+21s⁴+100s³+150s² → 系数向量[1,21,100,150,0,0]
den_temp21 = [1 0 0];  % 因式1:s²
den_temp22 = [1 15];   % 因式2:s+15
den_temp23 = [1 6 10]; % 因式3:s²+6s+10
den_tempy = conv(den_temp21, den_temp22);
den2 = conv(den_tempy, den_temp23);

% 系统3分母:s*(0.05s+1)*(0.1s+1) = 0.005s³+0.15s²+s → 系数向量[0.005,0.15,1,0]
den_temp31 = [1 0];    % 因式1:s
den_temp32 = [0.05 1]; % 因式2:0.05s+1
den_temp33 = [0.1 1];  % 因式3:0.1s+1
den_tempz = conv(den_temp31, den_temp32);
den3 = conv(den_tempz, den_temp33);

% 用细胞数组存储3个系统的分母(每个元素是独立的系数向量)
den_list = {den1, den2, den3};

% -------------------------- 步骤3:遍历系统,绘制频域图 --------------------------
for i = 1:length(num_list)  % 遍历3个系统(length(num_list)=3)
    % 提取当前系统的分子和分母
    num = num_list{i};  % 细胞数组用{}索引,获取第i个系统的分子向量
    den = den_list{i};  % 获取第i个系统的分母向量
    
    % 创建传递函数对象(规范用法,便于后续分析)
    G = tf(num, den);
    
    % 绘制奈奎斯特图(独立窗口)
    figure;
    nyquist(G);
    grid on;
    title(sprintf('系统%d的奈奎斯特图', i));  % 动态标题,标注系统编号
    
    % 绘制伯德图(独立窗口)
    figure;
    bode(G);
    grid on;
    title(sprintf('系统%d的伯德图', i));      % 动态标题,标注系统编号
end

实验现象:

posted @ 2025-11-26 22:00  RaLi  阅读(2)  评论(0)    收藏  举报  来源