SimuPy离散时间系统指南:采样数据仿真与零阶保持变换全解析
2026/8/24 11:08:01 网站建设 项目流程

SimuPy离散时间系统指南:采样数据仿真与零阶保持变换全解析

【免费下载链接】simupyA framework for modeling and simulating dynamical systems项目地址: https://gitcode.com/gh_mirrors/si/simupy

SimuPy 是开源的动力学系统仿真框架,本指南面向新手,完整讲解如何用 SimuPy 建模离散时间系统、进行采样数据仿真,并通过零阶保持(Zero-Order Hold)变换把连续时间模型精确离散化。全程只需一个采样参数dt和几行矩阵运算,无需任何 Simulink 环境。

为什么需要离散时间仿真?

真实世界的物理过程是连续的,但数字控制器(单片机、FPGA、软件 PLC)只能在固定时刻采样输入、更新输出。因此控制系统设计有两条必须走通的路:

场景需要的模型
物理对象 / 数学推导连续时间模型dx/dt = Ax + Bu
数字控制器 / 嵌入式实现离散时间模型x[k+1] = Ad·x[k] + Bd·u[k]

SimuPy 的 DynamicalSystem 基类用同一个接口同时支持这两类系统:状态方程函数对连续系统解释为导数,对离散系统解释为状态更新方程x[k+1]。关键区分点就是采样率参数dt

dt = 0(默认)→ 连续时间系统;dt > 0→ 离散时间系统,每经过一个采样周期更新一次状态。

第一步:建立连续时间 LTI 系统

以常见的二阶双积分器(弹簧-阻尼-质量)为例,使用LTISystem传入 A、B、C 矩阵即可,完整可运行版本见 examples/discrete_lti.py:

import numpy as np from scipy import signal, linalg from simupy.systems import LTISystem m, d, b, k = 1.0, 1.0, 1.0, 1.0 Ac = np.c_[[0, -k/m], [1, -b/m]] Bc = np.r_[0, d/m].reshape(-1, 1) Cc = np.eye(2) ct_sys = LTISystem(Ac, Bc, Cc) ct_sys.initial_condition = [1, 0]

第二步:零阶保持变换精确离散化

零阶保持假设:两个采样时刻之间输入u保持为常数。对这个假设下的线性时不变(LTI)系统,scipy.signal.cont2discrete给出的离散等效矩阵Ad、Bd 是精确的——在每个采样时刻t = kT,离散系统与连续系统的状态完全一致,不存在近似误差。

变换只需一行(示例代码 examples/discrete_lti.py):

dT = 1 / (2 * np.max(np.abs(np.linalg.eigvals(Ac)))) # 采样周期 Ad, Bd, Cd, Dd, dT = signal.cont2discrete((Ac, Bc, Cc, Dc), dT) dt_sys = LTISystem(Ad, Bd, Cd, dt=dT) # dt 参数声明这是离散系统 dt_sys.initial_condition = [1, 0]

💡采样周期怎么选?上式的启发式规则是dT = 1/(2·|最大特征值|):特征值越大,系统动态越快,所需采样频率越高。实际工程中还会结合奈奎斯特采样定理(采样频率 ≥ 2 倍信号最高频率)适当留裕量。

dt 参数揭秘:SimuPy 如何模拟采样

很多人好奇:SimuPy 的求解器是面向连续时间初值问题的(默认dopri5),它怎么跑离散系统?

答案在 simupy/systems/init.py 的dt属性中:当dt > 0时,SimuPy 自动把系统转换为事件驱动形式——

  1. 构造一个周期性事件方程sin(πt / dt),在每个采样时刻过零触发事件;
  2. 平时状态导数恒为 0(状态"冻结"),事件触发时由update_equation_function调用真实的状态更新方程,一次性推进到下一采样时刻;
  3. 无状态的离散环节(如离散控制器)则采用"保持上一次输出"的零阶保持语义。

也就是说,离散时间仿真在 SimuPy 内部是通过不连续性事件机制精确复现采样行为的,这正是它能与连续环节、反馈闭环无缝联仿的原因。

闭环反馈:离散控制器与离散系统联仿

离散化后的系统可以直接和离散控制器组成闭环,用BlockDiagram连接并调用simulate仿真(见 examples/discrete_lti.py):

from simupy.block_diagram import BlockDiagram Kd = np.linalg.solve(Bd.T @ Sd @ Bd + R, Bd.T @ Sd @ Ad) # 离散 LQR 增益 dt_ctr = LTISystem(-Kd, dt=dT) # 无状态离散控制器 dtdt_bd = BlockDiagram(dt_sys, dt_ctr) dtdt_bd.connect(dt_sys, dt_ctr) # 状态反馈给控制器 dtdt_bd.connect(dt_ctr, dt_sys) # 控制量回到系统 res = dtdt_bd.simulate(Tsim) # res.t / res.x / res.y 存放结果

simulate返回的SimulationResult带有txy数组属性,第一维索引时刻,第二维索引各信号分量,可直接喂给 matplotlib 绘图。示例脚本还会把"连续系统 + 离散控制器"与"全离散等效系统"的仿真结果画在同一张图上,直观验证零阶保持变换的精确性。

核心概念速查表

概念SimuPy 对应说明
采样周期LTISystem(..., dt=T)dt=0为连续系统,dt>0为离散系统
零阶保持变换scipy.signal.cont2discreteLTI 系统下精确离散化
离散状态更新state_equation_function解释为x[k+1] = f(t, x, u)
初始状态initial_condition默认全零
闭环联仿BlockDiagram支持连续/离散环节混接

快速上手

pip install simupy

要求 Python ≥ 3.6、NumPy ≥ 1.11、SciPy ≥ 0.18;更多接口细节可参考 docs/api/systems.rst 与 docs/api/block_diagram.rst。

🎯 掌握本文三个关键点——dt参数声明离散系统cont2discrete零阶保持变换BlockDiagram 闭环联仿——你就已经具备了用 SimuPy 完成采样数据控制系统仿真的全部基础,下一步可以打开 examples/discrete_lti.py 动手改参数、换模型,感受离散等效的精确性。

【免费下载链接】simupyA framework for modeling and simulating dynamical systems项目地址: https://gitcode.com/gh_mirrors/si/simupy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询