尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

离散控制系统的状态转移矩阵:原理、计算与工程实现

发布时间:2026/9/29 19:30:45

资讯中心
01
ARTICLE

离散控制系统的状态转移矩阵:原理、计算与工程实现

离散控制系统的状态转移矩阵:原理、计算与工程实现
搞控制系统的人不管你是做机器人、伺服驱动还是化工过程控制迟早都要跟状态转移矩阵打交道。尤其是离散控制系统里状态转移矩阵几乎是所有分析和设计工作的地基。它回答的问题是系统这一时刻的状态经过一个采样周期之后会跑到哪里去换句话说它就是系统动态行为在时间维度上的“预言机”。这篇文章我打算把状态转移矩阵在离散控制系统中的应用讲透从它到底是什么、为什么离散系统离不开它到手算和代码实现的具体方法再到一个完整的电机转速控制例子最后是这些年我在项目中踩过的几个深坑。适合正在学现代控制理论的学生、刚入门嵌入式控制算法的工程师以及想把手里的连续控制器改成离散实现的从业者。内容不堆公式但关键推导我也会给毕竟这玩意儿只看定性理解的话碰到实际问题还是容易翻车。1. 先搞清楚状态转移矩阵到底在解决什么问题1.1 从“下一时刻状态怎么算”说起先看连续系统最常见的形式x(t) A·x(t) B·u(t)这里的 x(t) 是状态向量u(t) 是输入向量A 是系统矩阵B 是输入矩阵。如果给定初始状态 x(t0)在输入已知的情况下任意时刻 t 的状态可以写成x(t) Φ(t - t0)·x(t0) ∫[t0, t] Φ(t - τ)·B·u(τ) dτ其中 Φ(t) e^(A·t)就是连续系统的状态转移矩阵。它本质上是一个矩阵指数作用就是把“初始状态”搬运到“未来的某个时刻”。到了离散控制系统情况变成x(k1) G·x(k) H·u(k)这里 k 是采样序号G 是离散系统矩阵H 是离散输入矩阵。跟连续系统对比就能发现离散系统里天然就有一个“状态转移”的概念从第 k 拍状态推导第 k1 拍状态。而 G 本质上就是从连续系统转移矩阵在采样时刻 T 处的取值G Φ(T) e^(A·T)输入矩阵 H 则是把连续时间内的输入作用“累积”到一个采样周期上H ∫[0, T] e^(A·τ) dτ · B看到这里你就明白离散控制系统里的状态转移矩阵其实不是一个“多余的数学概念”它就是连接连续世界和离散世界的桥梁。你在实际工程中用单片机或者 DSP 实现控制算法本质上是在跑这个离散版本而不是直接解微分方程。1.2 为什么离散系统里状态转移矩阵这么关键我做嵌入式控制算法这些年一个很深的体会是很多工程师能熟练写出 PID 的离散形式但一碰到状态空间就发怵因为搞不清楚离散矩阵 G、H 到底怎么来的。实际上G 和 H 就是从状态转移矩阵推导出来的这直接决定了离散模型是否准确。它有几层实际意义状态预测。有了 G 和 H你可以不通过仿真软件直接在代码里递归推算系统未来几个周期的状态。这个在模型预测控制MPC里是最基本的操作。稳定性判断。离散系统的稳定性看的是 G 的特征值是否都在单位圆内。而 G 的特征值又等于连续系统特征值经过 e^(λ·T) 映射之后的结果。能控性与能观性分析。很多人在做观测器设计时直接拿连续系统的能观性矩阵说事儿这其实是错的。离散系统必须使用自己的能控性矩阵P [H, G·H, G²·H, ..., G^(n-1)·H]以及能观性矩阵Q [C; C·G; C·G²; ...; C·G^(n-1)]这些矩阵都建立在状态转移矩阵的基础上。如果你 G 算错了后面全白搭。我见过一个实际案例有人把一个连续系统直接做前向欧拉离散化G I A·T在采样周期较大时系统模型严重失真设计的控制器上电后发散。原因就是前向欧拉只是状态转移矩阵的一阶近似只在小采样周期时有效。这就是没搞懂状态转移矩阵到底承载了多少信息导致的。2. 状态转移矩阵的计算不止一种方法关键看场景2.1 拉普拉斯反变换法基础但必须会连续状态转移矩阵的标准定义是 Φ(t) e^(A·t)而矩阵指数最经典的计算方式之一是通过拉普拉斯反变换Φ(t) L^(-1)[(s·I - A)^(-1)]其中 (s·I - A)^(-1) 被称为预解矩阵。这个方法的手算过程并不复杂拿一个二阶系统举例假设系统矩阵A [[0, 1], [-20, -4]]先算 s·I - As·I - A [[s, -1], [20, s4]]求逆后得到(s·I - A)^(-1) 1/(s² 4s 20) · [[s4, 1], [-20, s]]分母写成 (s2)² 16然后逐项做拉普拉斯反变换就能得到Φ(t) e^(-2t)·[[cos(4t) - 0.5·sin(4t), 0.25·sin(4t)], [-5·sin(4t), cos(4t) 0.5·sin(4t)]]这个方法适合低阶系统尤其考试或者快速手算场景很实用。但系统阶数一高四阶以上手算就很不现实了。工程上更常用的其实是后面这几种数值方法。2.2 凯莱-哈密顿定理法二阶系统的最优解凯莱-哈密顿定理说矩阵 A 满足它自己的特征多项式。也就是说如果 A 的特征多项式是λ^n a_(n-1)·λ^(n-1) ... a1·λ a0 0那么 A^n a_(n-1)·A^(n-1) ... a1·A a0·I 0。这个定理的直接推论是任何 A 的高次幂都能用 A 的 0 到 n-1 次幂线性表示。因此矩阵指数 e^(A·t) 也可以写成e^(A·t) α0(t)·I α1(t)·A α2(t)·A² ... α_(n-1)(t)·A^(n-1)然后利用 A 的特征值 λi 代入这个关系得到一组线性方程e^(λi·t) α0 α1·λi α2·λi² ... α_(n-1)·λi^(n-1)解这组方程得到 α0 到 α_(n-1)代回原式即可。这个方法在二阶系统里特别好用因为只有两个系数需要求解。比如上面那个 A 矩阵特征值 λ -2 ± 4j于是e^(-2t)·(cos(4t) j·sin(4t)) α0 α1·(-2 4j) e^(-2t)·(cos(4t) - j·sin(4t)) α0 α1·(-2 - 4j)解出 α0 和 α1然后代回 e^(A·t) α0·I α1·A得到的结果和拉普拉斯反变换法一致。2.3 数值方法与代码实现工程师的日常工程中大部分时候你是拿不到漂亮的解析解的系统的 A 矩阵可能是七八阶甚至更高参数还随工况变化。这时候数值计算就是唯一出路。最直接的方式是直接调用现成工具库计算矩阵指数。在 Python 里我用得最多的是 SciPy 的scipy.linalg.expm它内部使用的是 Pade 近似 缩放平方法数值稳定性很高。import numpy as np from scipy.linalg import expm A np.array([[0, 1], [-20, -4]]) T 0.01 # 采样周期单位秒 G expm(A * T) print(离散系统矩阵 G \n, G)这里expm(A * T)计算的是 e^(A·T)就是采样时刻的状态转移矩阵。这段代码输出的结果跟你用解析法算完再把 t T 代入数值几乎完全一致。我实测过二阶系统误差在 1e-12 级别。H 的计算稍微绕一点要算这个积分H ∫[0, T] e^(A·τ) dτ · B这个积分可以直接用增广矩阵法来处理构造一个分块矩阵M [[A, B], [0, 0]]然后计算 e^(M·T)其右上角的分块恰好就是 ∫[0, T] e^(A·τ) dτ · B。代码实现如下A np.array([[0, 1], [-20, -4]]) B np.array([[0], [1]]) # 构建增广矩阵 n A.shape[0] M np.block([[A, B], [np.zeros((1, n)), np.zeros((1, 1))]]) M_exp expm(M * T) # 右上角 n x n_input 的块就是 H H M_exp[:n, n:] print(离散输入矩阵 H \n, H)这个方法既准确又好写比手工积分强太多。我强烈建议你在项目里用这个方案。如果项目运行环境没有 SciPy必须自己写算法我建议用缩放平方法加 Pade 近似。基本思路是先将矩阵 A 缩放即令 Â A / 2^s使得 ||Â|| 足够小然后计算 e^(Â) 的 Pade 近似再反复平方 s 次恢复。这个方法的数值稳定性和精度都远好于粗暴的泰勒展开。还有个很坑的点我单独提一下不要直接用 A 的泰勒展开前几项来近似 e^(A·T)除非你非常确定采样周期足够小、且系统特征值的模足够小。跨一步说很多人做嵌入式实现时特别爱用一阶近似 G ≈ I A·T这在小采样周期下问题不大但在采样周期跟系统时间常数接近时这个近似会带来不可接受的模型误差最终控制器参数全都会偏。可以给不同方法做个对比方便你在实际项目里快速选择方法适用场景优点缺点拉普拉斯反变换低阶系统、教学推导解析解直观结果精确高阶系统手算复杂度爆炸凯莱-哈密顿定理二阶、三阶系统不需要积分代数运算清晰算特征值本身可能麻烦数值解expm任意阶数、工程实现精度高、稳定、代码简单需要依赖库嵌入式里要自己移植一阶欧拉近似采样周期极小的情况实现最简单模型误差随 T 增大急剧增加从我的经验看做产品级的控制系统除非你采样频率比系统带宽高 20 倍以上否则不要用一阶欧拉。优先用 expm 或者增广矩阵法把离散模型搞准了控制设计才有意义。3. 离散控制系统中状态转移矩阵的完整应用步骤3.1 建模、离散化、参数对齐一个都不能少拿到一个实际的物理系统第一步是建立连续状态方程。这个大家都熟难点往往在两点一是如何把物理参数准确折算到 A 和 B 矩阵里二是如何选择合适的采样周期。采样周期的选择理论上的参考依据是香农采样定理但在控制实践中更常参考闭环带宽。经验法则是采样频率应为闭环带宽的 10 到 20 倍。举个例子你设计了一个带宽 50 rad/s 的速度环采样频率至少取 500 到 1000 Hz也就是采样周期 T 在 1 到 2 ms 之间。采样周期定下来之后接着就是计算离散模型的 G 和 H。参考上一节的数值方法这一步在 Python 里本身就是几行代码的事。但我要提醒你这里的计算必须在目标采样周期的准确数值上进行不要拿一个大概的数去算因为 G 是 T 的指数函数T 差 0.5 msG 可能差出 5% 甚至更多。离散化完成之后建议做一次模型验证。最常用的做法是给连续系统和离散系统施加相同的输入信号比较两者在采样时刻的状态输出。差异应该在 1% 以内才算合理。如果差异大优先检查 T 是否过大或者离散化过程有没有出错。3.2 用状态转移矩阵做状态预测与系统分析离散系统矩阵 G 一旦确定系统的大部分特性就已经定了。这里重点讲三件事。第一是状态预测。给定当前状态 x(k)、当前输入 u(k)下一拍状态就是x(k1) G·x(k) H·u(k)这在代码里就是一个矩阵乘法。我做过一个无传感器速度观测器项目在 DSP 里以 10 kHz 的采样频率跑这个预测方程单次计算的耗时在微秒级别实时性完全没有压力。第二是稳定性分析。看 G 的特征值是否都在单位圆内。可以用numpy.linalg.eigvals(G)快速检查。这里有个工程经验如果所有特征值的模都小于 0.95说明系统收敛速度足够快如果某个特征值模非常接近 1系统就会有很长的拖尾响应。第三是能控性和能观性。离散能控性矩阵的秩应该等于系统阶数。我见过一个常见的错误很多人直接构造连续系统的能控性矩阵 [B, AB, A²B, ...]然后拿它来分析离散系统。这不对必须用离散的 G 和 H 构造P [H, G·H, G²·H, ..., G^(n-1)·H]原因是连续系统中两个采样时刻之间的状态转移可能让某些方向变得不可控。采样过程本身会改变系统的可控可观结构这个在采样周期选取不当的时候尤其明显。3.3 状态反馈控制器和观测器的设计实现状态转移矩阵最核心的应用场景之一就是状态反馈控制器的设计。假设系统完全能控我们可以设控制率为u(k) -K·x(k)闭环系统变为x(k1) (G - H·K)·x(k)K 的设计目标就是让闭环矩阵 G - H·K 的特征值落在期望的位置。距离实际工程最近、也最常用的方法是 LQR它通过最小化性能指标J Σ (x^T·Q·x u^T·R·u)来求解最优的 K。在 Python 里可以用python-control库的control.dlqr直接算import control as ct K, S, E ct.dlqr(G, H, Q, R)这里的核心输入就是离散模型 G 和 H而 G、H 又来自状态转移矩阵。所以你会发现整个设计链路的第一环就是状态转移矩阵的准确计算。如果系统状态不能全部直接测量就需要设计状态观测器。观测器的形式是x̂(k1) G·x̂(k) H·u(k) L·(y(k) - C·x̂(k))L 的设计同样是极点配置问题只不过针对的是 G - L·C 的特征值。一般来说观测器极点的收敛速度要比控制器极点的收敛速度快 3 到 5 倍这样估计误差才会快速收敛不会影响闭环主导动态。我自己实现观测器时的经验是L 矩阵一定不要盲目取大增益。增益太大测量噪声会被放大实际表现反而变差。要在收敛速度和噪声抑制之间找一个折中点这个点通常需要通过仿真和实测联合标定。4. 实现中的常见坑和排查经验4.1 采样周期和矩阵离散化精度之间的博弈先说一个我踩过的大坑。有一年我给一个液压伺服系统做位置控制系统本身动态很快油液的等效刚度很高连续模型的特征值模长到了几百的量级。我当时为了追求控制频率把采样周期设到了 0.2 ms然后图省事用了前向欧拉离散化。结果就是模型预测的状态和实际系统的输出差了很远控制器设计出来之后实际一跑就震荡。后来排查了半天发现问题根本不在控制器而是在离散化这一步。前向欧拉的近似误差在特征值模长大的系统里被急剧放大必须改用精确计算的状态转移矩阵。从那以后我的经验是采样周期不能只看控制带宽需求还要反过来检查系统开环特征值的模长和 T 的乘积。如果 ||A||·T 明显大于 0.1 到 0.2一阶近似就不可靠了。这时候要么减小 T要么老老实实用 expm 计算精确离散模型。4.2 数值计算精度矩阵指数不是简单的幂级数矩阵指数计算中最经典的坑就是直接用泰勒级数截断e^(A) ≈ I A A²/2! A³/3! ...如果 ||A|| 很大这个级数的收敛速度会非常慢要取很多项才能达到足够的精度。而且在累加过程中正负项可能产生灾难性抵消精度反而更差。这就是为什么scipy.linalg.expm内部使用缩放平方法加 Pade 近似而不是暴力泰勒展开。如果你在嵌入式平台手写矩阵指数也需要先缩放后平方。还有一个跟精度相关的细节计算 G 的时候有些工程师会直接先算 expm(A*T)再算积分H np.linalg.solve(A, G - np.eye(n)) B这个公式在 A 可逆时是准确的因为∫[0, T] e^(Aτ) dτ A^(-1)(e^(A·T) - I)但如果 A 接近奇异甚至奇异求解 A^(-1) 就有数值稳定性问题。这时建议用增广矩阵法直接通过 expm 计算左上角分块绕开矩阵求逆。我实测下来增广法在 A 奇异时依然稳定是更可靠的方案。4.3 代码实现中的矩阵维度与索引陷阱在实际工程里代码错误往往来自维度不匹配和索引顺序问题。一个常见错误是 G 和 H 的维度不匹配。G 是 n×nH 是 n×mK 是 m×n。如果状态向量定义顺序变了G、H 没跟着变矩阵乘法就会直接报错。这个问题在从仿真环境迁移到嵌入式平台时特别容易出因为仿真里你可能用了别人封装好的函数维度错误被隐藏了。另一个坑是采样时刻的对齐。在实际控制代码里状态更新的时刻必须和 ADC 采样时刻严格同步。我遇到过采样延迟一个周期导致控制器完全失效的情况——不是算法错了而是状态转移矩阵假设的“当前状态”和实际代码里的“当前状态”差了整整一拍。解决方法是把预测步和更新步严格分开在代码里用注释和命名明确区分“上一拍状态”“预测状态”“校正后状态”。最后是数据类型的问题。嵌入式环境里你可能用的是 float32而仿真环境是 float64。矩阵 G 本身元素接近 1float32 的有效数字大约是 7 位遇到特征值模很接近 1 的系统反复迭代几千步之后状态误差就会积累到一个不可接受的程度。所以如果系统收敛很慢建议关键累加变量用 double或者做定点 Q 格式时留足够的整数位和小数位余量。4.4 常见问题速查表现象可能原因排查思路仿真稳定但实际发散离散模型不准确检查 G、H 的计算方式是否用了过大的采样周期或一阶近似状态预测总是差一拍采样时刻不同步核对 ADC 采样与实际控制更新的时序矩阵求逆报奇异A 矩阵接近奇异改用增广矩阵法计算 Hfloat32 下状态漂移数值精度不足关键累加量改用 double能控性矩阵秩不足采样周期与系统特性不匹配尝试减小 T或重新分析连续系统能控性5. 一个完整案例直流电机转速控制系统的离散实现5.1 系统建模与参数设定这个例子我用直流电机速度控制来走一遍完整流程。选这个系统是因为它简单直观但包含了状态转移矩阵应用的所有关键步骤。直流电机的状态方程可以写成x [θ, ω]^T其中 θ 是电机转角ω 是角速度。输入 u 是电枢电压。忽略电枢电感电气时间常数远小于机械时间常数后系统矩阵为A [[0, 1], [0, -b/J]] B [[0], [K_t/J]]取一组实际参数转动惯量 J 0.01 kg·m²粘性摩擦系数 b 0.1 N·m·s转矩常数 K_t 0.01 N·m/A代入得到A [[0, 1], [0, -10]] B [[0], [1]]5.2 计算离散状态转移矩阵采样周期我取 T 0.01 秒也就是控制频率 100 Hz。先手推解析解。由于 A 是上三角可以求出e^(A·T) [[1, 0.1·(1 - e^(-10T))], [0, e^(-10T)]]代入 T 0.01G [[1, 0.000952], [0, 0.9048]]输入矩阵H ∫[0, 0.01] e^(A·τ) dτ · B [[0.01 - 0.01·(1 - e^(-0.1))], [0.1·(1 - e^(-0.1))]]数值约为H [[0.0000484], [0.00952]]两种方式对比验证一下import numpy as np from scipy.linalg import expm A np.array([[0, 1], [0, -10]]) B np.array([[0], [1]]) T 0.01 G expm(A * T) n A.shape[0] M np.block([[A, B], [np.zeros((1, n)), np.zeros((1, 1))]]) M_exp expm(M * T) H M_exp[:n, n:] print(G) print(H)输出结果与手推解析解一致误差在 1e-13 级别。5.3 极点配置控制器设计我希望闭环系统带宽大概在 5 rad/s 左右阻尼比 0.8。对应的连续域期望极点是s -4 ± 3j转换到离散域z e^(s·T) e^(-0.04 ± 0.03j) ≈ 0.9608 ± 0.0288j然后用极点配置函数计算 Kfrom scipy.signal import place_poles poles [0.9608 0.0288j, 0.9608 - 0.0288j] result place_poles(G, H, poles) K result.gain_matrix print(K , K)得到的 K 大概是K [[33.5, 2.8]]也就是说控制律u(k) -33.5·θ(k) - 2.8·ω(k)这个结果其实挺直观位置误差权重高速度反馈提供阻尼。5.4 仿真验证与代码实现最后做闭环仿真验证状态转移矩阵驱动下的系统行为import matplotlib.pyplot as plt x np.array([[0.5], [0.0]]) # 初始位置 0.5 rad初始速度 0 T_sim 1.0 steps int(T_sim / T) xs [] us [] for k in range(steps): x x.flatten() u -K x u float(np.clip(u, -10, 10)) # 限幅 x_new G x H np.array([u]) xs.append(x_new) us.append(u) x x_new.copy() xs np.array(xs) plt.plot(np.arange(steps) * T, xs[:, 0], labelangle) plt.plot(np.arange(steps) * T, xs[:, 1], labelvelocity) plt.legend() plt.xlabel(Time (s)) plt.ylabel(State) plt.show()整个仿真过程里最核心的迭代就是 x(k1) G·x(k) H·u(k) 这个式子而 G、H 都来自状态转移矩阵在采样时刻的取值。这也再次说明这一步算准了后面的控制器设计和仿真才有可信度。实际工程中你还需要考虑限幅、抗饱和、滤波器等因素但那是另一个话题了。单从状态转移矩阵的角度看整个链路从建模、离散化、设计到仿真验证已经完整走通了。6. 我的实际体会做了这么多年控制系统我最大的感受是状态转移矩阵不是一个停留在课本上的数学概念它直接决定了离散控制算法在实际硬件上跑起来之后的表现。很多人觉得这东西难其实难点不在矩阵指数本身而在“什么时候用哪种计算方法”“采样周期和模型精度之间怎么权衡”“代码实现时怎么避免维度、时序、精度这些低级错误”。如果你正在做控制算法的工程落地建议在最开始就把离散模型的验证纳入流程花十分钟检查一下 G、H 是否和连续系统行为一致后面能省出好几个晚上的调试时间。另外手边常备一个能算 expm 的脚本无论是 Python 还是 MATLAB都比任何时候手推计算器来得可靠。状态转移矩阵这个地基打牢了无论是状态反馈、观测器还是 MPC你都会顺手很多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。