第二节 控制理论基础回顾:传递函数、状态空间、稳定性、能控能观性及其在代码实现中的意义

控制理论是控制算法工程实现的基石。无论是PID参数整定、MPC预测控制,还是LQR最优控制,其底层逻辑都源于对系统模型的数学描述与分析。本节将系统回顾传递函数、状态空间、稳定性、能控性与能观性五大核心概念,并重点剖析这些概念在嵌入式代码、仿真建模与算法优化中的具体映射关系。理解这些理论如何转化为代码中的数据结构、判断条件与算法边界,是避免“调参靠运气、上线出事故”的关键前提。

控制理论核心概念与代码实现映射关系图 控制理论基础 传递函数 G(s) 频域模型:极点/零点/增益 代码意义:滤波器系数、 差分方程、z变换离散化 状态空间 (A,B,C,D) 时域模型:状态向量/输入/输出 代码意义:矩阵运算、 离散化、观测器设计 稳定性 极点位置/李雅普诺夫/增益裕度 代码意义:数值发散检查、 饱和处理、抗积分饱和 能控性 / 能观性 秩判据/卡尔曼分解 代码意义:状态估计可行性、 传感器配置合理性 代码实现:离散化 → 矩阵运算 → 边界保护 → 实时诊断

上图展示了控制理论四大核心概念与代码实现之间的映射关系。在实际工程中,传递函数与状态空间是两种等价的系统描述方式,但各自适用于不同的分析场景;稳定性是系统能否安全运行的前提;能控性与能观性则决定了控制器与观测器设计的可行性。下面逐一展开。

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°,需通过前馈补偿修正。

风险提示:离散化时若采样频率与陷波频率之比小于 10,双线性变换会产生频率畸变,需进行预畸变修正。此外,差分方程中的历史状态变量(x_prev1 等)在系统启动时必须初始化为 0,否则会出现瞬态冲击。

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 内恢复平衡。关键点在于状态向量的准确获取,这依赖于下文将讨论的能观性与观测器设计。

经验提醒:状态空间模型的数值条件数直接影响控制精度。若 A 矩阵特征值差异过大(如快慢模态相差 100 倍以上),建议对状态变量进行归一化或采用奇异摄动降阶处理,避免矩阵运算中的数值误差。

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%。

总结复盘:能控性与能观性分析应在系统设计阶段完成,而非等到代码实现后。若发现系统不完全能控,需调整执行器配置;若不完全能观,需增加传感器或改变测量点。在代码中,可通过在线计算能观性 Gramian 的条件数来动态评估观测器性能,但需注意计算开销,建议离线计算并查表。

2.5 理论到代码的完整映射与常见误区

核心原理

控制理论到代码实现并非简单的公式翻译,而是涉及离散化、数值精度、实时性、鲁棒性等多方面的系统工程。下表总结了核心概念在代码中的典型映射关系:

理论概念代码实现载体关键参数/函数常见错误
传递函数差分方程系数b[], a[] 数组系数未归一化、离散化方法不当
状态空间矩阵乘法函数Ad, Bd, Cd, Dd矩阵维度错误、未处理稀疏性
稳定性饱和函数、限幅器、NaN检查clamp(), isfinite()忽略积分饱和、未检测数值发散
能控性控制律设计(LQR/极点配置)K 矩阵未验证能控性矩阵秩
能观性观测器/卡尔曼滤波L 矩阵/Kalman增益传感器噪声协方差设置不合理

常见误区与规避策略

  • 误区一:认为连续域设计可直接用于离散代码。实际上,采样延迟、零阶保持器效应会改变系统相位,需在设计中预留相位裕度。
  • 误区二:忽视定点数精度。在定点 MCU 上,矩阵乘法中的中间结果可能溢出,需使用 Q 格式或混合精度策略。
  • 误区三:将稳定性分析视为一次性任务。参数漂移、老化、环境变化都会影响稳定性,代码中应包含在线稳定性监测。
  • 误区四:混淆能控性与能达性。能达性要求状态从零到达任意状态,而能控性要求从任意状态回到零,两者在连续系统中等价,但在离散系统中可能不同。
工程建议:在代码架构中,将控制算法与硬件驱动分离。控制算法模块接收标准化的状态向量与输出指令,内部完成离散化、矩阵运算、限幅保护等操作。这样便于在仿真环境(如 Simulink、Python)中复用同一套算法代码,实现模型在环(MIL)测试,大幅减少现场调试时间。