3、系统建模基础:状态空间模型与传递函数,如何为四旋翼建立预测模型

各位同学,欢迎来到第三章。前面我们聊了PID的局限,也画了MPC的大饼。但有个核心问题绕不开——你得先有个“模型”。

说白了,MPC不是拍脑袋控制,它是“算”出来的。算之前,你得告诉它:你的四旋翼长什么样,飞起来会怎么动。这就是系统建模。

我个人习惯把建模分成两步:先搞懂物理规律,再写成数学形式。今天我们就从最基础的传递函数,一路干到状态空间模型,最后告诉你——怎么给四旋翼搭一个能用的预测模型。

3.1 传递函数 vs 状态空间:到底选哪个?

很多初学者会纠结这个问题。我当年也纠结过。其实没那么玄乎,我一句话给你讲明白:

  • 传递函数:适合单输入单输出(SISO),只看输入输出关系,内部状态是黑箱。
  • 状态空间:适合多输入多输出(MIMO),能看到系统内部所有状态的变化。

四旋翼是什么?4个电机输入,6个自由度输出(位置x,y,z + 姿态roll,pitch,yaw)。典型的MIMO系统。所以——状态空间模型是必选项

核心结论:做四旋翼MPC,请直接上状态空间模型。传递函数可以作为理解基础,但别指望用它做预测控制。

3.2 从物理到数学:四旋翼的动力学方程

好,我们开始搭模型。先回忆一下四旋翼怎么飞的:

  • 四个电机,产生升力F1~F4
  • 总升力决定上下
  • 差动力矩决定姿态

嗯,这里要注意:四旋翼是个强耦合、非线性的系统。但MPC用的预测模型,通常要线性化。为什么?因为非线性MPC计算量太大,飞控芯片扛不住。

我在项目中遇到过这种情况:一开始想上非线性MPC,结果STM32H7算到冒烟,帧率掉到10Hz。后来老老实实线性化,跑50Hz稳稳的。

所以,我们先用牛顿-欧拉法写出完整动力学:

// 位置动力学(惯性系下)
m * p_ddot = [0, 0, -mg] + R * [0, 0, T]

// 姿态动力学(机体系下)
J * omega_dot = -omega × (J * omega) + tau

其中:

  • p = [x, y, z] 位置
  • R 是旋转矩阵(由欧拉角或四元数构成)
  • T 是总推力
  • J 是转动惯量矩阵
  • tau = [tau_phi, tau_theta, tau_psi] 是控制力矩

你看,这里有个R矩阵,里面全是sin和cos。这就是非线性的来源。

3.3 线性化:小角度假设

怎么处理非线性?最常用的方法——小角度假设

说白了,就是假设四旋翼在悬停或小幅度机动时,roll和pitch都很小(比如<15°)。这时候:

  • sin(θ) ≈ θ
  • cos(θ) ≈ 1
  • 旋转矩阵R可以简化

我曾经吃过这个亏:有一次做特技飞行测试,roll角直接干到60°,模型瞬间失效,MPC输出乱跳,飞机差点翻掉。所以——小角度假设只适用于悬停和慢速飞行,做特技得换模型。

线性化之后,我们可以把系统写成标准的状态空间形式:

x_dot = A * x + B * u
y = C * x + D * u

对于四旋翼,状态量通常选:

符号 含义 单位
x, y, z 位置 m
u, v, w 速度(机体系) m/s
φ, θ, ψ 欧拉角 rad
p, q, r 角速度 rad/s

控制量u通常是:

  • u1 = 总推力 T
  • u2 = roll力矩 tau_phi
  • u3 = pitch力矩 tau_theta
  • u4 = yaw力矩 tau_psi

3.4 离散化:让模型跑在芯片上

状态空间模型是连续的(x_dot)。但飞控是离散的(每隔dt算一次)。所以必须离散化。

最常用的方法是零阶保持法(ZOH)

A_d = expm(A * dt)
B_d = A^(-1) * (A_d - I) * B

嗯,这里要注意:expm是矩阵指数,不是逐元素exp。很多新手在这里写错。

我个人习惯用Python的scipy.signal.cont2discrete来做这一步,省得手算矩阵指数:

from scipy.signal import cont2discrete

# 连续系统
A = ...  # 12x12矩阵
B = ...  # 12x4矩阵

# 离散化,dt=0.02s (50Hz)
dt = 0.02
(A_d, B_d, C_d, D_d, _) = cont2discrete((A, B, C, D), dt, method='zoh')

离散化之后,预测模型就变成了:

x(k+1) = A_d * x(k) + B_d * u(k)

这就是MPC做预测的核心公式。给定当前状态x(k)和未来控制序列u(k), u(k+1), ...,你可以一步步算出未来状态。

3.5 画个图:四旋翼预测模型构建流程

说了这么多,我画个图帮你理清思路:

四旋翼预测模型构建流程 物理建模 牛顿-欧拉方程 线性化 小角度假设 状态空间 x_dot = Ax + Bu 离散化 ZOH / 欧拉法 预测模型 x(k+1)=A_d x(k)+B_d u(k) MPC优化器 滚动时域优化 反馈校正(状态更新) 关键:每一步都要做模型验证,别等飞起来才发现模型不对 ⚠ 常见坑:离散化步长选太大

3.6 避坑指南:建模时最容易犯的错

做建模这么多年,我踩过的坑能写一本书。挑几个最要命的跟你说:

坑1:忽略执行器动态

我曾经直接把电机转速当控制量,结果模型预测飞得挺好,实际飞起来抖成筛子。为什么?因为电机有响应延迟(一阶惯性环节),模型里没考虑。

解决办法:在B矩阵后面串一个执行器模型,比如:

u_real = (1 / (tau_motor * s + 1)) * u_cmd

坑2:离散化步长选太大

dt=0.05s(20Hz)?模型预测误差会大到离谱。四旋翼角速度响应很快,dt最好≤0.02s(50Hz)。

小技巧:模型建好后,先做开环仿真。给一个阶跃输入,看看响应曲线是否符合物理直觉。如果模型预测的上升时间跟实际差太多,赶紧回去检查参数。

3.7 总结:你需要记住的三件事

  1. 四旋翼MPC必须用状态空间模型,传递函数搞不定MIMO系统
  2. 线性化+离散化是工程标配,别想着上非线性MPC,除非你的芯片是i9
  3. 模型验证比建模本身更重要——我见过太多人花两周建模,却不愿意花两小时验证

好了,模型搭好了。下一章我们就要拿着这个模型,开始设计MPC控制器了。到时候你会看到,今天搭的每一个矩阵,都会变成优化问题里的约束条件。


公众号:蓝海资料掘金营,微信deep3321