Smith Predictor是针对时滞系统的。

原理:看Matlab help中的"Control of Processes with Long Dead Time: The Smith Predictor"足矣,写的非常好。

假设有一个有时滞的一阶模型,其传递函数如下:

s = tf('s');
P = exp(-93.9*s) * 5.6/(40.2*s+1);
P.InputName = 'u';
P.OutputName = 'y';
P

得到:

P =
 
  From input "u" to output "y":
                    5.6
  exp(-93.9*s) * ----------
                 40.2 s + 1

注意到时滞常数93.9是系统时间常数的两倍还多,

其阶跃响应如下:

step(P), grid on

 我们常使用PI控制器来控制被控对象P:

C为PI控制器:

Cpi =
 
             1      1 
  Kp * (1 + ---- * ---)
             Ti     s 

这里,我们用PIDTUNE指令来tune一个PI控制器,包括用pidstd创建一个标准的PID控制器(Kp=1,Ti=1),设定开环带宽为0.006rad/s:

Cpi = pidtune(P,pidstd(1,1),0.006);
Cpi

得到:

Cpi =
 
             1      1 
  Kp * (1 + ---- * ---)
             Ti     s 

  with Kp = 0.0501, Ti = 47.3
 
Continuous-time PI controller in standard form

闭环系统的阶跃响应如下(feedback的第一个参数为PI控制器开环传函,第二个参数为测量单元传函):

Tpi = feedback([P*Cpi,1],1,1,1);  % closed-loop model [ysp;d]->y
Tpi.InputName = {'ysp' 'd'};

step(Tpi), grid on

可以看出,闭环阶跃响应的超调幅度勉强可以接收,但是稳定的时间有点太长了(差不多600s)。为了提高响应速度,是否可以增加Kp呢?下面测试3种Kp:

Kp3 = [0.06;0.08;0.1];      % try three increasing values of Kp
Ti3 = repmat(Cpi.Ti,3,1);   % Ti remains the same
C3 = pidstd(Kp3,Ti3);       % corresponding three PI controllers
T3 = feedback(P*C3,1);
T3.InputName = 'ysp';

step(T3)
title('Loss of stability when increasing Kp')

 超调最大的就是Kp=0.1的情况。可以看出,在pidtune的情况下,增大Kp就增加了超调、引入了不稳定。

PI控制器对于时滞系统而言,其性能受限于long dead time,此时PI显得“缺乏耐心”。一个例子就是在我们用淋浴洗澡。因为水管比较长,因此它是一个时滞系统。如果我们“缺乏耐心”的调整水温,会频繁的冷热交替、让人非常烦恼。一个比较好的策略就是在进一步调整之前,等待当前setting的水温先发生变化。如果我们学习到了哪个setting可以得到我们想要的水温,我们就可以如尝所愿。这个就是“Smith compensator”的思想。

Smith预估器(或者称‘补偿器’)的框图如下:

假设P是水管,那么在Smith预估器中,我们就用一个Gp(系统内模)来预测没有时滞的系统输出(即上图中的yp)。在我们水管的例子中,Gp就是最佳水温对应的setting,yp就是水管长度为0时输出的水温。

然后将这个yp和ysp(水温设定值)进行比较,经过控制器C后得到控制量u。为了防止drift并抑制外部干扰,还需要将预测部分经过时滞环节的输出y1和实际被控对象的输出y进行比较,得到差值dy;dy经过滤波器F后会贡献给e。

综上可以看出,使用Smith预估器的前提是:

  • 准确估计系统的内模Gp(越接近实际的P越好)。
  • 准确估计系统的时滞环节τ
  • 设置控制器C

对于前述系统,

P =
 
  From input "u" to output "y":
                    5.6
  exp(-93.9*s) * ----------
                 40.2 s + 1

我们设置Gp和P一样(这里假设“百分百准确”的内模估计):

 F使用一个20s的一阶滤波器:

F = 1/(20*s+1);
F.InputName = 'dy';
F.OutputName = 'dp';

对于C,我们使用PI控制器。这样,我们便构建了一个Smith预估器。通过它,我们可以增加系统的开环带宽、减少超调。如下所示,在用connet构建了总的plant后,我们用pidtuneIptions设计了一个90°的相位裕度、带宽为0.08rad/s的系统:

% Prediction model
Gp = 5.6/(40.2*s+1);
Gp.InputName = 'u';
Gp.OutputName = 'yp';

Dp = exp(-93.9*s);
Dp.InputName = 'yp'; Dp.OutputName = 'y1';

% Overall plant
S1 = sumblk('ym = yp + dp');
S2 = sumblk('dy = y0 - y1');
Plant = connect(P,Gp,Dp,F,S1,S2,'u','ym');

% Design PI controller with 0.08 rad/s bandwidth and 90 degrees phase margin
Options = pidtuneOptions('PhaseMargin',90);
C = pidtune(Plant,pidstd(1,1),0.08,Options);
C.InputName = 'e';
C.OutputName = 'u';
C

下面比较一下有Smith预估器的闭环系统和只有PI控制器的系统的阶跃响应,前者的代码为:

% Assemble closed-loop model from [y_sp,d] to y
Sum1 = sumblk('e = ysp - yp - dp');
Sum2 = sumblk('y = y0 + d');
Sum3 = sumblk('dy = y - y1');
T = connect(P,Gp,Dp,C,F,Sum1,Sum2,Sum3,{'ysp','d'},'y');

比较:

step(T,'b',Tpi,'r--')
grid on
legend('Smith Predictor','PI Controller')

可以看出,Smith预估器没有超调、响应极快(当然,前提是估计的内模是完全准确的)。

对应的Bode图也印证了这一点,看下图中的带宽和相位裕度:

 

 ----------------------------------------------------Simulink分割线-----------------------------------------------------

上面的例子是用脚本写的。而在Simulink中,已经有了现成的Smith Predictor Controller模块,可以直接用。如果想用这个模块复现"Control of Processes with Long Dead Time: The Smith Predictor"的例子,需要注意:Smith Predictor Controller是离散的,因此在写传函时不能和连续的传函形式一样,而应该用Matlab的c2d函数先将例子中的TF进行转换:

>> h = tf(5.6,[40.2 1]); 
>> hd = c2d(h,0.1)

hd =
 
   0.01391
  ----------
  z - 0.9975
 
Sample time: 0.1 seconds
Discrete-time transfer function.

再设置Smith Predictor Controller中的Numerator和Denominator:

框图如下:

仿真结果如下(红色的y为Smith预估器的仿真输出,其他的y为PI控制器的仿真输出):

可以看出,在模型无误差的情况下,Smith预估器可以允许有更大的Kp、响应快速、且没有超调。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐