【问题标题】:matlab simulink convert PID continuous to discretematlab simulink将PID连续转换为离散
【发布时间】:2017-07-15 03:55:57
【问题描述】:

如何将连续 PID(s 形式)转换为离散形式(z 形式)?假设我有 PID 的调谐增益(以 s 形式):

Kp=2266.76751174231;
Ki=3461.10112077832;
Kd=360.96017761997;

现在,我想以 z 形式对 PID 应用相同的增益。但是,与连续相比,我无法在离散中获得相同的响应。下面是z框图:

这是 z 形式的响应:

s形式的框图:

这是连续形式的响应:

任何建议我的错误是什么? 谢谢!

【问题讨论】:

  • 你注意到第一个情节中的比例了吗?

标签: matlab simulink


【解决方案1】:

我尝试使用您指定的 PID 参数和微分增益滤波器系数的默认 N=100 连续运行模型。我使用带有默认参数的ode45 求解器,但我将最大时间步长限制为 0.01。不幸的是,我发现系统不稳定。

我使用启发式手动方法调整了收益(我认为从回答您的问题的角度来看,收益的值并不相关)。我确定了以下收益:

  • Kp = 6
  • Ki = 12
  • Kd = 1

我使用的模型如下所示。从 Simulink 图中可以看出,我构建了两个模型。它们(几乎)是等价的。但是,第一个模型(最上面的模型)使用标准 Simulink PID(s) 模块,第二个模型(最下面的模型)使用自定义传递函数模块而不是 Simulink PID(s) 模块。自定义传递函数应生成与 Simulink PID(s) 模块等效的输出,因为它们仅在实现上有所不同。创建第二个模型是为了帮助解释我用于将模型从 z 域转换为 s 域的方法。我还将它用作“健全性检查”,以确保 Simulink PID 的实现与我认为的实现方式没有什么不同。



连续时间模拟的 PID 参数。


与植物相关的传递功能块的参数。


连续时间模拟的结果。

为了将植物模型从 s 域转换为 z 域,我使用了 Tustin 变换。我使用 MATLAB 中的符号工具箱来执行转换。这是我的首选方法,因为与控制系统的内置工具箱相比,它可以提供更通用的解决方案。我还在 s 域中构建了 PID 函数,并使用相同的方法将其转换为 z 域。执行转换的脚本如下所示。请注意,我使用0.1 作为离散时间模拟的模拟时间步长。这个值也应该在 Simulink 的求解器配置中设置。

从 z 域中 Simulink 模型的构建角度来看,以下变量很重要:

  • NPlantCoeffs - 包含与 z 域中植物相关的传递函数的分子系数。作为参考,获得了以下值:[45 135 135 45]
  • DPlantCoeffs- 包含与 z 域中植物相关的传递函数的分母系数。作为参考,获得了以下值:[406502 -1104494 1035506 -333498]
  • NPIDFiltCoeffs - 包含与 z 域中的 PID 相关的传递函数的分子系数。作为参考,获得了以下值:[-349 515 -196]
  • DPIDFiltCoeffs - 包含与 z 域中的 PID 相关的传递函数的分母系数。作为参考,获得了以下值:[-15 5 10]
  • Tval - 时间步长的值。作为参考,使用了以下值:0.1

离散时间模拟参数定义脚本。

% Initialisation.
clear;
clc;

% Define the symbolic variables of interest.
% T is the time step for discrete simulation.
syms s z T; 

% Define the controller parameters. 
% The parameters should correspond to the parameters obtained from tuning
% the continuous system.
Kp = 6;
Ki = 12;
Kd = 1;
N = 100;

% Define the plant and the controller in the s-domain.
TFPlant = 0.09/(0.09*s^3 + 0.18*s^2 + s + 1.004);
TFPIDFilt = Kp + Ki/s + Kd*N/(1 + N/s);

% Obtain the numerator and the denominator of the transfer functions in the
% s-domain.
[NPIDCont, DPIDCont] = numden(collect(TFPIDFilt));
NPIDCont = sym2poly(NPIDCont);
DPIDCont = sym2poly(DPIDCont);

% Convert to z-domain using Tustin substitution (referred to as Trapezoidal
% method in Simulink block PID(s)).
TFPlant = collect(subs(TFPlant, s, (2/T)*(z - 1)/(z + 1)));
TFPIDFilt = collect(subs(TFPIDFilt, s, (2/T)*(z - 1)/(z + 1)));

% Define time step for discrete simulation.
Tval = 0.1;

% Perform substitution for the time step T.
TFPlant = subs(TFPlant, T, Tval);
TFPIDFilt = subs(TFPIDFilt, T, Tval);

% Decompose into the numerator and denominator.
[NPlant, DPlant] = numden(TFPlant);
[NPIDFilt, DPIDFilt] = numden(TFPIDFilt);

% Obtain the polynomial coefficients associated with the numerator and
% denominator.
NPlantCoeffs = sym2poly(NPlant);
DPlantCoeffs = sym2poly(DPlant);
NPIDFiltCoeffs = sym2poly(NPIDFilt);
DPIDFiltCoeffs = sym2poly(DPIDFilt);

对于离散时间仿真,重要的是选择固定时间步长求解器并将时间步长设置为与用于将工厂模型从 s 域转换到 z- 域的值等效的值领域。如下所示,我使用 z 域版本的连续时间 PID 控制器模块进行离散时间仿真。给定离散时间模拟的计算设备参数,模拟结果非常接近连续时间系统的模拟结果。


离散时间模拟的求解器配置。


离散时间模拟模型。


离散时间工厂模型参数。


用于离散时间仿真的 Simulink PID(s) 模块的参数化。


离散时间模拟的结果。


要回答您最初的问题,我不确定您的错误到底在哪里。但是,我提供以下几个假设:

  1. 您为连续时间模拟获得的 PID 增益有些奇怪。使用这些增益时,您在屏幕截图中指定的系统是不稳定的,除非我误读了屏幕截图中的工厂参数。
  2. 我不确定您将工厂模型从 s 域转换为 z 域所遵循的过程。我在答案中提出的转换过程应该为转换提供有效的方法。使用固定时间步长求解器进行离散时域仿真也很重要。此外,使用与将工厂模型从 s 域转换为 z 域所使用的时间步相同的时间步也很重要。

【讨论】:

  • 你能详细说明为什么你认为符号比c2d(G,'tustin') 更好吗?我对用例感兴趣。
  • 是的,我是独立于问题提出的。我是 Python 控件工具箱的作者,我对当前工具箱语法遇到的困难很感兴趣。
  • @percusse 从我的角度来看,这不是语法问题,而是仅限于您可以在与 MATLAB 工具箱关联的类上执行的预定义数量的标准操作(可识别性分析,例如)。您还可以通过查看 TF 系数/极点/零点采用符号形式的形式来推断出很多信息。此外,将符号传递函数转换为与 MATLAB 控制系统工具箱相关的某个类的实例并使用该工具箱执行您需要的操作从来都不是问题。
  • 你有什么具体的细节让你感到沮丧吗?
  • @percusse 我对控制系统工具箱中的任何东西都不感到沮丧。然而,符号工具箱提供了代数对象的更通用和参数化的表示。因此,我更喜欢先在符号工具箱中定义任何此类对象,然后再使用其他工具箱,以及我认为是否适合从它们的符号表示中生成的对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 2021-09-19
  • 2020-11-05
  • 1970-01-01
  • 2016-06-15
  • 2013-04-15
  • 2021-08-04
相关资源
最近更新 更多