首页 > 解决方案 > 将表达式重新排列为传递函数的标准形式

问题描述

我是 Python/Sympy 的新手,我希望它能让生活更轻松地理解控制系统主题。对我来说,一个常见的要求是对照我自己的推导交叉检查文献中开发的方程。当涉及到传递函数时,分母通常按照 s 的高阶在左侧进行排序,降序向右移动。最高阶 s 项具有统一系数。

这是一个示例(取自此处):

在此处输入图像描述

我已经使用 sympy 开发了自己的传递函数,我想以刚才描述的方式重新排列它。

import sympy as sp
from sympy import simplify
from IPython.display import display

s, tau_1, tau_2 = sp.symbols('s,tau_1,tau_2')
F = (1+s*tau_2)/(1+s*(tau_1+tau_2));

k_0, k_d, N = sp.symbols('k_0,k_d,N')
H = (k_0*k_d*F)/(s+((k_0*k_d*F/N)))

display(H.simplify())

产生:

在此处输入图像描述

现在,我并不是真的希望通过简化来知道我想要显示哪种格式的表达式,但我希望有一个现有的函数或一组函数可以帮助我按照我想要的方式安排它。在那儿?

进一步更新:

经过一些操作,我设法隔离了最高功率并除以系数顶部和底部,从而使最高阶项没有系数,如我所愿。它无论如何都不是完美的。一个改进是让每个术语独立并像大多数多项式表示一样从高到低排序。我注意到 collect() 并没有像您期望的那样对功率项进行排序。那是怎么回事!?

import sympy as sp
from sympy import simplify
from sympy import poly
from sympy import degree
from IPython.display import display

s, tau_1, tau_2 = sp.symbols('s,tau_1,tau_2')
F = (1+s*tau_2)/(1+s*(tau_1+tau_2));
display(F)

k_0, k_d, N = sp.symbols('k_0,k_d,N')
H = (k_0*k_d*F)/(s+((k_0*k_d*F/N)))
display(H)

def normTF(expr):
    H_c = expr.ratsimp().collect(s)
    n,d=sp.fraction(H_c)
    collected = sp.Poly(d, s).as_expr()
    degree = sp.degree(collected, gen=s)
    terms = dict(i.as_independent(s)[::-1] for i in sp.Add.make_args(collected))
    sn=(n/terms[s**degree]).ratsimp().collect(s)
    sd=(d/terms[s**degree]).ratsimp().collect(s)
    return sn/sd

display(normTF(H))

标签: functionformatsympytransferpolynomials

解决方案


也许这就是你想要的:

In [30]: H.cancel().collect(s)
Out[30]: 
           N⋅k₀⋅k_d⋅s⋅τ₂ + N⋅k₀⋅k_d          
─────────────────────────────────────────────
          2                                  
k₀⋅k_d + s ⋅(N⋅τ₁ + N⋅τ₂) + s⋅(N + k₀⋅k_d⋅τ₂)

推荐阅读