主要内容

pidstd

标准型 PID 控制器

    说明

    使用 pidstd 创建标准型 PID 控制器对象,或者将动态系统模型转换为标准型 PID 控制器。

    pidstd 控制器模型对象可以表示连续时间或离散时间的标准型 PID 控制器。

    • 连续时间 - C=Kp(1+1Ti1s+TdsTdNs+1)

    • 离散时间 - C=Kp(1+1TiIF(z)+TdTdN+DF(z))

    其中:

    • Kp 是比例增益。

    • Ti 是积分时间。

    • Td 是导数时间。

    • N 是一阶导数滤波器除数。

    • IF(z) 是离散时间控制器中用于计算积分的积分器方法。

    • DF(z) 是离散时间控制器中用于计算导数滤波器的积分器方法。

    然后,您可以将此对象与控制架构的其他组件(如被控对象、作动器、传感器)相组合,以表示您的控制系统。有关详细信息,请参阅使用模型对象进行控制系统建模

    您可以通过直接指定控制器参数,或通过将另一种类型的模型(如传递函数模型 tf)转换为 PID 控制器形式,来创建 PID 控制器模型对象。

    您还可以使用 pidstd 来创建广义状态空间 (genss) 模型或不确定状态空间 (uss (Robust Control Toolbox)) 模型。

    创建对象

    您可以通过以下方式之一获得 pidstd 控制器模型。

    • 使用 pidstd 函数创建模型。

    • 使用 pidtune 函数为被控对象模型调节 PID 控制器。使用 pidtune 函数的 C0 参量指定基线标准型 PID 控制器类型。例如:

      sys = zpk([],[-1 -1 -1],1);
      C0 = pidstd(1,1,1);
      C = pidtune(sys,C0)
    • 使用以下工具以交互方式为被控对象模型调节 PID 控制器:

    描述

    C = pidstd(Kp,Ti,Td,N) 创建连续时间标准型 PID 控制器模型,并设置属性 KpTiTdN。其余属性采用默认值。

    示例

    C = pidstd(Kp,Ti,Td,N,Ts) 创建采样时间为 Ts 的离散时间 PID 控制器模型。

    示例

    C = pidstd(Kp) 创建连续时间比例 (P) 控制器。

    C = pidstd(Kp,Ti) 创建比例和积分 (PI) 控制器。

    C = pidstd(Kp,Ti,Td) 创建比例、积分和导数 (PID) 控制器。

    C = pidstd(___,Name,Value) 使用以上任何输入参量组合中的一个或多个 Name,Value 参量设置指定 pidstd 控制器对象的属性。

    示例

    C = pidstd 创建具有默认属性值的控制器对象。要修改该控制器模型的属性,可使用圆点表示法。

    示例

    C = pidstd(sys) 将动态系统模型 sys 转换为标准型 pidstd 控制器对象。

    示例

    输入参量

    全部展开

    比例增益,指定为有限实数值或可调对象。

    • 要创建 pidstd 控制器对象,请使用有限实数标量值。

    • 要创建 pidstd 控制器对象数组,请使用有限实数值数组。

    • 要创建可调控制器模型,请使用可调参数 (realp) 或广义矩阵 (genmat)。

    • 要创建可调增益调度控制器模型,请使用通过 tunableSurface 创建的可调曲面。

    积分时间,指定为正实数值或可调对象。

    • 要创建 pidstd 控制器对象,请使用实数正标量值。

    • 要创建 pidstd 控制器对象数组,请使用实数正值数组。

    • 要创建可调控制器模型,请使用可调参数 (realp) 或广义矩阵 (genmat)。

    • 要创建可调增益调度控制器模型,请使用通过 tunableSurface 创建的可调曲面。

    导数时间,指定为有限非负实数值或可调对象。

    • 要创建 pidstd 控制器对象,请使用有限实数非负标量值。

    • 要创建 pidstd 控制器对象数组,请使用有限实数非负值数组。

    • 要创建可调控制器模型,请使用可调参数 (realp) 或广义矩阵 (genmat)。

    • 要创建可调增益调度控制器模型,请使用通过 tunableSurface 创建的可调曲面。

    一阶导数滤波器除数,指定为正实数值或可调对象。

    • 要创建 pidstd 控制器对象,请使用实数正标量值。

    • 要创建 pidstd 控制器对象数组,请使用实数正值数组。

    • 要创建可调控制器模型,请使用可调参数 (realp) 或广义矩阵 (genmat)。

    • 要创建可调增益调度控制器模型,请使用通过 tunableSurface 创建的可调曲面。

    N = Inf 时,控制器的导数作用没有滤波器。

    采样时间,指定为:

    • 0(适用于连续时间系统)。

    • 表示离散时间系统采样周期的正标量。以 TimeUnit 属性指定的时间单位指定 Ts

    pidstd 控制器数组中,所有控制器应用相同的 Ts

    PID 控制器模型不支持未指定的采样时间 (Ts = -1)。

    注意

    更改 Ts 不会对模型进行离散化或重采样。要在连续时间和离散时间表示之间转换,请使用 c2dd2c。要更改离散时间系统的采样时间,请使用 d2d

    离散化控制器的离散积分器公式取决于您使用的 c2d 离散化方法,如下表所示。

    c2d 离散化方法IFormulaDFormula
    'zoh'ForwardEulerForwardEuler
    'foh'TrapezoidalTrapezoidal
    'tustin'TrapezoidalTrapezoidal
    'impulse'ForwardEulerForwardEuler
    'matched'ForwardEulerForwardEuler

    有关 c2d 离散化方法的详细信息,请参阅 c2d

    如果您需要不同的离散积分器公式,可通过直接将 TsIFormulaDFormula 设置为所需值来对控制器进行离散化。然而,这种方法不会为离散化后的控制器计算新的增益和滤波器常数值。因此,与使用 c2d 相比,这种方法可能会导致连续时间和离散时间 PID 控制器之间的匹配度较差。

    动态系统,指定为一个 SISO 动态系统模型或 SISO 动态系统模型数组。您可以使用的动态系统包括:

    • 连续时间或离散时间数值 LTI 模型,如 tfzpksspidstd 模型。

    • 广义或不确定的 LTI 模型,如 genssuss (Robust Control Toolbox) 模型。

      得到的 PID 控制器假设:

      • 对于可调控制设计模块,采用可调组件的当前值。

      • 对于不确定的控制设计模块,采用标称模型值。

    • 辨识的 LTI 模型,如 idtf (System Identification Toolbox)idss (System Identification Toolbox)idproc (System Identification Toolbox)idpoly (System Identification Toolbox)idgrey (System Identification Toolbox) 模型。

    输出参量

    全部展开

    PID 控制器模型,以如下形式返回:

    • 当所有增益都为数值时,返回标准型 PID 控制器 (pidstd) 模型对象。当增益为数值数组时,Cpidstd 控制器对象数组。

    • 如果 numeratordenominator 输入参量包括可调参数,如 realp 参数或广义矩阵 (genmat),则返回为广义状态空间模型 (genss) 对象。

    • numeratordenominator 输入参量包括不确定参数时,返回为不确定状态空间模型 (uss) 对象。使用不确定模型需要 Robust Control Toolbox™ 软件。

    属性

    全部展开

    PID 控制器系数,指定为标量。在创建 pidstd 控制器对象或对象数组时,在 KpTiTdN 输入参量中指定这些系数。

    离散时间 pidstd 控制器积分器的离散积分器公式 IF(z):

    C=Kp(1+1TiIF(z)+TdTdN+DF(z)).

    IFormula 指定为以下公式之一:

    • 'ForwardEuler' - IF(z) = Tsz1.

      此公式最适合小采样时间,此时与控制器的带宽相比,奈奎斯特极限较大。对于较大的采样时间,ForwardEuler 公式可能会导致不稳定,即使在离散化连续时间稳定的系统时也是如此。

    • 'BackwardEuler' - IF(z) = Tszz1.

      BackwardEuler 公式的一个优点是,使用此公式离散化稳定的连续时间系统始终会产生稳定的离散时间结果。

    • 'Trapezoidal' - IF(z) = Ts2z+1z1.

      Trapezoidal 公式的一个优点是,使用此公式离散化稳定的连续时间系统始终会产生稳定的离散时间结果。在所有可用的积分公式中,Trapezoidal 能使离散化系统的频域特性与相应连续时间系统的频域特性最为接近。

    C 是连续时间控制器时,IFormula''

    离散时间 pidstd 控制器导数滤波器的离散积分器公式 DF(z):

    C=Kp(1+1TiIF(z)+TdTdN+DF(z)).

    DFormula 指定为以下公式之一:

    • 'ForwardEuler' - DF(z) = Tsz1.

      此公式最适合小采样时间,此时与控制器的带宽相比,奈奎斯特极限较大。对于较大的采样时间,ForwardEuler 公式可能会导致不稳定,即使在离散化连续时间稳定的系统时也是如此。

    • 'BackwardEuler' - DF(z) = Tszz1.

      BackwardEuler 公式的一个优点是,使用此公式离散化稳定的连续时间系统始终会产生稳定的离散时间结果。

    • 'Trapezoidal' - DF(z) = Ts2z+1z1.

      Trapezoidal 公式的一个优点是,使用此公式离散化稳定的连续时间系统始终会产生稳定的离散时间结果。在所有可用的积分公式中,Trapezoidal 能使离散化系统的频域特性与相应连续时间系统的频域特性最为接近。

    对于没有导数滤波器 (N = Inf) 的 pidstd 控制器,DFormulaTrapezoidal 值不可用。

    C 是连续时间控制器时,DFormula''

    此 属性 为只读。

    系统输入的时间延迟。对于 pidstd 控制器对象,InputDelay 始终为 0。

    此 属性 为只读。

    系统输出的时间延迟。对于 pidstd 控制器对象,OutputDelay 始终为 0。

    采样时间,指定为:

    • 0(适用于连续时间系统)。

    • 表示离散时间系统采样周期的正标量。以 TimeUnit 属性指定的时间单位指定 Ts

    如果 pidstd 是 PID 控制器数组,则所有控制器应用相同的 Ts

    时间变量单位,指定为以下项之一:

    • 'nanoseconds'

    • 'microseconds'

    • 'milliseconds'

    • 'seconds'

    • 'minutes'

    • 'hours'

    • 'days'

    • 'weeks'

    • 'months'

    • 'years'

    更改 TimeUnit 不会影响其他属性,但会更改整体系统行为。可使用 chgTimeUnit 在不修改系统行为的情况下转换时间单位。

    输入通道名称,指定为以下项之一:

    • 字符向量

    • ''(未指定名称)

    也可以按如下方式将名称 error 赋给控制器模型 C 的输入。

    C.InputName = 'error';

    您可以使用简化形式 u 来引用 InputName 属性。例如,C.u 等效于 C.InputName

    使用 InputName 可以:

    • 识别模型显示和绘图上的通道。

    • 互连模型时指定连接点。

    输入通道单位,指定为以下项之一:

    • 字符向量。

    • ''(未指定单位)。

    使用 InputUnit 指定输入信号单位。InputUnit 不会影响系统行为。

    例如,可按如下方式将浓度单位 'mol/m^3' 赋给控制器模型 C 的输入。

    C.InputUnit = 'mol/m^3';

    输入通道组。PID 控制器模型不需要此属性。

    默认情况下,InputGroup 是不包含字段的结构体。

    输出通道名称,指定为以下项之一:

    • 字符向量。

    • ''(未指定名称)。

    例如,可按如下方式将名称 'control' 赋给控制器模型 C 的输出。

    C.OutputName = 'control';

    您还可以使用简化形式 y 来引用 OutputName 属性。例如,C.y 等效于 C.OutputName

    使用 OutputName 可以:

    • 识别模型显示和绘图上的通道。

    • 互连模型时指定连接点。

    输出通道单位,指定为以下项之一:

    • 字符向量。

    • ''(未指定单位)。

    使用 OutputUnit 指定输出信号单位。OutputUnit 不会影响系统行为。

    例如,可按如下方式将单位 'volts' 赋给控制器模型 C 的输出。

    C.OutputUnit = 'volts';

    输出通道组。PID 控制器模型不需要此属性。

    默认情况下,OutputGroup 是不包含字段的结构体。

    用户指定的要与系统关联的文本,指定为字符向量或字符向量元胞数组。例如,'System is MIMO'

    要与系统关联的用户指定数据,指定为任何 MATLAB 数据类型。

    系统名称,指定为字符向量。例如,'system_1'

    模型数组的采样网格,指定为结构体数组。

    使用 SamplingGrid 跟踪与模型数组中每个模型相关联的变量值,包括辨识的线性时不变 (IDLTI) 模型数组。

    将结构体的字段名称设置为采样变量的名称。将字段值设置为与数组中每个模型相关联的采样变量值。所有采样变量都必须为数值标量,所有由采样值组成的数组都必须与模型数组的维度匹配。

    例如,您可以通过拍摄线性时变系统在时间 t = 0:10 处的快照,创建一个 11×1 线性模型数组 sysarr。以下代码随线性模型存储时间采样。

     sysarr.SamplingGrid = struct('time',0:10)

    同样,您可以通过对两个变量 zetaw 独立采样,创建一个 6×9 模型数组 M。以下代码将 (zeta,w) 值映射到 M

    [zeta,w] = ndgrid(<6 values of zeta>,<9 values of w>)
    M.SamplingGrid = struct('zeta',zeta,'w',w)

    当显示 M 时,数组中的每个条目都包括对应的 zetaw 值。

    M
    M(:,:,1,1) [zeta=0.3, w=5] =
     
            25
      --------------
      s^2 + 3 s + 25
     
    
    M(:,:,2,1) [zeta=0.35, w=5] =
     
             25
      ----------------
      s^2 + 3.5 s + 25
     
    ...

    对于通过在多个参数值或工作点处线性化 Simulink® 模型生成的模型数组,软件会自动使用与数组中每个条目对应的变量值填充 SamplingGrid。例如,Simulink Control Design™ 命令 linearize (Simulink Control Design)slLinearizer (Simulink Control Design) 会自动填充 SamplingGrid

    默认情况下,SamplingGrid 是不包含字段的结构体。

    对象函数

    以下列表包含可用于 pidstd 模型的部分代表性函数。一般情况下,任何适用于 动态系统模型 的函数也适用于 pidstd 对象。

    全部展开

    step动态系统的阶跃响应
    impulse动态系统的冲激响应图;冲激响应数据
    lsim计算动态系统对任意输入的时间响应仿真数据
    bode动态系统的波特频率响应
    nyquist动态系统的奈奎斯特响应
    nichols动态系统的尼柯尔斯响应
    bandwidth频率响应带宽
    polePoles of dynamic system
    zeroSISO 动态系统的零点和增益
    pzplotPlot pole-zero map of dynamic system
    margin增益裕度、相位裕度和穿越频率
    zpk零极点增益模型
    ss状态空间模型
    c2d将模型从连续时间转换为离散时间
    d2c将模型从离散时间转换为连续时间
    d2dResample discrete-time model
    feedback多个模型的反馈连接
    connectBlock diagram interconnections of dynamic systems
    series两个模型的串行连接
    parallel两个模型的并行连接
    pidtunePID tuning algorithm for linear plant model
    rlocus动态系统的根轨迹
    piddataAccess coefficients of parallel-form PID controller
    make2DOFConvert 1-DOF PID controller to 2-DOF controller
    pidTunerOpen PID Tuner for PID tuning
    tunablePIDTunable PID controller

    示例

    全部折叠

    创建一个具有比例项、导数项和滤波器除数的连续时间标准型 PDF 控制器。为此,请将积分时间设置为无穷大。将其他增益和滤波器除数常数设置为所需值。

    Kp = 1;
    Ti = Inf;
    Td = 3;
    N = 6;
    C = pidstd(Kp,Ti,Td,N)
    C =
     
                          s      
      Kp * (1 + Td * ------------)
                      (Td/N)*s+1 
    
      with Kp = 1, Td = 3, N = 6
     
    Continuous-time PDF controller in standard form
    Model Properties
    

    显示结果显示控制器类型、公式和参数值,并验证控制器没有积分器项。

    创建一个使用梯形离散化公式的离散时间标准型 PI 控制器。

    要创建离散时间 PI 控制器,请使用 Name,Value 语法来设置 Ts 的值和离散化公式。

    C2 = pidstd(1,0.5,'Ts',0.1,'IFormula','Trapezoidal') % Ts = 0.1s
    C2 =
     
                 1     Ts*(z+1)
      Kp * (1 + ---- * --------)
                 Ti    2*(z-1) 
    
      with Kp = 1, Ti = 0.5, Ts = 0.1
     
    Sample time: 0.1 seconds
    Discrete-time PI controller in standard form
    Model Properties
    

    您也可以通过在所有四个 PID 参数 KpTiTdN 之后提供 Ts 作为第五个输入参量来创建相同的离散时间控制器。由于您只需要一个 PI 控制器,因此请将 Td 设置为零,并将 N 设置为无穷大。

    C2 = pidstd(5,2.4,0,Inf,0.1,'IFormula','Trapezoidal')
    C2 =
     
                 1     Ts*(z+1)
      Kp * (1 + ---- * --------)
                 Ti    2*(z-1) 
    
      with Kp = 5, Ti = 2.4, Ts = 0.1
     
    Sample time: 0.1 seconds
    Discrete-time PI controller in standard form
    Model Properties
    

    显示结果显示 C1C2 是相同的。

    在您创建 PID 控制器时,可以设置动态系统属性 InputNameOutputName。例如,当您使用 connect 命令将创建的该 PID 控制器与其他动态系统模型互连时,这会很有用。

    C = pidstd(1,2,3,'InputName','e','OutputName','u')
    C =
     
                 1      1          
      Kp * (1 + ---- * --- + Td * s)
                 Ti     s          
    
      with Kp = 1, Ti = 2, Td = 3
     
    Continuous-time PID controller in standard form
    Model Properties
    

    显示结果未显示 PID 控制器的输入名称和输出名称,但您可以检查这些属性的值。例如,验证控制器的输入名称。

    C.InputName
    ans = 1×1 cell array
        {'e'}
    
    

    创建一个 2×3 的 PI 控制器网格,其中数组行中的比例增益范围为 1 到 2,列中的积分增益范围为 5 到 9。

    要构建该 PID 控制器数组,请先从表示增益的数组开始着手。

    Kp = [1 1 1;2 2 2];
    Ti = [5:2:9;5:2:9];

    当您将这些数组传递给 pidstd 命令时,该命令将返回一个控制器数组。

    pi_array = pidstd(Kp,Ti,'Ts',0.1,'IFormula','BackwardEuler');
    size(pi_array)
    2x3 array of PID controller.
    Each PID has 1 output and 1 input.
    

    或者,使用 stack 命令构建 PID 控制器数组。

    创建一个 PID 控制器。

    C = pidstd(1,5,0.1)
    C =
     
                 1      1          
      Kp * (1 + ---- * --- + Td * s)
                 Ti     s          
    
      with Kp = 1, Ti = 5, Td = 0.1
     
    Continuous-time PID controller in standard form
    Model Properties
    

    创建一个 PIDF 控制器。

    Cf = pidstd(1,5,0.1,0.5)
    Cf =
     
                 1      1              s      
      Kp * (1 + ---- * --- + Td * ------------)
                 Ti     s          (Td/N)*s+1 
    
      with Kp = 1, Ti = 5, Td = 0.1, N = 0.5
     
    Continuous-time PIDF controller in standard form
    Model Properties
    

    沿第二个数组维度堆叠这些控制器。

    pid_array = stack(2,C,Cf);

    此命令返回一个 1×2 的控制器数组。

    size(pid_array)
    1x2 array of PID controller.
    Each PID has 1 output and 1 input.
    

    数组中的所有 PID 控制器必须具有相同的采样时间、离散积分器公式和动态系统属性,例如 InputNameOutputName

    将并联型 pid 控制器转换为标准型。

    并联型 PID 用总比例、积分和导数增益 KpKiKd 以及滤波器时间常数 Tf 来表示控制器动作。您可以使用 pidstd 命令将任何并联型控制器转换为标准型控制器,前提是:

    • 并联型控制器不是纯积分器。

    • 增益 KpKiKd 的符号均相同。

    例如,假设有以下并联型控制器。

    Kp = 2;
    Ki = 3;
    Kd = 4;
    Tf = 5;
    C_par = pid(Kp,Ki,Kd,Tf)
    C_par =
     
                 1            s    
      Kp + Ki * --- + Kd * --------
                 s          Tf*s+1 
    
      with Kp = 2, Ki = 3, Kd = 4, Tf = 5
     
    Continuous-time PIDF controller in parallel form.
    Model Properties
    

    使用 pidstd 将此控制器转换为标准型控制器。

    C_std = pidstd(C_par)
    C_std =
     
                 1      1              s      
      Kp * (1 + ---- * --- + Td * ------------)
                 Ti     s          (Td/N)*s+1 
    
      with Kp = 2, Ti = 0.667, Td = 2, N = 0.4
     
    Continuous-time PIDF controller in standard form
    Model Properties
    

    将表示 PID 控制器的连续时间动态系统转换为标准型 pidstd

    以下具有一个积分器和两个零点的动态系统相当于一个 PID 控制器。

    H(s)=3(s+1)(s+2)s

    创建 Hzpk 模型。然后使用 pidstd 命令来获得以 PID 增益 KpTiTd 表示的 H

    H = zpk([-1,-2],0,3);
    C = pidstd(H)
    C =
     
                 1      1          
      Kp * (1 + ---- * --- + Td * s)
                 Ti     s          
    
      with Kp = 9, Ti = 1.5, Td = 0.333
     
    Continuous-time PID controller in standard form
    Model Properties
    

    将表示带有导数滤波器的 PID 控制器的离散时间动态系统转换为标准型 pidstd

    创建一个表示 PIDF 控制器(两个零点和两个极点,包括 z = 1 处的积分器极点)的离散时间 zpk 模型。

    sys = zpk([-0.5,-0.6],[1 -0.2],3,'Ts',0.1);

    当您将 sys 转换为 PID 形式时,结果取决于您为转换指定的离散积分器公式。例如,对积分器和导数都使用默认的 ForwardEuler 公式。

    C = pidstd(sys)
    C =
     
                 1       Ts                 1       
      Kp * (1 + ---- * ------ + Td * ---------------)
                 Ti      z-1         (Td/N)+Ts/(z-1)
    
      with Kp = 2.75, Ti = 0.0458, Td = 0.00758, N = 0.0909, Ts = 0.1
     
    Sample time: 0.1 seconds
    Discrete-time PIDF controller in standard form
    Model Properties
    

    对于这个特定的动态系统,您不能对导数滤波器使用 BackwardEuler 公式来将 sys 转换为标准型 PID。这样做会导致 N < 0,这是不允许的。在这种情况下,pidstd 会返回错误。

    同样,您也不能使用 Trapezoidal 公式来将 sys 转换为标准型 PID。这样做会导致 TiTd 为负,这是不允许的。

    对连续时间 PID 控制器进行离散化,并设置积分和导数滤波器公式。

    创建一个连续时间 PIDF 控制器,并使用 c2d 命令的零阶保持方法对其进行离散化。

    Ccon = pidstd(1,2,3,4);
    Cdis1 = c2d(Ccon,0.1,'zoh')
    Cdis1 =
     
                 1       Ts                 1       
      Kp * (1 + ---- * ------ + Td * ---------------)
                 Ti      z-1         (Td/N)+Ts/(z-1)
    
      with Kp = 1, Ti = 2, Td = 3.2, N = 4, Ts = 0.1
     
    Sample time: 0.1 seconds
    Discrete-time PIDF controller in standard form
    Model Properties
    

    显示结果显示 c2d 为离散时间控制器计算新的 PID 增益。

    离散化控制器的离散积分器公式取决于 c2d 离散化方法。对于 zoh 方法,IFormulaDFormula 都是 ForwardEuler

    Cdis1.IFormula
    ans = 
    'ForwardEuler'
    
    Cdis1.DFormula
    ans = 
    'ForwardEuler'
    

    如果您想使用与 c2d 返回的公式不同的公式,那么您可以直接将控制器的 TsIFormulaDFormula 属性设置为所需值。

    Cdis2 = Ccon;
    Cdis2.Ts = 0.1; 
    Cdis2.IFormula = 'BackwardEuler';
    Cdis2.DFormula = 'BackwardEuler';

    但是,这些命令不会为离散化控制器计算新的 PID 增益。要查看这一点,可以检查 Cdis2 并将系数与 CconCdis1 进行比较。

    Cdis2
    Cdis2 =
     
                 1      Ts*z                 1        
      Kp * (1 + ---- * ------ + Td * -----------------)
                 Ti      z-1         (Td/N)+Ts*z/(z-1)
    
      with Kp = 1, Ti = 2, Td = 3, N = 4, Ts = 0.1
     
    Sample time: 0.1 seconds
    Discrete-time PIDF controller in standard form
    Model Properties
    

    版本历史记录

    在 R2010b 中推出