做控制系统设计很多人第一反应就是拿 PID 先怼上去调几个参数看看波形不对再改。这种瞎试路数不是不行但遇到稍微复杂的对象比如多变量系统、带滞后环节、有强耦合的被控对象很快就会陷入调了这头坏了那头的泥潭。我这些年带过不少入门者最大的感触是真正科班的做法不是上手就写控制律而是先把一个叫作 MAD 的流程走通——建模Modeling、分析Analysis、设计Design这三个环节合在一起才是控制系统设计的完整路径。这篇博文就是控制系统建模仿真系列的第一篇核心目标很直接把 MAD 流程讲透再把 MATLAB 基础运算这个工具箱给你备齐。适合刚开始学自动控制的同学、刚从理论课转到仿真实操的工程师以及想系统梳理一遍控制设计流程的从业者。看完你至少能完成一件事把一个实际的物理装置例如直流电机变成 MATLAB 里的数学对象判断它稳不稳、快不快并且初步设计一个能用的控制器。后面系列文章我们会在 MAD 的框架下继续深入 Simulink 仿真、非线性因素和实物联调。1. 控制系统设计的 MAD 工作流三个环节到底在做什么1.1 建模、分析、设计各自的地盘和边界MAD是我习惯用来概括控制系统设计三条主线的缩写Modeling建模、Analysis分析、Design设计。注意这三个词的顺序不是随便排的它是工程上一种先搞清对象、再下结论、最后动手改的递进关系。建模解决的是我的系统到底长什么样。一个实物装置本质上是物理量之间的相互约束。比如直流电机电压、电流、转速、转矩之间由电路定律和力学定律约束水箱液位进水流量、出水流量、液体高度之间由物料守恒约束。建模就是把这些约束用微分方程、代数方程或者查表数据写出来让计算机能识别。分析解决的是这个系统本身具备什么性格。同一个装置模型建出来之后它稳不稳定阶跃响应超调多少抗扰动能力强不强这些问题是静态的——在还没有设计任何控制器之前系统的开环特性就已经决定了很大一部分。就好比体检先查清楚身体状况再决定要不要开药。设计解决的是我该加什么样的控制器让它变成我想要的样子。经过分析发现系统响应太慢那就加超前校正有稳态误差那就加积分作用对象本身不稳定那就用反馈重新配置极点。设计的输入是分析结论输出是一组具体的控制器参数或者一个完整的控制算法。这三个环节的边界要划清楚否则很容易犯一个常见错误模型还没建准就开始整定控制器最后仿真和实物对不上还反过来怪模型没用。1.2 为什么 MAD 是工程主流做法而不是书斋里的流程图教科书经常分章讲建模、分析、设计考完试大家容易把三者当成三个孤立的知识岛。但真实工程里MAD 是一个反复迭代的循环。我举一个实际做过的例子某实验室的电机角度伺服控制任务。起初我们对电机建立了一个二阶近似模型分析后发现系统是稳定的但相角裕度只有 18 度阶跃响应有明显振荡调节时间拖到接近 3 秒。这个结果显然不满足指标于是进入设计环节加了一个超前校正网络仿真显示相角裕度提升到 50 度调节时间降到 1 秒以内。按说设计完成了吧不问题来了。把设计好的控制器带回实物台架验证的时候发现实际系统在低速段有很强的摩擦力矩这个现象在最初的线性模型里根本没有体现。于是我们不得不回到建模环节加入摩擦非线性项重新分析、重新设计。这一轮迭代才让最终控制效果和仿真基本一致。所以 MAD 不是一张画在纸上的流程图而是一套发现问题—定位环节—回头修改的工程心智。你越早接受建模误差会传导到设计结果这件事就越不会在调参的时候盲目折腾。2. 准备 MATLAB 基础运算把地基先夯实2.1 命令行窗口和工作区它首先是个高级计算器很多人在 MATLAB 里做的第一件事是输入11然后回车。别小看这一步命令行窗口其实承担了快速验证想法的角色效率比任何脚本都高。我常用的几个基础操作都是每天都离不开的% 基本算术Matlab 默认单引号是注释 a 3 5*2 % 结果是 13 b (3 5)*2 % 结果是 16 c 2^0.5 % 开平方关键点在于分号。语句末尾加分号就不在命令行回显结果这在写脚本的时候非常有用否则中间变量会把屏幕刷爆。另外两个高频命令是clear和clcclear清空工作区变量clc清空命令行显示。我建议养成习惯每次跑新任务前先clear; clc;避免旧变量污染新计算。工作区Workspace是一个容易被忽略的面板。你在命令行里定义的所有变量都会出现在这里双击还能直接查看内容。对新手来说调试时多看一眼工作区往往比猜代码快得多。2.2 矩阵是 MATLAB 的一等公民星号和点号的区别必须刻进脑子MATLAB 的名字是 Matrix Laboratory 的缩写矩阵运算就是它的原生语言。如果你还在用它逐元素做 for 循环说明还没摸到门道。定义一个矩阵最简单的方式是分号分行A [1 2; 3 4] % 2x2 矩阵 B [5; 6] % 2x1 列向量冒号表达式是生成序列的利器x 0:0.1:1生成从 0 到 1、间隔 0.1 的向量。linspace(0,1,11)效果相同只是它是按点数生成的更适合指定样本数量。接下来是新手最容易踩坑的地方矩阵乘法*和对应元素相乘.*完全不同。前者是线性代数意义上的矩阵乘法要求左矩阵列数等于右矩阵行数后者是逐元素相乘要求两个矩阵形状一致。下面的例子一眼就能看清A [1 2; 3 4]; B [5 6; 7 8]; C A * B % 普通矩阵乘法 % 结果: [19 22; 43 50] D A .* B % 对应元素相乘 % 结果: [5 12; 21 32]这种差异在控制系统里无处不在。比如计算传递函数的并联、串联、反馈背后都是矩阵运算。如果你不区分星号和点号轻则报错重则算出一个看起来对但完全不是那个意思的结果。另外几个常用矩阵函数值得记住zeros(m,n)、ones(m,n)、eye(n)分别生成全零矩阵、全一矩阵、单位矩阵。单位矩阵在求解线性方程组和验证逆矩阵时特别有用。是转置inv(A)求逆det(A)求行列式。记住这些至少应付控制理论课程中的大量矩阵验算没问题。2.3 脚本和函数把随手算变成可复现的分水岭刚到实验室那会我也经常在命令行里敲完一堆代码然后因为一个参数要改就得全部重敲一遍。后来才意识到代码的复用和可复现比少写几个字重要得多。脚本文件.m是一段顺序执行的命令集合。最简单的用法是点击编辑器新建脚本写代码保存成my_demo.m然后直接输入文件名运行。脚本里的变量会出现在工作区运行结束后依然保留方便你查看中间结果。函数文件则不同它以function开头有自己的输入输出接口function y my_func(x) y x^2 2*x 1; end函数内部的变量默认是局部的不会污染工作区。做控制设计时我的习惯是用一个主脚本把整个 MAD 流程串起来把每个环节的核心逻辑拆成函数。比如plant_model.m负责返回对象模型controller_design.m根据指标返回控制器参数。这样改一个环节不影响其他环节排查问题的时候也能快速定位。一个非常实用的调试技巧在脚本里用disp()或fprintf()打印关键变量的值。比如设计完 PID 参数后打印fprintf(Kp %.3f, Ki %.3f\n, Kp, Ki);这样每次运行都能看到当前配置不用额外打开工作区面板。3. 建模环节实操把物理对象变成 MATLAB 里的数学模型3.1 从物理规律到微分方程先写数学再写代码建模最忌讳的是打开 MATLAB 就开始敲tf。正确的顺序是先从物理规律出发列出微分方程再翻译成代码。我就用最经典的直流电机转速控制来演示。直流电机的电气部分满足基尔霍夫电压定律电枢电压u一部分落在电阻R和电感L上一部分被反电动势Ke*ω抵消。机械部分满足牛顿第二定律电磁转矩Kt*i驱动负载一部分克服粘性阻尼b*ω一部分用来改变转速。于是有L * di/dt R*i Ke*ω u J * dω/dt b*ω Kt*i这里要注意一个工程取舍如果电枢电感L很小也就是电气时间常数远小于机械时间常数可以忽略电感项把系统降成二阶这在很多调速场合是合理的。但如果你现在在做高带宽电流控制电感就不能随便丢。建模阶段想清楚哪些项可以留哪些项可以砍决定了模型既不过于复杂又足够准确。为了演示我保留电感。另外在电机这类对象中反电动势常数Ke和转矩常数Kt在 SI 单位下数值相等统一记作K。这样模型参数就是R2欧、L0.5亨、J0.02千克·平方米、b0.01牛·米·秒/弧度、K0.1。3.2 用 tf 函数建立传递函数模型把上面的微分方程组联立消去中间变量电流i再对输入电压u求角速度ω的传递函数。推导过程略去结果是一个二阶系统的形式。但注意如果想要控制的是电机轴的角度转速的积分效应会额外产生一个1/s因子于是角度对电压的传递函数变成一个三阶系统G(s) K / [s * (L*J*s^2 (L*b R*J)*s (R*b K^2))]在 MATLAB 里建立这个模型直接写出分子和分母多项式系数即可R 2; L 0.5; J 0.02; b 0.01; K 0.1; num K; den [L*J, L*b R*J, R*b K^2, 0]; G tf(num, den)分母里最后多出来的那个 0就是积分环节在传递函数中对应的s因子。新手容易漏掉这个零系数导致分子分母阶次对不上MATLAB 会直接报错。tf函数要求分子分母的系数向量长度一致补零是常见操作。运行后你会看到模型以有理分式的形式显示出来这就完成了建模环节的第一步。3.3 状态空间模型另一种语言离现代控制更近传递函数适合单输入单输出系统的频域设计但遇到多变量系统、非线性系统状态空间更自然。状态空间描述把系统写成dx/dt A*x B*u y C*x D*uMATLAB 里用ss函数建立状态空间模型。对于刚才的电机选择状态变量为电流i、转速ω、角度θ就能直接写出矩阵 A、B、C、DA [-R/L, -K/L, 0; K/J, -b/J, 0; 0, 1, 0]; B [1/L; 0; 0]; C [0, 0, 1]; % 输出角度 D 0; sys_ss ss(A, B, C, D);注意这里A矩阵是 3x3反映了三个状态之间的耦合关系。用ss(G)也可以直接从传递函数转换到状态空间反过来用tf(sys_ss)也能转回传递函数。实际项目中我会两个都用经典 PID 设计看图用传递函数做 LQR、观测器设计时用状态空间。MATLAB 的双向转换非常自由不要有这两套体系选一个的心理负担。4. 分析环节实操稳定性与动态响应的判断方法4.1 零极点与稳定性先回答会不会崩建模完成之后别急着设计控制器先分析这个对象的性格。第一个问题是**开环下系统稳不稳定**判断依据很简单系统所有极点必须在复平面左半平面实数部小于零。两种方式查看极点pzmap(G) % 画零极点图稳定区域一眼看出 pole(G) % 直接返回极点数值回到刚才的电机模型pole(G)应该会得到一个零根和一对共轭复根。零根来自积分环节意味着系统处于临界稳定状态——角度会随时间匀速增长。这并不意外也恰恰说明如果你用纯比例控制去稳定它反馈需要提供足够的阻尼把积分环节压住。零极点图还有一个用途观察极点的阻尼比和自然频率。极点到原点的连线与虚轴之间的夹角决定了阻尼比。夹角越大阻尼越小系统超调越多。在这个阶段你看一眼图基本就能预判系统的动态响应是什么脾气。4.2 时域响应上升时间、超调量、调节时间怎么读光知道稳定还不够还要知道好不好用。给系统一个阶跃输入是最直观的考核方式step(G) stepinfo(G)stepinfo返回一个结构体里面包含上升时间RiseTime、超调量Overshoot、调节时间SettlingTime、稳态值FinalValue等关键指标。对于未经设计的开环模型看到的结果往往不理想——积分环节导致角度一直在增大根本达不到稳态。这其实是个有效信号说明必须通过闭环控制来整形系统行为。用生活化类比你开车踩一脚油门车速从起步到接近目标速度需要多久会不会先冲过头晃一下再回来多久稳下来上升时间、超调、调节时间描述的就是这三个体验。控制设计的本质就是在这些指标之间找平衡。4.3 频域分析用 bode 图看稳定裕度时域指标直观但设计控制器时工程师更常看频域。波特图bode展示了系统在不同频率下的增益和相位变化margin(G)则直接标出幅值裕度和相角裕度bode(G) margin(G)相角裕度是个特别实用的指标。工程经验上相角裕度在 30 度到 60 度之间系统通常有较好的鲁棒性——模型参数稍有偏差系统依然能稳住。裕度太低系统接近临界稳定有一点点延迟就容易振荡裕度太高系统又过于保守响应变慢。分析环节你就要判断当前模型的裕度够不够不够的话给设计环节留出明确的调整方向。5. 设计环节实操从分析结论到控制器参数5.1 先写下性能指标不看需求瞎调参都是耍流氓没有指标调参就没有终点。这一步必须放在设计动作之前。假设我们要求电机角度伺服系统达到阶跃响应上升时间小于 0.5 秒超调量小于 10%稳态误差为零角度最终准确到达指令把这些数值写进脚本开头作为注释后续所有设计都以它为准绳。只要有一项不达标就说明设计还没完成而不是差不多得了。5.2 比例控制先摸一遍系统的底数最基础的控制是比例反馈闭环系统的结构是C(s) Kp。用 MATLAB 的feedback函数计算闭环传递函数Kp 5; C Kp; Gcl feedback(G * C, 1); step(Gcl) stepinfo(Gcl)注意这里用的是G * C而不是C * G虽然单输入单输出下两者等价但养成对象在前、控制器在后的写法有助于理解信号流方向。feedback(G*C, 1)的含义是把开环通道G*C通过单位负反馈闭合。实测你会发现加大Kp能减小上升时间但超调也随之增大甚至振荡。而且因为对象里已经有积分环节所以纯比例控制就能做到角度伺服稳态无差这跟我们前面对模型的分析是对得上的。如果你在另一个没有积分环节的对象上做位置控制就会看到纯比例控制残留的稳态误差——这就是为什么必须回到建模环节看对象特性。5.3 加入积分与微分PID 三类作用的取舍对于调速系统对象没有天然积分环节稳态误差一般靠积分消除超调靠微分压制。经典 PID 在 MATLAB 里有一条捷径Kp 12; Ki 3; Kd 0.1; C pid(Kp, Ki, Kd); Gcl feedback(C * G, 1); step(Gcl)pid函数会自动把三个系数组合成并联形式的传递函数。我建议初学者先做两组对比一组有Ki一组没有Ki观察稳态误差的差异再一组有Kd一组没有Kd观察超调和振荡的差异。这样三类作用各自的贡献会在你的直觉里留下真实印象而不是停留在课本的定义上。实际整定中很容易遇到一个陷阱Kd太大会放大噪声尤其在实物系统里微分项会高频抖动。仿真阶段看不出来因为模型没有噪声源。这也是为什么经验上宁可用 PI 加滤波器也不盲目加大 D 项。5.4 借助 MATLAB 工具辅助整定rltool 和 pidtune如果手工试参试到头晕MATLAB 还提供了两个高频工具。rltool(G)打开根轨迹设计界面你可以直接用鼠标拖动闭环极点系统会实时刷新根轨迹和时域响应这对理解极点位置与动态性能的关系有奇效。pidtune(G, PID)则是自动整定给定目标带宽或相位裕度自动返回一组 PID 参数。不过我要泼一盆冷水自动整定给你的参数只是起点不是终点。它基于的是你给出的目标频带但未必满足你全部的时域指标。我的常规操作是用pidtune拿到一组初始参数然后手动微调再用stepinfo逐项核实指标。5.5 闭环仿真验证设计环节的收尾动作设计完成的标准不是参数看起来合理而是仿真结果满足所有指标。最后我都会跑这样一段完整验证脚本Kp 15; Ki 5; Kd 0.2; C pid(Kp, Ki, Kd); Gcl feedback(C * G, 1); info stepinfo(Gcl); disp(info); step(Gcl);如果RiseTime、Overshoot、SettlingTime全部达标设计环节可以暂时收工。别忘了记录下这组参数和被控对象版本最好连同日期一起写进脚本注释。后面改进设计时要能重现当时的全部条件这也是工程素养的一部分而不是强迫症。6. 常见问题与排查技巧实录6.1 模型建立阶段的高频坑第一个是num和den长度不一致。tf要求二者等长少的那边要用 0 补齐。比如三阶分母配三阶分子才合理如果分子明明是常数你得写成num [K]或补成[0 0 K]看你怎么组织。常见报错信息为Vectors must be the same lengths解决办法就是统一长度。第二个是参数单位混乱。模型里电阻用欧、电感用亨、惯量用千克·平方米这些 SI 单位混搭没问题但如果你从某个资料里拿了一组电阻 2惯量 0.02却没确认对方用的是不是毫亨、克·平方厘米画面就会变成仿真曲线完全不合常理。建模后先做一次量纲检查是最便宜的排错手段。6.2 分析阶段曲线看不懂怎么排查step出来是一条水平直线九成原因是闭环增益太小或控制器传函配置错误导致响应被压得很低。先算一下稳态值如果是1e-4级别基本就是增益量级问题。pzmap的坐标轴若默认范围太大极点挤在原点附近看不清可以手动调整横纵坐标范围放大关键区域。模型阶次过高的时候仿真可能很慢这时先检查是否存在多余的高频极点可以约掉。6.3 设计阶段反馈方向的致命细节feedback默认负反馈但如果你之前手写闭环表达式G/(1G)经常因为缺少一个负号算错。用feedback函数把反馈极性作为参数传进去才是稳妥路径。另外所有 PID 参数必须在合理的数量级内。Kp1e6这种参数在仿真里可能也能跑但已经脱离实际工程意义实物上别说执行器饱和光噪声就可能让系统炸掉。调参时记得把范围约束在 0.01 到 100 级别至少先让参数有人味。我还想特别提醒一个版本的坑调参别靠感觉要记录过程。我见过不少同学在命令行里敲了二十多组参数最后问到为什么这组能用的时候答不上来因为早就忘光了。正确的做法是把每组参数连同对应的性能指标写在一个表格或结构体里方便对比。哪怕只是用注释记录% 第3轮: Kp12, 超调 35%不满足也远比一片空白好。6.4 报错信息速查表报错表现常见原因处理办法Vectors must be the same lengthsnum 与 den 长度不一致检查补零统一阶次NaN或Inf出现在结果中模型发散或参数数量级离谱检查传递函数分母、PI 参数符号Error using feedback反馈通道维度错误确认对象与控制器是 SISO 还是 MIMOMatrix dimensions must agree混淆*与.*检查矩阵维度确认是否用错运算符阶跃响应出现尖峰震荡微分项系数过大减小Kd或加低通滤波这张表是我自己平时排错时最常遇到的几类问题远远算不上全但覆盖初学者 80% 的踩坑场景应该够了。真遇到这表里没有的记得把报错信息原样复制出来逐行对照变量名往往比盯着屏幕发呆有用。实际工作中我对 MAD 流程的体会把 MAD 复盘成习惯之后我最明显的变化是不再迷信调参手感。手感能解决有经验者熟悉的场景但在陌生对象的面前建模、分析、设计这条链路的每一步都在给你提供清晰的方向。你越依赖流程越不会在设计出问题时手忙脚乱——因为你知道问题出在哪个环节也知道该回退到哪一步去查。MATLAB 在这条链路里的定位说白了就是一个趁手的工具它有上百个函数但真正值钱的不是你会多少个函数而是你清楚现在处于 MAD 的哪一站、该调用哪一类工具。这一篇我们把基础运算和完整流程打通了下一篇可以接着往里填东西用 Simulink 搭更直观的框图、加入饱和与摩擦等非线性环节、把仿真结果跟实物采集的数据放在一起对比分析。那才是建模仿真四个字真正发挥威力的地方。
阅读完成 · 觉得有帮助?