SymPy 控制系统模块 LTI API 完全指南传递函数、状态空间与离散化实战【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy导读本文以 SymPy 官方文档 doc/src/modules/physics/control/lti.rst 为骨架系统讲解sympy.physics.control模块中 LTI线性时不变系统的全部公开 API包括连续/离散传递函数、串联并联与反馈互联、MIMO 传递函数矩阵、PID 控制器、状态空间模型以及三种经典离散化方法。读完本文你将能够用 SymPy 以纯符号方式建模、组合、分析控制系统的传递函数与状态空间并完成连续到离散的变换全程无需数值近似。一、模块概览纯符号的控制系统工具箱sympy.physics.control是 SymPy 的物理控制系统子模块当前聚焦于LTI线性时不变系统。根据官方总述 doc/src/modules/physics/control/control.rst该模块的核心建模对象包括连续时间传递函数TransferFunction工作在拉普拉斯域复变量s离散时间传递函数DiscreteTransferFunction工作在 z 域复变量z系统互联结构Parallel并联利用加法性、Series串联利用乘法性与Feedback负反馈互联MIMO 扩展以TransferFunctionMatrix为基类的MIMOSeries、MIMOParallel、MIMOFeedback状态空间模型StateSpace与DiscreteStateSpace支持可控性、可观性分析以及状态空间与传递函数之间的相互转换。该模块最大的特色是纯符号计算它不依赖数值方法逼近解求得的解精度高、形式紧凑可直接用于后续的符号化简与进一步分析。整个 LTI 实现集中在 sympy/physics/control/lti.py约 6800 行并通过 sympy/physics/control/init.py 对外导出TransferFunction、Series、Parallel、Feedback、StateSpace等 19 个符号。API 文档入口位于 doc/src/modules/physics/control/index.rst除本文讲解的lti.rst外还包含绘图模块 doc/src/modules/physics/control/control_plots.rst 与劳斯表模块 doc/src/modules/physics/control/routh_table.rst。二、类的继承体系LinearTimeInvariant 家族从源码结构sympy/physics/control/lti.py#L405-L478可以看到清晰的继承层级Basic (SymPy 基类) EvalfMixin └── LinearTimeInvariant (ABC所有 LTI 系统的公共基类) ├── SISOLinearTimeInvariant (单输入单输出_is_SISO True) │ ├── TransferFunctionBase → TransferFunction / DiscreteTransferFunction │ ├── Series / Parallel / Feedback │ └── PIDController └── MIMOLinearTimeInvariant (多输入多输出_is_SISO False) ├── TransferFunctionMatrix ├── MIMOSeries / MIMOParallel / MIMOFeedback └── StateSpace / DiscreteStateSpace (按 D 矩阵维数自动判定 SISO/MIMO)LinearTimeInvariantlti.py#L405本身是抽象类直接实例化会抛出NotImplementedError。它提供了三个关键属性is_continuous系统是否为连续时间is_SISO是否为单输入单输出sampling_time采样时间抽象属性子类实现。SISOLinearTimeInvariant固定num_inputs 1、num_outputs 1MIMOLinearTimeInvariant的_is_SISO False。在_check_time_compatibilitylti.py#L499中系统组合前会强制校验所有系统要么同为连续、要么同为离散且离散系统的采样时间必须一致否则抛出TypeError。这一兼容性检查通过_compatibility_decoratorlti.py#L525装饰在各类互联运算上。三、传递函数基类 TransferFunctionBaseTransferFunctionBaselti.py#L582是所有传递函数对象的抽象基类官方明确说明不应直接使用真正的用户入口是它的两个子类。它的类文档给出了完整的数学背景LTI 系统可由线性微分方程连续或线性差分方程离散描述通过拉普拉斯变换或 z 变换零初始条件下转换为复变量域中的有理函数$$H(p) \frac{Y(p)}{X(p)} \frac{a_{n}p^{n}a_{n-1}p^{n-1}\dotsa_{1}pa_{0}}{b_{m}p^{m}b_{m-1}p^{m-1}\dotsb_{1}pb_{0}}$$其中分子是输出信号的变换、分母是输入信号的变换。基类构造时的校验规则lti.py#L698包括var必须是Symbolden不能为零分子分母必须是数或含符号的表达式。3.1 三种便捷构造类方法除了直接TransferFunction(num, den, var)构造外基类提供了三个工厂类方法from_rational_expression(expr, varNone)直接从一个有理表达式构造。若表达式只有一个自由符号可省略var若有多个变量而未指定var会抛出ValueError纯数字表达式必须手动指定varlti.py#L729 from sympy.abc import s, p, a, z from sympy.physics.control.lti import TransferFunction, DiscreteTransferFunction expr1 (s 5)/(3*s**2 2*s 1) tf1 TransferFunction.from_rational_expression(expr1) TransferFunction(s 5, 3*s**2 2*s 1, s) expr3 (z 1)/(z**2 2*z 1) dtf DiscreteTransferFunction.from_rational_expression(expr3, z, sampling_time0.1) DiscreteTransferFunction(z 1, z**2 2*z 1, z, 0.1)from_coeff_lists(num_list, den_list, var)从降幂系数列表构造lti.py#L819 tf TransferFunction.from_coeff_lists([1, 0, 2], [3, 2, 2, 1], s) TransferFunction(s**2 2, 3*s**3 2*s**2 2*s 1, s)from_zpk(zeros, poles, gain, var)从零点、极点与增益构造lti.py#L876支持复数零极点与符号参数 tf2 TransferFunction.from_zpk([0], [1-1j, 11j, 2], -2, s) TransferFunction(-2*s, (s - 2)*(s - 1.0 - 1.0*I)*(s - 1.0 1.0*I), s)3.2 核心属性与方法名称说明源码位置num/den/var分子多项式、分母多项式、复变量lti.py#L927-L985poles()/zeros()返回极点、零点列表高阶多项式自动用rootof表示lti.py#L1063-L1100dc_gain()频率趋近 0 时的增益纯积分器返回oolti.py#L1032is_stable()通过劳斯-赫尔维茨条件判断稳定性lti.py#L1131is_proper/is_strictly_proper/is_biproper判断传递函数正则性lti.py#L1501-L1561expand()展开分子分母lti.py#L1011to_expr()转换为有理表达式lti.py#L1563rewrite(StateSpace)转换为可控规范型状态空间lti.py#L1771注意poles()/zeros()的实现lti.py#L41-L47先尝试roots求重根若求根数量不足阶数则回退到rootof用根对象精确表示高阶多项式的根从而保持符号精确性。四、TransferFunction连续时间传递函数TransferFunctionlti.py#L1593表示拉普拉斯域中的 LTI 系统构造参数为num、den、var且_is_continuous True、sampling_time恒为 0。类文档展示的典型用法均可在源码 docstring 中验证 from sympy.abc import s, p, a tf1 TransferFunction(s a, s**2 s 1, s) TransferFunction(a s, s**2 s 1, s)复变量任意var不限于s任何Symbol均可如TransferFunction(a*p**3 - a*p**2 s*p, p a**2, p)取负一元-运算符直接作用于分子乘方**运算符支持整数幂包括 0 次与负次幂tf**-1即分子分母互换算术运算生成结构对象、-、*分别生成未求值的Parallel与Series对象例如tf9 * tf10返回Series(...)这些结构可用.doit()或.rewrite(TransferFunction)合并为单一传递函数lti.py#L1707-L1713。TransferFunction.dc_gain()通过limit(num/den, var, 0)求极限实现get_asymptotic_stability_conditions()则对分母多项式调用hurwitz_conditions()返回一组不等式条件lti.py#L1756。五、DiscreteTransferFunction离散时间传递函数DiscreteTransferFunctionlti.py#L1814表示 z 域中的 LTI 系统构造参数为num、den、var、sampling_time。与连续版本的关键差异sampling_time为第四个位置参数表示两次连续采样时刻的间隔未指定时默认采样时间为 1若显式设为 0则直接返回一个TransferFunction实例sampling_time既可以是数也可以是Symbol便于做符号化的采样周期分析。从构造函数逻辑看create_transfer_functionlti.py#L534sampling_time 0返回连续对象sampling_time 0返回离散对象。这也是两个类之间分派的核心工厂 from sympy.abc import s, z tf create_transfer_function(s 5, 3*s**2 2*s 1, s) TransferFunction(s 5, 3*s**2 2*s 1, s) dtf create_transfer_function(z, z 1, z, 0.1) DiscreteTransferFunction(z, z 1, z, 0.1)六、系统互联Series、Parallel 与 Feedback6.1 Series串联与 Parallel并联Serieslti.py#L2436利用传递函数的乘法性表示级联总传递函数等于各子系统之积Parallellti.py#L3084利用加法性表示并联总传递函数等于各子系统之和。两者都是SISOLinearTimeInvariant子类。构造时可以传入任意多个系统_flatten_args会扁平化嵌套的同类型参数所有成员必须使用同一个复变量见LinearTimeInvariant._check_argslti.py#L417。调用.doit()可求值为合并后的单一传递函数。典型用法 from sympy.abc import s G1 TransferFunction(1, s 1, s) G2 TransferFunction(s, s**2 2, s) series G1 * G2 # 等价于 Series(G1, G2) series.doit() TransferFunction(s, (s 1)*(s**2 2), s)6.2 Feedback负反馈Feedbacklti.py#L3673表示两个输入输出系统之间的负反馈互联。设前向路径为G、反馈路径为H则闭环传递函数为$$\frac{G}{1 G \cdot H}$$其doit()方法lti.py#L3968默认对结果做约分cancelTrue并支持expand选项控制是否展开分子分母。七、PIDControllerPID 控制器PIDControllerlti.py#L2273是TransferFunction的子类用于在拉普拉斯域表示 PID 控制器。构造参数及其默认值参数含义默认值kp比例增益Symbol(kp)ki积分增益Symbol(ki)kd微分增益Symbol(kd)tf微分滤波时间常数用于滤除噪声0var复频率变量s从源码lti.py#L2335-L2340可以看到其内部实现构造时直接生成等效传递函数的分子kp*tf*var**2 kp*var ki*tf*var ki kd*var**2与分母tf*var**2 var。也就是说tf 0时实现的是带微分滤波的实用 PID 形式tf 0时退化为经典 PID。 from sympy import symbols from sympy.physics.control.lti import PIDController kp, ki, kd symbols(kp ki kd) p1 PIDController(kp, ki, kd) PIDController(kp, ki, kd, 0, s) p1.doit() TransferFunction(kd*s**2 ki kp*s, s, s) p1.kp, p1.ki, p1.kd, p1.tf, p1.var (kp, ki, kd, 0, s)doit()方法将其转换为普通TransferFunction各增益通过只读属性kp、ki、kd、tf、var访问。PID 对象可直接参与Series、Parallel、Feedback互联非常适合符号化设计控制器并分析闭环系统。八、MIMO 系统TransferFunctionMatrix 及其互联8.1 TransferFunctionMatrixTransferFunctionMatrixlti.py#L4605是 MIMO多输入多输出传递函数矩阵的基类是MIMOLinearTimeInvariant的子类。它将多个 SISO 传递函数组织为矩阵形式其中每个元素是TransferFunction或DiscreteTransferFunction且所有元素必须共享同一个复变量与采样时间。 from sympy.abc import s from sympy.physics.control.lti import TransferFunction, TransferFunctionMatrix G11 TransferFunction(1, s 1, s) G12 TransferFunction(s, s**2 2, s) G21 TransferFunction(1, s**2 3*s 2, s) G22 TransferFunction(1, s 4, s) tfm TransferFunctionMatrix([[G11, G12], [G21, G22]])8.2 MIMOSeries、MIMOParallel、MIMOFeedback它们是Series、Parallel、Feedback的 MIMO 等价物MIMOSerieslti.py#L2802MIMO 串联要求各系统的输入输出维数匹配MIMOParallellti.py#L3403MIMO 并联要求输入输出维数相同MIMOFeedbacklti.py#L4131MIMO 反馈互联内部用_is_invertiblelti.py#L4120判断I G·H是否可逆。MIMO 系统之间做运算时同样经过_check_other_MIMO与_check_time_compatibility校验保证维数与时间域一致。doit()方法如 lti.py#L4475将 MIMO 互联结构约简为单一TransferFunctionMatrix。九、状态空间StateSpace 与 DiscreteStateSpace9.1 数学定义与构造StateSpaceBaselti.py#L5383定义了标准状态空间模型。连续时间系统为$$\dot{x}(t) Ax(t) Bu(t), \qquad y(t) Cx(t) Du(t)$$离散时间系统为$$x[k1] Ax[k] Bu[k], \qquad y[k] Cx[k] Du[k]$$四矩阵含义A状态矩阵、B输入到状态矩阵、C状态到输出矩阵、D前馈直通矩阵。四个矩阵都可省略缺省时自动补零矩阵A缺省为 1×1 零矩阵其余按维数推导。构造时的形状校验lti.py#L5455-L5475包括A必须是方阵A与B行数相同C与D行数相同A与C列数相同B与D列数相同。任何不匹配都会抛出ShapeError。系统是 SISO 还是 MIMO 由D矩阵的维数自动判定1×1 为 SISO。 from sympy import Matrix A Matrix([[1, 0], [0, 1]]) B Matrix([1, 0]) C Matrix([1, 0]).T D Matrix([0]) create_state_space(A, B, C, D) StateSpace(Matrix([[1, 0], [0, 1]]), Matrix([[1], [0]]), Matrix([[1, 0]]), Matrix([[0]]))create_state_space(A, B, C, D, sampling_time0)lti.py#L5333与传递函数工厂逻辑一致sampling_time 0返回StateSpace否则返回DiscreteStateSpace。9.2 核心能力StateSpaceBase提供矩阵访问属性state_matrix、input_matrix、output_matrix、feedforward_matrix以及状态空间→传递函数转换to_transfer_function/transfer_function_matrix。MIMO 状态空间也受支持可通过num_inputs、num_outputs、is_SISO查询结构。两个关键的分析方法是is_controllable()lti.py#L6369通过可控性矩阵的秩判定系统能否由输入驱动至任意状态is_observable()lti.py#L6251通过对偶可观性矩阵的秩判定能否从输出重构全部状态。 ss StateSpace(Matrix([[0, 1], [-2, -3]]), Matrix([0, 1]), Matrix([[1, 0]]), Matrix([0])) ss.is_controllable() True ss.is_observable() TrueStateSpacelti.py#L6450与DiscreteStateSpacelti.py#L6644分别是连续与离散的具体实现。传递函数→状态空间方向通过TransferFunction.rewrite(StateSpace)完成返回可控规范型表示lti.py#L1771文档同时指出该转换不唯一——同一传递函数存在多个等价状态空间实现。反之连续传递函数不能改写为离散状态空间会抛TypeErrorlti.py#L1801。十、连续系统离散化gbt、bilinear、forward_diff、backward_diff这四个顶层函数用于把连续时间传递函数H(s)离散化为 z 域传递函数返回降幂排列的分子、分母系数列表即H(z) (az b)/(cz d)返回[a, b]、[c, d]。所有函数都要求输入为 SISO 系统MIMO 会抛NotImplementedError。函数替换关系alpha 参数源码位置gbt(tf, sample_per, alpha)$s(z)\frac{z-1}{T(\alpha z (1-\alpha))}$用户指定自动有理化lti.py#L49bilinear(tf, sample_per)$s(z)\frac{2}{T}\frac{z-1}{z1}$双线性/塔斯廷变换恒为 1/2lti.py#L135forward_diff(tf, sample_per)$s(z)\frac{z-1}{T}$前向差分恒为 0lti.py#L173backward_diff(tf, sample_per)$s(z)\frac{z-1}{Tz}$后向差分恒为 1lti.py#L211实际上后三者都是gbt的特例lti.py#L171 等核心实现gbt会对系数做归一化除以分母首项系数并将alpha通过Rational(...).limit_denominator(1000)有理化以便符号化简。官方文档示例以 RL 一阶电路 $H(s)1/(sLR)$ 为对象 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)]将alpha分别取 0、1、0.3 即可复现前向差分、后向差分与一般化的广义双线性结果离散化结果以采样周期T的符号表达式给出便于后续做符号层面的离散化误差分析。十一、频域分析phase_margin 与 gain_margin模块还提供两个频域稳定性指标函数非 autodoc 列表成员但属于 lti 模块并随包导出phase_margin(system)lti.py#L249返回连续系统的相位裕度。实现上令s jω代入先求幅值等于 10 dB处的穿越频率再在该频率处计算相位并映射到(-180°, 180°]。gain_margin(system)lti.py#L332返回增益裕度。先求相位穿越-180°的频率再取该处幅值的负 dB 值无穿越频率时返回oo。两者的共同约束仅适用于能生成有效波特图的 SISO 连续系统含时延项exp项抛NotImplementedError若存在除变换变量外的多余自由符号则抛ValueError。 from sympy.physics.control import TransferFunction, phase_margin, gain_margin from sympy.abc import s tf TransferFunction(1, s**3 2*s**2 s, s) phase_margin(tf).n() 21.3863897518751 gain_margin(tf).n() 6.02059991327962十二、测试验证与扩展阅读模块的测试覆盖非常完整sympy/physics/control/tests/test_lti.py近 5000 行逐一验证了本文涉及的各类构造方法、doit()化简、稳定性与可控/可观性判定、离散化函数以及 SISO/MIMO 互联的边界条件如变量不一致、采样时间冲突、矩阵维数不符等异常路径是学习 API 语义与坑点的第一手资料。与 LTI 模型配套的还有两个模块sympy/physics/control/control_plots.py为传递函数与状态空间提供波特图、奈奎斯特图、根轨迹等绘图功能对应文档 doc/src/modules/physics/control/control_plots.rstsympy/physics/control/routh_table.py构建劳斯表以判定多项式稳定性对应文档 doc/src/modules/physics/control/routh_table.rst。总结sympy.physics.control.lti提供了一个自成体系的纯符号 LTI 控制系统建模与分析栈从 SISO 的TransferFunction/DiscreteTransferFunction到Series/Parallel/Feedback互联再到 MIMO 的TransferFunctionMatrix与状态空间的StateSpace最后以gbt系列完成连续到离散的转换。所有结果均为精确符号表达式可直接用于理论推导、符号化简与进一步的自定义分析是控制系统课程、控制器设计验证与自动化教学实践的可靠工具。【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考