第二节 控制理论基础回顾:传递函数、状态空间、稳定性、能控能观性及其在代码实现中的意义
控制理论是控制算法工程实现的基石。无论是PID参数整定、MPC预测控制,还是LQR最优控制,其底层逻辑都源于对系统模型的数学描述与分析。本节将系统回顾传递函数、状态空间、稳定性、能控性与能观性五大核心概念,并重点剖析这些概念在嵌入式代码、仿真建模与算法优化中的具体映射关系。理解这些理论如何转化为代码中的数据结构、判断条件与算法边界,是避免“调参靠运气、上线出事故”的关键前提。
上图展示了控制理论四大核心概念与代码实现之间的映射关系。在实际工程中,传递函数与状态空间是两种等价的系统描述方式,但各自适用于不同的分析场景;稳定性是系统能否安全运行的前提;能控性与能观性则决定了控制器与观测器设计的可行性。下面逐一展开。
2.1 传递函数:频域视角与离散化实现
核心原理
传递函数 G(s) 是线性时不变系统在零初始条件下,输出拉普拉斯变换与输入拉普拉斯变换之比。它用极点、零点和增益三个要素完整描述系统的动态特性。极点决定系统的自然响应模态(衰减速度与振荡频率),零点影响各模态的权重,增益则缩放整体幅值。在频域中,传递函数还直接对应系统的幅频特性与相频特性,是频域设计(如陷波器、低通滤波器)的基础。
从连续域到离散代码
在数字控制器中,连续传递函数必须离散化为差分方程。常用方法包括:前向欧拉法、后向欧拉法、双线性变换(Tustin)和零极点匹配法。以双线性变换为例,将 s 替换为 (2/Ts)·(z-1)/(z+1),其中 Ts 为采样周期。离散化后得到 z 域传递函数,再通过逆 z 变换得到可直接在 MCU 中循环执行的差分方程。
// 示例:二阶低通滤波器离散化(双线性变换)
// 连续域:G(s) = wc^2 / (s^2 + 2*zeta*wc*s + wc^2)
// 采样周期 Ts = 0.001s,wc = 100 rad/s,zeta = 0.707
float b0 = 0.0098, b1 = 0.0196, b2 = 0.0098;
float a1 = -1.7647, a2 = 0.8039;
float x_prev1 = 0, x_prev2 = 0, y_prev1 = 0, y_prev2 = 0;
float filter_update(float input) {
float y = b0*input + b1*x_prev1 + b2*x_prev2 - a1*y_prev1 - a2*y_prev2;
x_prev2 = x_prev1; x_prev1 = input;
y_prev2 = y_prev1; y_prev1 = y;
return y;
}
代码中的 b0、b1、b2、a1、a2 即为离散化后的系数。这些系数对数值精度极其敏感,在定点 MCU 上需特别注意量化误差。建议使用浮点运算或 Q15/Q31 定点格式,并在仿真中验证离散化后的频率响应与连续域的一致性。
实战场景:电机电流环陷波器设计
某伺服驱动器在 2kHz 处存在机械谐振,导致电流环啸叫。工程师在连续域设计陷波器 G(s) = (s² + ωn²) / (s² + 2·ζ·ωn·s + ωn²),其中 ωn = 2π·2000 rad/s,ζ = 0.1。采样周期 Ts = 50μs。采用双线性变换离散化后,在代码中实现该陷波器。实测结果显示,2kHz 处增益衰减 25dB,啸叫消除,但相位滞后在 1kHz 处增加约 8°,需通过前馈补偿修正。
2.2 状态空间:时域建模与矩阵运算
核心原理
状态空间模型用一阶微分方程组描述系统:ẋ = Ax + Bu,y = Cx + Du。其中 x 为 n 维状态向量,u 为 m 维输入向量,y 为 p 维输出向量。A 为系统矩阵,B 为输入矩阵,C 为输出矩阵,D 为直通矩阵。状态空间模型不仅能描述输入输出关系,还能揭示系统内部状态的变化规律,是多变量系统、非线性系统线性化、观测器设计的基础。
离散化与代码实现
连续状态空间方程需离散化为 x[k+1] = Ad·x[k] + Bd·u[k],y[k] = Cd·x[k] + Dd·u[k]。离散化方法包括精确离散化(矩阵指数)和近似离散化(欧拉法)。精确离散化公式为 Ad = e^(A·Ts),Bd = ∫₀^Ts e^(A·τ)·B dτ。在代码中,Ad 和 Bd 通常预先计算并存储为常量矩阵,运行时仅执行矩阵乘法。
// 示例:一阶惯性系统状态空间离散化
// 连续域:dx/dt = (-1/T)*x + (K/T)*u, y = x
// 参数:T = 0.1s, K = 2, Ts = 0.01s
float Ad = 0.9048; // e^(-0.01/0.1)
float Bd = 0.1903; // K*(1 - e^(-Ts/T))
float x_state = 0;
float state_update(float u) {
x_state = Ad * x_state + Bd * u;
return x_state; // y = x
}
矩阵运算在代码中需注意维度匹配与内存布局。对于嵌入式系统,建议使用静态二维数组而非动态分配,并利用矩阵的稀疏性优化乘法次数。若状态维数较高(n>10),可考虑使用线性代数库(如 Eigen、Armadillo)或手写优化的矩阵乘法。
案例拆解:倒立摆状态反馈控制
考虑一阶倒立摆系统,状态向量 x = [位置, 速度, 角度, 角速度]ᵀ。通过线性化得到 A、B 矩阵。设计 LQR 控制器 u = -K·x,其中 K 为反馈增益矩阵。在代码中,每个控制周期执行以下步骤:读取编码器与 IMU 数据 → 构造状态向量 → 计算控制量 u = -K·x → 输出 PWM。实测中,LQR 控制使倒立摆在 ±10° 扰动下 1.5s 内恢复平衡。关键点在于状态向量的准确获取,这依赖于下文将讨论的能观性与观测器设计。
2.3 稳定性:从理论判据到代码保护
核心原理
稳定性是控制系统最基本的要求。对于线性时不变系统,渐近稳定的充要条件是系统矩阵 A 的所有特征值(或传递函数的所有极点)均具有负实部。在离散域中,要求所有极点位于单位圆内。工程上还常用李雅普诺夫第二法、奈奎斯特判据、增益裕度与相位裕度等工具分析稳定性。
代码中的稳定性保护
理论上的稳定性分析在代码实现中面临数值误差、非线性饱和、参数漂移等挑战。因此,工程代码必须包含以下保护机制:
- 数值发散检测:定期检查状态变量或输出是否超出合理范围(如 NaN、Inf、值超限),一旦异常立即切换至安全模式。
- 抗积分饱和:在 PID 控制器中,积分项需限制在 [min, max] 区间,防止 windup 导致大幅超调。
- 输出限幅与变化率限制:控制量输出需经过饱和函数,并限制每周期最大变化量,避免执行器冲击。
- 极点监控:在自适应控制或在线辨识中,实时计算离散极点的模长,若超出单位圆则冻结参数更新。
// 抗积分饱和示例(PID控制器)
float integral = 0;
float integral_limit = 10.0f;
float pid_update(float error, float kp, float ki, float kd, float dt) {
integral += error * dt;
// 积分限幅
if (integral > integral_limit) integral = integral_limit;
if (integral < -integral_limit) integral = -integral_limit;
float derivative = (error - error_prev) / dt;
error_prev = error;
return kp*error + ki*integral + kd*derivative;
}
实战场景:无人机姿态控制稳定性调试
某四旋翼无人机在悬停时出现低频振荡(约 2Hz)。通过分析姿态环的传递函数,发现角速度环的相位裕度仅 18°,低于 30° 的安全阈值。工程师在代码中增加了角速度环的低通滤波器(截止频率 30Hz),将相位裕度提升至 42°,振荡消除。同时,在代码中加入输出变化率限制(最大 30%/ms),防止执行器饱和引发二次振荡。
2.4 能控性与能观性:系统能力的边界
核心原理
能控性(Controllability)指系统状态能否在有限时间内由任意初始状态转移到任意目标状态,其判据为能控性矩阵 Qc = [B, AB, A²B, ..., Aⁿ⁻¹B] 满秩。能观性(Observability)指能否通过有限时间内的输出测量值唯一确定系统初始状态,其判据为能观性矩阵 Qo = [C; CA; CA²; ...; CAⁿ⁻¹] 满秩。这两个性质决定了控制器与观测器设计的可行性。
在代码实现中的意义
| 理论性质 | 代码实现中的意义 | 工程检查方法 |
|---|---|---|
| 能控性 | 若系统不完全能控,则某些状态模态无法通过输入影响,LQR/极点配置可能失败 | 计算能控性矩阵的秩,或在仿真中测试不同初始状态下的响应可达性 |
| 能观性 | 若系统不完全能观,则状态观测器(如卡尔曼滤波)无法收敛,状态反馈无法实施 | 检查传感器配置是否覆盖所有关键状态,或通过可观测性 Gramian 矩阵的条件数评估 |
| 冗余性 | 能控/能观性冗余可提高容错能力,但增加计算负担 | 在代码中实现传感器故障检测,动态切换观测器结构 |
案例拆解:基于卡尔曼滤波的电池 SOC 估计
某电池管理系统(BMS)需估计电池荷电状态(SOC)。建立二阶 RC 等效电路模型,状态向量 x = [SOC, V1, V2]ᵀ,其中 V1、V2 为两个 RC 网络的极化电压。测量输出为端电压 Vt。通过计算能观性矩阵,发现当电池处于静置状态(电流为 0)时,V1 和 V2 的能观性显著下降,导致 SOC 估计漂移。解决方案:在代码中增加静置检测逻辑,当电流小于 0.5A 持续 10s 时,将卡尔曼增益切换至低增益模式,并利用开路电压法修正 SOC。实测 SOC 估计误差从 8% 降至 3%。
2.5 理论到代码的完整映射与常见误区
核心原理
控制理论到代码实现并非简单的公式翻译,而是涉及离散化、数值精度、实时性、鲁棒性等多方面的系统工程。下表总结了核心概念在代码中的典型映射关系:
| 理论概念 | 代码实现载体 | 关键参数/函数 | 常见错误 |
|---|---|---|---|
| 传递函数 | 差分方程系数 | b[], a[] 数组 | 系数未归一化、离散化方法不当 |
| 状态空间 | 矩阵乘法函数 | Ad, Bd, Cd, Dd | 矩阵维度错误、未处理稀疏性 |
| 稳定性 | 饱和函数、限幅器、NaN检查 | clamp(), isfinite() | 忽略积分饱和、未检测数值发散 |
| 能控性 | 控制律设计(LQR/极点配置) | K 矩阵 | 未验证能控性矩阵秩 |
| 能观性 | 观测器/卡尔曼滤波 | L 矩阵/Kalman增益 | 传感器噪声协方差设置不合理 |
常见误区与规避策略
- 误区一:认为连续域设计可直接用于离散代码。实际上,采样延迟、零阶保持器效应会改变系统相位,需在设计中预留相位裕度。
- 误区二:忽视定点数精度。在定点 MCU 上,矩阵乘法中的中间结果可能溢出,需使用 Q 格式或混合精度策略。
- 误区三:将稳定性分析视为一次性任务。参数漂移、老化、环境变化都会影响稳定性,代码中应包含在线稳定性监测。
- 误区四:混淆能控性与能达性。能达性要求状态从零到达任意状态,而能控性要求从任意状态回到零,两者在连续系统中等价,但在离散系统中可能不同。