控制API#
长期激励#
- class sympy.physics.control.lti.TransferFunction(num, den, var)[源代码]#
A class for representing LTI (Linear, time-invariant) systems that can be strictly described by ratio of polynomials in the Laplace transform complex variable. The arguments are
num
,den
, andvar
, wherenum
andden
are numerator and denominator polynomials of theTransferFunction
respectively, and the third argument is a complex variable of the Laplace transform used by these polynomials of the transfer function.num
andden
can be either polynomials or numbers, whereasvar
has to be aSymbol
.- 参数:
num :Expr,编号
传递函数的分子多项式。
den :Expr,编号
传递函数的分母多项式。
var :符号
传递函数多项式使用的拉普拉斯变换的复变量。
- 加薪:
TypeError
When
var
is not a Symbol or whennum
orden
is not a number or a polynomial.ValueError
什么时候?
den
是零。
解释
Generally, a dynamical system representing a physical model can be described in terms of Linear Ordinary Differential Equations like -
\(\small{b_{m}y^{\left(m\right)}+b_{m-1}y^{\left(m-1\right)}+\dots+b_{1}y^{\left(1\right)}+b_{0}y= a_{n}x^{\left(n\right)}+a_{n-1}x^{\left(n-1\right)}+\dots+a_{1}x^{\left(1\right)}+a_{0}x}\)
Here, \(x\) is the input signal and \(y\) is the output signal and superscript on both is the order of derivative (not exponent). Derivative is taken with respect to the independent variable, \(t\). Also, generally \(m\) is greater than \(n\).
It is not feasible to analyse the properties of such systems in their native form therefore, we use mathematical tools like Laplace transform to get a better perspective. Taking the Laplace transform of both the sides in the equation (at zero initial conditions), we get -
\(\small{\mathcal{L}[b_{m}y^{\left(m\right)}+b_{m-1}y^{\left(m-1\right)}+\dots+b_{1}y^{\left(1\right)}+b_{0}y]= \mathcal{L}[a_{n}x^{\left(n\right)}+a_{n-1}x^{\left(n-1\right)}+\dots+a_{1}x^{\left(1\right)}+a_{0}x]}\)
Using the linearity property of Laplace transform and also considering zero initial conditions (i.e. \(\small{y(0^{-}) = 0}\), \(\small{y'(0^{-}) = 0}\) and so on), the equation above gets translated to -
\(\small{b_{m}\mathcal{L}[y^{\left(m\right)}]+\dots+b_{1}\mathcal{L}[y^{\left(1\right)}]+b_{0}\mathcal{L}[y]= a_{n}\mathcal{L}[x^{\left(n\right)}]+\dots+a_{1}\mathcal{L}[x^{\left(1\right)}]+a_{0}\mathcal{L}[x]}\)
Now, applying Derivative property of Laplace transform,
\(\small{b_{m}s^{m}\mathcal{L}[y]+\dots+b_{1}s\mathcal{L}[y]+b_{0}\mathcal{L}[y]= a_{n}s^{n}\mathcal{L}[x]+\dots+a_{1}s\mathcal{L}[x]+a_{0}\mathcal{L}[x]}\)
Here, the superscript on \(s\) is exponent. Note that the zero initial conditions assumption, mentioned above, is very important and cannot be ignored otherwise the dynamical system cannot be considered time-independent and the simplified equation above cannot be reached.
Collecting \(\mathcal{L}[y]\) and \(\mathcal{L}[x]\) terms from both the sides and taking the ratio \(\frac{ \mathcal{L}\left\{y\right\} }{ \mathcal{L}\left\{x\right\} }\), we get the typical rational form of transfer function.
The numerator of the transfer function is, therefore, the Laplace transform of the output signal (The signals are represented as functions of time) and similarly, the denominator of the transfer function is the Laplace transform of the input signal. It is also a convention to denote the input and output signal's Laplace transform with capital alphabets like shown below.
\(H(s) = \frac{Y(s)}{X(s)} = \frac{ \mathcal{L}\left\{y(t)\right\} }{ \mathcal{L}\left\{x(t)\right\} }\)
\(s\), also known as complex frequency, is a complex variable in the Laplace domain. It corresponds to the equivalent variable \(t\), in the time domain. Transfer functions are sometimes also referred to as the Laplace transform of the system's impulse response. Transfer function, \(H\), is represented as a rational function in \(s\) like,
\(H(s) =\ \frac{a_{n}s^{n}+a_{n-1}s^{n-1}+\dots+a_{1}s+a_{0}}{b_{m}s^{m}+b_{m-1}s^{m-1}+\dots+b_{1}s+b_{0}}\)
实例
>>> from sympy.abc import s, p, a >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction(s + a, s**2 + s + 1, s) >>> tf1 TransferFunction(a + s, s**2 + s + 1, s) >>> tf1.num a + s >>> tf1.den s**2 + s + 1 >>> tf1.var s >>> tf1.args (a + s, s**2 + s + 1, s)
任何复杂变量都可以用于
var
.>>> tf2 = TransferFunction(a*p**3 - a*p**2 + s*p, p + a**2, p) >>> tf2 TransferFunction(a*p**3 - a*p**2 + p*s, a**2 + p, p) >>> tf3 = TransferFunction((p + 3)*(p - 1), (p - 1)*(p + 5), p) >>> tf3 TransferFunction((p - 1)*(p + 3), (p - 1)*(p + 5), p)
对传递函数求反
-
运算符可以预先设置:>>> tf4 = TransferFunction(-a + s, p**2 + s, p) >>> -tf4 TransferFunction(a - s, p**2 + s, p) >>> tf5 = TransferFunction(s**4 - 2*s**3 + 5*s + 4, s + 4, s) >>> -tf5 TransferFunction(-s**4 + 2*s**3 - 5*s - 4, s + 4, s)
You can use a float or an integer (or other constants) as numerator and denominator:
>>> tf6 = TransferFunction(1/2, 4, s) >>> tf6.num 0.500000000000000 >>> tf6.den 4 >>> tf6.var s >>> tf6.args (0.5, 4, s)
可以使用
**
操作员:>>> tf7 = TransferFunction(s + a, s - a, s) >>> tf7**3 TransferFunction((a + s)**3, (-a + s)**3, s) >>> tf7**0 TransferFunction(1, 1, s) >>> tf8 = TransferFunction(p + 4, p - 3, p) >>> tf8**-1 TransferFunction(p - 3, p + 4, p)
传递函数的加法、减法和乘法可以形成未赋值
Series
或Parallel
物体。>>> tf9 = TransferFunction(s + 1, s**2 + s + 1, s) >>> tf10 = TransferFunction(s - p, s + 3, s) >>> tf11 = TransferFunction(4*s**2 + 2*s - 4, s - 1, s) >>> tf12 = TransferFunction(1 - s, s**2 + 4, s) >>> tf9 + tf10 Parallel(TransferFunction(s + 1, s**2 + s + 1, s), TransferFunction(-p + s, s + 3, s)) >>> tf10 - tf11 Parallel(TransferFunction(-p + s, s + 3, s), TransferFunction(-4*s**2 - 2*s + 4, s - 1, s)) >>> tf9 * tf10 Series(TransferFunction(s + 1, s**2 + s + 1, s), TransferFunction(-p + s, s + 3, s)) >>> tf10 - (tf9 + tf12) Parallel(TransferFunction(-p + s, s + 3, s), TransferFunction(-s - 1, s**2 + s + 1, s), TransferFunction(s - 1, s**2 + 4, s)) >>> tf10 - (tf9 * tf12) Parallel(TransferFunction(-p + s, s + 3, s), Series(TransferFunction(-1, 1, s), TransferFunction(s + 1, s**2 + s + 1, s), TransferFunction(1 - s, s**2 + 4, s))) >>> tf11 * tf10 * tf9 Series(TransferFunction(4*s**2 + 2*s - 4, s - 1, s), TransferFunction(-p + s, s + 3, s), TransferFunction(s + 1, s**2 + s + 1, s)) >>> tf9 * tf11 + tf10 * tf12 Parallel(Series(TransferFunction(s + 1, s**2 + s + 1, s), TransferFunction(4*s**2 + 2*s - 4, s - 1, s)), Series(TransferFunction(-p + s, s + 3, s), TransferFunction(1 - s, s**2 + 4, s))) >>> (tf9 + tf12) * (tf10 + tf11) Series(Parallel(TransferFunction(s + 1, s**2 + s + 1, s), TransferFunction(1 - s, s**2 + 4, s)), Parallel(TransferFunction(-p + s, s + 3, s), TransferFunction(4*s**2 + 2*s - 4, s - 1, s)))
这些未估价的
Series
或Parallel
对象可以使用.doit()
方法或方式.rewrite(TransferFunction)
.>>> ((tf9 + tf10) * tf12).doit() TransferFunction((1 - s)*((-p + s)*(s**2 + s + 1) + (s + 1)*(s + 3)), (s + 3)*(s**2 + 4)*(s**2 + s + 1), s) >>> (tf9 * tf10 - tf11 * tf12).rewrite(TransferFunction) TransferFunction(-(1 - s)*(s + 3)*(s**2 + s + 1)*(4*s**2 + 2*s - 4) + (-p + s)*(s - 1)*(s + 1)*(s**2 + 4), (s - 1)*(s + 3)*(s**2 + 4)*(s**2 + s + 1), s)
工具书类
- dc_gain()[源代码]#
计算频率接近零时的响应增益。
对于纯积分器系统,直流增益是无穷大的。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction(s + 3, s**2 - 9, s) >>> tf1.dc_gain() -1/3 >>> tf2 = TransferFunction(p**2, p - 3 + p**3, p) >>> tf2.dc_gain() 0 >>> tf3 = TransferFunction(a*p**2 - b, s + b, s) >>> tf3.dc_gain() (a*p**2 - b)/b >>> tf4 = TransferFunction(1, s, s) >>> tf4.dc_gain() oo
- property den#
返回传递函数的分母多项式。
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction >>> G1 = TransferFunction(s + 4, p**3 - 2*p + 4, s) >>> G1.den p**3 - 2*p + 4 >>> G2 = TransferFunction(3, 4, s) >>> G2.den 4
- eval_frequency(other)[源代码]#
Returns the system response at any point in the real or complex plane.
实例
>>> from sympy.abc import s, p, a >>> from sympy.physics.control.lti import TransferFunction >>> from sympy import I >>> tf1 = TransferFunction(1, s**2 + 2*s + 1, s) >>> omega = 0.1 >>> tf1.eval_frequency(I*omega) 1/(0.99 + 0.2*I) >>> tf2 = TransferFunction(s**2, a*s + p, s) >>> tf2.eval_frequency(2) 4/(2*a + p) >>> tf2.eval_frequency(I*2) -4/(2*I*a + p)
- expand()[源代码]#
以展开形式返回分子和分母的传递函数。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction >>> G1 = TransferFunction((a - s)**2, (s**2 + a)**2, s) >>> G1.expand() TransferFunction(a**2 - 2*a*s + s**2, a**2 + 2*a*s**2 + s**4, s) >>> G2 = TransferFunction((p + 3*b)*(p - b), (p - b)*(p + 2*b), p) >>> G2.expand() TransferFunction(-3*b**2 + 2*b*p + p**2, -2*b**2 + b*p + p**2, p)
- classmethod from_coeff_lists(num_list, den_list, var)[源代码]#
Creates a new
TransferFunction
efficiently from a list of coefficients.- 参数:
num_list : Sequence
Sequence comprising of numerator coefficients.
den_list : Sequence
Sequence comprising of denominator coefficients.
var :符号
传递函数多项式使用的拉普拉斯变换的复变量。
- 加薪:
ZeroDivisionError
When the constructed denominator is zero.
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction >>> num = [1, 0, 2] >>> den = [3, 2, 2, 1] >>> tf = TransferFunction.from_coeff_lists(num, den, s) >>> tf TransferFunction(s**2 + 2, 3*s**3 + 2*s**2 + 2*s + 1, s)
# Create a Transfer Function with more than one variable >>> tf1 = TransferFunction.from_coeff_lists([p, 1], [2*p, 0, 4], s) >>> tf1 TransferFunction(p*s + 1, 2*p*s**2 + 4, s)
- classmethod from_rational_expression(expr, var=None)[源代码]#
Creates a new
TransferFunction
efficiently from a rational expression.- 参数:
expr : Expr, Number
The rational expression representing the
TransferFunction
.var : Symbol, optional
传递函数多项式使用的拉普拉斯变换的复变量。
- 加薪:
ValueError
When
expr
is of typeNumber
and optional parametervar
is not passed.When
expr
has more than one variables and an optional parametervar
is not passed.ZeroDivisionError
When denominator of
expr
is zero or it hasComplexInfinity
in its numerator.
实例
>>> from sympy.abc import s, p, a >>> from sympy.physics.control.lti import TransferFunction >>> expr1 = (s + 5)/(3*s**2 + 2*s + 1) >>> tf1 = TransferFunction.from_rational_expression(expr1) >>> tf1 TransferFunction(s + 5, 3*s**2 + 2*s + 1, s) >>> expr2 = (a*p**3 - a*p**2 + s*p)/(p + a**2) # Expr with more than one variables >>> tf2 = TransferFunction.from_rational_expression(expr2, p) >>> tf2 TransferFunction(a*p**3 - a*p**2 + p*s, a**2 + p, p)
In case of conflict between two or more variables in a expression, SymPy will raise a
ValueError
, ifvar
is not passed by the user.>>> tf = TransferFunction.from_rational_expression((a + a*s)/(s**2 + s + 1)) Traceback (most recent call last): ... ValueError: Conflicting values found for positional argument `var` ({a, s}). Specify it manually.
This can be corrected by specifying the
var
parameter manually.>>> tf = TransferFunction.from_rational_expression((a + a*s)/(s**2 + s + 1), s) >>> tf TransferFunction(a*s + a, s**2 + s + 1, s)
var
also need to be specified whenexpr
is aNumber
>>> tf3 = TransferFunction.from_rational_expression(10, s) >>> tf3 TransferFunction(10, 1, s)
- classmethod from_zpk(zeros, poles, gain, var)[源代码]#
Creates a new
TransferFunction
from given zeros, poles and gain.- 参数:
zeros : Sequence
Sequence comprising of zeros of transfer function.
poles : Sequence
Sequence comprising of poles of transfer function.
gain : Number, Symbol, Expression
A scalar value specifying gain of the model.
var :符号
传递函数多项式使用的拉普拉斯变换的复变量。
实例
>>> from sympy.abc import s, p, k >>> from sympy.physics.control.lti import TransferFunction >>> zeros = [1, 2, 3] >>> poles = [6, 5, 4] >>> gain = 7 >>> tf = TransferFunction.from_zpk(zeros, poles, gain, s) >>> tf TransferFunction(7*(s - 3)*(s - 2)*(s - 1), (s - 6)*(s - 5)*(s - 4), s)
# Create a Transfer Function with variable poles and zeros >>> tf1 = TransferFunction.from_zpk([p, k], [p + k, p - k], 2, s) >>> tf1 TransferFunction(2*(-k + s)*(-p + s), (-k - p + s)*(k - p + s), s)
# Complex poles or zeros are acceptable >>> tf2 = TransferFunction.from_zpk([0], [1-1j, 1+1j, 2], -2, s) >>> tf2 TransferFunction(-2*s, (s - 2)*(s - 1.0 - 1.0*I)*(s - 1.0 + 1.0*I), s)
- property is_biproper#
若分子多项式的次数等于分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf1.is_biproper True >>> tf2 = TransferFunction(p**2, p + a, p) >>> tf2.is_biproper False
- property is_proper#
若分子多项式的次数小于或等于分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction(b*s**2 + p**2 - a*p + s, b - p**2, s) >>> tf1.is_proper False >>> tf2 = TransferFunction(p**2 - 4*p, p**3 + 3*p + 2, p) >>> tf2.is_proper True
- is_stable()[源代码]#
如果传递函数渐近稳定,则返回True;否则返回False。
这不会检查系统的边际稳定性或条件稳定性。
实例
>>> from sympy.abc import s, p, a >>> from sympy import symbols >>> from sympy.physics.control.lti import TransferFunction >>> q, r = symbols('q, r', negative=True) >>> tf1 = TransferFunction((1 - s)**2, (s + 1)**2, s) >>> tf1.is_stable() True >>> tf2 = TransferFunction((1 - p)**2, (s**2 + 1)**2, s) >>> tf2.is_stable() False >>> tf3 = TransferFunction(4, q*s - r, s) >>> tf3.is_stable() False >>> tf4 = TransferFunction(p + 1, a*p - s**2, p) >>> tf4.is_stable() is None # Not enough info about the symbols to determine stability True
- property is_strictly_proper#
若分子多项式的次数严格小于分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf1.is_strictly_proper False >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> tf2.is_strictly_proper True
- property num#
返回传递函数的分子多项式。
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction >>> G1 = TransferFunction(s**2 + p*s + 3, s - 4, s) >>> G1.num p*s + s**2 + 3 >>> G2 = TransferFunction((p + 5)*(p - 3), (p - 3)*(p + 1), p) >>> G2.num (p - 3)*(p + 5)
- poles()[源代码]#
返回传递函数的极点。
实例
>>> from sympy.abc import s, p, a >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction((p + 3)*(p - 1), (p - 1)*(p + 5), p) >>> tf1.poles() [-5, 1] >>> tf2 = TransferFunction((1 - s)**2, (s**2 + 1)**2, s) >>> tf2.poles() [I, I, -I, -I] >>> tf3 = TransferFunction(s**2, a*s + p, s) >>> tf3.poles() [-p/a]
- to_expr()[源代码]#
Converts a
TransferFunction
object to SymPy Expr.实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction >>> from sympy import Expr >>> tf1 = TransferFunction(s, a*s**2 + 1, s) >>> tf1.to_expr() s/(a*s**2 + 1) >>> isinstance(_, Expr) True >>> tf2 = TransferFunction(1, (p + 3*b)*(b - p), p) >>> tf2.to_expr() 1/((b - p)*(3*b + p)) >>> tf3 = TransferFunction((s - 2)*(s - 3), (s - 1)*(s - 2)*(s - 3), s) >>> tf3.to_expr() ((s - 3)*(s - 2))/(((s - 3)*(s - 2)*(s - 1)))
- property var#
返回传递函数多项式使用的拉普拉斯变换的复变量。
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction >>> G1 = TransferFunction(p**2 + 2*p + 4, p - 6, p) >>> G1.var p >>> G2 = TransferFunction(0, s - 5, s) >>> G2.var s
- zeros()[源代码]#
返回传递函数的零。
实例
>>> from sympy.abc import s, p, a >>> from sympy.physics.control.lti import TransferFunction >>> tf1 = TransferFunction((p + 3)*(p - 1), (p - 1)*(p + 5), p) >>> tf1.zeros() [-3, 1] >>> tf2 = TransferFunction((1 - s)**2, (s**2 + 1)**2, s) >>> tf2.zeros() [1, 1] >>> tf3 = TransferFunction(s**2, a*s + p, s) >>> tf3.zeros() [0, 0]
- class sympy.physics.control.lti.Series(*args, evaluate=False)[源代码]#
A class for representing a series configuration of SISO systems.
- 参数:
args : SISOLinearTimeInvariant
SISO systems in a series configuration.
evaluate : Boolean, Keyword
When passed
True
, returns the equivalentSeries(*args).doit()
. Set toFalse
by default.- 加薪:
ValueError
When no argument is passed.
var
attribute is not same for every system.TypeError
Any of the passed
*args
has unsupported typeA combination of SISO and MIMO systems is passed. There should be homogeneity in the type of systems passed, SISO in this case.
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Series, Parallel >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> tf3 = TransferFunction(p**2, p + s, s) >>> S1 = Series(tf1, tf2) >>> S1 Series(TransferFunction(a*p**2 + b*s, -p + s, s), TransferFunction(s**3 - 2, s**4 + 5*s + 6, s)) >>> S1.var s >>> S2 = Series(tf2, Parallel(tf3, -tf1)) >>> S2 Series(TransferFunction(s**3 - 2, s**4 + 5*s + 6, s), Parallel(TransferFunction(p**2, p + s, s), TransferFunction(-a*p**2 - b*s, -p + s, s))) >>> S2.var s >>> S3 = Series(Parallel(tf1, tf2), Parallel(tf2, tf3)) >>> S3 Series(Parallel(TransferFunction(a*p**2 + b*s, -p + s, s), TransferFunction(s**3 - 2, s**4 + 5*s + 6, s)), Parallel(TransferFunction(s**3 - 2, s**4 + 5*s + 6, s), TransferFunction(p**2, p + s, s))) >>> S3.var s
可以使用
.doit()
方法:>>> S3 = Series(tf1, tf2, -tf3) >>> S3.doit() TransferFunction(-p**2*(s**3 - 2)*(a*p**2 + b*s), (-p + s)*(p + s)*(s**4 + 5*s + 6), s) >>> S4 = Series(tf2, Parallel(tf1, -tf3)) >>> S4.doit() TransferFunction((s**3 - 2)*(-p**2*(-p + s) + (p + s)*(a*p**2 + b*s)), (-p + s)*(p + s)*(s**4 + 5*s + 6), s)
笔记
所有的传递函数都应该使用相同的复变量
var
拉普拉斯变换。- doit(**hints)[源代码]#
返回对串联配置中的传递函数求值后得到的结果传递函数。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Series >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> Series(tf2, tf1).doit() TransferFunction((s**3 - 2)*(a*p**2 + b*s), (-p + s)*(s**4 + 5*s + 6), s) >>> Series(-tf1, -tf2).doit() TransferFunction((2 - s**3)*(-a*p**2 - b*s), (-p + s)*(s**4 + 5*s + 6), s)
- property is_biproper#
若结果传递函数的分子多项式的次数等于分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Series >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(p, s**2, s) >>> tf3 = TransferFunction(s**2, 1, s) >>> S1 = Series(tf1, -tf2) >>> S1.is_biproper False >>> S2 = Series(tf2, tf3) >>> S2.is_biproper True
- property is_proper#
如果结果传递函数的分子多项式的次数小于或等于相同的分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Series >>> tf1 = TransferFunction(b*s**2 + p**2 - a*p + s, b - p**2, s) >>> tf2 = TransferFunction(p**2 - 4*p, p**3 + 3*s + 2, s) >>> tf3 = TransferFunction(s, s**2 + s + 1, s) >>> S1 = Series(-tf2, tf1) >>> S1.is_proper False >>> S2 = Series(tf1, tf2, tf3) >>> S2.is_proper True
- property is_strictly_proper#
如果结果传递函数的分子多项式的次数严格小于相同的分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Series >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**2 + 5*s + 6, s) >>> tf3 = TransferFunction(1, s**2 + s + 1, s) >>> S1 = Series(tf1, tf2) >>> S1.is_strictly_proper False >>> S2 = Series(tf1, tf2, tf3) >>> S2.is_strictly_proper True
- property var#
返回所有传递函数使用的复变量。
实例
>>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, Series, Parallel >>> G1 = TransferFunction(p**2 + 2*p + 4, p - 6, p) >>> G2 = TransferFunction(p, 4 - p, p) >>> G3 = TransferFunction(0, p**4 - 1, p) >>> Series(G1, G2).var p >>> Series(-G3, Parallel(G1, G2)).var p
- class sympy.physics.control.lti.Parallel(*args, evaluate=False)[源代码]#
A class for representing a parallel configuration of SISO systems.
- 参数:
args : SISOLinearTimeInvariant
SISO systems in a parallel arrangement.
evaluate : Boolean, Keyword
When passed
True
, returns the equivalentParallel(*args).doit()
. Set toFalse
by default.- 加薪:
ValueError
When no argument is passed.
var
attribute is not same for every system.TypeError
Any of the passed
*args
has unsupported typeA combination of SISO and MIMO systems is passed. There should be homogeneity in the type of systems passed.
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Parallel, Series >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> tf3 = TransferFunction(p**2, p + s, s) >>> P1 = Parallel(tf1, tf2) >>> P1 Parallel(TransferFunction(a*p**2 + b*s, -p + s, s), TransferFunction(s**3 - 2, s**4 + 5*s + 6, s)) >>> P1.var s >>> P2 = Parallel(tf2, Series(tf3, -tf1)) >>> P2 Parallel(TransferFunction(s**3 - 2, s**4 + 5*s + 6, s), Series(TransferFunction(p**2, p + s, s), TransferFunction(-a*p**2 - b*s, -p + s, s))) >>> P2.var s >>> P3 = Parallel(Series(tf1, tf2), Series(tf2, tf3)) >>> P3 Parallel(Series(TransferFunction(a*p**2 + b*s, -p + s, s), TransferFunction(s**3 - 2, s**4 + 5*s + 6, s)), Series(TransferFunction(s**3 - 2, s**4 + 5*s + 6, s), TransferFunction(p**2, p + s, s))) >>> P3.var s
可以使用
.doit()
方法:>>> Parallel(tf1, tf2, -tf3).doit() TransferFunction(-p**2*(-p + s)*(s**4 + 5*s + 6) + (-p + s)*(p + s)*(s**3 - 2) + (p + s)*(a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)*(p + s)*(s**4 + 5*s + 6), s) >>> Parallel(tf2, Series(tf1, -tf3)).doit() TransferFunction(-p**2*(a*p**2 + b*s)*(s**4 + 5*s + 6) + (-p + s)*(p + s)*(s**3 - 2), (-p + s)*(p + s)*(s**4 + 5*s + 6), s)
笔记
所有的传递函数都应该使用相同的复变量
var
拉普拉斯变换。- doit(**hints)[源代码]#
返回在并行配置中计算传递函数后获得的结果传递函数。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Parallel >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> Parallel(tf2, tf1).doit() TransferFunction((-p + s)*(s**3 - 2) + (a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)*(s**4 + 5*s + 6), s) >>> Parallel(-tf1, -tf2).doit() TransferFunction((2 - s**3)*(-p + s) + (-a*p**2 - b*s)*(s**4 + 5*s + 6), (-p + s)*(s**4 + 5*s + 6), s)
- property is_biproper#
若结果传递函数的分子多项式的次数等于分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Parallel >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(p**2, p + s, s) >>> tf3 = TransferFunction(s, s**2 + s + 1, s) >>> P1 = Parallel(tf1, -tf2) >>> P1.is_biproper True >>> P2 = Parallel(tf2, tf3) >>> P2.is_biproper False
- property is_proper#
如果结果传递函数的分子多项式的次数小于或等于相同的分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Parallel >>> tf1 = TransferFunction(b*s**2 + p**2 - a*p + s, b - p**2, s) >>> tf2 = TransferFunction(p**2 - 4*p, p**3 + 3*s + 2, s) >>> tf3 = TransferFunction(s, s**2 + s + 1, s) >>> P1 = Parallel(-tf2, tf1) >>> P1.is_proper False >>> P2 = Parallel(tf2, tf3) >>> P2.is_proper True
- property is_strictly_proper#
如果结果传递函数的分子多项式的次数严格小于相同的分母多项式的次数,则返回True,否则返回False。
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, Parallel >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> tf3 = TransferFunction(s, s**2 + s + 1, s) >>> P1 = Parallel(tf1, tf2) >>> P1.is_strictly_proper False >>> P2 = Parallel(tf2, tf3) >>> P2.is_strictly_proper True
- property var#
返回所有传递函数使用的复变量。
实例
>>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, Parallel, Series >>> G1 = TransferFunction(p**2 + 2*p + 4, p - 6, p) >>> G2 = TransferFunction(p, 4 - p, p) >>> G3 = TransferFunction(0, p**4 - 1, p) >>> Parallel(G1, G2).var p >>> Parallel(-G3, Series(G1, G2)).var p
- class sympy.physics.control.lti.Feedback(sys1, sys2=None, sign=-1)[源代码]#
A class for representing closed-loop feedback interconnection between two SISO input/output systems.
The first argument,
sys1
, is the feedforward part of the closed-loop system or in simple words, the dynamical model representing the process to be controlled. The second argument,sys2
, is the feedback system and controls the fed back signal tosys1
. Bothsys1
andsys2
can either beSeries
orTransferFunction
objects.- 参数:
sys1 : Series, TransferFunction
The feedforward path system.
sys2 : Series, TransferFunction, optional
The feedback path system (often a feedback controller). It is the model sitting on the feedback path.
If not specified explicitly, the sys2 is assumed to be unit (1.0) transfer function.
sign : int, optional
The sign of feedback. Can either be
1
(for positive feedback) or-1
(for negative feedback). Default value is \(-1\).- 加薪:
ValueError
When
sys1
andsys2
are not using the same complex variable of the Laplace transform.When a combination of
sys1
andsys2
yields zero denominator.TypeError
When either
sys1
orsys2
is not aSeries
or aTransferFunction
object.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> plant = TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> controller = TransferFunction(5*s - 10, s + 7, s) >>> F1 = Feedback(plant, controller) >>> F1 Feedback(TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s), TransferFunction(5*s - 10, s + 7, s), -1) >>> F1.var s >>> F1.args (TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s), TransferFunction(5*s - 10, s + 7, s), -1)
You can get the feedforward and feedback path systems by using
.sys1
and.sys2
respectively.>>> F1.sys1 TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> F1.sys2 TransferFunction(5*s - 10, s + 7, s)
你可以得到由负反馈互连得到的闭环传递函数
.doit()
方法。>>> F1.doit() TransferFunction((s + 7)*(s**2 - 4*s + 2)*(3*s**2 + 7*s - 3), ((s + 7)*(s**2 - 4*s + 2) + (5*s - 10)*(3*s**2 + 7*s - 3))*(s**2 - 4*s + 2), s) >>> G = TransferFunction(2*s**2 + 5*s + 1, s**2 + 2*s + 3, s) >>> C = TransferFunction(5*s + 10, s + 10, s) >>> F2 = Feedback(G*C, TransferFunction(1, 1, s)) >>> F2.doit() TransferFunction((s + 10)*(5*s + 10)*(s**2 + 2*s + 3)*(2*s**2 + 5*s + 1), (s + 10)*((s + 10)*(s**2 + 2*s + 3) + (5*s + 10)*(2*s**2 + 5*s + 1))*(s**2 + 2*s + 3), s)
否定
Feedback
对象-
运算符可以预先设置:>>> -F1 Feedback(TransferFunction(-3*s**2 - 7*s + 3, s**2 - 4*s + 2, s), TransferFunction(10 - 5*s, s + 7, s), -1) >>> -F2 Feedback(Series(TransferFunction(-1, 1, s), TransferFunction(2*s**2 + 5*s + 1, s**2 + 2*s + 3, s), TransferFunction(5*s + 10, s + 10, s)), TransferFunction(-1, 1, s), -1)
参见
- property den#
Returns the denominator of the closed loop feedback model.
- doit(cancel=False, expand=False, **hints)[源代码]#
Returns the resultant transfer function obtained by the feedback interconnection.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> plant = TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> controller = TransferFunction(5*s - 10, s + 7, s) >>> F1 = Feedback(plant, controller) >>> F1.doit() TransferFunction((s + 7)*(s**2 - 4*s + 2)*(3*s**2 + 7*s - 3), ((s + 7)*(s**2 - 4*s + 2) + (5*s - 10)*(3*s**2 + 7*s - 3))*(s**2 - 4*s + 2), s) >>> G = TransferFunction(2*s**2 + 5*s + 1, s**2 + 2*s + 3, s) >>> F2 = Feedback(G, TransferFunction(1, 1, s)) >>> F2.doit() TransferFunction((s**2 + 2*s + 3)*(2*s**2 + 5*s + 1), (s**2 + 2*s + 3)*(3*s**2 + 7*s + 4), s)
Use kwarg
expand=True
to expand the resultant transfer function. Usecancel=True
to cancel out the common terms in numerator and denominator.>>> F2.doit(cancel=True, expand=True) TransferFunction(2*s**2 + 5*s + 1, 3*s**2 + 7*s + 4, s) >>> F2.doit(expand=True) TransferFunction(2*s**4 + 9*s**3 + 17*s**2 + 17*s + 3, 3*s**4 + 13*s**3 + 27*s**2 + 29*s + 12, s)
- property num#
Returns the numerator of the closed loop feedback system.
- property sensitivity#
Returns the sensitivity function of the feedback loop.
Sensitivity of a Feedback system is the ratio of change in the open loop gain to the change in the closed loop gain.
备注
This method would not return the complementary sensitivity function.
实例
>>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> C = TransferFunction(5*p + 10, p + 10, p) >>> P = TransferFunction(1 - p, p + 2, p) >>> F_1 = Feedback(P, C) >>> F_1.sensitivity 1/((1 - p)*(5*p + 10)/((p + 2)*(p + 10)) + 1)
- property sign#
Returns the type of MIMO Feedback model.
1
for Positive and-1
for Negative.
- property sys1#
Returns the feedforward system of the feedback interconnection.
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> plant = TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> controller = TransferFunction(5*s - 10, s + 7, s) >>> F1 = Feedback(plant, controller) >>> F1.sys1 TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> G = TransferFunction(2*s**2 + 5*s + 1, p**2 + 2*p + 3, p) >>> C = TransferFunction(5*p + 10, p + 10, p) >>> P = TransferFunction(1 - s, p + 2, p) >>> F2 = Feedback(TransferFunction(1, 1, p), G*C*P) >>> F2.sys1 TransferFunction(1, 1, p)
- property sys2#
Returns the feedback controller of the feedback interconnection.
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> plant = TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> controller = TransferFunction(5*s - 10, s + 7, s) >>> F1 = Feedback(plant, controller) >>> F1.sys2 TransferFunction(5*s - 10, s + 7, s) >>> G = TransferFunction(2*s**2 + 5*s + 1, p**2 + 2*p + 3, p) >>> C = TransferFunction(5*p + 10, p + 10, p) >>> P = TransferFunction(1 - s, p + 2, p) >>> F2 = Feedback(TransferFunction(1, 1, p), G*C*P) >>> F2.sys2 Series(TransferFunction(2*s**2 + 5*s + 1, p**2 + 2*p + 3, p), TransferFunction(5*p + 10, p + 10, p), TransferFunction(1 - s, p + 2, p))
- to_expr()[源代码]#
Converts a
Feedback
object to SymPy Expr.实例
>>> from sympy.abc import s, a, b >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> from sympy import Expr >>> tf1 = TransferFunction(a+s, 1, s) >>> tf2 = TransferFunction(b+s, 1, s) >>> fd1 = Feedback(tf1, tf2) >>> fd1.to_expr() (a + s)/((a + s)*(b + s) + 1) >>> isinstance(_, Expr) True
- property var#
Returns the complex variable of the Laplace transform used by all the transfer functions involved in the feedback interconnection.
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction, Feedback >>> plant = TransferFunction(3*s**2 + 7*s - 3, s**2 - 4*s + 2, s) >>> controller = TransferFunction(5*s - 10, s + 7, s) >>> F1 = Feedback(plant, controller) >>> F1.var s >>> G = TransferFunction(2*s**2 + 5*s + 1, p**2 + 2*p + 3, p) >>> C = TransferFunction(5*p + 10, p + 10, p) >>> P = TransferFunction(1 - s, p + 2, p) >>> F2 = Feedback(TransferFunction(1, 1, p), G*C*P) >>> F2.var p
- class sympy.physics.control.lti.TransferFunctionMatrix(arg)[源代码]#
A class for representing the MIMO (multiple-input and multiple-output) generalization of the SISO (single-input and single-output) transfer function.
It is a matrix of transfer functions (
TransferFunction
, SISO-Series
or SISO-Parallel
). There is only one argument,arg
which is also the compulsory argument.arg
is expected to be strictly of the type list of lists which holds the transfer functions or reducible to transfer functions.- 参数:
arg : Nested
List
(strictly).Users are expected to input a nested list of
TransferFunction
,Series
and/orParallel
objects.
实例
备注
pprint()
can be used for better visualization ofTransferFunctionMatrix
objects.>>> from sympy.abc import s, p, a >>> from sympy import pprint >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, Series, Parallel >>> tf_1 = TransferFunction(s + a, s**2 + s + 1, s) >>> tf_2 = TransferFunction(p**4 - 3*p + 2, s + p, s) >>> tf_3 = TransferFunction(3, s + 2, s) >>> tf_4 = TransferFunction(-a + p, 9*s - 9, s) >>> tfm_1 = TransferFunctionMatrix([[tf_1], [tf_2], [tf_3]]) >>> tfm_1 TransferFunctionMatrix(((TransferFunction(a + s, s**2 + s + 1, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(3, s + 2, s),))) >>> tfm_1.var s >>> tfm_1.num_inputs 1 >>> tfm_1.num_outputs 3 >>> tfm_1.shape (3, 1) >>> tfm_1.args (((TransferFunction(a + s, s**2 + s + 1, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(3, s + 2, s),)),) >>> tfm_2 = TransferFunctionMatrix([[tf_1, -tf_3], [tf_2, -tf_1], [tf_3, -tf_2]]) >>> tfm_2 TransferFunctionMatrix(((TransferFunction(a + s, s**2 + s + 1, s), TransferFunction(-3, s + 2, s)), (TransferFunction(p**4 - 3*p + 2, p + s, s), TransferFunction(-a - s, s**2 + s + 1, s)), (TransferFunction(3, s + 2, s), TransferFunction(-p**4 + 3*p - 2, p + s, s)))) >>> pprint(tfm_2, use_unicode=False) # pretty-printing for better visualization [ a + s -3 ] [ ---------- ----- ] [ 2 s + 2 ] [ s + s + 1 ] [ ] [ 4 ] [p - 3*p + 2 -a - s ] [------------ ---------- ] [ p + s 2 ] [ s + s + 1 ] [ ] [ 4 ] [ 3 - p + 3*p - 2] [ ----- --------------] [ s + 2 p + s ]{t}
TransferFunctionMatrix can be transposed, if user wants to switch the input and output transfer functions
>>> tfm_2.transpose() TransferFunctionMatrix(((TransferFunction(a + s, s**2 + s + 1, s), TransferFunction(p**4 - 3*p + 2, p + s, s), TransferFunction(3, s + 2, s)), (TransferFunction(-3, s + 2, s), TransferFunction(-a - s, s**2 + s + 1, s), TransferFunction(-p**4 + 3*p - 2, p + s, s)))) >>> pprint(_, use_unicode=False) [ 4 ] [ a + s p - 3*p + 2 3 ] [---------- ------------ ----- ] [ 2 p + s s + 2 ] [s + s + 1 ] [ ] [ 4 ] [ -3 -a - s - p + 3*p - 2] [ ----- ---------- --------------] [ s + 2 2 p + s ] [ s + s + 1 ]{t}
>>> tf_5 = TransferFunction(5, s, s) >>> tf_6 = TransferFunction(5*s, (2 + s**2), s) >>> tf_7 = TransferFunction(5, (s*(2 + s**2)), s) >>> tf_8 = TransferFunction(5, 1, s) >>> tfm_3 = TransferFunctionMatrix([[tf_5, tf_6], [tf_7, tf_8]]) >>> tfm_3 TransferFunctionMatrix(((TransferFunction(5, s, s), TransferFunction(5*s, s**2 + 2, s)), (TransferFunction(5, s*(s**2 + 2), s), TransferFunction(5, 1, s)))) >>> pprint(tfm_3, use_unicode=False) [ 5 5*s ] [ - ------] [ s 2 ] [ s + 2] [ ] [ 5 5 ] [---------- - ] [ / 2 \ 1 ] [s*\s + 2/ ]{t} >>> tfm_3.var s >>> tfm_3.shape (2, 2) >>> tfm_3.num_outputs 2 >>> tfm_3.num_inputs 2 >>> tfm_3.args (((TransferFunction(5, s, s), TransferFunction(5*s, s**2 + 2, s)), (TransferFunction(5, s*(s**2 + 2), s), TransferFunction(5, 1, s))),)
To access the
TransferFunction
at any index in theTransferFunctionMatrix
, use the index notation.>>> tfm_3[1, 0] # gives the TransferFunction present at 2nd Row and 1st Col. Similar to that in Matrix classes TransferFunction(5, s*(s**2 + 2), s) >>> tfm_3[0, 0] # gives the TransferFunction present at 1st Row and 1st Col. TransferFunction(5, s, s) >>> tfm_3[:, 0] # gives the first column TransferFunctionMatrix(((TransferFunction(5, s, s),), (TransferFunction(5, s*(s**2 + 2), s),))) >>> pprint(_, use_unicode=False) [ 5 ] [ - ] [ s ] [ ] [ 5 ] [----------] [ / 2 \] [s*\s + 2/]{t} >>> tfm_3[0, :] # gives the first row TransferFunctionMatrix(((TransferFunction(5, s, s), TransferFunction(5*s, s**2 + 2, s)),)) >>> pprint(_, use_unicode=False) [5 5*s ] [- ------] [s 2 ] [ s + 2]{t}
To negate a transfer function matrix,
-
operator can be prepended:>>> tfm_4 = TransferFunctionMatrix([[tf_2], [-tf_1], [tf_3]]) >>> -tfm_4 TransferFunctionMatrix(((TransferFunction(-p**4 + 3*p - 2, p + s, s),), (TransferFunction(a + s, s**2 + s + 1, s),), (TransferFunction(-3, s + 2, s),))) >>> tfm_5 = TransferFunctionMatrix([[tf_1, tf_2], [tf_3, -tf_1]]) >>> -tfm_5 TransferFunctionMatrix(((TransferFunction(-a - s, s**2 + s + 1, s), TransferFunction(-p**4 + 3*p - 2, p + s, s)), (TransferFunction(-3, s + 2, s), TransferFunction(a + s, s**2 + s + 1, s))))
subs()
returns theTransferFunctionMatrix
object with the value substituted in the expression. This will not mutate your originalTransferFunctionMatrix
.>>> tfm_2.subs(p, 2) # substituting p everywhere in tfm_2 with 2. TransferFunctionMatrix(((TransferFunction(a + s, s**2 + s + 1, s), TransferFunction(-3, s + 2, s)), (TransferFunction(12, s + 2, s), TransferFunction(-a - s, s**2 + s + 1, s)), (TransferFunction(3, s + 2, s), TransferFunction(-12, s + 2, s)))) >>> pprint(_, use_unicode=False) [ a + s -3 ] [---------- ----- ] [ 2 s + 2 ] [s + s + 1 ] [ ] [ 12 -a - s ] [ ----- ----------] [ s + 2 2 ] [ s + s + 1] [ ] [ 3 -12 ] [ ----- ----- ] [ s + 2 s + 2 ]{t} >>> pprint(tfm_2, use_unicode=False) # State of tfm_2 is unchanged after substitution [ a + s -3 ] [ ---------- ----- ] [ 2 s + 2 ] [ s + s + 1 ] [ ] [ 4 ] [p - 3*p + 2 -a - s ] [------------ ---------- ] [ p + s 2 ] [ s + s + 1 ] [ ] [ 4 ] [ 3 - p + 3*p - 2] [ ----- --------------] [ s + 2 p + s ]{t}
subs()
also supports multiple substitutions.>>> tfm_2.subs({p: 2, a: 1}) # substituting p with 2 and a with 1 TransferFunctionMatrix(((TransferFunction(s + 1, s**2 + s + 1, s), TransferFunction(-3, s + 2, s)), (TransferFunction(12, s + 2, s), TransferFunction(-s - 1, s**2 + s + 1, s)), (TransferFunction(3, s + 2, s), TransferFunction(-12, s + 2, s)))) >>> pprint(_, use_unicode=False) [ s + 1 -3 ] [---------- ----- ] [ 2 s + 2 ] [s + s + 1 ] [ ] [ 12 -s - 1 ] [ ----- ----------] [ s + 2 2 ] [ s + s + 1] [ ] [ 3 -12 ] [ ----- ----- ] [ s + 2 s + 2 ]{t}
Users can reduce the
Series
andParallel
elements of the matrix toTransferFunction
by usingdoit()
.>>> tfm_6 = TransferFunctionMatrix([[Series(tf_3, tf_4), Parallel(tf_3, tf_4)]]) >>> tfm_6 TransferFunctionMatrix(((Series(TransferFunction(3, s + 2, s), TransferFunction(-a + p, 9*s - 9, s)), Parallel(TransferFunction(3, s + 2, s), TransferFunction(-a + p, 9*s - 9, s))),)) >>> pprint(tfm_6, use_unicode=False) [-a + p 3 -a + p 3 ] [-------*----- ------- + -----] [9*s - 9 s + 2 9*s - 9 s + 2]{t} >>> tfm_6.doit() TransferFunctionMatrix(((TransferFunction(-3*a + 3*p, (s + 2)*(9*s - 9), s), TransferFunction(27*s + (-a + p)*(s + 2) - 27, (s + 2)*(9*s - 9), s)),)) >>> pprint(_, use_unicode=False) [ -3*a + 3*p 27*s + (-a + p)*(s + 2) - 27] [----------------- ----------------------------] [(s + 2)*(9*s - 9) (s + 2)*(9*s - 9) ]{t} >>> tf_9 = TransferFunction(1, s, s) >>> tf_10 = TransferFunction(1, s**2, s) >>> tfm_7 = TransferFunctionMatrix([[Series(tf_9, tf_10), tf_9], [tf_10, Parallel(tf_9, tf_10)]]) >>> tfm_7 TransferFunctionMatrix(((Series(TransferFunction(1, s, s), TransferFunction(1, s**2, s)), TransferFunction(1, s, s)), (TransferFunction(1, s**2, s), Parallel(TransferFunction(1, s, s), TransferFunction(1, s**2, s))))) >>> pprint(tfm_7, use_unicode=False) [ 1 1 ] [---- - ] [ 2 s ] [s*s ] [ ] [ 1 1 1] [ -- -- + -] [ 2 2 s] [ s s ]{t} >>> tfm_7.doit() TransferFunctionMatrix(((TransferFunction(1, s**3, s), TransferFunction(1, s, s)), (TransferFunction(1, s**2, s), TransferFunction(s**2 + s, s**3, s)))) >>> pprint(_, use_unicode=False) [1 1 ] [-- - ] [ 3 s ] [s ] [ ] [ 2 ] [1 s + s] [-- ------] [ 2 3 ] [s s ]{t}
Addition, subtraction, and multiplication of transfer function matrices can form unevaluated
Series
orParallel
objects.For addition and subtraction: All the transfer function matrices must have the same shape.
For multiplication (C = A * B): The number of inputs of the first transfer function matrix (A) must be equal to the number of outputs of the second transfer function matrix (B).
Also, use pretty-printing (
pprint
) to analyse better.>>> tfm_8 = TransferFunctionMatrix([[tf_3], [tf_2], [-tf_1]]) >>> tfm_9 = TransferFunctionMatrix([[-tf_3]]) >>> tfm_10 = TransferFunctionMatrix([[tf_1], [tf_2], [tf_4]]) >>> tfm_11 = TransferFunctionMatrix([[tf_4], [-tf_1]]) >>> tfm_12 = TransferFunctionMatrix([[tf_4, -tf_1, tf_3], [-tf_2, -tf_4, -tf_3]]) >>> tfm_8 + tfm_10 MIMOParallel(TransferFunctionMatrix(((TransferFunction(3, s + 2, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(-a - s, s**2 + s + 1, s),))), TransferFunctionMatrix(((TransferFunction(a + s, s**2 + s + 1, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(-a + p, 9*s - 9, s),)))) >>> pprint(_, use_unicode=False) [ 3 ] [ a + s ] [ ----- ] [ ---------- ] [ s + 2 ] [ 2 ] [ ] [ s + s + 1 ] [ 4 ] [ ] [p - 3*p + 2] [ 4 ] [------------] + [p - 3*p + 2] [ p + s ] [------------] [ ] [ p + s ] [ -a - s ] [ ] [ ---------- ] [ -a + p ] [ 2 ] [ ------- ] [ s + s + 1 ]{t} [ 9*s - 9 ]{t} >>> -tfm_10 - tfm_8 MIMOParallel(TransferFunctionMatrix(((TransferFunction(-a - s, s**2 + s + 1, s),), (TransferFunction(-p**4 + 3*p - 2, p + s, s),), (TransferFunction(a - p, 9*s - 9, s),))), TransferFunctionMatrix(((TransferFunction(-3, s + 2, s),), (TransferFunction(-p**4 + 3*p - 2, p + s, s),), (TransferFunction(a + s, s**2 + s + 1, s),)))) >>> pprint(_, use_unicode=False) [ -a - s ] [ -3 ] [ ---------- ] [ ----- ] [ 2 ] [ s + 2 ] [ s + s + 1 ] [ ] [ ] [ 4 ] [ 4 ] [- p + 3*p - 2] [- p + 3*p - 2] + [--------------] [--------------] [ p + s ] [ p + s ] [ ] [ ] [ a + s ] [ a - p ] [ ---------- ] [ ------- ] [ 2 ] [ 9*s - 9 ]{t} [ s + s + 1 ]{t} >>> tfm_12 * tfm_8 MIMOSeries(TransferFunctionMatrix(((TransferFunction(3, s + 2, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(-a - s, s**2 + s + 1, s),))), TransferFunctionMatrix(((TransferFunction(-a + p, 9*s - 9, s), TransferFunction(-a - s, s**2 + s + 1, s), TransferFunction(3, s + 2, s)), (TransferFunction(-p**4 + 3*p - 2, p + s, s), TransferFunction(a - p, 9*s - 9, s), TransferFunction(-3, s + 2, s))))) >>> pprint(_, use_unicode=False) [ 3 ] [ ----- ] [ -a + p -a - s 3 ] [ s + 2 ] [ ------- ---------- -----] [ ] [ 9*s - 9 2 s + 2] [ 4 ] [ s + s + 1 ] [p - 3*p + 2] [ ] *[------------] [ 4 ] [ p + s ] [- p + 3*p - 2 a - p -3 ] [ ] [-------------- ------- -----] [ -a - s ] [ p + s 9*s - 9 s + 2]{t} [ ---------- ] [ 2 ] [ s + s + 1 ]{t} >>> tfm_12 * tfm_8 * tfm_9 MIMOSeries(TransferFunctionMatrix(((TransferFunction(-3, s + 2, s),),)), TransferFunctionMatrix(((TransferFunction(3, s + 2, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(-a - s, s**2 + s + 1, s),))), TransferFunctionMatrix(((TransferFunction(-a + p, 9*s - 9, s), TransferFunction(-a - s, s**2 + s + 1, s), TransferFunction(3, s + 2, s)), (TransferFunction(-p**4 + 3*p - 2, p + s, s), TransferFunction(a - p, 9*s - 9, s), TransferFunction(-3, s + 2, s))))) >>> pprint(_, use_unicode=False) [ 3 ] [ ----- ] [ -a + p -a - s 3 ] [ s + 2 ] [ ------- ---------- -----] [ ] [ 9*s - 9 2 s + 2] [ 4 ] [ s + s + 1 ] [p - 3*p + 2] [ -3 ] [ ] *[------------] *[-----] [ 4 ] [ p + s ] [s + 2]{t} [- p + 3*p - 2 a - p -3 ] [ ] [-------------- ------- -----] [ -a - s ] [ p + s 9*s - 9 s + 2]{t} [ ---------- ] [ 2 ] [ s + s + 1 ]{t} >>> tfm_10 + tfm_8*tfm_9 MIMOParallel(TransferFunctionMatrix(((TransferFunction(a + s, s**2 + s + 1, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(-a + p, 9*s - 9, s),))), MIMOSeries(TransferFunctionMatrix(((TransferFunction(-3, s + 2, s),),)), TransferFunctionMatrix(((TransferFunction(3, s + 2, s),), (TransferFunction(p**4 - 3*p + 2, p + s, s),), (TransferFunction(-a - s, s**2 + s + 1, s),))))) >>> pprint(_, use_unicode=False) [ a + s ] [ 3 ] [ ---------- ] [ ----- ] [ 2 ] [ s + 2 ] [ s + s + 1 ] [ ] [ ] [ 4 ] [ 4 ] [p - 3*p + 2] [ -3 ] [p - 3*p + 2] + [------------] *[-----] [------------] [ p + s ] [s + 2]{t} [ p + s ] [ ] [ ] [ -a - s ] [ -a + p ] [ ---------- ] [ ------- ] [ 2 ] [ 9*s - 9 ]{t} [ s + s + 1 ]{t}
These unevaluated
Series
orParallel
objects can convert into the resultant transfer function matrix using.doit()
method or by.rewrite(TransferFunctionMatrix)
.>>> (-tfm_8 + tfm_10 + tfm_8*tfm_9).doit() TransferFunctionMatrix(((TransferFunction((a + s)*(s + 2)**3 - 3*(s + 2)**2*(s**2 + s + 1) - 9*(s + 2)*(s**2 + s + 1), (s + 2)**3*(s**2 + s + 1), s),), (TransferFunction((p + s)*(-3*p**4 + 9*p - 6), (p + s)**2*(s + 2), s),), (TransferFunction((-a + p)*(s + 2)*(s**2 + s + 1)**2 + (a + s)*(s + 2)*(9*s - 9)*(s**2 + s + 1) + (3*a + 3*s)*(9*s - 9)*(s**2 + s + 1), (s + 2)*(9*s - 9)*(s**2 + s + 1)**2, s),))) >>> (-tfm_12 * -tfm_8 * -tfm_9).rewrite(TransferFunctionMatrix) TransferFunctionMatrix(((TransferFunction(3*(-3*a + 3*p)*(p + s)*(s + 2)*(s**2 + s + 1)**2 + 3*(-3*a - 3*s)*(p + s)*(s + 2)*(9*s - 9)*(s**2 + s + 1) + 3*(a + s)*(s + 2)**2*(9*s - 9)*(-p**4 + 3*p - 2)*(s**2 + s + 1), (p + s)*(s + 2)**3*(9*s - 9)*(s**2 + s + 1)**2, s),), (TransferFunction(3*(-a + p)*(p + s)*(s + 2)**2*(-p**4 + 3*p - 2)*(s**2 + s + 1) + 3*(3*a + 3*s)*(p + s)**2*(s + 2)*(9*s - 9) + 3*(p + s)*(s + 2)*(9*s - 9)*(-3*p**4 + 9*p - 6)*(s**2 + s + 1), (p + s)**2*(s + 2)**3*(9*s - 9)*(s**2 + s + 1), s),)))
- elem_poles()[源代码]#
Returns the poles of each element of the
TransferFunctionMatrix
.备注
Actual poles of a MIMO system are NOT the poles of individual elements.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix >>> tf_1 = TransferFunction(3, (s + 1), s) >>> tf_2 = TransferFunction(s + 6, (s + 1)*(s + 2), s) >>> tf_3 = TransferFunction(s + 3, s**2 + 3*s + 2, s) >>> tf_4 = TransferFunction(s + 2, s**2 + 5*s - 10, s) >>> tfm_1 = TransferFunctionMatrix([[tf_1, tf_2], [tf_3, tf_4]]) >>> tfm_1 TransferFunctionMatrix(((TransferFunction(3, s + 1, s), TransferFunction(s + 6, (s + 1)*(s + 2), s)), (TransferFunction(s + 3, s**2 + 3*s + 2, s), TransferFunction(s + 2, s**2 + 5*s - 10, s)))) >>> tfm_1.elem_poles() [[[-1], [-2, -1]], [[-2, -1], [-5/2 + sqrt(65)/2, -sqrt(65)/2 - 5/2]]]
参见
- elem_zeros()[源代码]#
Returns the zeros of each element of the
TransferFunctionMatrix
.备注
Actual zeros of a MIMO system are NOT the zeros of individual elements.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix >>> tf_1 = TransferFunction(3, (s + 1), s) >>> tf_2 = TransferFunction(s + 6, (s + 1)*(s + 2), s) >>> tf_3 = TransferFunction(s + 3, s**2 + 3*s + 2, s) >>> tf_4 = TransferFunction(s**2 - 9*s + 20, s**2 + 5*s - 10, s) >>> tfm_1 = TransferFunctionMatrix([[tf_1, tf_2], [tf_3, tf_4]]) >>> tfm_1 TransferFunctionMatrix(((TransferFunction(3, s + 1, s), TransferFunction(s + 6, (s + 1)*(s + 2), s)), (TransferFunction(s + 3, s**2 + 3*s + 2, s), TransferFunction(s**2 - 9*s + 20, s**2 + 5*s - 10, s)))) >>> tfm_1.elem_zeros() [[[], [-6]], [[-3], [4, 5]]]
参见
- eval_frequency(other)[源代码]#
Evaluates system response of each transfer function in the
TransferFunctionMatrix
at any point in the real or complex plane.实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix >>> from sympy import I >>> tf_1 = TransferFunction(3, (s + 1), s) >>> tf_2 = TransferFunction(s + 6, (s + 1)*(s + 2), s) >>> tf_3 = TransferFunction(s + 3, s**2 + 3*s + 2, s) >>> tf_4 = TransferFunction(s**2 - 9*s + 20, s**2 + 5*s - 10, s) >>> tfm_1 = TransferFunctionMatrix([[tf_1, tf_2], [tf_3, tf_4]]) >>> tfm_1 TransferFunctionMatrix(((TransferFunction(3, s + 1, s), TransferFunction(s + 6, (s + 1)*(s + 2), s)), (TransferFunction(s + 3, s**2 + 3*s + 2, s), TransferFunction(s**2 - 9*s + 20, s**2 + 5*s - 10, s)))) >>> tfm_1.eval_frequency(2) Matrix([ [ 1, 2/3], [5/12, 3/2]]) >>> tfm_1.eval_frequency(I*2) Matrix([ [ 3/5 - 6*I/5, -I], [3/20 - 11*I/20, -101/74 + 23*I/74]])
- classmethod from_Matrix(matrix, var)[源代码]#
Creates a new
TransferFunctionMatrix
efficiently from a SymPy Matrix ofExpr
objects.- 参数:
matrix :
ImmutableMatrix
havingExpr
/Number
elements.var :符号
Complex variable of the Laplace transform which will be used by the all the
TransferFunction
objects in theTransferFunctionMatrix
.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunctionMatrix >>> from sympy import Matrix, pprint >>> M = Matrix([[s, 1/s], [1/(s+1), s]]) >>> M_tf = TransferFunctionMatrix.from_Matrix(M, s) >>> pprint(M_tf, use_unicode=False) [ s 1] [ - -] [ 1 s] [ ] [ 1 s] [----- -] [s + 1 1]{t} >>> M_tf.elem_poles() [[[], [0]], [[-1], []]] >>> M_tf.elem_zeros() [[[0], []], [[], [0]]]
- property num_inputs#
Returns the number of inputs of the system.
实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix >>> G1 = TransferFunction(s + 3, s**2 - 3, s) >>> G2 = TransferFunction(4, s**2, s) >>> G3 = TransferFunction(p**2 + s**2, p - 3, s) >>> tfm_1 = TransferFunctionMatrix([[G2, -G1, G3], [-G2, -G1, -G3]]) >>> tfm_1.num_inputs 3
参见
- property num_outputs#
Returns the number of outputs of the system.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunctionMatrix >>> from sympy import Matrix >>> M_1 = Matrix([[s], [1/s]]) >>> TFM = TransferFunctionMatrix.from_Matrix(M_1, s) >>> print(TFM) TransferFunctionMatrix(((TransferFunction(s, 1, s),), (TransferFunction(1, s, s),))) >>> TFM.num_outputs 2
参见
- property shape#
Returns the shape of the transfer function matrix, that is,
(# of outputs, # of inputs)
.实例
>>> from sympy.abc import s, p >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix >>> tf1 = TransferFunction(p**2 - 1, s**4 + s**3 - p, p) >>> tf2 = TransferFunction(1 - p, p**2 - 3*p + 7, p) >>> tf3 = TransferFunction(3, 4, p) >>> tfm1 = TransferFunctionMatrix([[tf1, -tf2]]) >>> tfm1.shape (1, 2) >>> tfm2 = TransferFunctionMatrix([[-tf2, tf3], [tf1, -tf1]]) >>> tfm2.shape (2, 2)
- transpose()[源代码]#
Returns the transpose of the
TransferFunctionMatrix
(switched input and output layers).
- property var#
Returns the complex variable used by all the transfer functions or
Series
/Parallel
objects in a transfer function matrix.实例
>>> from sympy.abc import p, s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, Series, Parallel >>> G1 = TransferFunction(p**2 + 2*p + 4, p - 6, p) >>> G2 = TransferFunction(p, 4 - p, p) >>> G3 = TransferFunction(0, p**4 - 1, p) >>> G4 = TransferFunction(s + 1, s**2 + s + 1, s) >>> S1 = Series(G1, G2) >>> S2 = Series(-G3, Parallel(G2, -G1)) >>> tfm1 = TransferFunctionMatrix([[G1], [G2], [G3]]) >>> tfm1.var p >>> tfm2 = TransferFunctionMatrix([[-S1, -S2], [S1, S2]]) >>> tfm2.var p >>> tfm3 = TransferFunctionMatrix([[G4]]) >>> tfm3.var s
- class sympy.physics.control.lti.MIMOSeries(*args, evaluate=False)[源代码]#
A class for representing a series configuration of MIMO systems.
- 参数:
args : MIMOLinearTimeInvariant
MIMO systems in a series configuration.
evaluate : Boolean, Keyword
When passed
True
, returns the equivalentMIMOSeries(*args).doit()
. Set toFalse
by default.- 加薪:
ValueError
When no argument is passed.
var
attribute is not same for every system.num_outputs
of the MIMO system is not equal to thenum_inputs
of its adjacent MIMO system. (Matrix multiplication constraint, basically)TypeError
Any of the passed
*args
has unsupported typeA combination of SISO and MIMO systems is passed. There should be homogeneity in the type of systems passed, MIMO in this case.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import MIMOSeries, TransferFunctionMatrix >>> from sympy import Matrix, pprint >>> mat_a = Matrix([[5*s], [5]]) # 2 Outputs 1 Input >>> mat_b = Matrix([[5, 1/(6*s**2)]]) # 1 Output 2 Inputs >>> mat_c = Matrix([[1, s], [5/s, 1]]) # 2 Outputs 2 Inputs >>> tfm_a = TransferFunctionMatrix.from_Matrix(mat_a, s) >>> tfm_b = TransferFunctionMatrix.from_Matrix(mat_b, s) >>> tfm_c = TransferFunctionMatrix.from_Matrix(mat_c, s) >>> MIMOSeries(tfm_c, tfm_b, tfm_a) MIMOSeries(TransferFunctionMatrix(((TransferFunction(1, 1, s), TransferFunction(s, 1, s)), (TransferFunction(5, s, s), TransferFunction(1, 1, s)))), TransferFunctionMatrix(((TransferFunction(5, 1, s), TransferFunction(1, 6*s**2, s)),)), TransferFunctionMatrix(((TransferFunction(5*s, 1, s),), (TransferFunction(5, 1, s),)))) >>> pprint(_, use_unicode=False) # For Better Visualization [5*s] [1 s] [---] [5 1 ] [- -] [ 1 ] [- ----] [1 1] [ ] *[1 2] *[ ] [ 5 ] [ 6*s ]{t} [5 1] [ - ] [- -] [ 1 ]{t} [s 1]{t} >>> MIMOSeries(tfm_c, tfm_b, tfm_a).doit() TransferFunctionMatrix(((TransferFunction(150*s**4 + 25*s, 6*s**3, s), TransferFunction(150*s**4 + 5*s, 6*s**2, s)), (TransferFunction(150*s**3 + 25, 6*s**3, s), TransferFunction(150*s**3 + 5, 6*s**2, s)))) >>> pprint(_, use_unicode=False) # (2 Inputs -A-> 2 Outputs) -> (2 Inputs -B-> 1 Output) -> (1 Input -C-> 2 Outputs) is equivalent to (2 Inputs -Series Equivalent-> 2 Outputs). [ 4 4 ] [150*s + 25*s 150*s + 5*s] [------------- ------------] [ 3 2 ] [ 6*s 6*s ] [ ] [ 3 3 ] [ 150*s + 25 150*s + 5 ] [ ----------- ---------- ] [ 3 2 ] [ 6*s 6*s ]{t}
笔记
All the transfer function matrices should use the same complex variable
var
of the Laplace transform.MIMOSeries(A, B)
is not equivalent toA*B
. It is always in the reverse order, that isB*A
.参见
- doit(cancel=False, **kwargs)[源代码]#
Returns the resultant transfer function matrix obtained after evaluating the MIMO systems arranged in a series configuration.
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, MIMOSeries, TransferFunctionMatrix >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> tfm1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf2]]) >>> tfm2 = TransferFunctionMatrix([[tf2, tf1], [tf1, tf1]]) >>> MIMOSeries(tfm2, tfm1).doit() TransferFunctionMatrix(((TransferFunction(2*(-p + s)*(s**3 - 2)*(a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)**2*(s**4 + 5*s + 6)**2, s), TransferFunction((-p + s)**2*(s**3 - 2)*(a*p**2 + b*s) + (-p + s)*(a*p**2 + b*s)**2*(s**4 + 5*s + 6), (-p + s)**3*(s**4 + 5*s + 6), s)), (TransferFunction((-p + s)*(s**3 - 2)**2*(s**4 + 5*s + 6) + (s**3 - 2)*(a*p**2 + b*s)*(s**4 + 5*s + 6)**2, (-p + s)*(s**4 + 5*s + 6)**3, s), TransferFunction(2*(s**3 - 2)*(a*p**2 + b*s), (-p + s)*(s**4 + 5*s + 6), s))))
- property num_inputs#
Returns the number of input signals of the series system.
- property num_outputs#
Returns the number of output signals of the series system.
- property shape#
Returns the shape of the equivalent MIMO system.
- property var#
返回所有传递函数使用的复变量。
实例
>>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, MIMOSeries, TransferFunctionMatrix >>> G1 = TransferFunction(p**2 + 2*p + 4, p - 6, p) >>> G2 = TransferFunction(p, 4 - p, p) >>> G3 = TransferFunction(0, p**4 - 1, p) >>> tfm_1 = TransferFunctionMatrix([[G1, G2, G3]]) >>> tfm_2 = TransferFunctionMatrix([[G1], [G2], [G3]]) >>> MIMOSeries(tfm_2, tfm_1).var p
- class sympy.physics.control.lti.MIMOParallel(*args, evaluate=False)[源代码]#
A class for representing a parallel configuration of MIMO systems.
- 参数:
args : MIMOLinearTimeInvariant
MIMO Systems in a parallel arrangement.
evaluate : Boolean, Keyword
When passed
True
, returns the equivalentMIMOParallel(*args).doit()
. Set toFalse
by default.- 加薪:
ValueError
When no argument is passed.
var
attribute is not same for every system.All MIMO systems passed do not have same shape.
TypeError
Any of the passed
*args
has unsupported typeA combination of SISO and MIMO systems is passed. There should be homogeneity in the type of systems passed, MIMO in this case.
实例
>>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunctionMatrix, MIMOParallel >>> from sympy import Matrix, pprint >>> expr_1 = 1/s >>> expr_2 = s/(s**2-1) >>> expr_3 = (2 + s)/(s**2 - 1) >>> expr_4 = 5 >>> tfm_a = TransferFunctionMatrix.from_Matrix(Matrix([[expr_1, expr_2], [expr_3, expr_4]]), s) >>> tfm_b = TransferFunctionMatrix.from_Matrix(Matrix([[expr_2, expr_1], [expr_4, expr_3]]), s) >>> tfm_c = TransferFunctionMatrix.from_Matrix(Matrix([[expr_3, expr_4], [expr_1, expr_2]]), s) >>> MIMOParallel(tfm_a, tfm_b, tfm_c) MIMOParallel(TransferFunctionMatrix(((TransferFunction(1, s, s), TransferFunction(s, s**2 - 1, s)), (TransferFunction(s + 2, s**2 - 1, s), TransferFunction(5, 1, s)))), TransferFunctionMatrix(((TransferFunction(s, s**2 - 1, s), TransferFunction(1, s, s)), (TransferFunction(5, 1, s), TransferFunction(s + 2, s**2 - 1, s)))), TransferFunctionMatrix(((TransferFunction(s + 2, s**2 - 1, s), TransferFunction(5, 1, s)), (TransferFunction(1, s, s), TransferFunction(s, s**2 - 1, s))))) >>> pprint(_, use_unicode=False) # For Better Visualization [ 1 s ] [ s 1 ] [s + 2 5 ] [ - ------] [------ - ] [------ - ] [ s 2 ] [ 2 s ] [ 2 1 ] [ s - 1] [s - 1 ] [s - 1 ] [ ] + [ ] + [ ] [s + 2 5 ] [ 5 s + 2 ] [ 1 s ] [------ - ] [ - ------] [ - ------] [ 2 1 ] [ 1 2 ] [ s 2 ] [s - 1 ]{t} [ s - 1]{t} [ s - 1]{t} >>> MIMOParallel(tfm_a, tfm_b, tfm_c).doit() TransferFunctionMatrix(((TransferFunction(s**2 + s*(2*s + 2) - 1, s*(s**2 - 1), s), TransferFunction(2*s**2 + 5*s*(s**2 - 1) - 1, s*(s**2 - 1), s)), (TransferFunction(s**2 + s*(s + 2) + 5*s*(s**2 - 1) - 1, s*(s**2 - 1), s), TransferFunction(5*s**2 + 2*s - 3, s**2 - 1, s)))) >>> pprint(_, use_unicode=False) [ 2 2 / 2 \ ] [ s + s*(2*s + 2) - 1 2*s + 5*s*\s - 1/ - 1] [ -------------------- -----------------------] [ / 2 \ / 2 \ ] [ s*\s - 1/ s*\s - 1/ ] [ ] [ 2 / 2 \ 2 ] [s + s*(s + 2) + 5*s*\s - 1/ - 1 5*s + 2*s - 3 ] [--------------------------------- -------------- ] [ / 2 \ 2 ] [ s*\s - 1/ s - 1 ]{t}
笔记
All the transfer function matrices should use the same complex variable
var
of the Laplace transform.参见
- doit(**hints)[源代码]#
Returns the resultant transfer function matrix obtained after evaluating the MIMO systems arranged in a parallel configuration.
实例
>>> from sympy.abc import s, p, a, b >>> from sympy.physics.control.lti import TransferFunction, MIMOParallel, TransferFunctionMatrix >>> tf1 = TransferFunction(a*p**2 + b*s, s - p, s) >>> tf2 = TransferFunction(s**3 - 2, s**4 + 5*s + 6, s) >>> tfm_1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]]) >>> tfm_2 = TransferFunctionMatrix([[tf2, tf1], [tf1, tf2]]) >>> MIMOParallel(tfm_1, tfm_2).doit() TransferFunctionMatrix(((TransferFunction((-p + s)*(s**3 - 2) + (a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)*(s**4 + 5*s + 6), s), TransferFunction((-p + s)*(s**3 - 2) + (a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)*(s**4 + 5*s + 6), s)), (TransferFunction((-p + s)*(s**3 - 2) + (a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)*(s**4 + 5*s + 6), s), TransferFunction((-p + s)*(s**3 - 2) + (a*p**2 + b*s)*(s**4 + 5*s + 6), (-p + s)*(s**4 + 5*s + 6), s))))
- property num_inputs#
Returns the number of input signals of the parallel system.
- property num_outputs#
Returns the number of output signals of the parallel system.
- property shape#
Returns the shape of the equivalent MIMO system.
- property var#
Returns the complex variable used by all the systems.
实例
>>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, MIMOParallel >>> G1 = TransferFunction(p**2 + 2*p + 4, p - 6, p) >>> G2 = TransferFunction(p, 4 - p, p) >>> G3 = TransferFunction(0, p**4 - 1, p) >>> G4 = TransferFunction(p**2, p**2 - 1, p) >>> tfm_a = TransferFunctionMatrix([[G1, G2], [G3, G4]]) >>> tfm_b = TransferFunctionMatrix([[G2, G1], [G4, G3]]) >>> MIMOParallel(tfm_a, tfm_b).var p
- class sympy.physics.control.lti.MIMOFeedback(sys1, sys2, sign=-1)[源代码]#
A class for representing closed-loop feedback interconnection between two MIMO input/output systems.
- 参数:
sys1 : MIMOSeries, TransferFunctionMatrix
The MIMO system placed on the feedforward path.
sys2 : MIMOSeries, TransferFunctionMatrix
The system placed on the feedback path (often a feedback controller).
sign : int, optional
The sign of feedback. Can either be
1
(for positive feedback) or-1
(for negative feedback). Default value is \(-1\).- 加薪:
ValueError
When
sys1
andsys2
are not using the same complex variable of the Laplace transform.Forward path model should have an equal number of inputs/outputs to the feedback path outputs/inputs.
When product of
sys1
andsys2
is not a square matrix.When the equivalent MIMO system is not invertible.
TypeError
When either
sys1
orsys2
is not aMIMOSeries
or aTransferFunctionMatrix
object.
实例
>>> from sympy import Matrix, pprint >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunctionMatrix, MIMOFeedback >>> plant_mat = Matrix([[1, 1/s], [0, 1]]) >>> controller_mat = Matrix([[10, 0], [0, 10]]) # Constant Gain >>> plant = TransferFunctionMatrix.from_Matrix(plant_mat, s) >>> controller = TransferFunctionMatrix.from_Matrix(controller_mat, s) >>> feedback = MIMOFeedback(plant, controller) # Negative Feedback (default) >>> pprint(feedback, use_unicode=False) / [1 1] [10 0 ] \-1 [1 1] | [- -] [-- - ] | [- -] | [1 s] [1 1 ] | [1 s] |I + [ ] *[ ] | * [ ] | [0 1] [0 10] | [0 1] | [- -] [- --] | [- -] \ [1 1]{t} [1 1 ]{t}/ [1 1]{t}
To get the equivalent system matrix, use either
doit
orrewrite
method.>>> pprint(feedback.doit(), use_unicode=False) [1 1 ] [-- -----] [11 121*s] [ ] [0 1 ] [- -- ] [1 11 ]{t}
To negate the
MIMOFeedback
object, use-
operator.>>> neg_feedback = -feedback >>> pprint(neg_feedback.doit(), use_unicode=False) [-1 -1 ] [--- -----] [11 121*s] [ ] [ 0 -1 ] [ - --- ] [ 1 11 ]{t}
- doit(cancel=True, expand=False, **hints)[源代码]#
Returns the resultant transfer function matrix obtained by the feedback interconnection.
实例
>>> from sympy import pprint >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, MIMOFeedback >>> tf1 = TransferFunction(s, 1 - s, s) >>> tf2 = TransferFunction(1, s, s) >>> tf3 = TransferFunction(5, 1, s) >>> tf4 = TransferFunction(s - 1, s, s) >>> tf5 = TransferFunction(0, 1, s) >>> sys1 = TransferFunctionMatrix([[tf1, tf2], [tf3, tf4]]) >>> sys2 = TransferFunctionMatrix([[tf3, tf5], [tf5, tf5]]) >>> F_1 = MIMOFeedback(sys1, sys2, 1) >>> pprint(F_1, use_unicode=False) / [ s 1 ] [5 0] \-1 [ s 1 ] | [----- - ] [- -] | [----- - ] | [1 - s s ] [1 1] | [1 - s s ] |I - [ ] *[ ] | * [ ] | [ 5 s - 1] [0 0] | [ 5 s - 1] | [ - -----] [- -] | [ - -----] \ [ 1 s ]{t} [1 1]{t}/ [ 1 s ]{t} >>> pprint(F_1.doit(), use_unicode=False) [ -s s - 1 ] [------- ----------- ] [6*s - 1 s*(6*s - 1) ] [ ] [5*s - 5 (s - 1)*(6*s + 24)] [------- ------------------] [6*s - 1 s*(6*s - 1) ]{t}
If the user wants the resultant
TransferFunctionMatrix
object without canceling the common factors then thecancel
kwarg should be passedFalse
.>>> pprint(F_1.doit(cancel=False), use_unicode=False) [ s*(s - 1) s - 1 ] [ ----------------- ----------- ] [ (1 - s)*(6*s - 1) s*(6*s - 1) ] [ ] [s*(25*s - 25) + 5*(1 - s)*(6*s - 1) s*(s - 1)*(6*s - 1) + s*(25*s - 25)] [----------------------------------- -----------------------------------] [ (1 - s)*(6*s - 1) 2 ] [ s *(6*s - 1) ]{t}
If the user wants the expanded form of the resultant transfer function matrix, the
expand
kwarg should be passed asTrue
.>>> pprint(F_1.doit(expand=True), use_unicode=False) [ -s s - 1 ] [------- -------- ] [6*s - 1 2 ] [ 6*s - s ] [ ] [ 2 ] [5*s - 5 6*s + 18*s - 24] [------- ----------------] [6*s - 1 2 ] [ 6*s - s ]{t}
- property sensitivity#
Returns the sensitivity function matrix of the feedback loop.
Sensitivity of a closed-loop system is the ratio of change in the open loop gain to the change in the closed loop gain.
备注
This method would not return the complementary sensitivity function.
实例
>>> from sympy import pprint >>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, MIMOFeedback >>> tf1 = TransferFunction(p, 1 - p, p) >>> tf2 = TransferFunction(1, p, p) >>> tf3 = TransferFunction(1, 1, p) >>> sys1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]]) >>> sys2 = TransferFunctionMatrix([[tf1, tf3], [tf3, tf2]]) >>> F_1 = MIMOFeedback(sys1, sys2, 1) # Positive feedback >>> F_2 = MIMOFeedback(sys1, sys2) # Negative feedback >>> pprint(F_1.sensitivity, use_unicode=False) [ 4 3 2 5 4 2 ] [- p + 3*p - 4*p + 3*p - 1 p - 2*p + 3*p - 3*p + 1 ] [---------------------------- -----------------------------] [ 4 3 2 5 4 3 2 ] [ p + 3*p - 8*p + 8*p - 3 p + 3*p - 8*p + 8*p - 3*p] [ ] [ 4 3 2 3 2 ] [ p - p - p + p 3*p - 6*p + 4*p - 1 ] [ -------------------------- -------------------------- ] [ 4 3 2 4 3 2 ] [ p + 3*p - 8*p + 8*p - 3 p + 3*p - 8*p + 8*p - 3 ] >>> pprint(F_2.sensitivity, use_unicode=False) [ 4 3 2 5 4 2 ] [p - 3*p + 2*p + p - 1 p - 2*p + 3*p - 3*p + 1] [------------------------ --------------------------] [ 4 3 5 4 2 ] [ p - 3*p + 2*p - 1 p - 3*p + 2*p - p ] [ ] [ 4 3 2 4 3 ] [ p - p - p + p 2*p - 3*p + 2*p - 1 ] [ ------------------- --------------------- ] [ 4 3 4 3 ] [ p - 3*p + 2*p - 1 p - 3*p + 2*p - 1 ]
- property sign#
Returns the type of feedback interconnection of two models.
1
for Positive and-1
for Negative.
- property sys1#
Returns the system placed on the feedforward path of the MIMO feedback interconnection.
实例
>>> from sympy import pprint >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, MIMOFeedback >>> tf1 = TransferFunction(s**2 + s + 1, s**2 - s + 1, s) >>> tf2 = TransferFunction(1, s, s) >>> tf3 = TransferFunction(1, 1, s) >>> sys1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]]) >>> sys2 = TransferFunctionMatrix([[tf3, tf3], [tf3, tf2]]) >>> F_1 = MIMOFeedback(sys1, sys2, 1) >>> F_1.sys1 TransferFunctionMatrix(((TransferFunction(s**2 + s + 1, s**2 - s + 1, s), TransferFunction(1, s, s)), (TransferFunction(1, s, s), TransferFunction(s**2 + s + 1, s**2 - s + 1, s)))) >>> pprint(_, use_unicode=False) [ 2 ] [s + s + 1 1 ] [---------- - ] [ 2 s ] [s - s + 1 ] [ ] [ 2 ] [ 1 s + s + 1] [ - ----------] [ s 2 ] [ s - s + 1]{t}
- property sys2#
Returns the feedback controller of the MIMO feedback interconnection.
实例
>>> from sympy import pprint >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, MIMOFeedback >>> tf1 = TransferFunction(s**2, s**3 - s + 1, s) >>> tf2 = TransferFunction(1, s, s) >>> tf3 = TransferFunction(1, 1, s) >>> sys1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]]) >>> sys2 = TransferFunctionMatrix([[tf1, tf3], [tf3, tf2]]) >>> F_1 = MIMOFeedback(sys1, sys2) >>> F_1.sys2 TransferFunctionMatrix(((TransferFunction(s**2, s**3 - s + 1, s), TransferFunction(1, 1, s)), (TransferFunction(1, 1, s), TransferFunction(1, s, s)))) >>> pprint(_, use_unicode=False) [ 2 ] [ s 1] [---------- -] [ 3 1] [s - s + 1 ] [ ] [ 1 1] [ - -] [ 1 s]{t}
- property var#
Returns the complex variable of the Laplace transform used by all the transfer functions involved in the MIMO feedback loop.
实例
>>> from sympy.abc import p >>> from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix, MIMOFeedback >>> tf1 = TransferFunction(p, 1 - p, p) >>> tf2 = TransferFunction(1, p, p) >>> tf3 = TransferFunction(1, 1, p) >>> sys1 = TransferFunctionMatrix([[tf1, tf2], [tf2, tf1]]) >>> sys2 = TransferFunctionMatrix([[tf1, tf3], [tf3, tf2]]) >>> F_1 = MIMOFeedback(sys1, sys2, 1) # Positive feedback >>> F_1.var p
- sympy.physics.control.lti.gbt(tf, sample_per, alpha)[源代码]#
Returns falling coefficients of H(z) from numerator and denominator.
解释
Where H(z) is the corresponding discretized transfer function, discretized with the generalised bilinear transformation method. H(z) is obtained from the continuous transfer function H(s) by substituting \(s(z) = \frac{z-1}{T(\alpha z + (1-\alpha))}\) into H(s), where T is the sample period. Coefficients are falling, i.e. \(H(z) = \frac{az+b}{cz+d}\) is returned as [a, b], [c, d].
实例
>>> from sympy.physics.control.lti import TransferFunction, gbt >>> from sympy.abc import s, L, R, T
>>> tf = TransferFunction(1, s*L + R, s) >>> numZ, denZ = gbt(tf, T, 0.5) >>> numZ [T/(2*(L + R*T/2)), T/(2*(L + R*T/2))] >>> denZ [1, (-L + R*T/2)/(L + R*T/2)]
>>> numZ, denZ = gbt(tf, T, 0) >>> numZ [T/L] >>> denZ [1, (-L + R*T)/L]
>>> numZ, denZ = gbt(tf, T, 1) >>> numZ [T/(L + R*T), 0] >>> denZ [1, -L/(L + R*T)]
>>> numZ, denZ = gbt(tf, T, 0.3) >>> numZ [3*T/(10*(L + 3*R*T/10)), 7*T/(10*(L + 3*R*T/10))] >>> denZ [1, (-L + 7*R*T/10)/(L + 3*R*T/10)]
工具书类
- sympy.physics.control.lti.bilinear(tf, sample_per)[源代码]#
Returns falling coefficients of H(z) from numerator and denominator.
解释
Where H(z) is the corresponding discretized transfer function, discretized with the bilinear transform method. H(z) is obtained from the continuous transfer function H(s) by substituting \(s(z) = \frac{2}{T}\frac{z-1}{z+1}\) into H(s), where T is the sample period. Coefficients are falling, i.e. \(H(z) = \frac{az+b}{cz+d}\) is returned as [a, b], [c, d].
实例
>>> from sympy.physics.control.lti import TransferFunction, bilinear >>> from sympy.abc import s, L, R, T
>>> tf = TransferFunction(1, s*L + R, s) >>> numZ, denZ = bilinear(tf, T) >>> numZ [T/(2*(L + R*T/2)), T/(2*(L + R*T/2))] >>> denZ [1, (-L + R*T/2)/(L + R*T/2)]
- sympy.physics.control.lti.forward_diff(tf, sample_per)[源代码]#
Returns falling coefficients of H(z) from numerator and denominator.
解释
Where H(z) is the corresponding discretized transfer function, discretized with the forward difference transform method. H(z) is obtained from the continuous transfer function H(s) by substituting \(s(z) = \frac{z-1}{T}\) into H(s), where T is the sample period. Coefficients are falling, i.e. \(H(z) = \frac{az+b}{cz+d}\) is returned as [a, b], [c, d].
实例
>>> from sympy.physics.control.lti import TransferFunction, forward_diff >>> from sympy.abc import s, L, R, T
>>> tf = TransferFunction(1, s*L + R, s) >>> numZ, denZ = forward_diff(tf, T) >>> numZ [T/L] >>> denZ [1, (-L + R*T)/L]
- sympy.physics.control.lti.backward_diff(tf, sample_per)[源代码]#
Returns falling coefficients of H(z) from numerator and denominator.
解释
Where H(z) is the corresponding discretized transfer function, discretized with the backward difference transform method. H(z) is obtained from the continuous transfer function H(s) by substituting \(s(z) = \frac{z-1}{Tz}\) into H(s), where T is the sample period. Coefficients are falling, i.e. \(H(z) = \frac{az+b}{cz+d}\) is returned as [a, b], [c, d].
实例
>>> from sympy.physics.control.lti import TransferFunction, backward_diff >>> from sympy.abc import s, L, R, T
>>> tf = TransferFunction(1, s*L + R, s) >>> numZ, denZ = backward_diff(tf, T) >>> numZ [T/(L + R*T), 0] >>> denZ [1, -L/(L + R*T)]