上篇控制教程 —— 介绍篇:8.基于Simulink为火车系统建模介绍了如何使用Simulink对火车系统进行数学建模,这篇教程将介绍如何在Simulink中为建立好的火车系统设计控制器。
开环被控对象模型
回顾上节内容,我们建立了一个火车系统的数学模型。
假设火车沿直线方向运动,我们希望能对火车的牵引力进行控制,使其能够平稳的启动和停止,并能在稳态下以尽可能小的误差跟踪给定的恒定速度指令。
在Simulink中实现PID控制器
我们首先创建一个子系统来便于理解,删除三个scope
模块和Singal Generator
模块,并用sink
库中的 out
模块和 in
模块替代,给相应的模块编辑对应的标签,“x1_dot” ,“x1”,“x2”以及“F”。
接下来,选中所有模块(Ctrl+A
),然后右键单击,在弹出的菜单中选择Create Subsystem from Selection
(Ctrl+G
)。然后重新排列和标记后,可以得到如下模型
现在,我们可以向窗口中添加控制器,这里我们使用PID控制器,该控制器可以从Continuous
库中拖出,将该模块与火车子系统串联放置,如下图:
我们将控制器的输出定义为火车牵引力 “F”,双击PID Control
模块,我们首先将积分(I)增益设置为0,并将比例§和微分(D)增益分别设置为默认值1和0。接下来,从Math Operations
库中添加一个Sum
模块。双击该模块,然后将List of signs
修改为|+-
,我们希望控制的是火车头的速度,这里通过“x1_dot”信号上引出并连接到Sum
模块的负输入端。Sum
模块的输出将是火车头速度的误差, 应连接到PID控制器的输入端。调整模块连接并添加标签如下
接下来,从Source
库添加一个Signal Builder
模块作为火车头速度的给定。根据需求,我们想让火车能够平稳的加速并平稳的停下来,因此我们将给定速度升至 1m/s,然后再降到 0m/s。要生成这类信号,可以双击Signal Builder
模块,然后从模块对话框顶部的 Axes
菜单中选择 Change Time Range
。将Max time
设置为 300s。接下来,将启动阶跃设置在10s,停止阶跃设置在150s。这可以通过单击信号图的阶跃位置(左右垂直线),并将其拖动到需要的位置,或在窗口底部的T
中输入对应的时间。
再从Sink
库中拖一个Scope
,并用他替换火车速度的 Out1
模块,重新添加标签。
现在,我们准备运行仿真。
运行闭环模型仿真
在运行模型之前,我们需要对模型中使用的每个变量赋值,对于我们的模型,使用如下参数:
- M 1 M_1 M1 = 1 kg
- M 2 M_2 M2 = 0.5 kg
- k k k = 1 N/sec
- F F F = 1 N
- μ \mu μ = 0.02 sec/m
- g g g = 9.8 m/s^2
M1 = 1;
M2 = 0.5;
k = 1;
F = 1;
mu = 0.02;
g = 9.8;
在MATLAB命令窗口中执行以上命令,接下来,需要设置仿真运行时间,为了匹配Signal Builder
模块中时间范围。可将仿真Stop Time
设置为300。现在,运行仿真并观察 “x1_dot” 示波器的结果,从图中可以看出,系统是稳定的。
由于我们只是用了比例环节,产生的稳态误差并不能令人满意,因此我们将展示如何重新设计控制器。首先将演示如何将Simulink中的模型提取到MATLAB中进行分析和设计,然后,我们将演示如何直接在Simulink中设计控制器。
将模型提取到MATLAB
Simulink控制器设计工具箱提供了将模型从Simulink提取到MATLAB工作空间的功能。这对于复杂的或非线性的仿真模型特别有效。对于离散时间(采样)模型也非常有用。本示例中,让我们提取火车子系统的连续时间模型。首先,我们需要确定要提取的模型的输入和输出。火车系统的输入是牵引力
F
F
F 。我们可以通过右键单击标签为 F
信号并从菜单中选择Linear Analysis Points > Open-loop Input
。同样,我们可以右键单击 标签为x1_dot
的信号并从菜单中选择Linear Anasis Point > Open-loop Output
来确定系统的输出。这些输入和输出现在将由小箭头符号表示,如下图所示。由于我们希望自己在没有控制的情况下提取火车模型,因此我们需要进一步删除反馈信号,否则我们将提取的是从
F
F
F到
x
˙
1
\dot{x}_1
x˙1的闭环模型。
现在,我们可以通过选择APPS > Model Linearizer
来打开Model Linearizer
进行分析。
注:我使用的是MATLAB2020a,早期版本应该叫 Linear Analysis Tool
打开后的界面如下
该工具是将给定模型(可能是非线性)线性化成一个LTI对象,并允许您指定要线性化的工作点,由于我们的模型本来就是线性的,因此我们选择工作点没有作用,现在保持默认的“Model Initial Condition”,为了生成线性化模型,可以选择图中的step
按钮,该按钮由一个绿色三角形表示。
通过上述检查,可以自动生成线性化模型的阶跃响应。可以将该结果与上一篇博文介绍的阶跃响应结果进行对比,可以看到是相同的。此外,线性化过程还生成了对应的linsys1
对象。只需要将该对象从Linear Analysis Workspace
拖动到MATLAB Workspace
中,即可在MATLAB中使用该LTI模型。
提取该模型后,我们现在可以使用MATLAB提供的用于控制器设计的所有功能。例如,让我们使用以下命令来得到闭环系统的零极点。
sys_cl = feedback(linsys1,1);
p = pole(sys_cl)
z = zero(sys_cl)
从结果中可以看到存在零极点在原点处抵消的情况,此外,其余极点均具有负实部,这说明现在的模型闭环系统是稳定的,但零极点的分布说明主导极点的阻尼不足,将产生振荡,这与我们闭环仿真的结果一致,也可以通过工具画出零极点分布图。
接下来我们将设计一个新的控制器来抑制响应中的振荡。
Simulink中的控制器设计
我们可以使用自带的GUI工具来对PID参数进行快速调整,双击模型中的PID控制器,然后选择PID Tuner
,但本教程我们打算使用Control System Designer
进行控制器设计
打开后的界面如下
首先要做的是确定要调整的控制模块,点击添加模块按钮,然后从出现的窗口中选择PID控制器模块,如下所示,当然也可以选择其他类型的模块如传递函数,状态空间等表示的控制器。选择完成后在Edit Architecture
窗口中选择OK
按钮。
在进行控制器调整之前,我们必须确定要分析的闭环系统的输入和输出。这与我们将线性化模型提取到MATLAB中的方式类似。具体来说,右击速度命令信号(Signal Builder
的输出),然后从菜单中选择Linear Analysis Points > Input Perturbation
来作为闭环系统的输入,接下来右击速度信号(x1_dot
),然后从菜单中选择Linear Analysis Points > Output Measurement
来作为闭环系统的输出。
现在我们已经确定了要调整的模块以及我们的输入和输出信号,现在我们可以开始对控制器进行调参了。
选择Tuning Methods
按钮,我们将选择希望用于设计控制器的设计方式,在该示例中,我们将采用根轨迹方法,因此在Tuning Methods
下选择Root Locus Editor
。
然后,我们可以获取到该模型的根轨迹图,该轨迹图显示了在比例控制下闭环系统的所有可能的闭环极点位置,从图中可以看到所有环路增益都在左半平面,表明响应是稳定的。
如果我们想降低环路增益,则可以将闭环极点在左半平面进行移动来改变系统的表现。可以通过抓取粉红色方块标记的极点位置,向开环零点位置(用星号x标记)拖动来实现。
选定好增益后,我们可以选择ANALYSIS
下的New Plot
并选择New Step
来检查响应的闭环阶跃响应。选择New Input-Output Transfer Response
并选择对应的输入输出。
然后单击绘制按钮,从产生的闭环阶跃响应中,我们可以看到响应是稳定的,但存在一些稳态误差。
回顾一下,增加积分环节可以减小闭环系统稳态误差。调用以下形式的PI控制器。
C
(
s
)
=
K
p
+
K
i
s
=
K
p
s
+
K
i
s
C(s) = K_p + \frac{K_i}{s} = \frac{K_ps + K_i}{s}
C(s)=Kp+sKi=sKps+Ki
这个方程式表明要在系统中新增一个纯积分极点和一个零点。我们可以在根轨迹图中右键单击,然后从出现的菜单中选择Add Pole/Zero > Integrator
来添加纯积分极点,同样,可以选择Add Pole/Zero > Real Zero来新增一个实部零点,这样添加的话需要自己手动拖动零极点位置到合适的位置,当然,也可以通过选择Edit Compensator
直接输入要添加的零极点和位置,我们将采用这种方法,在打开的窗口中,添加一个在 -0.15
的零点和一个纯积分极点,并将环路增益配置在 0.05
。
得到的根轨迹如图
和之前一样,可以获得当前参数下的阶跃响应。
现在,可以将新得到的参数更新到原来的PID控制器中,然后重新进行仿真。
总体而言,这种响应似乎可以达到我们想要火车能平稳的启动和停止的目标,同时还需要保持最小的稳态误差。