尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Koopman-EDMD与LQR:四旋翼无人机数据驱动控制实践

Koopman-EDMD与LQR:四旋翼无人机数据驱动控制实践 简介非线性系统的分析与控制是工程领域长期面临的挑战传统小扰动线性化方法只在平衡点附近有效大机动工况下模型失准问题突出。Koopman算子理论通过将非线性动力学提升到高维线性空间为这一难题提供了新思路。EDMD扩展动态模态分解作为数据驱动辨识工具可直接从输入输出数据中构建Koopman矩阵避免复杂的机理建模。以四旋翼无人机为对象利用EDMD结合字典函数建立高维线性模型进而设计LQR控制器并引入积分项消除稳态误差实现大范围姿态跟踪与轨迹控制。该方法融合数据驱动与线性控制理论显著提升了强非线性系统的控制性能为无人机工程实践提供了可复现的解决路径。本文完整阐述了从数据生成、字典设计、模型辨识到闭环控制的实现细节并总结了常见问题与调试经验。 做四旋翼无人机控制这几年我越来越觉得“模型与控制”之间那道坎特别有意思。传统做法里非线性太强了就用反馈线性化、反步法要么把模型算得很精细要么控制律设计得极其复杂一旦参数漂移或者工况变了整套东西就跟着变脆。后来接触了 Koopman 算子理论再用 EDMD扩展动态模态分解在 Matlab 里把四旋翼的模型用数据驱动方式“提升”成高维线性系统整个设计思路一下就清爽了——非线性问题丢进高维空间变成线性问题然后用现成的 LQR 等线性工具处理。这篇文章想把从模型搭建、数据生成、EDMD 辨识到 LQR 闭环控制的完整链路、实现细节和踩坑点都写清楚适合理工科研究生、无人机方向工程师以及被非线性控制头疼折磨的同学参考。我不会只贴一堆现成结论而是把每一步“为什么这么设计”也一并讲透。你在复现过程中遇到问题也能在这篇文章里找到对应的排查思路。内容全部基于我在 Matlab 2022b 环境下的真实试验版本老一点或新一点都没关系核心逻辑不受影响。1. 为什么四旋翼控制要引入 Koopman-EDMD1.1 四旋翼模型的非线性痛点与线性化局限四旋翼无人机看着飞行姿态灵活其实动力学上是个不折不扣的强非线性系统。它的非线性主要来自几个方面姿态角与角速度之间的三角函数关系、旋转矩阵带来的惯性耦合、电机转速与推力之间的平方关系还有飞行时气动阻力、陀螺效应这些难精确建模的量。这些非线性项叠加在一起直接导致很多线性控制方法没法大范围使用。传统工程上最常用的做法是“小扰动线性化”在悬停平衡点附近做一阶泰勒展开得到线性状态空间模型然后套用 LQR、PID 或者 H∞ 这类成熟线性控制器。这个方法在悬停点附近很有效可一旦飞行器做大机动动作比如大角度俯仰、急加减速、偏航快速转向模型误差就会迅速放大控制性能跟着跳水。我自己做过一组对比悬停附近线性化模型的迎角响应在 5 度以内还行超过 20 度后开环预测轨迹基本偏离实际值一大截。另一种思路是反步法、滑模控制这类直接面向非线性模型的设计。它们对模型精度要求高控制律推导复杂参数整定也不直观。工程现场最怕的是“模型和实际对不上”桨叶磨损、载荷变化、电池电压下降引起的推力衰减都会让基于精确模型的控制器失效。数据驱动控制的优势就在这——它不依赖手推的物理模型而是直接从输入输出数据中学习系统的动态行为。1.2 Koopman 算子的核心思想换个视角看非线性Koopman 算子理论最早要追溯到 1931 年但直到近几年才在控制领域火起来。它的核心思想用一句话概括任何非线性动力学系统都可以被嵌入到一个无限维线性算子框架中。怎么理解这句话假设系统状态是 x非线性离散动力学方程是 x_{k1}F(x_k)。传统线性化是在状态空间中找一个局部的线性近似而 Koopman 的思路是不再直接观察状态 x而是观察 x 的某个标量函数 g(x)比如 x 的平方、x 的三次方、sin(x)、exp(x) 等等。系统在状态空间里的非线性演化在观测函数空间里就可以被一个线性算子 K 作用在 g 上来刻画也就是 (Kg)(x)g∘F(x)。对任意一个观测函数 gK 把 g 映到另一个观测函数 g这个映射本身是线性的。可以打个比方把非线性系统想象成一条在平面上弯弯曲曲的山路线性控制工具相当于在路面上做一条直线的近似只能覆盖一小段。而 Koopman 算子相当于把整条山路抬升到高维空间用一座高架桥从上方笔直穿过去桥上是直线的、线性的。问题是从桥面往下看路怎么走都是清晰的非线性被藏到了“抬升”这一步里。这里的代价是观测函数空间是无限维的。也就是说要用线性工具处理非线性系统必须处理一个无穷维线性系统。幸运的是我们并不需要全部的无穷维空间只要选取一组足够丰富的观测函数也就是字典把系统状态映射到一个高维但有限维的空间就能得到 Koopman 算子的一个有限维近似。1.3 EDMD从数据到 Koopman 矩阵的桥梁理论上 Koopman 算子是无限维的实际工程中怎么拿到它的有限维表示EDMDExtended Dynamic Mode Decomposition扩展动态模态分解是目前最主流的方法本质上是一个基于数据的最小二乘拟合问题。具体来说先选定一组基函数字典 ψ(x)[ψ_1(x), ψ_2(x), ..., ψ_N(x)]^T。然后采集系统的状态轨迹数据一对一对相邻时刻的状态快照 (x_k, x_{k1})。接着构造两个矩阵G (1/M) Σ ψ(x_k) ψ(x_k)^TA (1/M) Σ ψ(x_k) ψ(x_{k1})^T于是 Koopman 矩阵的有限维近似就是 K G^{-1} A。这个矩阵把一个时刻的提升状态 z_kψ(x_k) 映射到下一时刻 z_{k1}≈K z_k。算出来之后非线性系统的预测问题就变成了高维线性系统的预测问题LQR、MPC 这些工具直接可以用上。这个流程里最核心的变量是字典函数的选择和数据的质量。EDMD 的名字里带了个“扩展”就是因为相比早期的 DMD动态模态分解它不再局限于线性观测而是通过字典把系统提升到非线性观测空间从而使线性近似在大工作域内成立。我实测下来只要字典选得合适Koopman 模型在较大机动范围内的预测精度远优于小扰动线性化模型。2. 四旋翼动力学模型与仿真环境搭建2.1 刚体动力学方程与控制分配做数据驱动建模第一步得有足够可靠的被控系统数据。四旋翼的动力学方程分为运动学和动力学两部分。运动学描述位置、姿态与速度、角速度的关系动力学描述受力与加速度、力矩与角加速度的关系。常用简化模型选取状态变量为 x [p_x, p_y, p_z, φ, θ, ψ, v_x, v_y, v_z, ω_x, ω_y, ω_z]^T其中 (p_x, p_y, p_z) 为位置(φ, θ, ψ) 为滚转、俯仰、偏航角(v_x, v_y, v_z) 为机体速度ω 为机体角速度。控制输入通常取 u [T, τ_φ, τ_θ, τ_ψ]^T即总推力与三个轴的力矩。动力学方程可以写成线加速度m v_dot m g e_z R(φ, θ, ψ) [0,0,T]^T - 阻力项角加速度I ω_dot -ω × (I ω) τ其中 I 是惯量矩阵R 是旋转矩阵。这个方程包含了三角函数、叉乘和非线性惯性耦合是典型的非线性系统。控制分配部分四个电机转速 Ω_i 的平方与推力和力矩之间有固定映射矩阵将 T 和 τ 分配到各电机转速常用等比例分配矩阵。在 Matlab 里实现时我建议把动力学方程封装成一个函数输入当前状态与控制量输出状态导数再用 ode45 积分得到轨迹。注意这里的欧拉角在接近 ±90° 时会出现万向锁问题但四旋翼正常飞行姿态不会到那个范围作为数据生成和中等幅度机动验证是够用的。2.2 物理参数与仿真设定建模时我采用的是一组典型的小型四旋翼参数不算特别精确但足以验证算法链路。质量 m0.8 kg重力加速度 g9.81 m/s²机臂长度 l0.15 m惯量矩阵取对角形式 I_x0.005 kg·m²I_y0.005 kg·m²I_z0.009 kg·m²推力系数 c_T1.4e-5扭矩系数 c_M2.6e-7。这些参数单位必须保持统一我一开始就吃过单位不一致的亏算出来的 K 矩阵完全不对。仿真设置方面我把采样周期设为 0.02 s50 Hz与常见飞控传感器输出频率一致。仿真时长设定为 30 s生成的数据用于后续 EDMD 辨识。推进器模型考虑了一阶惯性环节模拟真实电机响应延迟实测下来这个延迟对辨识结果的影响很大不能省。数据生成时还需要给系统加一点测量噪声。实际传感器不可能输出完美数据加噪声还能顺带考察 Koopman 模型对噪声的鲁棒性。我用的是高斯白噪声位置和姿态通道的标准差设为相应量程的 1%速度通道设 2%这个比例大概能模拟 GPSIMU 融合后的水平。3. 基于 EDMD 的 Koopman 模型辨识完整流程3.1 激励信号设计数据质量决定模型上限做数据驱动建模最容易被低估的就是数据怎么采。EDMD 题目看起来线性回归很简单但模型能学到什么完全取决于你喂给它什么。系统从来没有展示过的运动范围模型必然预测不准。激励信号要做到“充分激励”。对四旋翼这类多输入多输出系统每个输入通道都要有足够丰富的频带覆盖。我最常用的方案是 chirp 扫频信号叠加多正弦外加少量随机白噪声。chirp 信号从 0.1 Hz 扫到 5 Hz覆盖了四旋翼主要的刚体模态白噪声保证高频段激励逐通道轮流扫同时保持其他通道小幅抖动这样可以避免输入耦合导致的辨识偏差。幅值选择也要讲究。四旋翼的姿态角机动范围我设在 ±25°速度机动范围 ±1 m/s。幅值太小的话系统主要在小范围内运动辨识出的模型还是偏局部幅值太大则容易触碰执行器饱和把非线性效应推到极限。我踩过坑一开始为了“探索充分”把姿态激励加到 ±45°结果电机转速进入饱和区数据里混入了严重的非线性失真K 矩阵估计出来根本没法用。后来把幅值控制在 ±25° 以内效果就好多了。采集数据的长度也很关键。一条 30 秒的数据量可以用来做初步辨识但要让模型在更大工作域内可靠我习惯把多个不同幅值、不同频率组合的试验数据拼接起来用数据集总时长拉到 60 到 90 秒。EDMD 对数据量的需求没有深度神经网络那么苛刻但数据“覆盖范围广”比“数量多”重要得多。3.2 字典提升函数的选择与参数设置EDMD 的核心机密全在字典函数 ψ(x) 里。字典选得好不好直接决定 Koopman 矩阵近似误差的下限。我试过三类字典多项式基比如 x_1、x_1²、x_1x_2、x_1³ 等。实现简单在光滑非线性系统上效果不错但阶数高了容易造成矩阵病态。三角函数基sin、cos、tanh 这类适合描述含周期或饱和特性的动力学。径向基函数RBF比如高斯核 exp(-||x-c||²/σ²)拟合能力强但中心点和带宽需要额外设置字典维度容易爆炸。实际项目里我比较推荐“多项式三角函数”的混合字典兼顾光滑非线性拟合和周期项刻画。对四旋翼状态量 12 个如果每个状态取到二阶项再补充少量交叉项和三角函数项字典维度大概在 40 到 60 之间。我最终用的是 52 维。维度不是越高越好太高了 G 矩阵容易近奇异最小二乘解对噪声极其敏感模型泛化能力反而下降。另外提醒一句字典里必须包含原始状态本身也就是至少要有一个恒等映射把状态 x 原样放进提升状态里。否则你后续做状态反馈控制时没法从提升状态中还原出真实状态。这个细节容易漏但一漏就是连环 bug。正则化也是必选项。EDMD 的 K G^{-1} A 如果直接用反斜杠求解在 G 条件数较大时会得到剧烈震荡的解。我通常加一个岭正则化项把求解改为 K (G λI)^{-1} A其中 λ 是个小量一般在 1e-6 到 1e-4 之间。需要根据条件数实际调整。这个操作对模型稳定性的提升非常明显。3.3 Koopman 矩阵求解与模型验证EDMD 的算法流程可以用下面这段 Matlab 代码概括% Psi: M x N 字典矩阵 % X: M x n 状态快照 % Yp: M x n 下一时刻状态快照 Phi dict(X); % 提升状态 z_k Psi dict(Yp); % 提升状态 z_{k1} G Phi * Phi / M; A Phi * Psi / M; K (G lambda * eye(N)) \ A;其中 dict 函数根据你选定的字典计算提升状态。我把字典函数单独写成一个脚本方便切换不同字典组合。注意矩阵规模不大时直接用密集矩阵没问题但如果字典维度超过 100 且数据量很大建议用稀疏矩阵或分块计算避免内存爆炸。模型辨识出来之后关键一步是验证。单步预测误差小不代表多步预测稳定很多 Koopman 模型会出现“短期精确、长期发散”的问题。我习惯做两个层面的验证一是开环多步预测。从某一初始状态出发用 K 矩阵连续递推 2 到 5 秒对比预测轨迹与实际仿真轨迹。四旋翼是高度不稳定的系统开环预测误差累积很快所以我更关注前 2 秒内的吻合度以及整体趋势是否一致。二是计算方差解释率VAFVariance Accounted For公式为 VAF (1 - ||y_pred - y_true||² / ||y_true - mean(y_true)||²) × 100%。80% 以上算合格90% 以上算良好。我调好的模型在姿态通道 VAF 能到 92% 左右位置通道稍低在 85% 左右。这个指标也可以用来对比不同字典的优劣比肉眼看图要客观。4. 基于 Koopman 模型的线性控制器设计4.1 在提升空间设计 LQRKoopman 模型的最大卖点是辨识完成后系统变成了线性的 z_{k1} K z_k B u_k但这个 B 矩阵怎么来EDMD 的扩展形式需要在辨识时同时考虑控制输入的影响。常见做法是把输入也纳入数据快照定义增广状态 x_aug [x^T, u]^T然后对增广系统做 EDMD。但这样会把输入也“提升”到非线性空间导致控制器设计时 u 的计算变复杂。更常用、也更好用的方案是分两段处理先用一组零输入或常值输入的数据辨识系统的零输入动态 K再通过额外的小幅脉冲实验估计输入矩阵 B。这样做的好处是控制通道的线性假设更干净LQR 设计也更直观。代价是 B 矩阵是局部的线性近似但在中等机动范围内足够用。在提升空间设计 LQR 时代价函数沿用线性二次型形式 J Σ (z^T Q z u^T R u)状态反馈控制率为 u -K_lqr z。这里 z 是 52 维的提升状态所以 Q 矩阵是 52×52 的。如何设 Q 是个难点不能像原始状态那样直接设定。我的做法是先把 Q 映射回原始状态空间提升空间中的 Q 矩阵取为 Φ^T Q_x Φ相当于把对原始状态的惩罚投影到提升空间。这样设计出来的控制权重物理意义清楚调试也直观。R 则直接对四个控制通道设权重初始值取单位矩阵然后微调。4.2 引入积分项实现轨迹跟踪单纯的状态反馈 LQR 只能做调节没法实现对参考轨迹的跟踪。要跟踪轨迹最直接的办法是在提升空间中引入误差积分项。定义参考提升状态 z_ref误差 e z - z_ref。在增广状态中加入误差积分 z_i ∫e dt扩展后的状态维度变成 53 或更高如果多个通道分开积分会更高。扩展后的系统矩阵写成A_aug [K, zeros(N, Ni); -C, zeros(Ni, Ni)]; B_aug [B; zeros(Ni, m)];其中 C 是输出选择矩阵选择需要积分控制的状态跟踪误差。Ni 是积分状态数量。然后对增广系统重新设计 LQR。积分增益的作用是消除模型误差和外部扰动带来的稳态误差这一点我实测下来非常关键不加积分项姿态跟踪会有 2 到 3 度的常值偏差加了之后偏差降到 0.2 度以内。控制率变成 u -K1 z - K2 ∫e dt。注意这里的 z 是实时从状态 x 通过字典函数计算出来的所以控制器内部还需要一个字典计算模块实时把当前量测状态映射到提升空间。这部分代码要写得高效因为每个控制周期都要执行一次字典计算。4.3 控制器效果对比与调参要点我用同一套四旋翼模型和同一组工况跑三个控制器的对比传统的悬停点线性化 LQR、基于 Koopman-EDMD 模型的 LQR、以及带积分项的 Koopman-LQR 轨迹跟踪。测试工况包括大幅俯仰机动、圆形轨迹跟踪和抗风扰动。结果是Koopman-LQR 在机动幅度达到 ±25° 时姿态跟踪误差只有传统线性化 LQR 的三分之一左右。圆形轨迹跟踪时位置误差 R1m 的圆上Koopman-LQR 的最大跟偏约 0.12 m传统线性化 LQR 约 0.35 m。差距的原因就是 Koopman 模型在整个机动包络内提供了更准确的预测LQR 反馈增益不再是为单一工作点“量身定做”的。调参上我建议按“先大机动性能、再稳态精度”的顺序来。先把 Q_x 设大、R 设小让系统跟得紧看是否出现高频抖动如果抖了就加大 R 中对应通道的权重。四旋翼的偏航通道响应比横滚、俯仰慢相应 R 的权重要设得大一点否则控制器会过度激进。积分项的增益不要一开始就调大积分饱和会导致大机动后长时间振荡。我在实际调试中给积分项加了一个限幅效果立竿见影。5. Matlab 实现要点与代码框架5.1 工程文件结构Matlab 工程虽然不需要像大型软件那样做精细模块划分但合理的文件组织能让你在修改参数或换数据集时省下大量时间。我的项目文件结构如下params.m物理参数与控制器参数统一配置脚本drone_dynamics.m四旋翼非线性动力学方程函数data_generation.m生成激励信号并采集训练数据dict_func.m字典提升函数计算函数edmd_training.mEDMD 辨识主脚本输出 K、B 矩阵model_validation.m多步预测与 VAF 指标计算lqr_design.m增广状态 LQR 设计simulation_closed_loop.m闭环仿真主程序这样拆分的核心价值是隔离。比如你想换一组字典只需要改 dict_func.m其他脚本不用动。想换一组激励改动 data_generation.m 即可。我在最初把所有逻辑写在一个脚本里结果调参时每次都得从头跑遇到 bug 排查也极度痛苦。拆分之后每个环节可以独立调试效率提升非常多。5.2 训练与仿真关键代码EDMD 训练核心代码前面已经展示了几个关键行这里再补充闭环仿真的核心结构% 主循环 for k 1:N_steps % 当前状态 - 提升状态 z dict_func(x_current); % 误差积分 err_int err_int (z_ref - z) * dt; % 控制律 u -K_lqr * [z; err_int] u_ff; % 系统动力学一步积分 x_next rk4_step(drone_dynamics, x_current, u, dt); end这里用了 RK4 积分器做系统推进比直接调 ode45 在循环里跑要快得多。控制周期是 0.02 s和仿真积分步长一致保证控制器与系统同步。仿真中还有一个关键点是控制输入限幅。四旋翼每个电机转速有上下限对应总推力有限制。控制器输出的期望推力如果超过限幅必须做饱和处理。不处理的话LQR 在大误差状态下会输出离谱的控制指令仿真结果直接发散。我在控制输出后加了一个 saturate 操作实测非常关键。由于 EDMD 训练涉及大量矩阵乘法数据量上来后 for 循环速度会拖后腿。我在数据生成和字典计算阶段都做了向量化处理一次算完整个数据集的字典矩阵比逐条循环快了一个数量级。如果你的数据规模更大还可以考虑用 tall array 或并行池但小微场景下没必要。6. 常见问题与排查技巧实录6.1 高频问题速查表现象原因排查与解决方法开环预测模型快速发散K 矩阵特征值幅值大于 1 且振型落在不稳定区域字典覆盖不足检查字典是否包含充分非线性项增加数据覆盖范围加正则化必要时对 K 做稳定化修正单步预测精度高多步预测精确度很差数据激励不足系统某些模态未被激发增加扫频段与幅值补充多组不同工况数据Koopman 矩阵条件数巨大字典维度过高或基函数相关性太强删减高次项加入岭正则化检查字典是否有线性相关列闭环仿真控制指令剧烈振荡Q/R 权重不合适或 LQR 参考状态计算有误积分项过大加大 R 对应通道权重先关积分项调纯状态反馈检查 z_ref 是否计算正确跟踪稳态误差始终无法消除积分项未加或积分饱和加入误差积分状态并设置积分限幅字典里漏了原始状态映射控制器输出乱跳无法从提升状态还原真实状态在 dict_func.m 中强制保留恒等映射项训练数据和验证数据差异过大导致建模异常激励信号不一致或数据分段拼接时系统状态不连续拼接数据时保证每段初始状态连续或重新生成统一的合成轨迹这七条是我实际复现过程中碰到最频繁的问题。其中“单步精度高、多步发散”这个坑最隐蔽因为初期验证很容易只看单步预测误差模型看起来很好一上闭环就崩。我建议从一开始就坚持做多步预测验证哪怕先只看 1 秒内的趋势。6.2 几个值得长期保留的经验第一数据比算法更重要。EDMD 的数学原理不复杂复杂在怎么让数据把系统的真实动态完整交出来。我花了大量时间在信号设计和仿真参数调整上最终它对模型质量的提升比换更复杂的字典都明显。第二字典的维度不是拍脑袋定的。我摸索出一个实用套路先用纯二次多项式字典跑通全流程确认闭环没问题再逐步加三角函数、高次项每次加完都重新验证模型稳定性和控制性能。这样能清楚定位每一项对模型的贡献比一次性上一个大字典然后出问题无从下手要高效得多。第三Koopman-EDMD 适合中等维度的非线性系统四旋翼正好是这个量级。状态量 12 个字典 50 维左右计算负担完全可控。如果状态量上百个EDMD 的性能会明显下降这时候可能需要深层字典或神经网络 Koopman 这类更进阶的解法。第四Matlab 里求 K 矩阵我用的是反斜杠\而不是显式的求逆。Matlab 的反斜杠会根据矩阵结构自动选择求解策略数值稳定性和速度都更好。写代码时养成这个习惯矩阵大了以后差距很明显。按我个人的经验Koopman-EDMD 这条路最妙的地方在于它给了控制工程师一种“带着数据工具箱去做控制”的思维模式不再纠结于非线性项怎么消掉而是让数据自己去“发现”一个线性化的坐标系统。这篇文章里所有代码和参数都是在真实工程逻辑下反复调出来的你顺着流程走一遍应该能体会到从数据到模型、再到控制器的完整闭环。后续如果你想继续扩展还可以试试闭环辨识、用 MPC 替换 LQR或者把 Koopman 模型用于故障检测方向很多但核心链路就是这套打牢了比什么都强。本文还有配套的精品资源点击获取
返回列表